@vzn/vx-dte 0.0.650 → 0.0.652
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/README.md +75 -31
- package/package.json +3 -3
- package/src/dispatch.ts +501 -26
- package/src/forecast.ts +1 -2
- package/src/github.ts +16 -5
- package/src/messages.ts +52 -31
- package/src/orchestrator.ts +551 -352
- package/src/planner.ts +1322 -172
- package/src/plugin.ts +48 -8
- package/src/seal.ts +11 -4
- package/src/wire-host.ts +98 -0
- package/src/wire-thread.ts +168 -0
- package/src/wire.ts +117 -68
- package/src/worker.ts +112 -62
package/src/messages.ts
CHANGED
|
@@ -2,15 +2,7 @@
|
|
|
2
2
|
// (the relay never reads it): orders and status only. Every task's files
|
|
3
3
|
// and output go through the workspace's cache, by the keys these name.
|
|
4
4
|
|
|
5
|
-
import type { CacheFacts,
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* A worker says what it holds every this many heartbeats, and a task's
|
|
9
|
-
* lease is three of them. Every heartbeat (2026-10-25: the fastest, not
|
|
10
|
-
* a free plan's message count): a task its worker dropped while alive
|
|
11
|
-
* goes back in 15 s, not 90.
|
|
12
|
-
*/
|
|
13
|
-
export const HELD_EVERY = 1
|
|
5
|
+
import type { CacheFacts, ExecuteResult, SandboxConfig } from '@vzn/vx'
|
|
14
6
|
|
|
15
7
|
/** A worker's `join` info. */
|
|
16
8
|
export interface WorkerInfo {
|
|
@@ -72,15 +64,25 @@ export interface RunOrder {
|
|
|
72
64
|
/**
|
|
73
65
|
* Its `exec.sandbox`, and for a cached task the projects its key answers
|
|
74
66
|
* for (workspace-relative): the worker builds the request on its own
|
|
75
|
-
* paths and OS (`sandboxRequestFor`), as its orchestrator may run another
|
|
67
|
+
* paths and OS (`sandboxRequestFor`), as its orchestrator may run another;
|
|
68
|
+
* `reads`, the dependencies' outputs it may read (workspace-relative).
|
|
76
69
|
*/
|
|
77
|
-
sandbox?: { config: SandboxConfig; keyed?: string[] }
|
|
70
|
+
sandbox?: { config: SandboxConfig; keyed?: string[]; reads?: string[] }
|
|
78
71
|
/** Its persistent dependencies (`ServerSpec`), `cwd` workspace-relative: the worker starts each once. */
|
|
79
72
|
servers?: ServerOrder[]
|
|
80
73
|
/** The runtime probes its key includes, as the orchestrator answered them: the worker's must answer the same. */
|
|
81
74
|
runtime?: RuntimeOrder[]
|
|
82
75
|
}
|
|
83
76
|
|
|
77
|
+
/**
|
|
78
|
+
* A dependency as an order carries it: whole the first time its worker is
|
|
79
|
+
* sent it under that key, then by its task's name alone.
|
|
80
|
+
*/
|
|
81
|
+
export type WiredDep = DepOrder | string
|
|
82
|
+
|
|
83
|
+
/** A `RunOrder` as it travels: its deps `WiredDep`s, made whole again by the worker. */
|
|
84
|
+
export type SentOrder = Omit<RunOrder, 'deps'> & { deps: WiredDep[] }
|
|
85
|
+
|
|
84
86
|
export interface RuntimeOrder {
|
|
85
87
|
command: string
|
|
86
88
|
output: string
|
|
@@ -100,18 +102,22 @@ export interface ServerOrder {
|
|
|
100
102
|
}
|
|
101
103
|
|
|
102
104
|
export type ToWorker =
|
|
103
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Tasks that fit what it has free: taken, each runs at once. `n` counts
|
|
107
|
+
* its batches, so its report says which it had read.
|
|
108
|
+
*/
|
|
104
109
|
| {
|
|
105
110
|
type: 'batch'
|
|
111
|
+
n: number
|
|
106
112
|
root: string
|
|
107
113
|
/** `root`'s real path, as sandbox paths spell it. */
|
|
108
114
|
realRoot: string
|
|
109
|
-
tasks:
|
|
115
|
+
tasks: SentOrder[]
|
|
110
116
|
/** The run's sandboxed tasks' `exec.sandbox`, in a worker's first batch that has a sandboxed task. */
|
|
111
117
|
sandboxes?: SandboxConfig[]
|
|
112
118
|
}
|
|
113
119
|
/** Part of an order's `deps`, ahead of the batch whose order was too long for one frame. */
|
|
114
|
-
| { type: 'deps'; task: string; deps:
|
|
120
|
+
| { type: 'deps'; task: string; deps: WiredDep[] }
|
|
115
121
|
| { type: 'cancel'; task: string }
|
|
116
122
|
/**
|
|
117
123
|
* It was taken into the run, under the name the run's output gives it,
|
|
@@ -146,26 +152,48 @@ export interface Load {
|
|
|
146
152
|
* `cpu` (one that sent 3, each as a task started, read 0.6 of 2.0 used).
|
|
147
153
|
*/
|
|
148
154
|
readonly avg?: number
|
|
155
|
+
/** When it was read, by the worker's clock: its task times are read against it. */
|
|
156
|
+
readonly at?: number
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** A task's times on its worker, epoch ms by the worker's clock: begun, command ended. */
|
|
160
|
+
export interface Ran {
|
|
161
|
+
readonly startedAt: number
|
|
162
|
+
readonly ranAt: number
|
|
149
163
|
}
|
|
150
164
|
|
|
151
165
|
export type ToOrchestrator =
|
|
152
|
-
/**
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
166
|
+
/**
|
|
167
|
+
* Its command is done; its outputs save now, its cores are free. Never
|
|
168
|
+
* sent alone: it rides the next message, or its `end` says it.
|
|
169
|
+
*/
|
|
170
|
+
| ({ type: 'ran'; task: string; load?: Load } & Ran)
|
|
171
|
+
/**
|
|
172
|
+
* A heartbeat with nothing else said: what it runs, the last batch it
|
|
173
|
+
* read, its live load. A task of that batch or before it no longer
|
|
174
|
+
* names goes back.
|
|
175
|
+
*/
|
|
176
|
+
| { type: 'report'; running: string[]; batch: number; load: Load }
|
|
177
|
+
/** Messages said at one moment, as one frame: waiting `ran`s and the event they ride. */
|
|
178
|
+
| { type: 'together'; messages: ToOrchestrator[] }
|
|
158
179
|
/** It could not run a task it began, not a non-zero exit: a full disk, a failed unpack. */
|
|
159
|
-
| { type: 'fault'; task: string; reason: string }
|
|
180
|
+
| { type: 'fault'; task: string; reason: string; load?: Load }
|
|
160
181
|
/** It ran the task and saved it under `key`; its output is in that entry. */
|
|
161
|
-
| {
|
|
182
|
+
| ({
|
|
183
|
+
type: 'end'
|
|
184
|
+
task: string
|
|
185
|
+
key: string
|
|
186
|
+
result: WiredResult
|
|
187
|
+
endedAt: number
|
|
188
|
+
load?: Load
|
|
189
|
+
} & Ran)
|
|
162
190
|
/**
|
|
163
191
|
* Ahead of an `end` too long for one relay frame, some of its lists:
|
|
164
192
|
* the `end` that follows adds its own to them. One `end` with a sandboxed
|
|
165
193
|
* task's 9000 violations was over the relay's 1 MiB, and the run waited
|
|
166
194
|
* for it (2026-10-25).
|
|
167
195
|
*/
|
|
168
|
-
| ({ type: 'part'; task: string } & Partial<Pick<WiredResult, PartList>>)
|
|
196
|
+
| ({ type: 'part'; task: string; load?: Load } & Partial<Pick<WiredResult, PartList>>)
|
|
169
197
|
|
|
170
198
|
/**
|
|
171
199
|
* A message's JSON in UTF-8 bytes, what a relay frame holds: counted in
|
|
@@ -175,7 +203,7 @@ export type ToOrchestrator =
|
|
|
175
203
|
export const bytesOf = (body: unknown): number => Buffer.byteLength(JSON.stringify(body))
|
|
176
204
|
|
|
177
205
|
/** The lists a long result sends ahead of its `end`, in parts. */
|
|
178
|
-
export const PART_LISTS = ['violations', 'changed', 'removed'
|
|
206
|
+
export const PART_LISTS = ['violations', 'changed', 'removed'] as const
|
|
179
207
|
export type PartList = (typeof PART_LISTS)[number]
|
|
180
208
|
|
|
181
209
|
/** A result as JSON carries it: its output stays in the cache entry, and a violation's time is a string. */
|
|
@@ -187,13 +215,6 @@ export type WiredResult = Omit<ExecuteResult, 'violations' | 'outputs' | 'stdout
|
|
|
187
215
|
removed?: string[]
|
|
188
216
|
/** Dependency keys whose remote copy did not read back: this machine sends its own over them. */
|
|
189
217
|
unread?: string[]
|
|
190
|
-
/**
|
|
191
|
-
* No remote took its entry's upload (too big, a 429): its files are on
|
|
192
|
-
* that worker alone, and its output comes here in `output`.
|
|
193
|
-
*/
|
|
194
|
-
unshared?: true
|
|
195
|
-
/** Its output, both streams in the order written, when `unshared`. */
|
|
196
|
-
output?: CapturedChunk[]
|
|
197
218
|
}
|
|
198
219
|
|
|
199
220
|
/**
|