fix: handle scenario where provisionerdserver deletes task before coderd (#21220)

This commit is contained in:
Danielle Maywood
2025-12-11 13:04:13 +00:00
committed by GitHub
parent 84b7a0364d
commit c3224b793e
2 changed files with 14 additions and 1 deletions
+7 -1
View File
@@ -2,6 +2,8 @@ package coderd
import (
"context"
"database/sql"
"errors"
"fmt"
"net"
"net/http"
@@ -622,11 +624,15 @@ func (api *API) taskDelete(rw http.ResponseWriter, r *http.Request) {
}
}
// As an implementation detail of the workspace build transition, we also delete
// the associated task. This means that we have a race between provisionerdserver
// and here with deleting the task. In a real world scenario we'll never lose the
// race but we should still handle it anyways.
_, err := api.Database.DeleteTask(ctx, database.DeleteTaskParams{
ID: task.ID,
DeletedAt: dbtime.Time(now),
})
if err != nil {
if err != nil && !errors.Is(err, sql.ErrNoRows) {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Failed to delete task",
Detail: err.Error(),
@@ -2267,6 +2267,13 @@ func (s *server) completeWorkspaceBuildJob(ctx context.Context, job database.Pro
if err != nil {
return xerrors.Errorf("update workspace deleted: %w", err)
}
// A user might delete their task workspace directly, instead of
// deleting the task. To avoid leaving the Task in a scenario where
// it has no workspace, we also attempt to delete the task.
//
// Deleting the task may fail if it has already been deleted as part
// of the typical task deletion workflow, so we explicitly allow that.
if workspace.TaskID.Valid {
if _, err := db.DeleteTask(ctx, database.DeleteTaskParams{
ID: workspace.TaskID.UUID,