diff --git a/worker/worker.go b/worker/worker.go index e06a469..58790f0 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -6,6 +6,7 @@ import ( "time" log "github.com/sirupsen/logrus" + "github.com/trustwallet/go-libs/metrics" ) @@ -62,6 +63,14 @@ func (w *worker) Name() string { } func (w *worker) Start(ctx context.Context, wg *sync.WaitGroup) { + if w.options.Interval == -1 { + w.hold(ctx, wg) + return + } + w.start(ctx, wg) +} + +func (w *worker) start(ctx context.Context, wg *sync.WaitGroup) { wg.Add(1) go func() { defer wg.Done() @@ -80,7 +89,7 @@ func (w *worker) Start(ctx context.Context, wg *sync.WaitGroup) { if w.stopFn != nil { log.WithField("worker", w.name).Info("stopping...") if err := w.stopFn(); err != nil { - log.WithField("worker", w.name).WithError(err).Warn("error ocurred while stopping the worker") + log.WithField("worker", w.name).WithError(err).Warn("error occurred while stopping the worker") } } log.WithField("worker", w.name).Info("stopped") @@ -101,6 +110,27 @@ func (w *worker) Start(ctx context.Context, wg *sync.WaitGroup) { }() } +func (w *worker) hold(ctx context.Context, wg *sync.WaitGroup) { + wg.Add(1) + + logger := log.WithField("worker", w.name) + logger.Info("worker started, but won't be executed") + + go func() { + defer wg.Done() + + _ = <-ctx.Done() + + if w.stopFn != nil { + logger.Info("stopping...") + if err := w.stopFn(); err != nil { + logger.WithError(err).Warn("error occurred while stopping the worker") + } + } + logger.Info("stopped") + }() +} + func (w *worker) invoke() { metric := w.options.PerformanceMetric if metric == nil { diff --git a/worker/worker_test.go b/worker/worker_test.go index 2d74dc7..5ab1628 100644 --- a/worker/worker_test.go +++ b/worker/worker_test.go @@ -6,8 +6,9 @@ import ( "testing" "time" - "github.com/trustwallet/go-libs/worker" "gotest.tools/assert" + + "github.com/trustwallet/go-libs/worker" ) func TestWorkerWithDefaultOptions(t *testing.T) { @@ -18,15 +19,14 @@ func TestWorkerWithDefaultOptions(t *testing.T) { }).WithOptions(worker.DefaultWorkerOptions(100 * time.Millisecond)).Build() wg := &sync.WaitGroup{} - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithTimeout(context.Background(), 350*time.Millisecond) + defer cancel() worker.Start(ctx, wg) - time.Sleep(350 * time.Millisecond) - cancel() wg.Wait() - assert.Equal(t, 4, counter, "Should execute 4 times - 1st immidietly, and 3 after") + assert.Equal(t, 4, counter, "Should execute 4 times - 1st immediately, and 3 after") } func TestWorkerStartsConsequently(t *testing.T) { @@ -41,13 +41,33 @@ func TestWorkerStartsConsequently(t *testing.T) { }).WithOptions(options).Build() wg := &sync.WaitGroup{} - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithTimeout(context.Background(), 350*time.Millisecond) + defer cancel() + + worker.Start(ctx, wg) + + wg.Wait() + + assert.Equal(t, 3, counter, "Should execute 3 times - 1st immediately, and 2 after with delay between runs") +} + +func TestWorkerStartsWithoutExecution(t *testing.T) { + counter := 0 + options := worker.DefaultWorkerOptions(100 * time.Millisecond) + options.Interval = -1 + + worker := worker.NewWorkerBuilder("test", func() error { + counter++ + return nil + }).WithOptions(options).Build() + + wg := &sync.WaitGroup{} + ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) + defer cancel() worker.Start(ctx, wg) - time.Sleep(350 * time.Millisecond) - cancel() wg.Wait() - assert.Equal(t, 3, counter, "Should execute 3 times - 1st immidietly, and 2 after with delay between runs") + assert.Equal(t, 0, counter, "Should never be executed") }