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

feat: cancel pending prebuilds from non-active template versions#20387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
ssncferreira merged 23 commits intomainfromssncferreira/feat-cancel-pending-prebuilds
Oct 24, 2025

Conversation

@ssncferreira
Copy link
Contributor

@ssncferreirassncferreira commentedOct 20, 2025
edited
Loading

Description

This PR introduces an optimization to automatically cancel pending prebuild-related jobs from non-active template versions in the reconciliation loop.

Problem

Currently, when a template is configured with more prebuild instances than available provisioners, the provisioner queue can become flooded with pending prebuild jobs. This issue is worsened when provisioning/deprovisioning operations take a long time.

When the prebuild reconciliation loop generates jobs faster than provisioners can process them, pending jobs accumulate in the queue. Since prebuilt workspaces should always run the latest active template version, pending prebuild jobs from non-active versions become obsolete once a new version is promoted.

Solution

The reconciliation loop cancels pending prebuild-related jobs from non-active template versions that match the following criteria:

  • Build number: 1 (initial build created by the reconciliation loop)
  • Job status:pending
  • Not yet picked up by a provisioner (worker_id isNULL)
  • Owned by the prebuilds system user
  • Workspace transition:start

This prevents the queue from being cluttered with stale prebuild jobs that would provision workspaces on an outdated template version that would consequently need to be deprovisioned.

Changes

  • Added new SQL queryCountPendingNonActivePrebuilds to identify presets with pending jobs from non-active versions
  • Added new SQL queryUpdatePrebuildProvisionerJobWithCancel to cancel jobs for a specific preset
  • New reconciliation action typeActionTypeCancelPending handles the cancellation logic
  • Cancellation is non-blocking: failures to cancel prebuild jobs are logged as errors and don't prevent other reconciliation actions

Follow-up PR

Canceling pending prebuild jobs leaves workspaces in a Canceled state. While no Terraform resources need to be destroyed (since jobs were canceled before provisioning started), these database records should still be cleaned up. This will be addressed in a follow-up PR.

Closes:#20242

@ssncferreirassncferreiraforce-pushed thessncferreira/feat-cancel-pending-prebuilds branch 6 times, most recently fromf1a8e32 to9cfb23aCompareOctober 21, 2025 11:58
@ssncferreirassncferreiraforce-pushed thessncferreira/feat-cancel-pending-prebuilds branch from9cfb23a to29cc88eCompareOctober 21, 2025 17:28
@ssncferreirassncferreiraforce-pushed thessncferreira/feat-cancel-pending-prebuilds branch from73cf135 to51fa3efCompareOctober 21, 2025 18:04
@ssncferreirassncferreira marked this pull request as ready for reviewOctober 21, 2025 19:04
Copy link
Member

@johnstcnjohnstcn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Mostly LGTM, but I'm not 100% convinced about the row locking?

func (q*querier)UpdatePrebuildProvisionerJobWithCancel(ctx context.Context,arg database.UpdatePrebuildProvisionerJobWithCancelParams) ([]uuid.UUID,error) {
// This is a system-only operation for canceling pending prebuild-related jobs
// when a new template version is promoted.
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceSystem);err!=nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

note(non-blocking): just want to noterbac.ResourceSystem usage here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

If we givesubjectPrebuildsOrchestrator the ability to read/update provisioner jobs, we should be able to userbac.ResourceProvisionerJob here.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yeah, permissions are a bit tricky here.

There is aResourceProvisionerJobs that we could use here, but that would mean that all users with this permissions would be abel to execute it.

The way it is done forUpdateProvisionerJobWithCancelByID, for instance, is to check theUpdate permissions on the workspace. Since it is a prebuild, we could also do a
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourcePrebuiltWorkspace); err != nil { Maybe this one makes the most sense 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

That's not a bad approximation actually 👍

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Added therbac.ResourcePrebuiltWorkspace update check indcb6de1

@ssncferreirassncferreira removed the request for review fromSasSwartOctober 22, 2025 10:25
@ssncferreira
Copy link
ContributorAuthor

Note: Moving this PR back to draft.

After internal discussion, we've decided to move the logic to cancel pending prebuilds to the prebuilds reconciliation loop rather than handling it in thepatchActiveTemplateVersion endpoint.

This PR will be updated to reflect these changes:

  • Prebuild cancellation logic will be moved to the reconciliation loop
  • Implementation for deleting cancelled prebuilds will be handled in a separate PR for simplicity

The PR will be marked ready for review once the new implementation is in place.

@ssncferreirassncferreira marked this pull request as draftOctober 22, 2025 10:58
@ssncferreirassncferreira marked this pull request as ready for reviewOctober 23, 2025 10:28
func (q*querier)UpdatePrebuildProvisionerJobWithCancel(ctx context.Context,arg database.UpdatePrebuildProvisionerJobWithCancelParams) ([]uuid.UUID,error) {
// This is a system-only operation for canceling pending prebuild-related jobs
// when a new template version is promoted.
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceSystem);err!=nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

If we givesubjectPrebuildsOrchestrator the ability to read/update provisioner jobs, we should be able to userbac.ResourceProvisionerJob here.

Comment on lines +300 to +301
-- Cancels all pending provisioner jobs for prebuilt workspaces on a specific preset from an
-- inactive template version.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

nit: This comment is slightly misleading, the query doesn't check that the preset relates to an inactive template version. It's currently the responsibility of the caller to verify that@preset_id is not related to the current active version ID.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

That is a good catch! I've updated the query to filter out active template versions:0497f8b

funcTestCancelPendingPrebuilds(t*testing.T) {
t.Parallel()

for_,tt:=range []struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

nit, non-blocking: Since these tests all boil down to "only these jobs should be canceled and nothing else", I think we could collapse this to a single test case with all of the "should not cancel" data in one. The rationale for this is twofold:

  1. It reduces the number of test databases we have to create
  2. It gives us better assurance that only the jobs we care about are being canceled in the presence of more antagonist data.

@ssncferreirassncferreira changed the titlefeat: cancel pending prebuilds on template publishfeat: cancel pending prebuilds from non-active template versionsOct 23, 2025
Copy link
Contributor

@SasSwartSasSwart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

One nit/question. Otherwise, looks good!

@ssncferreirassncferreira merged commitf6e86c6 intomainOct 24, 2025
30 checks passed
@ssncferreirassncferreira deleted the ssncferreira/feat-cancel-pending-prebuilds branchOctober 24, 2025 14:27
@github-actionsgithub-actionsbot locked and limited conversation to collaboratorsOct 24, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.

Reviewers

@DanielleMaywoodDanielleMaywoodDanielleMaywood left review comments

@johnstcnjohnstcnjohnstcn approved these changes

@SasSwartSasSwartSasSwart approved these changes

Assignees

@ssncferreirassncferreira

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Cancel pending prebuild-related jobs from previous version

5 participants

@ssncferreira@johnstcn@SasSwart@DanielleMaywood

[8]ページ先頭

©2009-2025 Movatter.jp