feat: add database migrations for DAG and worker system
Migration 014: dag_nodes, dag_edges, dag_cross_edges tables for the feature-level dependency graph with validation state tracking. Migration 015: runners, job_definitions, jobs, job_log tables for the async compute job system with PostgreSQL-backed work queue. Update TruncateAll in testutil to include new tables.
This commit is contained in:
109
migrations/015_jobs_runners.sql
Normal file
109
migrations/015_jobs_runners.sql
Normal file
@@ -0,0 +1,109 @@
|
||||
-- Worker system: runners, job definitions, jobs, and job log.
|
||||
-- Migration: 015_jobs_runners
|
||||
-- Date: 2026-02
|
||||
|
||||
BEGIN;
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Runners (registered compute workers)
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE runners (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT UNIQUE NOT NULL,
|
||||
token_hash TEXT NOT NULL,
|
||||
token_prefix TEXT NOT NULL,
|
||||
tags TEXT[] NOT NULL DEFAULT '{}',
|
||||
status TEXT NOT NULL DEFAULT 'offline',
|
||||
last_heartbeat TIMESTAMPTZ,
|
||||
last_job_id UUID,
|
||||
metadata JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_runners_status ON runners(status);
|
||||
CREATE INDEX idx_runners_token ON runners(token_hash);
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Job Definitions (parsed from YAML, stored for reference and FK)
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE job_definitions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT UNIQUE NOT NULL,
|
||||
version INTEGER NOT NULL DEFAULT 1,
|
||||
trigger_type TEXT NOT NULL,
|
||||
scope_type TEXT NOT NULL,
|
||||
compute_type TEXT NOT NULL,
|
||||
runner_tags TEXT[] NOT NULL DEFAULT '{}',
|
||||
timeout_seconds INTEGER NOT NULL DEFAULT 600,
|
||||
max_retries INTEGER NOT NULL DEFAULT 1,
|
||||
priority INTEGER NOT NULL DEFAULT 100,
|
||||
definition JSONB NOT NULL,
|
||||
enabled BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_job_defs_trigger ON job_definitions(trigger_type);
|
||||
CREATE INDEX idx_job_defs_enabled ON job_definitions(enabled) WHERE enabled = true;
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Jobs (individual compute job instances)
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
CREATE TYPE job_status AS ENUM (
|
||||
'pending', 'claimed', 'running', 'completed', 'failed', 'cancelled'
|
||||
);
|
||||
|
||||
CREATE TABLE jobs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
job_definition_id UUID REFERENCES job_definitions(id) ON DELETE SET NULL,
|
||||
definition_name TEXT NOT NULL,
|
||||
status job_status NOT NULL DEFAULT 'pending',
|
||||
priority INTEGER NOT NULL DEFAULT 100,
|
||||
item_id UUID REFERENCES items(id) ON DELETE CASCADE,
|
||||
project_id UUID REFERENCES projects(id) ON DELETE SET NULL,
|
||||
scope_metadata JSONB DEFAULT '{}',
|
||||
runner_id UUID REFERENCES runners(id) ON DELETE SET NULL,
|
||||
runner_tags TEXT[] NOT NULL DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
claimed_at TIMESTAMPTZ,
|
||||
started_at TIMESTAMPTZ,
|
||||
completed_at TIMESTAMPTZ,
|
||||
timeout_seconds INTEGER NOT NULL DEFAULT 600,
|
||||
expires_at TIMESTAMPTZ,
|
||||
progress INTEGER DEFAULT 0,
|
||||
progress_message TEXT,
|
||||
result JSONB,
|
||||
error_message TEXT,
|
||||
retry_count INTEGER NOT NULL DEFAULT 0,
|
||||
max_retries INTEGER NOT NULL DEFAULT 1,
|
||||
created_by TEXT,
|
||||
cancelled_by TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX idx_jobs_status ON jobs(status);
|
||||
CREATE INDEX idx_jobs_pending ON jobs(status, priority, created_at)
|
||||
WHERE status = 'pending';
|
||||
CREATE INDEX idx_jobs_item ON jobs(item_id);
|
||||
CREATE INDEX idx_jobs_runner ON jobs(runner_id);
|
||||
CREATE INDEX idx_jobs_definition ON jobs(job_definition_id);
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Job Log (append-only progress entries)
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE job_log (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
job_id UUID NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
|
||||
timestamp TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
level TEXT NOT NULL DEFAULT 'info',
|
||||
message TEXT NOT NULL,
|
||||
metadata JSONB DEFAULT '{}'
|
||||
);
|
||||
|
||||
CREATE INDEX idx_job_log_job ON job_log(job_id, timestamp);
|
||||
|
||||
COMMIT;
|
||||
Reference in New Issue
Block a user