@kici-dev/orchestrator 0.1.17 → 0.1.19
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/dist/agent/dispatcher.d.ts +9 -0
- package/dist/agent/host-roster-reaper.d.ts +42 -0
- package/dist/agent/host-roster.d.ts +110 -0
- package/dist/agent/registry.d.ts +65 -2
- package/dist/app.d.ts +3 -0
- package/dist/cli/commands/host.d.ts +13 -0
- package/dist/cli/commands/shared/versioned-upgrade.d.ts +23 -0
- package/dist/cli/service/compose.d.ts +2 -1
- package/dist/cli/service/index.d.ts +2 -2
- package/dist/cli/service/instance/manifest.d.ts +12 -0
- package/dist/cli/service/instance/resolve.d.ts +12 -2
- package/dist/cli/service/launchd.d.ts +4 -1
- package/dist/cli/service/platform-detect.d.ts +5 -0
- package/dist/cli/service/systemd.d.ts +2 -1
- package/dist/cli/service/types.d.ts +37 -0
- package/dist/cli/service/windows.d.ts +2 -1
- package/dist/cli.js +797 -202
- package/dist/cluster/coordinator.d.ts +5 -1
- package/dist/config/schema.d.ts +4 -0
- package/dist/config/types.d.ts +9 -0
- package/dist/config.d.ts +6 -0
- package/dist/db/migrations/039_host_roster.d.ts +19 -0
- package/dist/db/migrations/040_runsonall_pin.d.ts +4 -0
- package/dist/db/migrations/041_wave_gated.d.ts +4 -0
- package/dist/db/migrations/042_dispatch_queue_patterns.d.ts +4 -0
- package/dist/db/types.d.ts +61 -0
- package/dist/diagnostics/fleet-collector.d.ts +1 -1
- package/dist/environments/held-runs.d.ts +9 -0
- package/dist/lockfile-redos-guard.d.ts +19 -0
- package/dist/metrics/prometheus.d.ts +13 -0
- package/dist/metrics/scheduled-jobs.d.ts +2 -2
- package/dist/orchestrator-core.d.ts +46 -1
- package/dist/pipeline/dispatch-matched-workflow.d.ts +42 -1
- package/dist/pipeline/processor.d.ts +25 -0
- package/dist/pipeline/wave-scheduler.d.ts +60 -0
- package/dist/queue/job-queue.d.ts +61 -2
- package/dist/reporting/execution-tracker.d.ts +28 -0
- package/dist/server.js +52760 -51263
- package/dist/standalone.js +1953 -500
- package/installer-image-digests.json +3 -3
- package/package.json +22 -22
- package/sbom.spdx.json +3227 -6682
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Kysely } from 'kysely';
|
|
2
|
-
import type
|
|
2
|
+
import { type LabelMatcher, type ResourceRequest } from '@kici-dev/engine';
|
|
3
3
|
import type { Database } from '../db/types.js';
|
|
4
4
|
/** Info about an expired dispatch_queue entry, returned by markExpired(). */
|
|
5
5
|
export interface ExpiredJobInfo {
|
|
@@ -92,12 +92,26 @@ export interface QueuedJobInput {
|
|
|
92
92
|
requestId?: string;
|
|
93
93
|
/** Labels that the dispatched agent must NOT have. */
|
|
94
94
|
excludeLabels?: string[];
|
|
95
|
+
/** Regex matchers the agent's labels must satisfy (JS post-filter on the exact @> prefilter). */
|
|
96
|
+
runsOnPatterns?: LabelMatcher[];
|
|
97
|
+
/** Regex matchers that disqualify an agent (JS post-filter). */
|
|
98
|
+
excludePatterns?: LabelMatcher[];
|
|
95
99
|
/**
|
|
96
100
|
* Per-job resource request and limit (K8s-style). Drives scaler cap accounting
|
|
97
101
|
* (`requests`) and kernel-side enforcement on the spawned agent (`limits`).
|
|
98
102
|
* Stored inside `jobConfig` JSON; this typed field is a convenience for callers.
|
|
99
103
|
*/
|
|
100
104
|
resources?: ResourceRequest;
|
|
105
|
+
/**
|
|
106
|
+
* For a runsOnAll host-fanout child: the agent this job is pinned to. The
|
|
107
|
+
* dispatcher routes it only to that agent; the drain never hands it to another.
|
|
108
|
+
*/
|
|
109
|
+
pinnedAgentId?: string;
|
|
110
|
+
/**
|
|
111
|
+
* For a pinned child: which orchestrator instance owns the pinned agent's live
|
|
112
|
+
* WS (null = not currently connected). Used by the cross-cluster pin reroute.
|
|
113
|
+
*/
|
|
114
|
+
connectedInstanceId?: string | null;
|
|
101
115
|
}
|
|
102
116
|
/**
|
|
103
117
|
* Full queued job as stored in the database.
|
|
@@ -135,11 +149,17 @@ export interface QueuedJob {
|
|
|
135
149
|
requestId?: string;
|
|
136
150
|
/** Labels that the dispatched agent must NOT have. */
|
|
137
151
|
excludeLabels: string[];
|
|
152
|
+
/** Regex matchers the agent's labels must satisfy (JS post-filter on the exact @> prefilter). */
|
|
153
|
+
runsOnPatterns: LabelMatcher[];
|
|
154
|
+
/** Regex matchers that disqualify an agent (JS post-filter). */
|
|
155
|
+
excludePatterns: LabelMatcher[];
|
|
138
156
|
/**
|
|
139
157
|
* Per-job resource request and limit (K8s-style). Materialized from `jobConfig.resources`
|
|
140
158
|
* by `rowToQueuedJob` so callers can read it without re-parsing the JSON column.
|
|
141
159
|
*/
|
|
142
160
|
resources?: ResourceRequest;
|
|
161
|
+
/** For a runsOnAll host-fanout child: the agent this job is pinned to. */
|
|
162
|
+
pinnedAgentId?: string;
|
|
143
163
|
}
|
|
144
164
|
/**
|
|
145
165
|
* DB-backed FIFO job dispatch queue using Kysely (PostgreSQL only).
|
|
@@ -188,7 +208,46 @@ export declare class JobQueue {
|
|
|
188
208
|
* (empty for static / non-scaler agents).
|
|
189
209
|
* @returns The matching job, or null if none found.
|
|
190
210
|
*/
|
|
191
|
-
dequeueForLabels(agentLabels: string[], agentMandatoryLabels?: string[]): Promise<QueuedJob | null>;
|
|
211
|
+
dequeueForLabels(agentLabels: string[], agentMandatoryLabels?: string[], agentId?: string): Promise<QueuedJob | null>;
|
|
212
|
+
/**
|
|
213
|
+
* Build the shared drain WHERE chain (status / expiry / exact-label @> /
|
|
214
|
+
* exclude-label / pin / mandatory-label gate) common to both drain passes.
|
|
215
|
+
* The pattern columns are NOT filtered here — each pass adds its own
|
|
216
|
+
* pattern-free / pattern-bearing guard on top.
|
|
217
|
+
*/
|
|
218
|
+
private drainBaseQuery;
|
|
219
|
+
/**
|
|
220
|
+
* Fast path: claim the oldest pending pattern-free row. The
|
|
221
|
+
* `runs_on_patterns = '[]' AND exclude_patterns = '[]'` guard restricts this
|
|
222
|
+
* pass to rows that need no JS post-filter, so the single-row atomic claim
|
|
223
|
+
* (FOR UPDATE SKIP LOCKED) keeps the original hot-path semantics intact.
|
|
224
|
+
*/
|
|
225
|
+
private claimPatternFree;
|
|
226
|
+
/**
|
|
227
|
+
* Pattern path: load a small batch of pattern-bearing candidate rows, apply
|
|
228
|
+
* the JS regex post-filter (matcherSatisfiedBy), and atomically claim the
|
|
229
|
+
* first match by id with a conditional `status = Pending` guard. The claim is
|
|
230
|
+
* a conditional UPDATE rather than relying on the SELECT lock alone because
|
|
231
|
+
* the JS filter runs after the per-statement lock window has closed, so two
|
|
232
|
+
* agents could both pass the filter for the same row; the `where status =
|
|
233
|
+
* Pending` makes exactly one of them win. The claim transitions the row to
|
|
234
|
+
* Dispatched, matching the value the caller-side markDispatched would set
|
|
235
|
+
* (which then re-sets it idempotently).
|
|
236
|
+
*/
|
|
237
|
+
private claimWithPatterns;
|
|
238
|
+
/**
|
|
239
|
+
* Atomically claim the oldest pending job pinned to a specific agent. Used by
|
|
240
|
+
* the eager pin drain when the pinned agent (re)registers or frees a slot —
|
|
241
|
+
* the host-fanout analog of `dispatchBoundJob`'s eager path. Ignores the exact
|
|
242
|
+
* label gate: the pin was resolved against the roster at materialize time.
|
|
243
|
+
*
|
|
244
|
+
* Still applies the JS regex post-filter (`jobPatternsSatisfiedBy`) when
|
|
245
|
+
* `agentLabels` is supplied, mirroring `dequeueById`: a pinned child whose
|
|
246
|
+
* `runsOn`/`exclude` patterns no longer match the agent's current labels must
|
|
247
|
+
* not be claimed. The single matching authority is the engine's
|
|
248
|
+
* `matcherSatisfiedBy` (never a Postgres `~`).
|
|
249
|
+
*/
|
|
250
|
+
dequeueByPinnedAgent(agentId: string, agentLabels?: string[]): Promise<QueuedJob | null>;
|
|
192
251
|
/**
|
|
193
252
|
* Atomically claim a specific pending job by ID, validating it still
|
|
194
253
|
* matches the agent's labels and isn't expired.
|
|
@@ -202,6 +202,12 @@ export declare class ExecutionTracker {
|
|
|
202
202
|
jobName: string;
|
|
203
203
|
matrixValues?: Record<string, unknown>;
|
|
204
204
|
runsOnLabels?: string[];
|
|
205
|
+
baseJobName?: string;
|
|
206
|
+
variantKind?: string;
|
|
207
|
+
variantLabel?: string;
|
|
208
|
+
waveGated?: boolean;
|
|
209
|
+
waveMaxParallel?: number;
|
|
210
|
+
waveFailFast?: boolean;
|
|
205
211
|
}>, routingKey?: string,
|
|
206
212
|
/** Secret context names dispatched with jobs (for context-disable job lookup). */
|
|
207
213
|
dispatchedContexts?: string[],
|
|
@@ -237,6 +243,13 @@ export declare class ExecutionTracker {
|
|
|
237
243
|
* which peer owns the downstream dispatch.
|
|
238
244
|
*/
|
|
239
245
|
findSyntheticJobId(runId: string, jobName: string): Promise<string | undefined>;
|
|
246
|
+
/**
|
|
247
|
+
* Find the synthetic deferred-eval placeholder job ID for a result-aware
|
|
248
|
+
* dynamic generator's eval job. Mirrors {@link findSyntheticJobId} but keys on
|
|
249
|
+
* the `dynamic-eval-pending-<evalJobName>-` prefix that registerDeferredEvalJob
|
|
250
|
+
* uses, so dispatchEvalJob can swap it for the real eval job id.
|
|
251
|
+
*/
|
|
252
|
+
findDynamicEvalSyntheticId(runId: string, evalJobName: string): Promise<string | undefined>;
|
|
240
253
|
/**
|
|
241
254
|
* Run `fn` while holding a per-run lock, serializing the run-mutating methods
|
|
242
255
|
* (`onJobStatus`, `addJobsToRun`) so a status reply cannot interleave with the
|
|
@@ -258,6 +271,9 @@ export declare class ExecutionTracker {
|
|
|
258
271
|
jobName: string;
|
|
259
272
|
matrixValues?: Record<string, unknown>;
|
|
260
273
|
runsOnLabels?: string[];
|
|
274
|
+
baseJobName?: string;
|
|
275
|
+
variantKind?: string;
|
|
276
|
+
variantLabel?: string;
|
|
261
277
|
}>, dispatchedContexts?: string[],
|
|
262
278
|
/** Synthetic job ID to replace (e.g. needs-pending-deploy-{uuid}). */
|
|
263
279
|
replaceSyntheticId?: string): Promise<void>;
|
|
@@ -339,6 +355,18 @@ export declare class ExecutionTracker {
|
|
|
339
355
|
* so recursive skip propagation terminates naturally.
|
|
340
356
|
*/
|
|
341
357
|
private runSchedulerHook;
|
|
358
|
+
/**
|
|
359
|
+
* Rolling-wave hook: fires beside the needs-scheduler when a fan-out child of
|
|
360
|
+
* a bounded wave (`maxParallel` set) reaches terminal. Reads the completed
|
|
361
|
+
* child's row to recover the base + wave policy, asks {@link evaluateWave}
|
|
362
|
+
* what to do, then performs it:
|
|
363
|
+
*
|
|
364
|
+
* - `release`: clear the next held sibling's `wave_gated` flag and fire the
|
|
365
|
+
* onJobReady callback (the existing ready→dispatch path).
|
|
366
|
+
* - `skip-remaining`: mark every still-held sibling `skipped` (failFast).
|
|
367
|
+
* - `noop`: nothing — a later terminal will free the next slot.
|
|
368
|
+
*/
|
|
369
|
+
private runWaveSchedulerHook;
|
|
342
370
|
/**
|
|
343
371
|
* Phase 9: stuck-jobs invariant check ( Layer 3).
|
|
344
372
|
* Before declaring a run complete, verify no stuck jobs exist. If any are
|