task-manager-logic 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/processors.ts +35 -6
package/package.json
CHANGED
package/src/processors.ts
CHANGED
|
@@ -497,15 +497,10 @@ export async function replanTask(
|
|
|
497
497
|
tasks: input.plan.tasks,
|
|
498
498
|
relations: input.plan.relations,
|
|
499
499
|
};
|
|
500
|
+
assertReplanDurableTasksImmutable(snapshot, definition);
|
|
500
501
|
validateTaskSpaceDefinition(definition, normalizeTaskProcessorConfig(config));
|
|
501
502
|
const artifactBodies = input.artifactBodies ?? [];
|
|
502
503
|
await assertArtifactAuthority(runtime.owner, input.taskSpaceId, definition.tasks.flatMap(({ inputArtifacts }) => inputArtifacts), artifactBodies);
|
|
503
|
-
const nextIds = new Set(definition.tasks.map(({ taskId }) => taskId));
|
|
504
|
-
for (const prior of snapshot.tasks) {
|
|
505
|
-
if (!nextIds.has(prior.taskId) && (isTerminal(prior.status) || prior.activeClaim)) {
|
|
506
|
-
throw new TaskManagerError('terminal-task-immutable', `replan cannot remove durable task ${prior.taskId}`);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
504
|
const provisional: TaskRecord[] = definition.tasks.map((nextDefinition) => {
|
|
510
505
|
const prior = taskRecordById(snapshot, nextDefinition.taskId);
|
|
511
506
|
if (prior) return { ...prior, definition: nextDefinition, updatedAt: input.replannedAt };
|
|
@@ -714,6 +709,40 @@ function replaceTask(snapshot: TaskSpaceSnapshot, replacement: TaskRecord): Task
|
|
|
714
709
|
return snapshot.tasks.map((task) => task.taskId === replacement.taskId ? replacement : task);
|
|
715
710
|
}
|
|
716
711
|
|
|
712
|
+
function assertReplanDurableTasksImmutable(
|
|
713
|
+
snapshot: TaskSpaceSnapshot,
|
|
714
|
+
nextDefinition: TaskSpaceDefinition,
|
|
715
|
+
): void {
|
|
716
|
+
for (const prior of snapshot.tasks) {
|
|
717
|
+
const next = nextDefinition.tasks.find(({ taskId }) => taskId === prior.taskId);
|
|
718
|
+
if (!next) {
|
|
719
|
+
if (isTerminal(prior.status) || prior.activeClaim) {
|
|
720
|
+
throw new TaskManagerError('terminal-task-immutable', `replan cannot remove durable task ${prior.taskId}`);
|
|
721
|
+
}
|
|
722
|
+
continue;
|
|
723
|
+
}
|
|
724
|
+
if (!isTerminal(prior.status)) continue;
|
|
725
|
+
const priorRelations = incidentRelations(snapshot.definition, prior.taskId);
|
|
726
|
+
const nextRelations = incidentRelations(nextDefinition, prior.taskId);
|
|
727
|
+
if (canonicalOwnDataDigest(prior.definition) !== canonicalOwnDataDigest(next)
|
|
728
|
+
|| canonicalOwnDataDigest(priorRelations) !== canonicalOwnDataDigest(nextRelations)) {
|
|
729
|
+
throw new TaskManagerError(
|
|
730
|
+
'terminal-task-immutable',
|
|
731
|
+
`replan cannot rewrite terminal task ${prior.taskId} definition, profile, identity or relations`,
|
|
732
|
+
);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
function incidentRelations(
|
|
738
|
+
definition: TaskSpaceDefinition,
|
|
739
|
+
taskId: TaskId,
|
|
740
|
+
): TaskSpaceDefinition['relations'] {
|
|
741
|
+
return definition.relations.filter((relation) => relation.kind === 'parent-child'
|
|
742
|
+
? relation.parentTaskId === taskId || relation.childTaskId === taskId
|
|
743
|
+
: relation.predecessorTaskId === taskId || relation.successorTaskId === taskId);
|
|
744
|
+
}
|
|
745
|
+
|
|
717
746
|
function dependenciesSucceeded(
|
|
718
747
|
completionGraph: TaskCompletionGraph,
|
|
719
748
|
tasks: readonly TaskRecord[],
|