github.com/wfusion/gofusion@v1.1.14/common/infra/asynq/forwarder.go (about) 1 // Copyright 2020 Kentaro Hibino. All rights reserved. 2 // Use of this source code is governed by a MIT license 3 // that can be found in the LICENSE file. 4 5 package asynq 6 7 import ( 8 "sync" 9 "time" 10 11 "github.com/wfusion/gofusion/common/infra/asynq/pkg/base" 12 "github.com/wfusion/gofusion/common/infra/asynq/pkg/log" 13 ) 14 15 // A forwarder is responsible for moving scheduled and retry tasks to pending state 16 // so that the tasks get processed by the workers. 17 type forwarder struct { 18 logger *log.Logger 19 broker base.Broker 20 21 // channel to communicate back to the long running "forwarder" goroutine. 22 done chan struct{} 23 24 // list of queue names to check and enqueue. 25 queues []string 26 27 // poll interval on average 28 avgInterval time.Duration 29 } 30 31 type forwarderParams struct { 32 logger *log.Logger 33 broker base.Broker 34 queues []string 35 interval time.Duration 36 } 37 38 func newForwarder(params forwarderParams) *forwarder { 39 return &forwarder{ 40 logger: params.logger, 41 broker: params.broker, 42 done: make(chan struct{}), 43 queues: params.queues, 44 avgInterval: params.interval, 45 } 46 } 47 48 func (f *forwarder) shutdown() { 49 f.logger.Debug("[Common] asynq forwarder shutting down...") 50 // Signal the forwarder goroutine to stop polling. 51 f.done <- struct{}{} 52 } 53 54 // start starts the "forwarder" goroutine. 55 func (f *forwarder) start(wg *sync.WaitGroup) { 56 wg.Add(1) 57 go func() { 58 defer wg.Done() 59 timer := time.NewTimer(f.avgInterval) 60 for { 61 select { 62 case <-f.done: 63 f.logger.Debug("[Common] asynq forwarder done") 64 return 65 case <-timer.C: 66 f.exec() 67 timer.Reset(f.avgInterval) 68 } 69 } 70 }() 71 } 72 73 func (f *forwarder) exec() { 74 if err := f.broker.ForwardIfReady(f.queues...); err != nil { 75 f.logger.Errorf("[Common] asynq failed to forward scheduled tasks: %v", err) 76 } 77 }