scouting: Allow background tasks to cancel themselves
I have a use case where I want a background task to run until it
succeeds. Once it succeeds, it should stop. This patch lets me do that
by adding a `StopFromWithinTask()` function.
Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: I06a504a9528d1b88937abcec5688021d621ff921
diff --git a/scouting/background_task/background_task.go b/scouting/background_task/background_task.go
index 6980042..3d7d29a 100644
--- a/scouting/background_task/background_task.go
+++ b/scouting/background_task/background_task.go
@@ -43,6 +43,12 @@
}()
}
+// Stops the background task from within the background task. The Stop()
+// function still needs to be called from outside the task.
+func (task *backgroundTask) StopFromWithinTask() {
+ task.stopRequested <- true
+}
+
func (task *backgroundTask) Stop() {
task.stopRequested <- true
task.ticker.Stop()
diff --git a/scouting/background_task/background_task_test.go b/scouting/background_task/background_task_test.go
index 5326d14..d4fb7ee 100644
--- a/scouting/background_task/background_task_test.go
+++ b/scouting/background_task/background_task_test.go
@@ -19,3 +19,32 @@
time.Sleep(100 * time.Millisecond)
}
}
+
+func TestSelfCancellation(t *testing.T) {
+ task := New(100 * time.Millisecond)
+
+ done := false
+ counter := 0
+ task.Start(func() {
+ counter += 1
+
+ if done {
+ t.Fatal("callback should not be called after cancellation")
+ }
+
+ if counter == 10 {
+ task.StopFromWithinTask()
+ done = true
+ }
+ })
+
+ // Block until the background task has cancelled itself.
+ for !done {
+ time.Sleep(100 * time.Millisecond)
+ }
+
+ // Then sleep for a little longer to make sure that the task won't
+ // invoke the t.Fatal().
+ time.Sleep(time.Second)
+ task.Stop()
+}