Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit776231d

Browse files
authored
fix(coderd): add blocking GetProvisionerJobByIDWithLock for workspace build cancellation (#19737)
Closescoder/internal#885Adds a new database method GetProvisionerJobByIDWithLock that uses FORUPDATE without SKIP LOCKED to fix workspace build cancellation returning500 errors when jobs are locked.
1 parent065c7c3 commit776231d

File tree

9 files changed

+109
-2
lines changed

9 files changed

+109
-2
lines changed

‎coderd/database/dbauthz/dbauthz.go‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2610,6 +2610,18 @@ func (q *querier) GetProvisionerJobByIDForUpdate(ctx context.Context, id uuid.UU
26102610
returnjob,nil
26112611
}
26122612

2613+
func (q*querier)GetProvisionerJobByIDWithLock(ctx context.Context,id uuid.UUID) (database.ProvisionerJob,error) {
2614+
job,err:=q.db.GetProvisionerJobByIDWithLock(ctx,id)
2615+
iferr!=nil {
2616+
return database.ProvisionerJob{},err
2617+
}
2618+
2619+
iferr:=q.authorizeProvisionerJob(ctx,job);err!=nil {
2620+
return database.ProvisionerJob{},err
2621+
}
2622+
returnjob,nil
2623+
}
2624+
26132625
func (q*querier)GetProvisionerJobTimingsByJobID(ctx context.Context,jobID uuid.UUID) ([]database.ProvisionerJobTiming,error) {
26142626
_,err:=q.GetProvisionerJobByID(ctx,jobID)
26152627
iferr!=nil {

‎coderd/database/dbauthz/dbauthz_test.go‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,24 @@ func (s *MethodTestSuite) TestProvisionerJob() {
664664
dbm.EXPECT().GetProvisionerLogsAfterID(gomock.Any(),arg).Return([]database.ProvisionerJobLog{},nil).AnyTimes()
665665
check.Args(arg).Asserts(ws,policy.ActionRead).Returns([]database.ProvisionerJobLog{})
666666
}))
667+
s.Run("Build/GetProvisionerJobByIDWithLock",s.Mocked(func(dbm*dbmock.MockStore,faker*gofakeit.Faker,check*expects) {
668+
ws:=testutil.Fake(s.T(),faker, database.Workspace{})
669+
j:=testutil.Fake(s.T(),faker, database.ProvisionerJob{Type:database.ProvisionerJobTypeWorkspaceBuild})
670+
build:=testutil.Fake(s.T(),faker, database.WorkspaceBuild{WorkspaceID:ws.ID,JobID:j.ID})
671+
dbm.EXPECT().GetProvisionerJobByIDWithLock(gomock.Any(),j.ID).Return(j,nil).AnyTimes()
672+
dbm.EXPECT().GetWorkspaceBuildByJobID(gomock.Any(),j.ID).Return(build,nil).AnyTimes()
673+
dbm.EXPECT().GetWorkspaceByID(gomock.Any(),build.WorkspaceID).Return(ws,nil).AnyTimes()
674+
check.Args(j.ID).Asserts(ws,policy.ActionRead).Returns(j)
675+
}))
676+
s.Run("TemplateVersion/GetProvisionerJobByIDWithLock",s.Mocked(func(dbm*dbmock.MockStore,faker*gofakeit.Faker,check*expects) {
677+
tpl:=testutil.Fake(s.T(),faker, database.Template{})
678+
j:=testutil.Fake(s.T(),faker, database.ProvisionerJob{Type:database.ProvisionerJobTypeTemplateVersionImport})
679+
v:=testutil.Fake(s.T(),faker, database.TemplateVersion{JobID:j.ID,TemplateID: uuid.NullUUID{UUID:tpl.ID,Valid:true}})
680+
dbm.EXPECT().GetProvisionerJobByIDWithLock(gomock.Any(),j.ID).Return(j,nil).AnyTimes()
681+
dbm.EXPECT().GetTemplateVersionByJobID(gomock.Any(),j.ID).Return(v,nil).AnyTimes()
682+
dbm.EXPECT().GetTemplateByID(gomock.Any(),tpl.ID).Return(tpl,nil).AnyTimes()
683+
check.Args(j.ID).Asserts(v.RBACObject(tpl),policy.ActionRead).Returns(j)
684+
}))
667685
}
668686

669687
func (s*MethodTestSuite)TestLicense() {

‎coderd/database/dbmetrics/querymetrics.go‎

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dbmock/dbmock.go‎

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/querier.go‎

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries.sql.go‎

Lines changed: 41 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries/provisionerjobs.sql‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ WHERE
5555
FORUPDATE
5656
SKIP LOCKED;
5757

58+
-- name: GetProvisionerJobByIDWithLock :one
59+
-- Gets a provisioner job by ID with exclusive lock.
60+
-- Blocks until the row is available for update.
61+
SELECT
62+
*
63+
FROM
64+
provisioner_jobs
65+
WHERE
66+
id= $1
67+
FORUPDATE;
68+
5869
-- name: GetProvisionerJobsByIDs :many
5970
SELECT
6071
*

‎coderd/workspacebuilds.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ func (api *API) patchCancelWorkspaceBuild(rw http.ResponseWriter, r *http.Reques
663663
returnxerrors.New("user is not allowed to cancel workspace builds")
664664
}
665665

666-
job,err:=db.GetProvisionerJobByIDForUpdate(ctx,workspaceBuild.JobID)
666+
job,err:=db.GetProvisionerJobByIDWithLock(ctx,workspaceBuild.JobID)
667667
iferr!=nil {
668668
code=http.StatusInternalServerError
669669
resp.Message="Internal error fetching provisioner job."

‎coderd/workspacebuilds_test.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ func TestPatchCancelWorkspaceBuild(t *testing.T) {
580580

581581
require.Eventually(t,func()bool {
582582
err:=client.CancelWorkspaceBuild(ctx,build.ID, codersdk.CancelWorkspaceBuildParams{})
583-
returnassert.NoError(t,err)
583+
returnerr==nil
584584
},testutil.WaitShort,testutil.IntervalMedium)
585585

586586
require.Eventually(t,func()bool {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp