feat: harden orchestrator execution runtime
This commit is contained in:
@@ -335,13 +335,67 @@ export async function migrateSchema(pool) {
|
||||
updated_at BIGINT NOT NULL,
|
||||
started_at BIGINT NULL,
|
||||
completed_at BIGINT NULL,
|
||||
required_runtime_root VARCHAR(1024) NULL,
|
||||
required_build_id VARCHAR(128) NULL,
|
||||
claimed_worker_id VARCHAR(255) NULL,
|
||||
claimed_runtime_root VARCHAR(1024) NULL,
|
||||
claimed_build_id VARCHAR(128) NULL,
|
||||
UNIQUE KEY uq_h5_agent_run_request (user_id, request_id),
|
||||
KEY idx_h5_agent_run_user_status (user_id, status, updated_at),
|
||||
KEY idx_h5_agent_run_session (agent_session_id, updated_at),
|
||||
KEY idx_h5_agent_run_runtime_status (required_build_id, status, updated_at),
|
||||
CONSTRAINT fk_h5_agent_run_user FOREIGN KEY (user_id) REFERENCES h5_users(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_h5_agent_run_session FOREIGN KEY (agent_session_id) REFERENCES h5_user_sessions(agent_session_id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`);
|
||||
const agentRunRuntimeColumns = [
|
||||
['required_runtime_root', 'VARCHAR(1024) NULL AFTER completed_at'],
|
||||
['required_build_id', 'VARCHAR(128) NULL AFTER required_runtime_root'],
|
||||
['claimed_worker_id', 'VARCHAR(255) NULL AFTER required_build_id'],
|
||||
['claimed_runtime_root', 'VARCHAR(1024) NULL AFTER claimed_worker_id'],
|
||||
['claimed_build_id', 'VARCHAR(128) NULL AFTER claimed_runtime_root'],
|
||||
];
|
||||
for (const [column, definition] of agentRunRuntimeColumns) {
|
||||
if (!(await columnExists(pool, 'h5_agent_runs', column))) {
|
||||
await pool.query(`ALTER TABLE h5_agent_runs ADD COLUMN \`${column}\` ${definition}`);
|
||||
}
|
||||
}
|
||||
if (!(await indexExists(pool, 'h5_agent_runs', 'idx_h5_agent_run_runtime_status'))) {
|
||||
await pool.query(
|
||||
`ALTER TABLE h5_agent_runs
|
||||
ADD KEY idx_h5_agent_run_runtime_status (required_build_id, status, updated_at)`,
|
||||
);
|
||||
}
|
||||
const [claimGuardRows] = await pool.query(
|
||||
`SELECT 1
|
||||
FROM information_schema.TRIGGERS
|
||||
WHERE TRIGGER_SCHEMA = DATABASE()
|
||||
AND TRIGGER_NAME = 'trg_h5_agent_runs_claim_identity'
|
||||
LIMIT 1`,
|
||||
);
|
||||
if (claimGuardRows.length === 0) {
|
||||
await pool.query(`
|
||||
CREATE TRIGGER trg_h5_agent_runs_claim_identity
|
||||
BEFORE UPDATE ON h5_agent_runs
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
IF NEW.status = 'running'
|
||||
AND OLD.status IN ('queued', 'retryable')
|
||||
AND NEW.required_runtime_root IS NOT NULL
|
||||
AND (
|
||||
NEW.claimed_worker_id IS NULL
|
||||
OR NEW.claimed_runtime_root IS NULL
|
||||
OR NEW.claimed_build_id IS NULL
|
||||
OR NEW.claimed_runtime_root <> NEW.required_runtime_root
|
||||
OR NEW.claimed_build_id <> NEW.required_build_id
|
||||
)
|
||||
THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'agent run worker identity mismatch';
|
||||
END IF;
|
||||
END
|
||||
`);
|
||||
}
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS h5_agent_run_events (
|
||||
|
||||
Reference in New Issue
Block a user