Skip to content

Commit 9185c06

Browse files
committed
chore: fix buffered provisioner job logs close flake
See https://github.com/coder/coder/actions/runs/4357599919/jobs/7617111287
1 parent f8494d2 commit 9185c06

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

coderd/provisionerjobs.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ func (api *API) provisionerJobLogs(rw http.ResponseWriter, r *http.Request, job
5050
// between the end of our query and the start of the subscription. We might get duplicates, so we'll keep track
5151
// of processed IDs.
5252
var bufferedLogs <-chan database.ProvisionerJobLog
53+
var bufferedLogClosed chan struct{}
5354
if follow {
54-
bl, closeFollow, err := api.followLogs(actor, job.ID)
55+
bl, closed, closeFollow, err := api.followLogs(actor, job.ID)
5556
if err != nil {
5657
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
5758
Message: "Internal error watching provisioner logs.",
@@ -61,6 +62,7 @@ func (api *API) provisionerJobLogs(rw http.ResponseWriter, r *http.Request, job
6162
}
6263
defer closeFollow()
6364
bufferedLogs = bl
65+
bufferedLogClosed = closed
6466

6567
// Next query the job itself to see if it is complete. If so, the historical query to the database will return
6668
// the full set of logs. It's a little sad to have to query the job again, given that our caller definitely
@@ -188,6 +190,12 @@ func (api *API) provisionerJobLogs(rw http.ResponseWriter, r *http.Request, job
188190
return
189191
}
190192
}
193+
// This must come after the buffered logs check above, because
194+
// it's important that all buffered logs are flushed before we
195+
// close the connection!
196+
case <-bufferedLogClosed:
197+
logger.Debug(context.Background(), "done with buffered logs")
198+
return
191199
}
192200
}
193201
}
@@ -369,7 +377,7 @@ type provisionerJobLogsMessage struct {
369377
EndOfLogs bool `json:"end_of_logs,omitempty"`
370378
}
371379

372-
func (api *API) followLogs(actor rbac.Subject, jobID uuid.UUID) (<-chan database.ProvisionerJobLog, func(), error) {
380+
func (api *API) followLogs(actor rbac.Subject, jobID uuid.UUID) (<-chan database.ProvisionerJobLog, chan struct{}, func(), error) {
373381
logger := api.Logger.With(slog.F("job_id", jobID))
374382

375383
var (
@@ -447,7 +455,7 @@ func (api *API) followLogs(actor rbac.Subject, jobID uuid.UUID) (<-chan database
447455
},
448456
)
449457
if err != nil {
450-
return nil, nil, err
458+
return nil, nil, nil, err
451459
}
452-
return bufferedLogs, closeSubscribe, nil
460+
return bufferedLogs, closed, closeSubscribe, nil
453461
}

0 commit comments

Comments
 (0)