proxy-pool/internal/domain/upstream/pool.go

71 lines
1.4 KiB
Go

package upstream
import (
"time"
proxyDomain "proxy-pool/internal/domain/proxy"
)
type ProxyCapacity struct {
State proxyDomain.State
ExpiresAt time.Time
Max int64
Active int64
Reserved int64
}
type Inventory struct {
Proxies []ProxyCapacity
PendingExpected int
MaxSize int
}
func (i Inventory) AvailableSlots(now time.Time, safetyMargin time.Duration) int64 {
var available int64
deadline := now.Add(safetyMargin)
for _, candidate := range i.Proxies {
if candidate.State != proxyDomain.StateAvailable {
continue
}
if !candidate.ExpiresAt.IsZero() && !candidate.ExpiresAt.After(deadline) {
continue
}
slots := candidate.Max - candidate.Active - candidate.Reserved
if slots > 0 {
available += slots
}
}
return available
}
func (i Inventory) ManagedCount() int {
count := max(i.PendingExpected, 0)
for _, candidate := range i.Proxies {
if managedState(candidate.State) {
count++
}
}
return count
}
func (i Inventory) FetchAllowance(requested int) int {
if requested <= 0 || i.MaxSize <= 0 {
return 0
}
allowed := min(requested, max(i.MaxSize-i.ManagedCount(), 0))
return allowed
}
func managedState(state proxyDomain.State) bool {
switch state {
case proxyDomain.StateFetched,
proxyDomain.StateChecking,
proxyDomain.StateAvailable,
proxyDomain.StateSuspect,
proxyDomain.StateDraining:
return true
default:
return false
}
}