@vzn/vx 0.0.374 → 0.0.375
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 +5 -5
- package/src/graph/index.ts +1 -0
- package/src/graph/scheduler.ts +22 -13
- package/src/orchestrator/run.ts +19 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vzn/vx",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.375",
|
|
4
4
|
"description": "A fast, correct task runner and build cache for JavaScript monorepos.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"node": ">=18"
|
|
22
22
|
},
|
|
23
23
|
"optionalDependencies": {
|
|
24
|
-
"@vzn/vx-linux-x64": "0.0.
|
|
25
|
-
"@vzn/vx-linux-arm64": "0.0.
|
|
26
|
-
"@vzn/vx-darwin-x64": "0.0.
|
|
27
|
-
"@vzn/vx-darwin-arm64": "0.0.
|
|
24
|
+
"@vzn/vx-linux-x64": "0.0.375",
|
|
25
|
+
"@vzn/vx-linux-arm64": "0.0.375",
|
|
26
|
+
"@vzn/vx-darwin-x64": "0.0.375",
|
|
27
|
+
"@vzn/vx-darwin-arm64": "0.0.375"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@anthropic-ai/sandbox-runtime": "^0.0.76"
|
package/src/graph/index.ts
CHANGED
package/src/graph/scheduler.ts
CHANGED
|
@@ -338,6 +338,26 @@ class ReadyHeap {
|
|
|
338
338
|
}
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
+
/**
|
|
342
|
+
* The dead server a dependency stands for: itself, or one a group reaches.
|
|
343
|
+
* A group is a name for its deps, and it finished the moment the server
|
|
344
|
+
* was ready, so a task behind it ran against the dead one.
|
|
345
|
+
*/
|
|
346
|
+
export function deadServerBehind(
|
|
347
|
+
nodes: ReadonlyMap<string, TaskNode>,
|
|
348
|
+
serverDied: (id: string) => boolean,
|
|
349
|
+
id: string,
|
|
350
|
+
): string | undefined {
|
|
351
|
+
if (serverDied(id)) return id
|
|
352
|
+
const n = nodes.get(id)
|
|
353
|
+
if (n === undefined || !isGroupTask(n)) return undefined
|
|
354
|
+
for (const d of n.deps) {
|
|
355
|
+
const dead = deadServerBehind(nodes, serverDied, d)
|
|
356
|
+
if (dead !== undefined) return dead
|
|
357
|
+
}
|
|
358
|
+
return undefined
|
|
359
|
+
}
|
|
360
|
+
|
|
341
361
|
/**
|
|
342
362
|
* Run the task graph. Independent tasks run in parallel up to `concurrency`.
|
|
343
363
|
* If a task fails, its dependents are marked `skipped` but unrelated tasks
|
|
@@ -572,19 +592,8 @@ export async function runGraph(options: ScheduleOptions): Promise<Map<string, Ta
|
|
|
572
592
|
// could fail anyway.
|
|
573
593
|
const aborted = (): boolean => options.signal?.aborted === true
|
|
574
594
|
const serverDied = options.serverDied ?? ((): boolean => false)
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
// the server was ready, so a task behind it ran against the dead one.
|
|
578
|
-
const deadServerVia = (id: string): string | undefined => {
|
|
579
|
-
if (serverDied(id)) return id
|
|
580
|
-
const n = nodes.get(id)
|
|
581
|
-
if (n === undefined || !isGroupTask(n)) return undefined
|
|
582
|
-
for (const d of n.deps) {
|
|
583
|
-
const dead = deadServerVia(d)
|
|
584
|
-
if (dead !== undefined) return dead
|
|
585
|
-
}
|
|
586
|
-
return undefined
|
|
587
|
-
}
|
|
595
|
+
const deadServerVia = (id: string): string | undefined =>
|
|
596
|
+
deadServerBehind(nodes, serverDied, id)
|
|
588
597
|
const servers =
|
|
589
598
|
options.serverDied === undefined
|
|
590
599
|
? []
|
package/src/orchestrator/run.ts
CHANGED
|
@@ -22,6 +22,7 @@ import { DeferredOutputs } from './deferred-outputs.js'
|
|
|
22
22
|
import { resolveDownloadModes } from './download-policy.js'
|
|
23
23
|
import type { TaskExecutor } from '../exec/index.js'
|
|
24
24
|
import {
|
|
25
|
+
deadServerBehind,
|
|
25
26
|
isGroupTask,
|
|
26
27
|
markSurfacedDeps,
|
|
27
28
|
runGraph,
|
|
@@ -873,12 +874,28 @@ async function runOnBus(
|
|
|
873
874
|
`[vx] --exclude-dependencies: ${excluded.unsaved} cached task(s) build on a skipped dependency; what they build is not saved`,
|
|
874
875
|
)
|
|
875
876
|
}
|
|
876
|
-
|
|
877
|
+
// A server that ended on its own is failed (the end of the run says
|
|
878
|
+
// so); what has not yet started hears it before it dispatches (C-88).
|
|
879
|
+
const serverDied = (id: string): boolean => {
|
|
880
|
+
const child = persistentRegistry.get(id)
|
|
881
|
+
return child !== undefined && hasEnded(child) && child.exitCode !== 0
|
|
882
|
+
}
|
|
883
|
+
// Under `always` a task that starts while a server it depends on is
|
|
884
|
+
// dead runs on a failure the outcomes do not hold yet (the server's
|
|
885
|
+
// says `success` until the run ends), so it is seeded here, at its
|
|
886
|
+
// dispatch, and the tracker carries it to what is built on it.
|
|
887
|
+
const taintSeeds = new Set(excluded.seeds)
|
|
888
|
+
const taint = taintTracker(options.continueMode === 'always', taintSeeds, nodes)
|
|
877
889
|
const dependedOn = new Set<string>()
|
|
878
890
|
for (const n of nodes.values()) for (const d of n.deps) dependedOn.add(d)
|
|
879
891
|
|
|
880
892
|
const buildExecuteArgs = (node: TaskNode, upstream: TaskOutcome[], reuseProbe = true) => {
|
|
881
893
|
const probe = reuseProbe ? shortCircuit.preProbed.get(node.id) : undefined
|
|
894
|
+
if (
|
|
895
|
+
options.continueMode === 'always' &&
|
|
896
|
+
node.deps.some((d) => deadServerBehind(nodes, serverDied, d) !== undefined)
|
|
897
|
+
)
|
|
898
|
+
taintSeeds.add(node.id)
|
|
882
899
|
const tainted = taint.judge(node, upstream)
|
|
883
900
|
return {
|
|
884
901
|
node,
|
|
@@ -940,12 +957,7 @@ async function runOnBus(
|
|
|
940
957
|
...(hasPooledExecutor(executors) ? { poolOf: poolOfPlacement(placements) } : {}),
|
|
941
958
|
...(admit !== undefined ? { admit } : {}),
|
|
942
959
|
...(options.continueMode !== undefined ? { continueMode: options.continueMode } : {}),
|
|
943
|
-
|
|
944
|
-
// so); what has not yet started hears it before it dispatches (C-88).
|
|
945
|
-
serverDied: (id) => {
|
|
946
|
-
const child = persistentRegistry.get(id)
|
|
947
|
-
return child !== undefined && hasEnded(child) && child.exitCode !== 0
|
|
948
|
-
},
|
|
960
|
+
serverDied,
|
|
949
961
|
signal: stopRun.signal,
|
|
950
962
|
onStart: (node) => {
|
|
951
963
|
log.taskStart?.(node)
|