Skip to content

Commit 7d055d2

Browse files
committed
Cancel goroutine immediately on stop
Signed-off-by: Danny Kopping <danny@coder.com>
1 parent ff73789 commit 7d055d2

File tree

2 files changed

+11
-14
lines changed

2 files changed

+11
-14
lines changed

coderd/database/pubsub/latency.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ type LatencyMeasurer struct {
2323
// background measurement members
2424
collections atomic.Int64
2525
last atomic.Value
26-
asyncTick *time.Ticker
27-
stop chan struct{}
26+
asyncCancel context.CancelCauseFunc
2827
}
2928

3029
type LatencyMeasurement struct {
@@ -39,7 +38,6 @@ func NewLatencyMeasurer(logger slog.Logger) *LatencyMeasurer {
3938
return &LatencyMeasurer{
4039
channel: uuid.New(),
4140
logger: logger,
42-
stop: make(chan struct{}, 1),
4341
}
4442
}
4543

@@ -86,8 +84,11 @@ func (lm *LatencyMeasurer) Measure(ctx context.Context, p Pubsub) LatencyMeasure
8684
// MeasureAsync runs latency measurements asynchronously on a given interval.
8785
// This function is expected to be run in a goroutine and will exit when the context is canceled.
8886
func (lm *LatencyMeasurer) MeasureAsync(ctx context.Context, p Pubsub, interval time.Duration) {
89-
lm.asyncTick = time.NewTicker(interval)
90-
defer lm.asyncTick.Stop()
87+
tick := time.NewTicker(interval)
88+
defer tick.Stop()
89+
90+
ctx, cancel := context.WithCancelCause(ctx)
91+
lm.asyncCancel = cancel
9192

9293
for {
9394
// run immediately on first call, then sleep a tick before each invocation
@@ -101,14 +102,12 @@ func (lm *LatencyMeasurer) MeasureAsync(ctx context.Context, p Pubsub, interval
101102
lm.last.Store(&measure)
102103

103104
select {
104-
case <-lm.asyncTick.C:
105+
case <-tick.C:
105106
continue
106107

107108
// bail out if signaled
108-
case <-lm.stop:
109-
return
110109
case <-ctx.Done():
111-
lm.logger.Debug(ctx, "async measurement context canceled", slog.Error(ctx.Err()))
110+
lm.logger.Debug(ctx, "async measurement canceled", slog.Error(ctx.Err()))
112111
return
113112
}
114113
}
@@ -130,11 +129,9 @@ func (lm *LatencyMeasurer) MeasurementCount() int64 {
130129

131130
// Stop stops any background measurements.
132131
func (lm *LatencyMeasurer) Stop() {
133-
if lm.asyncTick == nil {
134-
return
132+
if lm.asyncCancel != nil {
133+
lm.asyncCancel(xerrors.New("stopped"))
135134
}
136-
lm.asyncTick.Stop()
137-
lm.stop <- struct{}{}
138135
}
139136

140137
func (lm *LatencyMeasurer) latencyChannelName() string {

coderd/database/pubsub/pubsub_linux_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ func TestMeasureLatency(t *testing.T) {
342342
ps, done := newPubsub()
343343
defer done()
344344

345-
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(-time.Minute))
345+
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(-time.Hour))
346346
defer cancel()
347347

348348
l := pubsub.NewLatencyMeasurer(logger).Measure(ctx, ps)

0 commit comments

Comments
 (0)