mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
952c69f412
This change updates the `task_workspace_apps` table structure for improved linking to workspace builds and adds queries to manage tasks and a view to expose task status. Updates coder/internal#948 Supersedes coder/coder#20212 Supersedes coder/coder#19773
105 lines
3.5 KiB
SQL
105 lines
3.5 KiB
SQL
-- Replace workspace_build_id with workspace_build_number.
|
|
ALTER TABLE task_workspace_apps
|
|
ADD COLUMN workspace_build_number INTEGER;
|
|
|
|
-- Try to populate workspace_build_number from workspace_builds.
|
|
UPDATE task_workspace_apps
|
|
SET workspace_build_number = workspace_builds.build_number
|
|
FROM workspace_builds
|
|
WHERE workspace_builds.id = task_workspace_apps.workspace_build_id;
|
|
|
|
-- Remove rows that couldn't be migrated.
|
|
DELETE FROM task_workspace_apps
|
|
WHERE workspace_build_number IS NULL;
|
|
|
|
ALTER TABLE task_workspace_apps
|
|
DROP COLUMN workspace_build_id,
|
|
ALTER COLUMN workspace_build_number SET NOT NULL,
|
|
ALTER COLUMN workspace_agent_id DROP NOT NULL,
|
|
ALTER COLUMN workspace_app_id DROP NOT NULL,
|
|
ADD CONSTRAINT task_workspace_apps_pkey PRIMARY KEY (task_id, workspace_build_number);
|
|
|
|
-- Add indexes for common joins or filters.
|
|
CREATE INDEX IF NOT EXISTS tasks_workspace_id_idx ON tasks (workspace_id);
|
|
CREATE INDEX IF NOT EXISTS tasks_owner_id_idx ON tasks (owner_id);
|
|
CREATE INDEX IF NOT EXISTS tasks_organization_id_idx ON tasks (organization_id);
|
|
|
|
CREATE TYPE task_status AS ENUM (
|
|
'pending',
|
|
'initializing',
|
|
'active',
|
|
'paused',
|
|
'unknown',
|
|
'error'
|
|
);
|
|
|
|
CREATE VIEW
|
|
tasks_with_status
|
|
AS
|
|
SELECT
|
|
tasks.*,
|
|
CASE
|
|
WHEN tasks.workspace_id IS NULL OR latest_build.job_status IS NULL THEN 'pending'::task_status
|
|
|
|
WHEN latest_build.job_status = 'failed' THEN 'error'::task_status
|
|
|
|
WHEN latest_build.transition IN ('stop', 'delete')
|
|
AND latest_build.job_status = 'succeeded' THEN 'paused'::task_status
|
|
|
|
WHEN latest_build.transition = 'start'
|
|
AND latest_build.job_status = 'pending' THEN 'initializing'::task_status
|
|
|
|
WHEN latest_build.transition = 'start' AND latest_build.job_status IN ('running', 'succeeded') THEN
|
|
CASE
|
|
WHEN agent_status.none THEN 'initializing'::task_status
|
|
WHEN agent_status.connecting THEN 'initializing'::task_status
|
|
WHEN agent_status.connected THEN
|
|
CASE
|
|
WHEN app_status.any_unhealthy THEN 'error'::task_status
|
|
WHEN app_status.any_initializing THEN 'initializing'::task_status
|
|
WHEN app_status.all_healthy_or_disabled THEN 'active'::task_status
|
|
ELSE 'unknown'::task_status
|
|
END
|
|
ELSE 'unknown'::task_status
|
|
END
|
|
|
|
ELSE 'unknown'::task_status
|
|
END AS status
|
|
FROM
|
|
tasks
|
|
LEFT JOIN LATERAL (
|
|
SELECT workspace_build_number, workspace_agent_id, workspace_app_id
|
|
FROM task_workspace_apps task_app
|
|
WHERE task_id = tasks.id
|
|
ORDER BY workspace_build_number DESC
|
|
LIMIT 1
|
|
) task_app ON TRUE
|
|
LEFT JOIN LATERAL (
|
|
SELECT
|
|
workspace_build.transition,
|
|
provisioner_job.job_status,
|
|
workspace_build.job_id
|
|
FROM workspace_builds workspace_build
|
|
JOIN provisioner_jobs provisioner_job ON provisioner_job.id = workspace_build.job_id
|
|
WHERE workspace_build.workspace_id = tasks.workspace_id
|
|
AND workspace_build.build_number = task_app.workspace_build_number
|
|
) latest_build ON TRUE
|
|
CROSS JOIN LATERAL (
|
|
SELECT
|
|
COUNT(*) = 0 AS none,
|
|
bool_or(workspace_agent.lifecycle_state IN ('created', 'starting')) AS connecting,
|
|
bool_and(workspace_agent.lifecycle_state = 'ready') AS connected
|
|
FROM workspace_agents workspace_agent
|
|
WHERE workspace_agent.id = task_app.workspace_agent_id
|
|
) agent_status
|
|
CROSS JOIN LATERAL (
|
|
SELECT
|
|
bool_or(workspace_app.health = 'unhealthy') AS any_unhealthy,
|
|
bool_or(workspace_app.health = 'initializing') AS any_initializing,
|
|
bool_and(workspace_app.health IN ('healthy', 'disabled')) AS all_healthy_or_disabled
|
|
FROM workspace_apps workspace_app
|
|
WHERE workspace_app.id = task_app.workspace_app_id
|
|
) app_status
|
|
WHERE
|
|
tasks.deleted_at IS NULL;
|