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.
110 lines
4.3 KiB
PL/PgSQL
110 lines
4.3 KiB
PL/PgSQL
-- 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;
|