From 740b824ac2ebdf64c11acd585f6e5a896f8241d5 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Fri, 28 Nov 2014 15:14:49 -0500 Subject: [PATCH] Add a util.Forever variant that ends on a stop channel --- pkg/util/util.go | 12 ++++++++++++ pkg/util/util_test.go | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/pkg/util/util.go b/pkg/util/util.go index 7baffc31af7..3216146b90a 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -51,7 +51,19 @@ func HandleCrash() { // Forever loops forever running f every d. Catches any panics, and keeps going. func Forever(f func(), period time.Duration) { + Until(f, period, nil) +} + +// Until loops until stop channel is closed, running f every d. +// Catches any panics, and keeps going. f may not be invoked if +// stop channel is already closed. +func Until(f func(), period time.Duration, stopCh <-chan struct{}) { for { + select { + case <-stopCh: + return + default: + } func() { defer HandleCrash() f() diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index 2c253c33a27..48bc07e2e0f 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -24,6 +24,26 @@ import ( "gopkg.in/v1/yaml" ) +func TestUntil(t *testing.T) { + ch := make(chan struct{}) + close(ch) + Until(func() { + t.Fatal("should not have been invoked") + }, 0, ch) + + ch = make(chan struct{}) + called := make(chan struct{}) + go func() { + Until(func() { + called <- struct{}{} + }, 0, ch) + close(called) + }() + <-called + close(ch) + <-called +} + func TestHandleCrash(t *testing.T) { count := 0 expect := 10