ha executor
Some checks failed
CI / Rustfmt (pull_request) Successful in 19s
CI / Cargo Audit & Deny (pull_request) Successful in 33s
CI / Security Blocking Checks (pull_request) Successful in 5s
CI / Web Blocking Checks (pull_request) Successful in 49s
CI / Web Advisory Checks (pull_request) Successful in 33s
CI / Clippy (pull_request) Has been cancelled
CI / Security Advisory Checks (pull_request) Has been cancelled
CI / Tests (pull_request) Has been cancelled
Some checks failed
CI / Rustfmt (pull_request) Successful in 19s
CI / Cargo Audit & Deny (pull_request) Successful in 33s
CI / Security Blocking Checks (pull_request) Successful in 5s
CI / Web Blocking Checks (pull_request) Successful in 49s
CI / Web Advisory Checks (pull_request) Successful in 33s
CI / Clippy (pull_request) Has been cancelled
CI / Security Advisory Checks (pull_request) Has been cancelled
CI / Tests (pull_request) Has been cancelled
This commit is contained in:
@@ -201,6 +201,9 @@ CREATE INDEX idx_enforcement_rule_status ON enforcement(rule, status);
|
||||
CREATE INDEX idx_enforcement_event_status ON enforcement(event, status);
|
||||
CREATE INDEX idx_enforcement_payload_gin ON enforcement USING GIN (payload);
|
||||
CREATE INDEX idx_enforcement_conditions_gin ON enforcement USING GIN (conditions);
|
||||
CREATE UNIQUE INDEX uq_enforcement_rule_event
|
||||
ON enforcement (rule, event)
|
||||
WHERE rule IS NOT NULL AND event IS NOT NULL;
|
||||
|
||||
-- Comments
|
||||
COMMENT ON TABLE enforcement IS 'Enforcements represent rule triggering by events';
|
||||
|
||||
@@ -4,13 +4,8 @@
|
||||
-- Consolidates former migrations: 000006 (execution_system), 000008
|
||||
-- (worker_notification), 000014 (worker_table), and 20260209 (phase3).
|
||||
--
|
||||
-- NOTE: The execution table is converted to a TimescaleDB hypertable in
|
||||
-- migration 000009. Hypertables cannot be the target of FK constraints,
|
||||
-- so columns referencing execution (inquiry.execution, workflow_execution.execution)
|
||||
-- are plain BIGINT with no FK. Similarly, columns ON the execution table that
|
||||
-- would self-reference or reference other hypertables (parent, enforcement,
|
||||
-- original_execution) are plain BIGINT. The action and executor FKs are also
|
||||
-- omitted since they would need to be dropped during hypertable conversion.
|
||||
-- NOTE: `execution` remains a regular PostgreSQL table. Time-series
|
||||
-- audit and analytics are handled by `execution_history`.
|
||||
-- Version: 20250101000005
|
||||
|
||||
-- ============================================================================
|
||||
@@ -19,27 +14,27 @@
|
||||
|
||||
CREATE TABLE execution (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
action BIGINT, -- references action(id); no FK because execution becomes a hypertable
|
||||
action BIGINT,
|
||||
action_ref TEXT NOT NULL,
|
||||
config JSONB,
|
||||
env_vars JSONB,
|
||||
parent BIGINT, -- self-reference; no FK because execution becomes a hypertable
|
||||
enforcement BIGINT, -- references enforcement(id); no FK (both are hypertables)
|
||||
executor BIGINT, -- references identity(id); no FK because execution becomes a hypertable
|
||||
worker BIGINT, -- references worker(id); no FK because execution becomes a hypertable
|
||||
parent BIGINT,
|
||||
enforcement BIGINT,
|
||||
executor BIGINT,
|
||||
worker BIGINT,
|
||||
status execution_status_enum NOT NULL DEFAULT 'requested',
|
||||
result JSONB,
|
||||
started_at TIMESTAMPTZ, -- set when execution transitions to 'running'
|
||||
created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
is_workflow BOOLEAN DEFAULT false NOT NULL,
|
||||
workflow_def BIGINT, -- references workflow_definition(id); no FK because execution becomes a hypertable
|
||||
workflow_def BIGINT,
|
||||
workflow_task JSONB,
|
||||
|
||||
-- Retry tracking (baked in from phase 3)
|
||||
retry_count INTEGER NOT NULL DEFAULT 0,
|
||||
max_retries INTEGER,
|
||||
retry_reason TEXT,
|
||||
original_execution BIGINT, -- self-reference; no FK because execution becomes a hypertable
|
||||
original_execution BIGINT,
|
||||
|
||||
updated TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
@@ -64,6 +59,11 @@ CREATE INDEX idx_execution_result_gin ON execution USING GIN (result);
|
||||
CREATE INDEX idx_execution_env_vars_gin ON execution USING GIN (env_vars);
|
||||
CREATE INDEX idx_execution_original_execution ON execution(original_execution) WHERE original_execution IS NOT NULL;
|
||||
CREATE INDEX idx_execution_status_retry ON execution(status, retry_count) WHERE status = 'failed' AND retry_count < COALESCE(max_retries, 0);
|
||||
CREATE UNIQUE INDEX uq_execution_top_level_enforcement
|
||||
ON execution (enforcement)
|
||||
WHERE enforcement IS NOT NULL
|
||||
AND parent IS NULL
|
||||
AND (config IS NULL OR NOT (config ? 'retry_of'));
|
||||
|
||||
-- Trigger
|
||||
CREATE TRIGGER update_execution_updated
|
||||
@@ -77,10 +77,10 @@ COMMENT ON COLUMN execution.action IS 'Action being executed (may be null if act
|
||||
COMMENT ON COLUMN execution.action_ref IS 'Action reference (preserved even if action deleted)';
|
||||
COMMENT ON COLUMN execution.config IS 'Snapshot of action configuration at execution time';
|
||||
COMMENT ON COLUMN execution.env_vars IS 'Environment variables for this execution as key-value pairs (string -> string). These are set in the execution environment and are separate from action parameters. Used for execution context, configuration, and non-sensitive metadata.';
|
||||
COMMENT ON COLUMN execution.parent IS 'Parent execution ID for workflow hierarchies (no FK — execution is a hypertable)';
|
||||
COMMENT ON COLUMN execution.enforcement IS 'Enforcement that triggered this execution (no FK — both are hypertables)';
|
||||
COMMENT ON COLUMN execution.executor IS 'Identity that initiated the execution (no FK — execution is a hypertable)';
|
||||
COMMENT ON COLUMN execution.worker IS 'Assigned worker handling this execution (no FK — execution is a hypertable)';
|
||||
COMMENT ON COLUMN execution.parent IS 'Parent execution ID for workflow hierarchies';
|
||||
COMMENT ON COLUMN execution.enforcement IS 'Enforcement that triggered this execution';
|
||||
COMMENT ON COLUMN execution.executor IS 'Identity that initiated the execution';
|
||||
COMMENT ON COLUMN execution.worker IS 'Assigned worker handling this execution';
|
||||
COMMENT ON COLUMN execution.status IS 'Current execution lifecycle status';
|
||||
COMMENT ON COLUMN execution.result IS 'Execution output/results';
|
||||
COMMENT ON COLUMN execution.retry_count IS 'Current retry attempt number (0 = first attempt, 1 = first retry, etc.)';
|
||||
@@ -96,7 +96,7 @@ COMMENT ON COLUMN execution.original_execution IS 'ID of the original execution
|
||||
|
||||
CREATE TABLE inquiry (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
execution BIGINT NOT NULL, -- references execution(id); no FK because execution is a hypertable
|
||||
execution BIGINT NOT NULL,
|
||||
prompt TEXT NOT NULL,
|
||||
response_schema JSONB,
|
||||
assigned_to BIGINT REFERENCES identity(id) ON DELETE SET NULL,
|
||||
@@ -109,7 +109,7 @@ CREATE TABLE inquiry (
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX idx_inquiry_execution ON inquiry(execution);
|
||||
CREATE UNIQUE INDEX uq_inquiry_execution ON inquiry(execution) WHERE execution IS NOT NULL;
|
||||
CREATE INDEX idx_inquiry_assigned_to ON inquiry(assigned_to);
|
||||
CREATE INDEX idx_inquiry_status ON inquiry(status);
|
||||
CREATE INDEX idx_inquiry_timeout_at ON inquiry(timeout_at) WHERE timeout_at IS NOT NULL;
|
||||
@@ -127,7 +127,31 @@ CREATE TRIGGER update_inquiry_updated
|
||||
|
||||
-- Comments
|
||||
COMMENT ON TABLE inquiry IS 'Inquiries enable human-in-the-loop workflows with async user interactions';
|
||||
COMMENT ON COLUMN inquiry.execution IS 'Execution that is waiting on this inquiry (no FK — execution is a hypertable)';
|
||||
COMMENT ON COLUMN inquiry.execution IS 'Execution that is waiting on this inquiry';
|
||||
|
||||
ALTER TABLE execution
|
||||
ADD CONSTRAINT execution_action_fkey
|
||||
FOREIGN KEY (action) REFERENCES action(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE execution
|
||||
ADD CONSTRAINT execution_parent_fkey
|
||||
FOREIGN KEY (parent) REFERENCES execution(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE execution
|
||||
ADD CONSTRAINT execution_original_execution_fkey
|
||||
FOREIGN KEY (original_execution) REFERENCES execution(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE execution
|
||||
ADD CONSTRAINT execution_enforcement_fkey
|
||||
FOREIGN KEY (enforcement) REFERENCES enforcement(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE execution
|
||||
ADD CONSTRAINT execution_executor_fkey
|
||||
FOREIGN KEY (executor) REFERENCES identity(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE inquiry
|
||||
ADD CONSTRAINT inquiry_execution_fkey
|
||||
FOREIGN KEY (execution) REFERENCES execution(id) ON DELETE CASCADE;
|
||||
COMMENT ON COLUMN inquiry.prompt IS 'Question or prompt text for the user';
|
||||
COMMENT ON COLUMN inquiry.response_schema IS 'JSON schema defining expected response format';
|
||||
COMMENT ON COLUMN inquiry.assigned_to IS 'Identity who should respond to this inquiry';
|
||||
@@ -261,6 +285,10 @@ COMMENT ON COLUMN worker.capabilities IS 'Worker capabilities (e.g., max_concurr
|
||||
COMMENT ON COLUMN worker.meta IS 'Additional worker metadata';
|
||||
COMMENT ON COLUMN worker.last_heartbeat IS 'Timestamp of last heartbeat from worker';
|
||||
|
||||
ALTER TABLE execution
|
||||
ADD CONSTRAINT execution_worker_fkey
|
||||
FOREIGN KEY (worker) REFERENCES worker(id) ON DELETE SET NULL;
|
||||
|
||||
-- ============================================================================
|
||||
-- NOTIFICATION TABLE
|
||||
-- ============================================================================
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
-- Migration: Workflow System
|
||||
-- Description: Creates workflow_definition and workflow_execution tables
|
||||
-- Description: Creates workflow_definition, workflow_execution, and
|
||||
-- workflow_task_dispatch tables
|
||||
-- (workflow_task_execution consolidated into execution.workflow_task JSONB)
|
||||
--
|
||||
-- NOTE: The execution table is converted to a TimescaleDB hypertable in
|
||||
-- migration 000009. Hypertables cannot be the target of FK constraints,
|
||||
-- so workflow_execution.execution is a plain BIGINT with no FK.
|
||||
-- execution.workflow_def also has no FK (added as plain BIGINT in 000005)
|
||||
-- since execution is a hypertable and FKs from hypertables are only
|
||||
-- supported for simple cases — we omit it for consistency.
|
||||
-- NOTE: `execution` remains a regular PostgreSQL table, so
|
||||
-- workflow_execution.execution, workflow_task_dispatch.execution_id,
|
||||
-- and execution.workflow_def use normal foreign keys.
|
||||
-- Version: 20250101000006
|
||||
|
||||
-- ============================================================================
|
||||
@@ -54,7 +52,7 @@ COMMENT ON COLUMN workflow_definition.out_schema IS 'JSON schema for workflow ou
|
||||
|
||||
CREATE TABLE workflow_execution (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
execution BIGINT NOT NULL, -- references execution(id); no FK because execution is a hypertable
|
||||
execution BIGINT NOT NULL REFERENCES execution(id) ON DELETE CASCADE,
|
||||
workflow_def BIGINT NOT NULL REFERENCES workflow_definition(id) ON DELETE CASCADE,
|
||||
current_tasks TEXT[] DEFAULT '{}',
|
||||
completed_tasks TEXT[] DEFAULT '{}',
|
||||
@@ -83,12 +81,51 @@ CREATE TRIGGER update_workflow_execution_updated
|
||||
EXECUTE FUNCTION update_updated_column();
|
||||
|
||||
-- Comments
|
||||
COMMENT ON TABLE workflow_execution IS 'Runtime state tracking for workflow executions. execution column has no FK — execution is a hypertable.';
|
||||
COMMENT ON TABLE workflow_execution IS 'Runtime state tracking for workflow executions.';
|
||||
COMMENT ON COLUMN workflow_execution.variables IS 'Workflow-scoped variables, updated via publish directives';
|
||||
COMMENT ON COLUMN workflow_execution.task_graph IS 'Execution graph with dependencies and transitions';
|
||||
COMMENT ON COLUMN workflow_execution.current_tasks IS 'Array of task names currently executing';
|
||||
COMMENT ON COLUMN workflow_execution.paused IS 'True if workflow execution is paused (can be resumed)';
|
||||
|
||||
-- ============================================================================
|
||||
-- WORKFLOW TASK DISPATCH TABLE
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE workflow_task_dispatch (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
workflow_execution BIGINT NOT NULL REFERENCES workflow_execution(id) ON DELETE CASCADE,
|
||||
task_name TEXT NOT NULL,
|
||||
task_index INT,
|
||||
execution_id BIGINT,
|
||||
created TIMESTAMPTZ DEFAULT NOW() NOT NULL,
|
||||
updated TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uq_workflow_task_dispatch_identity
|
||||
ON workflow_task_dispatch (
|
||||
workflow_execution,
|
||||
task_name,
|
||||
COALESCE(task_index, -1)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_workflow_task_dispatch_execution_id
|
||||
ON workflow_task_dispatch (execution_id)
|
||||
WHERE execution_id IS NOT NULL;
|
||||
|
||||
CREATE TRIGGER update_workflow_task_dispatch_updated
|
||||
BEFORE UPDATE ON workflow_task_dispatch
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_column();
|
||||
|
||||
COMMENT ON TABLE workflow_task_dispatch IS
|
||||
'Durable dedupe/ownership records for workflow child execution dispatch';
|
||||
COMMENT ON COLUMN workflow_task_dispatch.execution_id IS
|
||||
'Associated execution.id';
|
||||
|
||||
ALTER TABLE workflow_task_dispatch
|
||||
ADD CONSTRAINT workflow_task_dispatch_execution_id_fkey
|
||||
FOREIGN KEY (execution_id) REFERENCES execution(id) ON DELETE CASCADE;
|
||||
|
||||
-- ============================================================================
|
||||
-- MODIFY ACTION TABLE - Add Workflow Support
|
||||
-- ============================================================================
|
||||
@@ -100,9 +137,9 @@ CREATE INDEX idx_action_workflow_def ON action(workflow_def);
|
||||
|
||||
COMMENT ON COLUMN action.workflow_def IS 'Reference to workflow definition (non-null means this action is a workflow)';
|
||||
|
||||
-- NOTE: execution.workflow_def has no FK constraint because execution is a
|
||||
-- TimescaleDB hypertable (converted in migration 000009). The column was
|
||||
-- created as a plain BIGINT in migration 000005.
|
||||
ALTER TABLE execution
|
||||
ADD CONSTRAINT execution_workflow_def_fkey
|
||||
FOREIGN KEY (workflow_def) REFERENCES workflow_definition(id) ON DELETE SET NULL;
|
||||
|
||||
-- ============================================================================
|
||||
-- WORKFLOW VIEWS
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- Migration: Supporting Systems
|
||||
-- Description: Creates keys, artifacts, queue_stats, pack_environment, pack_testing,
|
||||
-- and webhook function tables.
|
||||
-- Description: Creates keys, artifacts, queue_stats, execution_admission,
|
||||
-- pack_environment, pack_testing, and webhook function tables.
|
||||
-- Consolidates former migrations: 000009 (keys_artifacts), 000010 (webhook_system),
|
||||
-- 000011 (pack_environments), and 000012 (pack_testing).
|
||||
-- Version: 20250101000007
|
||||
@@ -206,6 +206,76 @@ COMMENT ON COLUMN queue_stats.total_enqueued IS 'Total executions enqueued since
|
||||
COMMENT ON COLUMN queue_stats.total_completed IS 'Total executions completed since queue creation';
|
||||
COMMENT ON COLUMN queue_stats.last_updated IS 'Timestamp of last statistics update';
|
||||
|
||||
-- ============================================================================
|
||||
-- EXECUTION ADMISSION TABLES
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE execution_admission_state (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
action_id BIGINT NOT NULL REFERENCES action(id) ON DELETE CASCADE,
|
||||
group_key TEXT,
|
||||
group_key_normalized TEXT GENERATED ALWAYS AS (COALESCE(group_key, '')) STORED,
|
||||
max_concurrent INTEGER NOT NULL,
|
||||
next_queue_order BIGINT NOT NULL DEFAULT 1,
|
||||
total_enqueued BIGINT NOT NULL DEFAULT 0,
|
||||
total_completed BIGINT NOT NULL DEFAULT 0,
|
||||
created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT uq_execution_admission_state_identity
|
||||
UNIQUE (action_id, group_key_normalized)
|
||||
);
|
||||
|
||||
CREATE TABLE execution_admission_entry (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
state_id BIGINT NOT NULL REFERENCES execution_admission_state(id) ON DELETE CASCADE,
|
||||
execution_id BIGINT NOT NULL UNIQUE REFERENCES execution(id) ON DELETE CASCADE,
|
||||
status TEXT NOT NULL CHECK (status IN ('active', 'queued')),
|
||||
queue_order BIGINT NOT NULL,
|
||||
enqueued_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
activated_at TIMESTAMPTZ,
|
||||
created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_execution_admission_state_action
|
||||
ON execution_admission_state (action_id);
|
||||
|
||||
CREATE INDEX idx_execution_admission_entry_state_status_queue
|
||||
ON execution_admission_entry (state_id, status, queue_order);
|
||||
|
||||
CREATE INDEX idx_execution_admission_entry_execution
|
||||
ON execution_admission_entry (execution_id);
|
||||
|
||||
CREATE TRIGGER update_execution_admission_state_updated
|
||||
BEFORE UPDATE ON execution_admission_state
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_column();
|
||||
|
||||
CREATE TRIGGER update_execution_admission_entry_updated
|
||||
BEFORE UPDATE ON execution_admission_entry
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_column();
|
||||
|
||||
COMMENT ON TABLE execution_admission_state IS
|
||||
'Shared admission state per action/group for executor concurrency and FIFO coordination';
|
||||
COMMENT ON COLUMN execution_admission_state.group_key IS
|
||||
'Optional parameter-derived concurrency grouping key';
|
||||
COMMENT ON COLUMN execution_admission_state.max_concurrent IS
|
||||
'Current concurrency limit for this action/group queue';
|
||||
COMMENT ON COLUMN execution_admission_state.next_queue_order IS
|
||||
'Monotonic sequence used to preserve exact FIFO order for queued executions';
|
||||
COMMENT ON COLUMN execution_admission_state.total_enqueued IS
|
||||
'Cumulative number of executions admitted into this queue';
|
||||
COMMENT ON COLUMN execution_admission_state.total_completed IS
|
||||
'Cumulative number of active executions released from this queue';
|
||||
|
||||
COMMENT ON TABLE execution_admission_entry IS
|
||||
'Active slot ownership and queued executions for shared admission control';
|
||||
COMMENT ON COLUMN execution_admission_entry.status IS
|
||||
'active rows own a concurrency slot; queued rows wait in FIFO order';
|
||||
COMMENT ON COLUMN execution_admission_entry.queue_order IS
|
||||
'Durable FIFO position within an action/group queue';
|
||||
|
||||
-- ============================================================================
|
||||
-- PACK ENVIRONMENT TABLE
|
||||
-- ============================================================================
|
||||
|
||||
@@ -143,52 +143,8 @@ SELECT create_hypertable('event', 'created',
|
||||
|
||||
COMMENT ON TABLE event IS 'Events are instances of triggers firing (TimescaleDB hypertable partitioned on created)';
|
||||
|
||||
-- ============================================================================
|
||||
-- CONVERT ENFORCEMENT TABLE TO HYPERTABLE
|
||||
-- ============================================================================
|
||||
-- Enforcements are created and then updated exactly once (status changes from
|
||||
-- `created` to `processed` or `disabled` within ~1 second). This single update
|
||||
-- happens well before the 7-day compression window, so UPDATE on uncompressed
|
||||
-- chunks works without issues.
|
||||
--
|
||||
-- No FK constraints reference enforcement(id) — execution.enforcement was
|
||||
-- created as a plain BIGINT in migration 000005.
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
ALTER TABLE enforcement DROP CONSTRAINT enforcement_pkey;
|
||||
ALTER TABLE enforcement ADD PRIMARY KEY (id, created);
|
||||
|
||||
SELECT create_hypertable('enforcement', 'created',
|
||||
chunk_time_interval => INTERVAL '1 day',
|
||||
migrate_data => true);
|
||||
|
||||
COMMENT ON TABLE enforcement IS 'Enforcements represent rule triggering by events (TimescaleDB hypertable partitioned on created)';
|
||||
|
||||
-- ============================================================================
|
||||
-- CONVERT EXECUTION TABLE TO HYPERTABLE
|
||||
-- ============================================================================
|
||||
-- Executions are updated ~4 times during their lifecycle (requested → scheduled
|
||||
-- → running → completed/failed), completing within at most ~1 day — well before
|
||||
-- the 7-day compression window. The `updated` column and its BEFORE UPDATE
|
||||
-- trigger are preserved (used by timeout monitor and UI).
|
||||
--
|
||||
-- No FK constraints reference execution(id) — inquiry.execution,
|
||||
-- workflow_execution.execution, execution.parent, and execution.original_execution
|
||||
-- were all created as plain BIGINT columns in migrations 000005 and 000006.
|
||||
--
|
||||
-- The existing execution_history hypertable and its trigger are preserved —
|
||||
-- they track field-level diffs of each update, which remains valuable for
|
||||
-- a mutable table.
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
ALTER TABLE execution DROP CONSTRAINT execution_pkey;
|
||||
ALTER TABLE execution ADD PRIMARY KEY (id, created);
|
||||
|
||||
SELECT create_hypertable('execution', 'created',
|
||||
chunk_time_interval => INTERVAL '1 day',
|
||||
migrate_data => true);
|
||||
|
||||
COMMENT ON TABLE execution IS 'Executions represent action runs with workflow support (TimescaleDB hypertable partitioned on created). Updated ~4 times during lifecycle, completing within ~1 day (well before 7-day compression window).';
|
||||
COMMENT ON TABLE enforcement IS 'Enforcements represent rule triggering by events';
|
||||
COMMENT ON TABLE execution IS 'Executions represent action runs with workflow support. History and analytics are stored in execution_history.';
|
||||
|
||||
-- ============================================================================
|
||||
-- TRIGGER FUNCTIONS
|
||||
@@ -410,22 +366,6 @@ ALTER TABLE event SET (
|
||||
);
|
||||
SELECT add_compression_policy('event', INTERVAL '7 days');
|
||||
|
||||
-- Enforcement table (hypertable)
|
||||
ALTER TABLE enforcement SET (
|
||||
timescaledb.compress,
|
||||
timescaledb.compress_segmentby = 'rule_ref',
|
||||
timescaledb.compress_orderby = 'created DESC'
|
||||
);
|
||||
SELECT add_compression_policy('enforcement', INTERVAL '7 days');
|
||||
|
||||
-- Execution table (hypertable)
|
||||
ALTER TABLE execution SET (
|
||||
timescaledb.compress,
|
||||
timescaledb.compress_segmentby = 'action_ref',
|
||||
timescaledb.compress_orderby = 'created DESC'
|
||||
);
|
||||
SELECT add_compression_policy('execution', INTERVAL '7 days');
|
||||
|
||||
-- ============================================================================
|
||||
-- RETENTION POLICIES
|
||||
-- ============================================================================
|
||||
@@ -433,8 +373,6 @@ SELECT add_compression_policy('execution', INTERVAL '7 days');
|
||||
SELECT add_retention_policy('execution_history', INTERVAL '90 days');
|
||||
SELECT add_retention_policy('worker_history', INTERVAL '180 days');
|
||||
SELECT add_retention_policy('event', INTERVAL '90 days');
|
||||
SELECT add_retention_policy('enforcement', INTERVAL '90 days');
|
||||
SELECT add_retention_policy('execution', INTERVAL '90 days');
|
||||
|
||||
-- ============================================================================
|
||||
-- CONTINUOUS AGGREGATES
|
||||
@@ -449,6 +387,8 @@ DROP MATERIALIZED VIEW IF EXISTS event_volume_hourly CASCADE;
|
||||
DROP MATERIALIZED VIEW IF EXISTS worker_status_hourly CASCADE;
|
||||
DROP MATERIALIZED VIEW IF EXISTS enforcement_volume_hourly CASCADE;
|
||||
DROP MATERIALIZED VIEW IF EXISTS execution_volume_hourly CASCADE;
|
||||
DROP VIEW IF EXISTS enforcement_volume_hourly CASCADE;
|
||||
DROP VIEW IF EXISTS execution_volume_hourly CASCADE;
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- execution_status_hourly
|
||||
@@ -553,49 +493,35 @@ SELECT add_continuous_aggregate_policy('worker_status_hourly',
|
||||
-- instead of a separate enforcement_history table.
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE MATERIALIZED VIEW enforcement_volume_hourly
|
||||
WITH (timescaledb.continuous) AS
|
||||
CREATE VIEW enforcement_volume_hourly AS
|
||||
SELECT
|
||||
time_bucket('1 hour', created) AS bucket,
|
||||
date_trunc('hour', created) AS bucket,
|
||||
rule_ref,
|
||||
COUNT(*) AS enforcement_count
|
||||
FROM enforcement
|
||||
GROUP BY bucket, rule_ref
|
||||
WITH NO DATA;
|
||||
|
||||
SELECT add_continuous_aggregate_policy('enforcement_volume_hourly',
|
||||
start_offset => INTERVAL '7 days',
|
||||
end_offset => INTERVAL '1 hour',
|
||||
schedule_interval => INTERVAL '30 minutes'
|
||||
);
|
||||
;
|
||||
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- execution_volume_hourly
|
||||
-- Tracks execution creation volume per hour by action_ref and status.
|
||||
-- This queries the execution hypertable directly (like event_volume_hourly
|
||||
-- queries the event table). Complements the existing execution_status_hourly
|
||||
-- and execution_throughput_hourly aggregates which query execution_history.
|
||||
-- This queries the execution table directly. Complements the existing
|
||||
-- execution_status_hourly and execution_throughput_hourly aggregates which
|
||||
-- query execution_history.
|
||||
--
|
||||
-- Use case: direct execution volume monitoring without relying on the history
|
||||
-- trigger (belt-and-suspenders, plus captures the initial status at creation).
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE MATERIALIZED VIEW execution_volume_hourly
|
||||
WITH (timescaledb.continuous) AS
|
||||
CREATE VIEW execution_volume_hourly AS
|
||||
SELECT
|
||||
time_bucket('1 hour', created) AS bucket,
|
||||
date_trunc('hour', created) AS bucket,
|
||||
action_ref,
|
||||
status AS initial_status,
|
||||
COUNT(*) AS execution_count
|
||||
FROM execution
|
||||
GROUP BY bucket, action_ref, status
|
||||
WITH NO DATA;
|
||||
|
||||
SELECT add_continuous_aggregate_policy('execution_volume_hourly',
|
||||
start_offset => INTERVAL '7 days',
|
||||
end_offset => INTERVAL '1 hour',
|
||||
schedule_interval => INTERVAL '30 minutes'
|
||||
);
|
||||
;
|
||||
|
||||
-- ============================================================================
|
||||
-- INITIAL REFRESH NOTE
|
||||
|
||||
@@ -26,7 +26,7 @@ ALTER TABLE artifact ADD COLUMN IF NOT EXISTS content_type TEXT;
|
||||
-- Total size in bytes of the latest version's content (NULL for progress artifacts)
|
||||
ALTER TABLE artifact ADD COLUMN IF NOT EXISTS size_bytes BIGINT;
|
||||
|
||||
-- Execution that produced/owns this artifact (plain BIGINT, no FK — execution is a hypertable)
|
||||
-- Execution that produced/owns this artifact (plain BIGINT, no FK by design)
|
||||
ALTER TABLE artifact ADD COLUMN IF NOT EXISTS execution BIGINT;
|
||||
|
||||
-- Structured data for progress-type artifacts and small structured payloads.
|
||||
@@ -52,7 +52,7 @@ COMMENT ON COLUMN artifact.name IS 'Human-readable artifact name';
|
||||
COMMENT ON COLUMN artifact.description IS 'Optional description of the artifact';
|
||||
COMMENT ON COLUMN artifact.content_type IS 'MIME content type (e.g. application/json, text/plain)';
|
||||
COMMENT ON COLUMN artifact.size_bytes IS 'Size of latest version content in bytes';
|
||||
COMMENT ON COLUMN artifact.execution IS 'Execution that produced this artifact (no FK — execution is a hypertable)';
|
||||
COMMENT ON COLUMN artifact.execution IS 'Execution that produced this artifact (no FK by design)';
|
||||
COMMENT ON COLUMN artifact.data IS 'Structured JSONB data for progress artifacts or metadata';
|
||||
COMMENT ON COLUMN artifact.visibility IS 'Access visibility: public (all users) or private (scope/owner-restricted)';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user