mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-21 00:17:47 +08:00
225 lines
5.8 KiB
TypeScript
225 lines
5.8 KiB
TypeScript
export const DEPLOYMENT_PROFILES = [
|
|
'edge',
|
|
'standalone',
|
|
'cluster-control',
|
|
'worker',
|
|
] as const;
|
|
|
|
export type DeploymentProfile = (typeof DEPLOYMENT_PROFILES)[number];
|
|
|
|
export interface BoundedRecoveryResourcePolicy {
|
|
intervalMs: number;
|
|
initialDelayMs: number;
|
|
stopTimeoutMs: number;
|
|
pageSize: number;
|
|
maxPages: number;
|
|
}
|
|
|
|
export interface LocalArtifactRetentionResourcePolicy {
|
|
intervalMs: number;
|
|
initialDelayMs: number;
|
|
stopTimeoutMs: number;
|
|
pageSize: number;
|
|
maximumDeletions: number;
|
|
normalRetentionMs: number;
|
|
pressureRetentionMs: number;
|
|
}
|
|
|
|
export interface ApprovedActionResourcePolicy {
|
|
intervalMs: number;
|
|
initialDelayMs: number;
|
|
stopTimeoutMs: number;
|
|
dispatch: {
|
|
pageSize: number;
|
|
maxPages: number;
|
|
};
|
|
recovery: {
|
|
pageSize: number;
|
|
maxPages: number;
|
|
};
|
|
}
|
|
|
|
export interface LocalPrimaryResourcePolicy {
|
|
profile: 'edge' | 'standalone';
|
|
receiptPublishGraceMs: number;
|
|
receiptTerminalMissingRetentionMs: number;
|
|
receiptQuarantineRetentionMs: number;
|
|
completion: BoundedRecoveryResourcePolicy;
|
|
cancellation: BoundedRecoveryResourcePolicy;
|
|
timeout: BoundedRecoveryResourcePolicy;
|
|
retry: BoundedRecoveryResourcePolicy;
|
|
approvedAction: ApprovedActionResourcePolicy;
|
|
artifactRetention: LocalArtifactRetentionResourcePolicy;
|
|
}
|
|
|
|
const VALID_PROFILES = new Set<DeploymentProfile>(DEPLOYMENT_PROFILES);
|
|
|
|
const LOCAL_PRIMARY_POLICIES: Record<
|
|
LocalPrimaryResourcePolicy['profile'],
|
|
LocalPrimaryResourcePolicy
|
|
> = {
|
|
edge: {
|
|
profile: 'edge',
|
|
receiptPublishGraceMs: 50,
|
|
receiptTerminalMissingRetentionMs: 2 * 60_000,
|
|
receiptQuarantineRetentionMs: 5 * 60_000,
|
|
completion: {
|
|
intervalMs: 30_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
pageSize: 8,
|
|
maxPages: 2,
|
|
},
|
|
cancellation: {
|
|
intervalMs: 5_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
pageSize: 8,
|
|
maxPages: 2,
|
|
},
|
|
timeout: {
|
|
intervalMs: 30_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
pageSize: 8,
|
|
maxPages: 2,
|
|
},
|
|
retry: {
|
|
intervalMs: 30_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
pageSize: 8,
|
|
maxPages: 1,
|
|
},
|
|
approvedAction: {
|
|
intervalMs: 30_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
dispatch: { pageSize: 8, maxPages: 1 },
|
|
recovery: { pageSize: 8, maxPages: 1 },
|
|
},
|
|
artifactRetention: {
|
|
intervalMs: 5 * 60_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
pageSize: 8,
|
|
maximumDeletions: 4,
|
|
normalRetentionMs: 7 * 24 * 60 * 60_000,
|
|
pressureRetentionMs: 24 * 60 * 60_000,
|
|
},
|
|
},
|
|
standalone: {
|
|
profile: 'standalone',
|
|
receiptPublishGraceMs: 100,
|
|
receiptTerminalMissingRetentionMs: 60_000,
|
|
receiptQuarantineRetentionMs: 60 * 60_000,
|
|
completion: {
|
|
intervalMs: 2_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
pageSize: 32,
|
|
maxPages: 4,
|
|
},
|
|
cancellation: {
|
|
intervalMs: 1_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
pageSize: 32,
|
|
maxPages: 4,
|
|
},
|
|
timeout: {
|
|
intervalMs: 5_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
pageSize: 32,
|
|
maxPages: 4,
|
|
},
|
|
retry: {
|
|
intervalMs: 5_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
pageSize: 32,
|
|
maxPages: 1,
|
|
},
|
|
approvedAction: {
|
|
intervalMs: 2_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
dispatch: { pageSize: 32, maxPages: 4 },
|
|
recovery: { pageSize: 16, maxPages: 2 },
|
|
},
|
|
artifactRetention: {
|
|
intervalMs: 60_000,
|
|
initialDelayMs: 0,
|
|
stopTimeoutMs: 5_000,
|
|
pageSize: 32,
|
|
maximumDeletions: 16,
|
|
normalRetentionMs: 30 * 24 * 60 * 60_000,
|
|
pressureRetentionMs: 7 * 24 * 60 * 60_000,
|
|
},
|
|
},
|
|
};
|
|
|
|
export function parseDeploymentProfile(
|
|
value: string | undefined,
|
|
): DeploymentProfile {
|
|
if (value === undefined || value === '') return 'standalone';
|
|
if (
|
|
value.trim() !== value ||
|
|
!VALID_PROFILES.has(value as DeploymentProfile)
|
|
) {
|
|
throw new TypeError('QL_DEPLOYMENT_PROFILE is invalid');
|
|
}
|
|
return value as DeploymentProfile;
|
|
}
|
|
|
|
function cloneRecoveryPolicy(
|
|
policy: BoundedRecoveryResourcePolicy,
|
|
): BoundedRecoveryResourcePolicy {
|
|
return { ...policy };
|
|
}
|
|
|
|
function cloneArtifactRetentionPolicy(
|
|
policy: LocalArtifactRetentionResourcePolicy,
|
|
): LocalArtifactRetentionResourcePolicy {
|
|
return { ...policy };
|
|
}
|
|
|
|
function cloneApprovedActionPolicy(
|
|
policy: ApprovedActionResourcePolicy,
|
|
): ApprovedActionResourcePolicy {
|
|
return {
|
|
...policy,
|
|
dispatch: { ...policy.dispatch },
|
|
recovery: { ...policy.recovery },
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The incubating SQLite + LocalProcess Primary stack is intentionally local.
|
|
* Cluster control needs PostgreSQL/shared artifacts; worker has a separate boot
|
|
* topology. Refusing those profiles prevents accidental shared-SQLite clusters.
|
|
*/
|
|
export function localPrimaryResourcePolicy(
|
|
profile: DeploymentProfile,
|
|
): LocalPrimaryResourcePolicy {
|
|
if (profile !== 'edge' && profile !== 'standalone') {
|
|
throw new TypeError(
|
|
`Deployment profile ${profile} cannot host the local SQLite Primary stack`,
|
|
);
|
|
}
|
|
const policy = LOCAL_PRIMARY_POLICIES[profile];
|
|
return {
|
|
profile,
|
|
receiptPublishGraceMs: policy.receiptPublishGraceMs,
|
|
receiptTerminalMissingRetentionMs: policy.receiptTerminalMissingRetentionMs,
|
|
receiptQuarantineRetentionMs: policy.receiptQuarantineRetentionMs,
|
|
completion: cloneRecoveryPolicy(policy.completion),
|
|
cancellation: cloneRecoveryPolicy(policy.cancellation),
|
|
timeout: cloneRecoveryPolicy(policy.timeout),
|
|
retry: cloneRecoveryPolicy(policy.retry),
|
|
approvedAction: cloneApprovedActionPolicy(policy.approvedAction),
|
|
artifactRetention: cloneArtifactRetentionPolicy(policy.artifactRetention),
|
|
};
|
|
}
|