Closed
Description
Create a scheduler/executor implementation for workspace auto on/off.
-
Add table
workspace_lifecycle_job
CREATE TYPE workspace_lifecycle_operation AS ENUM ('stop', 'start') CREATE TABLE workspace_lifecycle_job ( id uuid NOT NULL, -- unique job ID created_at timestamp with time zone NOT NULL, -- when the job was created updated_at timestamp with time zone NOT NULL, -- when the job was last updated started_at timestamp with time zone, -- when the job was started, null means it's pending cancelled_at timestamp with time zone, -- when the job was cancelled, null means it hasn't been cancelled completed_at timestamp with time zone, -- when the job was completed, null means it hasn't finished yet error text, -- any errors encountered from the job workspace_id uuid NOT NULL, -- target workspace operation workspace_lifecycle_operation NOT NULL, -- start or stop deadline timestamp with time zone NOT NULL, -- when the job is to be executed PRIMARY KEY (id) )
-
Add table
workspace_lifecycle_job_logs
CREATE TABLE workspace_lifecycle_job_logs ( id uuid NOT NULL, -- unique row id job_id uuid NOT NULL, -- uuid of the workspace lifecycle job that created it created_at timestamp with time zone NOT NULL, -- when the logs were created level log_level NOT NULL, -- level of the log output character varying(1024) NOT NULL -- content of the log );
-
Add required methods to
querier.go
:AcquireWorkspaceLifecycleJob
acquires the lock for a single workspace lifecycle job that isn't started, completed, or cancelled using SKIP LOCKED.InsertWorkspaceLifecycleJob
inserts a new row into theworkspace_lifecycle_job
tableInsertWorkspaceLifecycleJobLogs
inserts a new row into theworkspace_lifecycle_job_logs
tableUpdateWorkspaceLifecycleJobByID
updates a row of theworkspace_lifecycle_job_logs
tableUpdateWorkspaceLifecycleJobWithCancelByID
marks a row of theworkspace_lifecycle_job
table as cancelledUpdateWorkspaceLifecycleJobWithCompleteByID
marks a row of theworkspace_lifecycle_job
table as completed
-
Create a
WorkspaceLifecycleJobScheduler
that schedules starting and stopping workspaces at their scheduled start time/stop time- A goroutine tied to the application lifecycle will iterate over all workspaces periodically.
- If a workspace is running and has a defined auto-stop time, if there is no corresponding auto-stop job pending then create said job.
- If a workspace is stopped and has a defined auto-start time, if there is no corresponding auto-start job pending then create said job.
- If an auto-start job is pending for a workspace that has no defined auto-start time, mark the job as cancelled.
- If an auto-stop job is pending for a workspace that has no defined auto-stop time, mark the job as cancelled.
-
Create an
WorkspaceLifecycleJobExecutor
that executes jobs fromworkspace_lifecycle_job
:- A goroutine tied to the application lifecycle will continuously wait for a pending workspace lifecycle job that has not been claimed.
- When an unclaimed job is found:
- Mark the job as claimed (setting
started_at
andupdated_at
) - Triggers the workspace stop/start unless the workspace is already in the desired state (stopped for auto-stop, running for auto-start)
- Mark the job as completed
- Mark the job as claimed (setting