prebuilds

package
v2.22.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 15, 2025 License: AGPL-3.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoClaimablePrebuiltWorkspaces        = xerrors.New("no claimable prebuilt workspaces found")
	ErrAGPLDoesNotSupportPrebuiltWorkspaces = xerrors.New("prebuilt workspaces functionality is not supported under the AGPL license")
)
View Source
var SystemUserID = uuid.MustParse("c42fdf75-3097-471c-8c33-fb52454d81c0")

Functions

func GenerateName added in v2.22.0

func GenerateName() (string, error)

GenerateName generates a 20-byte prebuild name which should safe to use without truncation in most situations. UUIDs may be too long for a resource name in cloud providers (since this ID will be used in the prebuild's name).

We're generating a 9-byte suffix (72 bits of entropy): 1 - e^(-1e9^2 / (2 * 2^72)) = ~0.01% likelihood of collision in 1 billion IDs. See https://en.wikipedia.org/wiki/Birthday_attack.

Types

type ActionType added in v2.22.0

type ActionType int

ActionType represents the type of action needed to reconcile prebuilds.

const (
	// ActionTypeUndefined represents an uninitialized or invalid action type.
	ActionTypeUndefined ActionType = iota

	// ActionTypeCreate indicates that new prebuilds should be created.
	ActionTypeCreate

	// ActionTypeDelete indicates that existing prebuilds should be deleted.
	ActionTypeDelete

	// ActionTypeBackoff indicates that prebuild creation should be delayed.
	ActionTypeBackoff
)

type Claimer added in v2.22.0

type Claimer interface {
	Claim(ctx context.Context, userID uuid.UUID, name string, presetID uuid.UUID) (*uuid.UUID, error)
	Initiator() uuid.UUID
}
var DefaultClaimer Claimer = NoopClaimer{}

type GlobalSnapshot added in v2.22.0

type GlobalSnapshot struct {
	Presets             []database.GetTemplatePresetsWithPrebuildsRow
	RunningPrebuilds    []database.GetRunningPrebuiltWorkspacesRow
	PrebuildsInProgress []database.CountInProgressPrebuildsRow
	Backoffs            []database.GetPresetsBackoffRow
}

GlobalSnapshot represents a full point-in-time snapshot of state relating to prebuilds across all templates.

func NewGlobalSnapshot added in v2.22.0

func (GlobalSnapshot) FilterByPreset added in v2.22.0

func (s GlobalSnapshot) FilterByPreset(presetID uuid.UUID) (*PresetSnapshot, error)

type NoopClaimer added in v2.22.0

type NoopClaimer struct{}

func (NoopClaimer) Claim added in v2.22.0

func (NoopClaimer) Initiator added in v2.22.0

func (NoopClaimer) Initiator() uuid.UUID

type NoopReconciler added in v2.22.0

type NoopReconciler struct{}

func (NoopReconciler) CalculateActions added in v2.22.0

func (NoopReconciler) ReconcileAll added in v2.22.0

func (NoopReconciler) ReconcileAll(context.Context) error

func (NoopReconciler) ReconcilePreset added in v2.22.0

func (NoopReconciler) Run added in v2.22.0

func (NoopReconciler) SnapshotState added in v2.22.0

func (NoopReconciler) Stop added in v2.22.0

func (NoopReconciler) TrackResourceReplacement added in v2.22.0

func (NoopReconciler) TrackResourceReplacement(context.Context, uuid.UUID, uuid.UUID, []*sdkproto.ResourceReplacement)

type PresetSnapshot added in v2.22.0

PresetSnapshot is a filtered view of GlobalSnapshot focused on a single preset. It contains the raw data needed to calculate the current state of a preset's prebuilds, including running prebuilds, in-progress builds, and backoff information.

func (PresetSnapshot) CalculateActions added in v2.22.0

func (p PresetSnapshot) CalculateActions(clock quartz.Clock, backoffInterval time.Duration) (*ReconciliationActions, error)

CalculateActions determines what actions are needed to reconcile the current state with the desired state. The function: 1. First checks if a backoff period is needed (if previous builds failed) 2. If the preset is inactive (template version is not active), it will delete all running prebuilds 3. For active presets, it calculates the number of prebuilds to create or delete based on:

  • The desired number of instances
  • Currently running prebuilds
  • Prebuilds in transition states (starting/stopping/deleting)
  • Any extraneous prebuilds that need to be removed

The function returns a ReconciliationActions struct that will have exactly one action type set: - ActionTypeBackoff: Only BackoffUntil is set, indicating when to retry - ActionTypeCreate: Only Create is set, indicating how many prebuilds to create - ActionTypeDelete: Only DeleteIDs is set, containing IDs of prebuilds to delete

func (PresetSnapshot) CalculateState added in v2.22.0

func (p PresetSnapshot) CalculateState() *ReconciliationState

CalculateState computes the current state of prebuilds for a preset, including: - Actual: Number of currently running prebuilds - Desired: Number of prebuilds desired as defined in the preset - Eligible: Number of prebuilds that are ready to be claimed - Extraneous: Number of extra running prebuilds beyond the desired count - Starting/Stopping/Deleting: Counts of prebuilds in various transition states

The function takes into account whether the preset is active (using the active template version) and calculates appropriate counts based on the current state of running prebuilds and in-progress transitions. This state information is used to determine what reconciliation actions are needed to reach the desired state.

type PubsubWorkspaceClaimListener added in v2.22.0

type PubsubWorkspaceClaimListener struct {
	// contains filtered or unexported fields
}

func NewPubsubWorkspaceClaimListener added in v2.22.0

func NewPubsubWorkspaceClaimListener(ps pubsub.Pubsub, logger slog.Logger) *PubsubWorkspaceClaimListener

func (PubsubWorkspaceClaimListener) ListenForWorkspaceClaims added in v2.22.0

func (p PubsubWorkspaceClaimListener) ListenForWorkspaceClaims(ctx context.Context, workspaceID uuid.UUID, reinitEvents chan<- agentsdk.ReinitializationEvent) (func(), error)

ListenForWorkspaceClaims subscribes to a pubsub channel and sends any received events on the chan that it returns. pubsub.Pubsub does not communicate when its last callback has been called after it has been closed. As such the chan returned by this method is never closed. Call the returned cancel() function to close the subscription when it is no longer needed. cancel() will be called if ctx expires or is canceled.

type PubsubWorkspaceClaimPublisher added in v2.22.0

type PubsubWorkspaceClaimPublisher struct {
	// contains filtered or unexported fields
}

func NewPubsubWorkspaceClaimPublisher added in v2.22.0

func NewPubsubWorkspaceClaimPublisher(ps pubsub.Pubsub) *PubsubWorkspaceClaimPublisher

func (PubsubWorkspaceClaimPublisher) PublishWorkspaceClaim added in v2.22.0

func (p PubsubWorkspaceClaimPublisher) PublishWorkspaceClaim(claim agentsdk.ReinitializationEvent) error

type Reconciler added in v2.22.0

type Reconciler interface {
	StateSnapshotter

	// ReconcileAll orchestrates the reconciliation of all prebuilds across all templates.
	// It takes a global snapshot of the system state and then reconciles each preset
	// in parallel, creating or deleting prebuilds as needed to reach their desired states.
	ReconcileAll(ctx context.Context) error
}

type ReconciliationActions added in v2.22.0

type ReconciliationActions struct {
	// ActionType determines which field is set and what action should be taken
	ActionType ActionType

	// Create is set when ActionType is ActionTypeCreate and indicates the number of prebuilds to create
	Create int32

	// DeleteIDs is set when ActionType is ActionTypeDelete and contains the IDs of prebuilds to delete
	DeleteIDs []uuid.UUID

	// BackoffUntil is set when ActionType is ActionTypeBackoff and indicates when to retry creating prebuilds
	BackoffUntil time.Time
}

ReconciliationActions represents actions needed to reconcile the current state with the desired state. Based on ActionType, exactly one of Create, DeleteIDs, or BackoffUntil will be set.

func (*ReconciliationActions) IsNoop added in v2.22.0

func (ra *ReconciliationActions) IsNoop() bool

type ReconciliationOrchestrator added in v2.22.0

type ReconciliationOrchestrator interface {
	Reconciler

	// Run starts a continuous reconciliation loop that periodically calls ReconcileAll
	// to ensure all prebuilds are in their desired states. The loop runs until the context
	// is canceled or Stop is called.
	Run(ctx context.Context)

	// Stop gracefully shuts down the orchestrator with the given cause.
	// The cause is used for logging and error reporting.
	Stop(ctx context.Context, cause error)

	// TrackResourceReplacement handles a pathological situation whereby a terraform resource is replaced due to drift,
	// which can obviate the whole point of pre-provisioning a prebuilt workspace.
	// See more detail at https://coder.com/docs/admin/templates/extending-templates/prebuilt-workspaces#preventing-resource-replacement.
	TrackResourceReplacement(ctx context.Context, workspaceID, buildID uuid.UUID, replacements []*sdkproto.ResourceReplacement)
}

ReconciliationOrchestrator manages the lifecycle of prebuild reconciliation. It runs a continuous loop to check and reconcile prebuild states, and can be stopped gracefully.

var DefaultReconciler ReconciliationOrchestrator = NoopReconciler{}

type ReconciliationState added in v2.22.0

type ReconciliationState struct {
	Actual     int32 // Number of currently running prebuilds
	Desired    int32 // Number of prebuilds desired as defined in the preset
	Eligible   int32 // Number of prebuilds that are ready to be claimed
	Extraneous int32 // Number of extra running prebuilds beyond the desired count

	// Counts of prebuilds in various transition states
	Starting int32
	Stopping int32
	Deleting int32
}

ReconciliationState represents the processed state of a preset's prebuilds, calculated from a PresetSnapshot. While PresetSnapshot contains raw data, ReconciliationState contains derived metrics that are directly used to determine what actions are needed (create, delete, or backoff). For example, it calculates how many prebuilds are eligible, how many are extraneous, and how many are in various transition states.

type StateSnapshotter added in v2.22.0

type StateSnapshotter interface {
	// SnapshotState captures the current state of all prebuilds across templates.
	// It creates a global database snapshot that can be viewed as a collection of PresetSnapshots,
	// each representing the state of prebuilds for a specific preset.
	// MUST be called inside a repeatable-read transaction.
	SnapshotState(ctx context.Context, store database.Store) (*GlobalSnapshot, error)
}

StateSnapshotter defines the operations necessary to capture workspace prebuilds state.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL