Files
qinglong/back/migrations/0011-run-retry-policy.ts

116 lines
3.6 KiB
TypeScript

import { createHash } from 'crypto';
import { DataTypes, Op } from 'sequelize';
import { RUN_TABLE } from './0002-run-schema';
import type { Migration } from './types';
export const RUN_RETRY_POLICY_TABLE = 'RunRetryPolicies';
export const RUN_RETRY_POLICY_DUE_INDEX = 'run_retry_policies_due_idx';
export const RUN_LOST_RETRY_INDEX = 'runs_lost_retry_idx';
const manifest = {
table: RUN_RETRY_POLICY_TABLE,
columns: [
'run_id',
'max_attempts',
'retry_on_lost',
'safety',
'backoff_base_ms',
'backoff_max_ms',
'next_attempt_at_ms',
'version',
'created_at_ms',
'updated_at_ms',
],
indexes: [
`${RUN_LOST_RETRY_INDEX}(execution_owner,status,id)`,
`${RUN_RETRY_POLICY_DUE_INDEX}(next_attempt_at_ms,run_id) WHERE next_attempt_at_ms IS NOT NULL`,
],
constraints: [
'run_retry_policies_max_attempts_check',
'run_retry_policies_backoff_base_check',
'run_retry_policies_backoff_max_check',
'run_retry_policies_version_check',
],
};
export const runRetryPolicyManifest = manifest;
export const runRetryPolicyMigration: Migration = {
id: '0011-run-retry-policy',
checksum: createHash('sha256').update(JSON.stringify(manifest)).digest('hex'),
async up({ queryInterface, transaction }) {
await queryInterface.createTable(
RUN_RETRY_POLICY_TABLE,
{
run_id: {
type: DataTypes.STRING(36),
allowNull: false,
primaryKey: true,
references: { model: RUN_TABLE, key: 'id' },
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
},
max_attempts: { type: DataTypes.INTEGER, allowNull: false },
retry_on_lost: { type: DataTypes.BOOLEAN, allowNull: false },
safety: { type: DataTypes.STRING(16), allowNull: false },
backoff_base_ms: { type: DataTypes.BIGINT, allowNull: false },
backoff_max_ms: { type: DataTypes.BIGINT, allowNull: false },
next_attempt_at_ms: { type: DataTypes.BIGINT, allowNull: true },
version: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
},
created_at_ms: { type: DataTypes.BIGINT, allowNull: false },
updated_at_ms: { type: DataTypes.BIGINT, allowNull: false },
},
{ transaction },
);
await queryInterface.addConstraint(RUN_RETRY_POLICY_TABLE, {
fields: ['max_attempts'],
type: 'check',
where: { max_attempts: { [Op.between]: [1, 16] } },
name: 'run_retry_policies_max_attempts_check',
transaction,
});
await queryInterface.addConstraint(RUN_RETRY_POLICY_TABLE, {
fields: ['backoff_base_ms'],
type: 'check',
where: { backoff_base_ms: { [Op.gte]: 0 } },
name: 'run_retry_policies_backoff_base_check',
transaction,
});
await queryInterface.addConstraint(RUN_RETRY_POLICY_TABLE, {
fields: ['backoff_max_ms'],
type: 'check',
where: { backoff_max_ms: { [Op.gte]: 0 } },
name: 'run_retry_policies_backoff_max_check',
transaction,
});
await queryInterface.addConstraint(RUN_RETRY_POLICY_TABLE, {
fields: ['version'],
type: 'check',
where: { version: { [Op.gte]: 0 } },
name: 'run_retry_policies_version_check',
transaction,
});
await queryInterface.addIndex(
RUN_TABLE,
['execution_owner', 'status', 'id'],
{
name: RUN_LOST_RETRY_INDEX,
transaction,
},
);
await queryInterface.addIndex(
RUN_RETRY_POLICY_TABLE,
['next_attempt_at_ms', 'run_id'],
{
name: RUN_RETRY_POLICY_DUE_INDEX,
where: { next_attempt_at_ms: { [Op.ne]: null } },
transaction,
},
);
},
};