@vzn/vx 0.0.616 → 0.0.617
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/priorities.ts +11 -1
- package/src/graph/scheduler.ts +17 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vzn/vx",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.617",
|
|
4
4
|
"description": "The fastest 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.617",
|
|
25
|
+
"@vzn/vx-linux-arm64": "0.0.617",
|
|
26
|
+
"@vzn/vx-darwin-x64": "0.0.617",
|
|
27
|
+
"@vzn/vx-darwin-arm64": "0.0.617"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@anthropic-ai/sandbox-runtime": "^0.0.76"
|
package/src/graph/priorities.ts
CHANGED
|
@@ -24,7 +24,17 @@ export function tieredReverseDepCount(
|
|
|
24
24
|
): Map<string, number> {
|
|
25
25
|
const exec = new Map<string, TaskNode>()
|
|
26
26
|
for (const [id, node] of nodes) if (!restoreTier.has(id)) exec.set(id, node)
|
|
27
|
-
|
|
27
|
+
// An exec tier with no edge inside it (a warm run's groups) counts 0
|
|
28
|
+
// everywhere: no closure to build.
|
|
29
|
+
let linked = false
|
|
30
|
+
for (const node of exec.values()) {
|
|
31
|
+
if (node.deps.some((d) => exec.has(d))) {
|
|
32
|
+
linked = true
|
|
33
|
+
break
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const counts = linked ? computeReverseDepCount(exec) : new Map<string, number>()
|
|
37
|
+
if (!linked) for (const id of exec.keys()) counts.set(id, 0)
|
|
28
38
|
let feeds = false
|
|
29
39
|
for (const node of exec.values()) {
|
|
30
40
|
const weight = 1 + counts.get(node.id)!
|
package/src/graph/scheduler.ts
CHANGED
|
@@ -324,6 +324,9 @@ export interface ScheduleOptions {
|
|
|
324
324
|
class ReadyHeap {
|
|
325
325
|
private readonly ids: string[] = []
|
|
326
326
|
private readonly seq: number[] = []
|
|
327
|
+
// Each slot's priority, read once at push: a map lookup per comparison
|
|
328
|
+
// was two per heap level on every push and pop.
|
|
329
|
+
private readonly prio: number[] = []
|
|
327
330
|
private next = 0
|
|
328
331
|
constructor(private readonly priority: ReadonlyMap<string, number>) {}
|
|
329
332
|
get size(): number {
|
|
@@ -331,8 +334,8 @@ class ReadyHeap {
|
|
|
331
334
|
}
|
|
332
335
|
/** True if slot i outranks slot j (higher priority, or equal priority + earlier seq). */
|
|
333
336
|
private higher(i: number, j: number): boolean {
|
|
334
|
-
const pi = this.
|
|
335
|
-
const pj = this.
|
|
337
|
+
const pi = this.prio[i]!
|
|
338
|
+
const pj = this.prio[j]!
|
|
336
339
|
return pi !== pj ? pi > pj : this.seq[i]! < this.seq[j]!
|
|
337
340
|
}
|
|
338
341
|
private swap(i: number, j: number): void {
|
|
@@ -342,6 +345,9 @@ class ReadyHeap {
|
|
|
342
345
|
const si = this.seq[i]!
|
|
343
346
|
this.seq[i] = this.seq[j]!
|
|
344
347
|
this.seq[j] = si
|
|
348
|
+
const pi = this.prio[i]!
|
|
349
|
+
this.prio[i] = this.prio[j]!
|
|
350
|
+
this.prio[j] = pi
|
|
345
351
|
}
|
|
346
352
|
/**
|
|
347
353
|
* `seq` defaults to a fresh monotonic counter. A parked-then-repushed
|
|
@@ -361,6 +367,7 @@ class ReadyHeap {
|
|
|
361
367
|
push(id: string, seq: number = this.next++): void {
|
|
362
368
|
this.ids.push(id)
|
|
363
369
|
this.seq.push(seq)
|
|
370
|
+
this.prio.push(this.priority.get(id) ?? 0)
|
|
364
371
|
let i = this.ids.length - 1
|
|
365
372
|
while (i > 0) {
|
|
366
373
|
const parent = (i - 1) >> 1
|
|
@@ -379,9 +386,11 @@ class ReadyHeap {
|
|
|
379
386
|
const top = this.ids[0]!
|
|
380
387
|
const lastId = this.ids.pop()!
|
|
381
388
|
const lastSeq = this.seq.pop()!
|
|
389
|
+
const lastPrio = this.prio.pop()!
|
|
382
390
|
if (n > 1) {
|
|
383
391
|
this.ids[0] = lastId
|
|
384
392
|
this.seq[0] = lastSeq
|
|
393
|
+
this.prio[0] = lastPrio
|
|
385
394
|
let i = 0
|
|
386
395
|
for (;;) {
|
|
387
396
|
const l = 2 * i + 1
|
|
@@ -701,14 +710,18 @@ export async function runGraph(options: ScheduleOptions): Promise<Map<string, Ta
|
|
|
701
710
|
// could fail anyway.
|
|
702
711
|
const aborted = (): boolean => options.signal?.aborted === true
|
|
703
712
|
const serverDied = options.serverDied ?? ((): boolean => false)
|
|
704
|
-
const deadServerVia = (id: string): string | undefined =>
|
|
705
|
-
deadServerBehind(nodes, serverDied, id)
|
|
706
713
|
const servers =
|
|
707
714
|
options.serverDied === undefined
|
|
708
715
|
? []
|
|
709
716
|
: [...nodes.values()]
|
|
710
717
|
.filter((n) => n.config.exec?.persistent !== undefined)
|
|
711
718
|
.map((n) => n.id)
|
|
719
|
+
// Only a server can die: with none in the graph, no walk (a stack and
|
|
720
|
+
// a set per dependency of every exec-tier task, X-171).
|
|
721
|
+
const deadServerVia =
|
|
722
|
+
servers.length === 0
|
|
723
|
+
? (): undefined => undefined
|
|
724
|
+
: (id: string): string | undefined => deadServerBehind(nodes, serverDied, id)
|
|
712
725
|
const willSkip = (id: string): boolean => {
|
|
713
726
|
if (failFastTripped || aborted()) return true
|
|
714
727
|
if (continueMode === 'never' && servers.some(serverDied)) {
|