mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-22 10:32:40 +08:00
feat(ql3): add postgres cancellation dispatch
This commit is contained in:
@@ -4810,6 +4810,7 @@ export const runAttempts = ql3Schema.table(
|
||||
table.runId,
|
||||
table.attempt,
|
||||
),
|
||||
uniqueIndex('ql3_run_attempts_run_id_uidx').on(table.runId, table.id),
|
||||
index('ql3_run_attempts_dispatch_candidates_idx').on(
|
||||
table.status,
|
||||
table.runId,
|
||||
@@ -4830,6 +4831,75 @@ export const runAttempts = ql3Schema.table(
|
||||
],
|
||||
);
|
||||
|
||||
export const runCancellationDispatches = ql3Schema.table(
|
||||
'run_cancellation_dispatches',
|
||||
{
|
||||
runId: varchar('run_id', { length: 36 }).primaryKey(),
|
||||
attemptId: varchar('attempt_id', { length: 36 }).notNull(),
|
||||
status: varchar('status', { length: 32 }).notNull(),
|
||||
version: integer('version').notNull(),
|
||||
dispatchCount: integer('dispatch_count').notNull(),
|
||||
nextAttemptAtMs: bigint('next_attempt_at_ms', { mode: 'number' }),
|
||||
leaseOwner: varchar('lease_owner', { length: 128 }),
|
||||
leaseTokenDigest: char('lease_token_digest', { length: 64 }),
|
||||
leaseExpiresAtMs: bigint('lease_expires_at_ms', { mode: 'number' }),
|
||||
lastResult: varchar('last_result', { length: 32 }),
|
||||
lastDispatchedAtMs: bigint('last_dispatched_at_ms', { mode: 'number' }),
|
||||
createdAtMs: bigint('created_at_ms', { mode: 'number' }).notNull(),
|
||||
updatedAtMs: bigint('updated_at_ms', { mode: 'number' }).notNull(),
|
||||
},
|
||||
(table) => [
|
||||
foreignKey({
|
||||
name: 'ql3_run_cancellation_dispatch_run_fk',
|
||||
columns: [table.runId],
|
||||
foreignColumns: [runs.id],
|
||||
})
|
||||
.onDelete('cascade')
|
||||
.onUpdate('restrict'),
|
||||
foreignKey({
|
||||
name: 'ql3_run_cancellation_dispatch_attempt_fk',
|
||||
columns: [table.runId, table.attemptId],
|
||||
foreignColumns: [runAttempts.runId, runAttempts.id],
|
||||
})
|
||||
.onDelete('cascade')
|
||||
.onUpdate('restrict'),
|
||||
check(
|
||||
'ql3_run_cancellation_dispatch_status_check',
|
||||
sql`${table.status} in ('pending', 'leased', 'retry_wait', 'dispatched', 'blocked')`,
|
||||
),
|
||||
check(
|
||||
'ql3_run_cancellation_dispatch_result_check',
|
||||
sql`${table.lastResult} is null or ${table.lastResult} in ('termination_requested', 'already_exited', 'identity_mismatch', 'pid_mismatch', 'unsupported', 'invalid', 'controller_missing', 'handle_missing', 'dispatch_error')`,
|
||||
),
|
||||
check(
|
||||
'ql3_run_cancellation_dispatch_counter_check',
|
||||
sql`${table.version} between 0 and 2147483647 and ${table.dispatchCount} between 0 and 2147483647 and ${table.version} >= ${table.dispatchCount} and ((${table.status} = 'pending' and ${table.version} = 0 and ${table.dispatchCount} = 0) or (${table.status} <> 'pending' and ${table.dispatchCount} >= 1))`,
|
||||
),
|
||||
check(
|
||||
'ql3_run_cancellation_dispatch_time_check',
|
||||
sql`(${table.nextAttemptAtMs} is null or ${table.nextAttemptAtMs} >= 0) and (${table.leaseExpiresAtMs} is null or ${table.leaseExpiresAtMs} >= 0) and (${table.lastDispatchedAtMs} is null or ${table.lastDispatchedAtMs} >= 0) and ${table.createdAtMs} >= 0 and ${table.updatedAtMs} >= ${table.createdAtMs}`,
|
||||
),
|
||||
check(
|
||||
'ql3_run_cancellation_dispatch_lease_digest_check',
|
||||
sql`${table.leaseTokenDigest} is null or ${table.leaseTokenDigest} ~ '^[0-9a-f]{64}$'`,
|
||||
),
|
||||
check(
|
||||
'ql3_run_cancellation_dispatch_shape_check',
|
||||
sql`(${table.status} = 'leased' and ${table.nextAttemptAtMs} is null and ${table.leaseOwner} is not null and octet_length(${table.leaseOwner}) between 1 and 128 and ${table.leaseOwner} !~ '[[:cntrl:]]' and ${table.leaseTokenDigest} is not null and ${table.leaseExpiresAtMs} is not null) or (${table.status} in ('pending', 'retry_wait') and ${table.nextAttemptAtMs} is not null and ${table.leaseOwner} is null and ${table.leaseTokenDigest} is null and ${table.leaseExpiresAtMs} is null) or (${table.status} in ('dispatched', 'blocked') and ${table.nextAttemptAtMs} is null and ${table.leaseOwner} is null and ${table.leaseTokenDigest} is null and ${table.leaseExpiresAtMs} is null and ${table.lastResult} is not null)`,
|
||||
),
|
||||
check(
|
||||
'ql3_run_cancellation_dispatch_result_state_check',
|
||||
sql`(${table.status} = 'pending' and ${table.lastResult} is null) or (${table.status} in ('leased', 'retry_wait') and (${table.lastResult} is null or ${table.lastResult} in ('controller_missing', 'handle_missing', 'dispatch_error'))) or (${table.status} = 'dispatched' and ${table.lastResult} in ('termination_requested', 'already_exited')) or (${table.status} = 'blocked' and ${table.lastResult} in ('identity_mismatch', 'pid_mismatch', 'unsupported', 'invalid'))`,
|
||||
),
|
||||
index('ql3_run_cancellation_dispatch_due_idx')
|
||||
.on(table.nextAttemptAtMs, table.runId)
|
||||
.where(sql`${table.status} in ('pending', 'retry_wait')`),
|
||||
index('ql3_run_cancellation_dispatch_lease_expiry_idx')
|
||||
.on(table.leaseExpiresAtMs, table.runId)
|
||||
.where(sql`${table.status} = 'leased'`),
|
||||
],
|
||||
);
|
||||
|
||||
export const runAttemptLogRetentionControls = ql3Schema.table(
|
||||
'run_attempt_log_retention_controls',
|
||||
{
|
||||
@@ -6211,6 +6281,7 @@ export const ql3PostgresTables = [
|
||||
toolExecutionResultRekeyHeads,
|
||||
toolResultKeyRetirementReceipts,
|
||||
runAttempts,
|
||||
runCancellationDispatches,
|
||||
runAttemptLogRetentionControls,
|
||||
runAttemptLogArtifactTombstones,
|
||||
workerSessions,
|
||||
|
||||
@@ -21,12 +21,13 @@ export interface PostgresSchemaContractTrigger {
|
||||
export interface PostgresSchemaContract {
|
||||
readonly schema: 'ql3';
|
||||
readonly contractName: 'control-core';
|
||||
readonly contractVersion: 64;
|
||||
readonly migrationId: 'pg-0065-approved-action-manual-recovery';
|
||||
readonly contractVersion: 65;
|
||||
readonly migrationId: 'pg-0066-cancellation-dispatch';
|
||||
readonly minimumServerMajor: 16;
|
||||
readonly maximumServerMajor: 18;
|
||||
readonly capabilities: Readonly<{
|
||||
run_core: 1;
|
||||
run_cancellation_dispatch: 1;
|
||||
run_attempt_log_retention: 1;
|
||||
run_management_boundary: 1;
|
||||
run_management_stop: 1;
|
||||
@@ -118,8 +119,8 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
Object.freeze({
|
||||
schema: 'ql3',
|
||||
contractName: 'control-core',
|
||||
contractVersion: 64,
|
||||
migrationId: 'pg-0065-approved-action-manual-recovery',
|
||||
contractVersion: 65,
|
||||
migrationId: 'pg-0066-cancellation-dispatch',
|
||||
minimumServerMajor: 16,
|
||||
maximumServerMajor: 18,
|
||||
capabilities: Object.freeze({
|
||||
@@ -167,6 +168,7 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
project_policy: 1,
|
||||
project_tool_definition_snapshot: 1,
|
||||
run_core: 1,
|
||||
run_cancellation_dispatch: 1,
|
||||
run_attempt_log_retention: 1,
|
||||
run_management_boundary: 1,
|
||||
run_management_stop: 1,
|
||||
@@ -1289,6 +1291,21 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
'error_code',
|
||||
'error_summary',
|
||||
]),
|
||||
table('run_cancellation_dispatches', [
|
||||
'run_id',
|
||||
'attempt_id',
|
||||
'status',
|
||||
'version',
|
||||
'dispatch_count',
|
||||
'next_attempt_at_ms',
|
||||
'lease_owner',
|
||||
'lease_token_digest',
|
||||
'lease_expires_at_ms',
|
||||
'last_result',
|
||||
'last_dispatched_at_ms',
|
||||
'created_at_ms',
|
||||
'updated_at_ms',
|
||||
]),
|
||||
table('run_attempt_log_retention_controls', [
|
||||
'attempt_id',
|
||||
'project_id',
|
||||
@@ -1770,9 +1787,13 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
'ql3_result_retirement_catalog_idx',
|
||||
'run_attempts_pkey',
|
||||
'ql3_run_attempts_run_attempt_uidx',
|
||||
'ql3_run_attempts_run_id_uidx',
|
||||
'ql3_run_attempts_dispatch_candidates_idx',
|
||||
'ql3_run_attempts_recovery_idx',
|
||||
'ql3_run_attempts_lease_idx',
|
||||
'run_cancellation_dispatches_pkey',
|
||||
'ql3_run_cancellation_dispatch_due_idx',
|
||||
'ql3_run_cancellation_dispatch_lease_expiry_idx',
|
||||
'run_attempt_log_retention_controls_pkey',
|
||||
'ql3_run_log_retention_control_artifact_key',
|
||||
'ql3_run_log_retention_retry_idx',
|
||||
@@ -2106,6 +2127,13 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
'ql3_runs_cancel_reason_check',
|
||||
'ql3_run_attempts_attempt_check',
|
||||
'ql3_run_attempts_status_check',
|
||||
'ql3_run_cancellation_dispatch_status_check',
|
||||
'ql3_run_cancellation_dispatch_result_check',
|
||||
'ql3_run_cancellation_dispatch_counter_check',
|
||||
'ql3_run_cancellation_dispatch_time_check',
|
||||
'ql3_run_cancellation_dispatch_lease_digest_check',
|
||||
'ql3_run_cancellation_dispatch_shape_check',
|
||||
'ql3_run_cancellation_dispatch_result_state_check',
|
||||
'ql3_run_attempts_pid_check',
|
||||
'ql3_run_attempts_lease_expiry_check',
|
||||
'ql3_run_attempts_worker_session_id_check',
|
||||
@@ -2445,6 +2473,8 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
|
||||
'ql3_result_rekey_head_overlay_fk',
|
||||
'ql3_result_retirement_catalog_fk',
|
||||
'ql3_run_attempts_run_fk',
|
||||
'ql3_run_cancellation_dispatch_run_fk',
|
||||
'ql3_run_cancellation_dispatch_attempt_fk',
|
||||
'ql3_run_attempts_step_run_fk',
|
||||
'ql3_run_log_retention_control_attempt_fk',
|
||||
'ql3_run_log_retention_control_run_fk',
|
||||
|
||||
@@ -588,6 +588,12 @@ const REQUIRED_RUNTIME_PRIVILEGES = Object.freeze({
|
||||
update: true,
|
||||
delete: false,
|
||||
}),
|
||||
run_cancellation_dispatches: Object.freeze({
|
||||
select: true,
|
||||
insert: true,
|
||||
update: true,
|
||||
delete: false,
|
||||
}),
|
||||
run_attempt_log_retention_controls: Object.freeze({
|
||||
select: true,
|
||||
insert: true,
|
||||
@@ -1131,6 +1137,12 @@ const REQUIRED_ADMIN_PRIVILEGES = Object.freeze({
|
||||
update: false,
|
||||
delete: false,
|
||||
}),
|
||||
run_cancellation_dispatches: Object.freeze({
|
||||
select: false,
|
||||
insert: false,
|
||||
update: false,
|
||||
delete: false,
|
||||
}),
|
||||
run_attempt_log_retention_controls: Object.freeze({
|
||||
select: false,
|
||||
insert: false,
|
||||
|
||||
Reference in New Issue
Block a user