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] }