mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import type {
|
||||
ExecutionCommand,
|
||||
ExecutionResourcePolicy,
|
||||
ExecutionSpec,
|
||||
ExecutorType,
|
||||
} from './execution';
|
||||
import { EXECUTOR_TYPES } from './execution';
|
||||
import { cloneExecutionSpec } from './executionSpec';
|
||||
import type { RunDispatchCandidate } from './runDispatchCandidate';
|
||||
|
||||
export interface TaskExecutionSpecTemplate {
|
||||
command: ExecutionCommand;
|
||||
workingDirectory?: string;
|
||||
environmentPolicy: ExecutionSpec['environmentPolicy'];
|
||||
timeoutMs?: number;
|
||||
terminationGraceMs: number;
|
||||
resourcePolicy?: ExecutionResourcePolicy;
|
||||
}
|
||||
|
||||
export interface PinnedTaskExecutionRevision {
|
||||
projectId: string;
|
||||
taskId: string;
|
||||
taskRevision: string;
|
||||
executorType: ExecutorType;
|
||||
execution: TaskExecutionSpecTemplate;
|
||||
/** Opaque immutable recipe for Secret, output and callback capabilities. */
|
||||
contextRef: string;
|
||||
}
|
||||
|
||||
function assertIdentifier(name: string, value: string, maximum: number): void {
|
||||
if (
|
||||
typeof value !== 'string' ||
|
||||
value.length < 1 ||
|
||||
value.length > maximum ||
|
||||
/[\u0000-\u001f\u007f]/.test(value)
|
||||
) {
|
||||
throw new TypeError(`${name} is invalid`);
|
||||
}
|
||||
}
|
||||
|
||||
function templateSpec(
|
||||
revision: PinnedTaskExecutionRevision,
|
||||
identity: Pick<
|
||||
ExecutionSpec,
|
||||
'runId' | 'attemptId' | 'projectId' | 'taskId' | 'taskRevision'
|
||||
>,
|
||||
): ExecutionSpec {
|
||||
const execution = revision.execution;
|
||||
return {
|
||||
runId: identity.runId,
|
||||
attemptId: identity.attemptId,
|
||||
projectId: identity.projectId,
|
||||
taskId: identity.taskId,
|
||||
taskRevision: identity.taskRevision,
|
||||
command: execution.command,
|
||||
...(execution.workingDirectory === undefined
|
||||
? {}
|
||||
: { workingDirectory: execution.workingDirectory }),
|
||||
environmentPolicy: execution.environmentPolicy,
|
||||
...(execution.timeoutMs === undefined
|
||||
? {}
|
||||
: { timeoutMs: execution.timeoutMs }),
|
||||
terminationGraceMs: execution.terminationGraceMs,
|
||||
...(execution.resourcePolicy === undefined
|
||||
? {}
|
||||
: { resourcePolicy: execution.resourcePolicy }),
|
||||
};
|
||||
}
|
||||
|
||||
export function assertPinnedTaskExecutionRevision(
|
||||
revision: PinnedTaskExecutionRevision,
|
||||
): void {
|
||||
if (!revision || typeof revision !== 'object' || Array.isArray(revision)) {
|
||||
throw new TypeError('Pinned Task execution revision must be an object');
|
||||
}
|
||||
assertIdentifier('projectId', revision.projectId, 128);
|
||||
assertIdentifier('taskId', revision.taskId, 255);
|
||||
assertIdentifier('taskRevision', revision.taskRevision, 128);
|
||||
assertIdentifier('contextRef', revision.contextRef, 512);
|
||||
if (!EXECUTOR_TYPES.includes(revision.executorType)) {
|
||||
throw new TypeError('Pinned Task executorType is invalid');
|
||||
}
|
||||
cloneExecutionSpec(
|
||||
templateSpec(revision, {
|
||||
runId: 'revision-validation-run',
|
||||
attemptId: 'revision-validation-attempt',
|
||||
projectId: revision.projectId,
|
||||
taskId: revision.taskId,
|
||||
taskRevision: revision.taskRevision,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export function executionSpecFromPinnedTaskRevision(
|
||||
candidate: RunDispatchCandidate,
|
||||
revision: PinnedTaskExecutionRevision,
|
||||
): ExecutionSpec {
|
||||
assertPinnedTaskExecutionRevision(revision);
|
||||
if (
|
||||
revision.projectId !== candidate.projectId ||
|
||||
revision.taskId !== candidate.taskId ||
|
||||
revision.taskRevision !== candidate.taskRevision ||
|
||||
revision.executorType !== candidate.executorType
|
||||
) {
|
||||
throw new TypeError(
|
||||
'Pinned Task execution revision does not match its dispatch candidate',
|
||||
);
|
||||
}
|
||||
return cloneExecutionSpec(
|
||||
templateSpec(revision, {
|
||||
runId: candidate.runId,
|
||||
attemptId: candidate.attemptId,
|
||||
projectId: candidate.projectId,
|
||||
taskId: candidate.taskId,
|
||||
taskRevision: candidate.taskRevision,
|
||||
}),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user