mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-05 00:45:29 +08:00
100 lines
2.0 KiB
Go
100 lines
2.0 KiB
Go
package account
|
|
|
|
import (
|
|
"context"
|
|
|
|
"ds2api/internal/config"
|
|
)
|
|
|
|
func (p *Pool) Acquire(target string, exclude map[string]bool) (config.Account, bool) {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
return p.acquireLocked(target, normalizeExclude(exclude))
|
|
}
|
|
|
|
func (p *Pool) AcquireWait(ctx context.Context, target string, exclude map[string]bool) (config.Account, bool) {
|
|
if ctx == nil {
|
|
ctx = context.Background()
|
|
}
|
|
exclude = normalizeExclude(exclude)
|
|
for {
|
|
if ctx.Err() != nil {
|
|
return config.Account{}, false
|
|
}
|
|
|
|
p.mu.Lock()
|
|
if acc, ok := p.acquireLocked(target, exclude); ok {
|
|
p.mu.Unlock()
|
|
return acc, true
|
|
}
|
|
if !p.canQueueLocked(target, exclude) {
|
|
p.mu.Unlock()
|
|
return config.Account{}, false
|
|
}
|
|
waiter := make(chan struct{})
|
|
p.waiters = append(p.waiters, waiter)
|
|
p.mu.Unlock()
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
p.mu.Lock()
|
|
p.removeWaiterLocked(waiter)
|
|
p.mu.Unlock()
|
|
return config.Account{}, false
|
|
case <-waiter:
|
|
}
|
|
}
|
|
}
|
|
|
|
func (p *Pool) acquireLocked(target string, exclude map[string]bool) (config.Account, bool) {
|
|
if target != "" {
|
|
if exclude[target] || !p.canAcquireIDLocked(target) {
|
|
return config.Account{}, false
|
|
}
|
|
acc, ok := p.store.FindAccount(target)
|
|
if !ok {
|
|
return config.Account{}, false
|
|
}
|
|
p.inUse[target]++
|
|
p.bumpQueue(target)
|
|
return acc, true
|
|
}
|
|
|
|
return p.tryAcquire(exclude)
|
|
}
|
|
|
|
func (p *Pool) tryAcquire(exclude map[string]bool) (config.Account, bool) {
|
|
for i := 0; i < len(p.queue); i++ {
|
|
id := p.queue[i]
|
|
if exclude[id] || !p.canAcquireIDLocked(id) {
|
|
continue
|
|
}
|
|
acc, ok := p.store.FindAccount(id)
|
|
if !ok {
|
|
continue
|
|
}
|
|
p.inUse[id]++
|
|
p.bumpQueue(id)
|
|
return acc, true
|
|
}
|
|
return config.Account{}, false
|
|
}
|
|
|
|
func (p *Pool) bumpQueue(accountID string) {
|
|
for i, id := range p.queue {
|
|
if id != accountID {
|
|
continue
|
|
}
|
|
p.queue = append(p.queue[:i], p.queue[i+1:]...)
|
|
p.queue = append(p.queue, accountID)
|
|
return
|
|
}
|
|
}
|
|
|
|
func normalizeExclude(exclude map[string]bool) map[string]bool {
|
|
if exclude == nil {
|
|
return map[string]bool{}
|
|
}
|
|
return exclude
|
|
}
|