package swarm import ( "context" "log" ) type defaultScheduler[T any] struct { worker chan chan T request chan T log *log.Logger calFn context.CancelFunc ctx context.Context } func newdefaultScheduler[T any](log *log.Logger) *defaultScheduler[T] { res := new(defaultScheduler[T]) res.worker = make(chan chan T) res.request = make(chan T) res.log = log res.ctx, res.calFn = context.WithCancel(context.TODO()) return res } func (s *defaultScheduler[T]) Submit(req T) { s.request <- req } func (s *defaultScheduler[T]) Done(worker chan T) { s.worker <- worker } func (s *defaultScheduler[T]) GenChannel() chan T { return make(chan T) } func (s *defaultScheduler[T]) Stop() { s.calFn() } func (s *defaultScheduler[T]) Run() error { var workers []chan T var requests []T for { var work chan T var req T if len(workers) > 0 && len(requests) > 0 { work = workers[0] req = requests[0] } select { case <-s.ctx.Done(): s.log.Printf("%sScheduler: %p down...", logPrefix, s) return s.ctx.Err() case w := <-s.worker: workers = append(workers, w) case r := <-s.request: requests = append(requests, r) case work <- req: workers = workers[1:] requests = requests[1:] } } }