diff --git a/utils.go b/utils.go index aa6b0bd4..48f2c4a1 100644 --- a/utils.go +++ b/utils.go @@ -23,17 +23,27 @@ var eventError = func(e *Event) (err error) { return } -// Every triggers f every t time until the end of days. It does not wait for the -// previous execution of f to finish before it fires the next f. -func Every(t time.Duration, f func()) { +// Every triggers f every t time until the end of days, or when a +// bool value is sent to the channel returned by the Every function. +// It does not wait for the previous execution of f to finish before +// it fires the next f. +func Every(t time.Duration, f func()) chan bool { + done := make(chan bool) c := time.Tick(t) go func() { for { - <-c - go f() + select { + case <-done: + break + default: + <-c + go f() + } } }() + + return done } // After triggers f after t duration. diff --git a/utils_test.go b/utils_test.go index 7d702e1d..212fe500 100644 --- a/utils_test.go +++ b/utils_test.go @@ -24,6 +24,18 @@ func TestEvery(t *testing.T) { } } +func TestEveryWhenDone(t *testing.T) { + i := 0 + done := Every(20*time.Millisecond, func() { + i++ + }) + <-time.After(20 * time.Millisecond) + done <- true + if i > 1 { + t.Error("Test should have stopped after 20ms") + } +} + func TestAfter(t *testing.T) { i := 0 After(1*time.Millisecond, func() {