Skip to content

Commit 078926f

Browse files
authored
fix: select on context to avoid leak in logFollower (#7792)
Signed-off-by: Spike Curtis <spike@coder.com>
1 parent 004ad17 commit 078926f

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

coderd/provisionerjobs.go

+17-3
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,9 @@ func newLogFollower(
300300
}
301301

302302
func (f *logFollower) follow() {
303+
var cancel context.CancelFunc
304+
f.ctx, cancel = context.WithCancel(f.ctx)
305+
defer cancel()
303306
// note that we only need to subscribe to updates if the job is not yet
304307
// complete.
305308
if !f.complete {
@@ -405,17 +408,28 @@ func (f *logFollower) follow() {
405408
}
406409

407410
func (f *logFollower) listener(_ context.Context, message []byte, err error) {
411+
// in this function we always pair writes to channels with a select on the context
412+
// otherwise we could block a goroutine if the follow() method exits.
408413
if err != nil {
409-
f.errors <- err
414+
select {
415+
case <-f.ctx.Done():
416+
case f.errors <- err:
417+
}
410418
return
411419
}
412420
var n provisionersdk.ProvisionerJobLogsNotifyMessage
413421
err = json.Unmarshal(message, &n)
414422
if err != nil {
415-
f.errors <- err
423+
select {
424+
case <-f.ctx.Done():
425+
case f.errors <- err:
426+
}
416427
return
417428
}
418-
f.notifications <- n
429+
select {
430+
case <-f.ctx.Done():
431+
case f.notifications <- n:
432+
}
419433
}
420434

421435
// query fetches the latest job logs from the database and writes them to the

0 commit comments

Comments
 (0)