util/eventbus: add a Done method to the Monitor type (#17263)

Some systems need to tell whether the monitored goroutine has finished
alongside other channel operations (notably in this case the relay server, but
there seem likely to be others similarly situated).

Updates #15160

Change-Id: I5f0f3fae827b07f9b7102a3b08f60cda9737fe28
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This commit is contained in:
M. J. Fromberger
2025-09-24 09:14:41 -07:00
committed by GitHub
parent b3e9a128af
commit df747f1c1b
2 changed files with 38 additions and 3 deletions
+25 -2
View File
@@ -236,6 +236,17 @@ func TestMonitor(t *testing.T) {
}
})
t.Run("ZeroDone", func(t *testing.T) {
var zero eventbus.Monitor
select {
case <-zero.Done():
// OK
case <-time.After(time.Second):
t.Fatal("timeout waiting for zero monitor to be done")
}
})
t.Run("ZeroClose", func(t *testing.T) {
var zero eventbus.Monitor
@@ -276,7 +287,13 @@ func TestMonitor(t *testing.T) {
// While the goroutine is running, Wait does not complete.
select {
case <-done:
t.Error("monitor is ready before its goroutine is finished")
t.Error("monitor is ready before its goroutine is finished (Wait)")
default:
// OK
}
select {
case <-m.Done():
t.Error("monitor is ready before its goroutine is finished (Done)")
default:
// OK
}
@@ -286,7 +303,13 @@ func TestMonitor(t *testing.T) {
case <-done:
// OK
case <-time.After(time.Second):
t.Fatal("timeout waiting for monitor to complete")
t.Fatal("timeout waiting for monitor to complete (Wait)")
}
select {
case <-m.Done():
// OK
case <-time.After(time.Second):
t.Fatal("timeout waiting for monitor to complete (Done)")
}
}
}