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  }