proxy-pool/internal/domain/routing/sequential.go

62 lines
1.2 KiB
Go

package routing
import (
"fmt"
"sync"
)
type Sequential struct {
mu sync.RWMutex
upstreams []string
threshold int
current int
empty map[string]int
}
func NewSequential(upstreams []string, threshold int) (*Sequential, error) {
if len(upstreams) == 0 {
return nil, fmt.Errorf("sequential strategy requires at least one upstream")
}
if threshold <= 0 {
return nil, fmt.Errorf("sequential threshold must be greater than zero")
}
return &Sequential{
upstreams: append([]string(nil), upstreams...),
threshold: threshold,
empty: make(map[string]int, len(upstreams)),
}, nil
}
func (s *Sequential) Current() string {
s.mu.RLock()
defer s.mu.RUnlock()
return s.upstreams[s.current]
}
func (s *Sequential) ObserveEmpty(upstream string) bool {
s.mu.Lock()
defer s.mu.Unlock()
s.empty[upstream]++
if s.upstreams[s.current] != upstream || s.empty[upstream] < s.threshold {
return false
}
if s.current+1 >= len(s.upstreams) {
return false
}
s.current++
return true
}
func (s *Sequential) ObserveValid(upstream string) {
s.mu.Lock()
defer s.mu.Unlock()
s.empty[upstream] = 0
}
func (s *Sequential) EmptyCount(upstream string) int {
s.mu.RLock()
defer s.mu.RUnlock()
return s.empty[upstream]
}