deepline 0.3.246 → 0.3.248
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/bundling-sources/sdk/src/client.ts +177 -13
- package/dist/bundling-sources/sdk/src/index.ts +8 -0
- package/dist/bundling-sources/sdk/src/plays/input-example.ts +40 -0
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/runs/overview.ts +457 -0
- package/dist/bundling-sources/sdk/src/runs/receipts.ts +23 -0
- package/dist/bundling-sources/sdk/src/tool-calls.ts +21 -1
- package/dist/bundling-sources/sdk/src/types.ts +16 -1
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +37 -1
- package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/column-names.ts +17 -3
- package/dist/bundling-sources/shared_libs/play-data-plane/sheet-contract.ts +40 -8
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +26 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +150 -19
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +2 -1
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-runtime-config.ts +6 -3
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +26 -21
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +23 -21
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/log-context.ts +105 -0
- package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +8 -1
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-event-transport.ts +40 -4
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +50 -5
- package/dist/bundling-sources/shared_libs/play-runtime/run-lifecycle-policy.ts +3 -1
- package/dist/bundling-sources/shared_libs/play-runtime/run-log-buffer.ts +28 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +14 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +56 -16
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-control-transport.ts +184 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +327 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +87 -30
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +24 -13
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-start-admission.ts +23 -6
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +76 -33
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +90 -35
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +62 -21
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +368 -66
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +22 -4
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +106 -81
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +1347 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-queue-health.ts +16 -19
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-value-storage.ts +14 -6
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +40 -0
- package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +3 -2
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +5 -2
- package/dist/bundling-sources/shared_libs/plays/dataset-summary.ts +11 -7
- package/dist/bundling-sources/shared_libs/plays/static-pipeline-storage-codec.ts +5 -2
- package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +11 -2
- package/dist/cli/index.js +3504 -2368
- package/dist/cli/index.mjs +3188 -2052
- package/dist/{compiler-manifest-n8ZtPv2h.d.mts → compiler-manifest-DavmLa8y.d.mts} +1 -0
- package/dist/{compiler-manifest-n8ZtPv2h.d.ts → compiler-manifest-DavmLa8y.d.ts} +1 -0
- package/dist/index.d.mts +97 -5
- package/dist/index.d.ts +97 -5
- package/dist/index.js +135 -15
- package/dist/index.mjs +135 -15
- package/dist/install-integrity.json +9 -2
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/dist/plays/bundle-play-file.mjs +1 -1
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts
CHANGED
|
@@ -361,13 +361,21 @@ function requireReceiptScope(
|
|
|
361
361
|
if (!scope.orgId || !scope.playName || !scope.runId) {
|
|
362
362
|
return receiptGatewayJsonResponse(
|
|
363
363
|
{ error: 'Executor token is missing org/run/play scope.' },
|
|
364
|
-
{
|
|
364
|
+
{
|
|
365
|
+
status: 403,
|
|
366
|
+
headers: { 'x-deepline-error-code': 'runtime_receipt_scope_missing' },
|
|
367
|
+
},
|
|
365
368
|
);
|
|
366
369
|
}
|
|
367
370
|
if (body.playName !== scope.playName) {
|
|
368
371
|
return receiptGatewayJsonResponse(
|
|
369
372
|
{ error: 'Receipt request playName does not match executor token.' },
|
|
370
|
-
{
|
|
373
|
+
{
|
|
374
|
+
status: 403,
|
|
375
|
+
headers: {
|
|
376
|
+
'x-deepline-error-code': 'runtime_receipt_play_scope_mismatch',
|
|
377
|
+
},
|
|
378
|
+
},
|
|
371
379
|
);
|
|
372
380
|
}
|
|
373
381
|
if (body.runId && body.runId !== scope.runId) {
|
|
@@ -378,7 +386,12 @@ function requireReceiptScope(
|
|
|
378
386
|
});
|
|
379
387
|
return receiptGatewayJsonResponse(
|
|
380
388
|
{ error: 'Receipt request runId does not match executor token.' },
|
|
381
|
-
{
|
|
389
|
+
{
|
|
390
|
+
status: 403,
|
|
391
|
+
headers: {
|
|
392
|
+
'x-deepline-error-code': 'runtime_receipt_run_scope_mismatch',
|
|
393
|
+
},
|
|
394
|
+
},
|
|
382
395
|
);
|
|
383
396
|
}
|
|
384
397
|
return null;
|
|
@@ -403,7 +416,12 @@ function requireSameRunReceipts(
|
|
|
403
416
|
return invalid
|
|
404
417
|
? receiptGatewayJsonResponse(
|
|
405
418
|
{ error: 'Receipt runId does not match executor token scope.' },
|
|
406
|
-
{
|
|
419
|
+
{
|
|
420
|
+
status: 403,
|
|
421
|
+
headers: {
|
|
422
|
+
'x-deepline-error-code': 'runtime_receipt_run_scope_mismatch',
|
|
423
|
+
},
|
|
424
|
+
},
|
|
407
425
|
)
|
|
408
426
|
: null;
|
|
409
427
|
}
|
|
@@ -41,7 +41,7 @@ const MAX_TIMEOUT_MS = 2_147_483_647;
|
|
|
41
41
|
* therefore a network/projection concurrency budget, deliberately independent
|
|
42
42
|
* of the projector's much smaller Postgres pool.
|
|
43
43
|
*
|
|
44
|
-
* A single successful probe
|
|
44
|
+
* A single successful probe fills bounded delivery slots; an idle projector still
|
|
45
45
|
* performs only one indexed head read per safety wake. `SKIP LOCKED` leases
|
|
46
46
|
* distinct runs, retaining strict causal ordering within every run.
|
|
47
47
|
*/
|
|
@@ -125,6 +125,7 @@ export function startRunLedgerOutboxRecovery(
|
|
|
125
125
|
let failureCount = 0;
|
|
126
126
|
let timer: RecoveryTimer | null = null;
|
|
127
127
|
let drainPromise: Promise<void> | null = null;
|
|
128
|
+
let wakeActiveDrain: (() => void) | null = null;
|
|
128
129
|
let cooldownUntilMs: number | null = null;
|
|
129
130
|
let hubLease: PgNotifyHubLease | null = null;
|
|
130
131
|
let unsubscribeNotify: (() => void) | undefined;
|
|
@@ -162,7 +163,10 @@ export function startRunLedgerOutboxRecovery(
|
|
|
162
163
|
requested = true;
|
|
163
164
|
if (cooldownUntilMs !== null && now() < cooldownUntilMs) return;
|
|
164
165
|
clearWakeTimer();
|
|
165
|
-
if (drainPromise)
|
|
166
|
+
if (drainPromise) {
|
|
167
|
+
wakeActiveDrain?.();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
166
170
|
drainPromise = drain(reason)
|
|
167
171
|
.catch((error) => {
|
|
168
172
|
// drain() handles expected database/projection faults itself. This is a
|
|
@@ -179,7 +183,6 @@ export function startRunLedgerOutboxRecovery(
|
|
|
179
183
|
};
|
|
180
184
|
|
|
181
185
|
const recordProjectionRetry = (retrying: number) => {
|
|
182
|
-
failureCount += 1;
|
|
183
186
|
logger.warn('[run-ledger-outbox.recovery_retry]', {
|
|
184
187
|
stage: 'projection',
|
|
185
188
|
retrying,
|
|
@@ -205,6 +208,7 @@ export function startRunLedgerOutboxRecovery(
|
|
|
205
208
|
delayMs,
|
|
206
209
|
error: error instanceof Error ? error.message : String(error),
|
|
207
210
|
});
|
|
211
|
+
if (closed) return;
|
|
208
212
|
clearWakeTimer();
|
|
209
213
|
cooldownUntilMs = now() + delayMs;
|
|
210
214
|
timer = setTimer(() => {
|
|
@@ -216,6 +220,7 @@ export function startRunLedgerOutboxRecovery(
|
|
|
216
220
|
};
|
|
217
221
|
|
|
218
222
|
const scheduleNextDue = async (): Promise<void> => {
|
|
223
|
+
if (closed) return;
|
|
219
224
|
let dueAt: Date | null;
|
|
220
225
|
try {
|
|
221
226
|
dueAt = await deps.readNextDueAt();
|
|
@@ -247,79 +252,26 @@ export function startRunLedgerOutboxRecovery(
|
|
|
247
252
|
};
|
|
248
253
|
|
|
249
254
|
const drain = async (reason: string): Promise<void> => {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const settled = [
|
|
264
|
-
{
|
|
265
|
-
status: 'fulfilled' as const,
|
|
266
|
-
value: first,
|
|
267
|
-
},
|
|
268
|
-
...(first.attempted === 0
|
|
269
|
-
? []
|
|
270
|
-
: await Promise.allSettled(
|
|
271
|
-
Array.from({ length: parallelism - 1 }, () =>
|
|
272
|
-
deps.dispatchOnce(),
|
|
273
|
-
),
|
|
274
|
-
)),
|
|
275
|
-
];
|
|
276
|
-
const rejected = settled.find(
|
|
277
|
-
(result): result is PromiseRejectedResult =>
|
|
278
|
-
result.status === 'rejected',
|
|
279
|
-
);
|
|
280
|
-
if (rejected) {
|
|
281
|
-
scheduleFailureRetry('dispatch', rejected.reason);
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
const results = settled.map(
|
|
286
|
-
(result) =>
|
|
287
|
-
(
|
|
288
|
-
result as PromiseFulfilledResult<PostgresSchedulerOutboxProjectionResult>
|
|
289
|
-
).value,
|
|
290
|
-
);
|
|
291
|
-
const retrying = results.reduce(
|
|
292
|
-
(total, result) => total + result.retrying,
|
|
293
|
-
0,
|
|
294
|
-
);
|
|
295
|
-
const attempted = results.reduce(
|
|
296
|
-
(total, result) => total + result.attempted,
|
|
297
|
-
0,
|
|
298
|
-
);
|
|
299
|
-
const projected = results.reduce(
|
|
300
|
-
(total, result) => total + result.projected,
|
|
301
|
-
0,
|
|
302
|
-
);
|
|
303
|
-
const blocked = results.reduce(
|
|
304
|
-
(total, result) => total + result.failed,
|
|
305
|
-
0,
|
|
306
|
-
);
|
|
307
|
-
|
|
308
|
-
if (retrying > 0) {
|
|
309
|
-
// The failed row owns its own durable retry clock. Do NOT stop this
|
|
310
|
-
// drain: the claim query preserves causal order within a run, while
|
|
311
|
-
// independent runs are safe to project now. Returning here turns one
|
|
312
|
-
// transient projection failure into global head-of-line blocking when
|
|
313
|
-
// this is the only healthy projector replica.
|
|
314
|
-
recordProjectionRetry(retrying);
|
|
315
|
-
} else {
|
|
316
|
-
failureCount = 0;
|
|
317
|
-
}
|
|
255
|
+
type Delivery = {
|
|
256
|
+
id: symbol;
|
|
257
|
+
result: PromiseSettledResult<PostgresSchedulerOutboxProjectionResult> | { status: 'skipped' };
|
|
258
|
+
};
|
|
259
|
+
const pending = new Set<symbol>();
|
|
260
|
+
const deliveries: Delivery[] = [];
|
|
261
|
+
let refill = false;
|
|
262
|
+
let dispatchFailed = false;
|
|
263
|
+
let completed = 0;
|
|
264
|
+
let attempted = 0;
|
|
265
|
+
let projected = 0;
|
|
266
|
+
let retrying = 0;
|
|
267
|
+
let blocked = 0;
|
|
318
268
|
|
|
269
|
+
const reportDeliveries = () => {
|
|
270
|
+
if (retrying > 0) recordProjectionRetry(retrying);
|
|
271
|
+
else if (!dispatchFailed) failureCount = 0;
|
|
319
272
|
if (attempted > 0) {
|
|
320
|
-
//
|
|
321
|
-
//
|
|
322
|
-
// without emitting one noisy log line per normal database checkout.
|
|
273
|
+
// Retain the existing throughput event, aggregated over at most one
|
|
274
|
+
// slot-set of completions without making that set a delivery barrier.
|
|
323
275
|
logger.info('[run-ledger-outbox.recovery_wave]', {
|
|
324
276
|
reason,
|
|
325
277
|
parallelism,
|
|
@@ -329,16 +281,88 @@ export function startRunLedgerOutboxRecovery(
|
|
|
329
281
|
blocked,
|
|
330
282
|
});
|
|
331
283
|
}
|
|
284
|
+
completed = attempted = projected = retrying = blocked = 0;
|
|
285
|
+
};
|
|
332
286
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
287
|
+
const launch = () => {
|
|
288
|
+
const id = Symbol();
|
|
289
|
+
pending.add(id);
|
|
290
|
+
const settle = (result: Delivery['result']) => {
|
|
291
|
+
if (result.status === 'rejected' && !dispatchFailed) {
|
|
292
|
+
dispatchFailed = true;
|
|
293
|
+
scheduleFailureRetry('dispatch', result.reason);
|
|
294
|
+
}
|
|
295
|
+
deliveries.push({ id, result });
|
|
296
|
+
wakeActiveDrain?.();
|
|
297
|
+
};
|
|
298
|
+
// Subscribe once per delivery. Repeated Promise.race calls would retain
|
|
299
|
+
// a new reaction on a slow callback every time a faster slot completes.
|
|
300
|
+
void Promise.resolve().then(async () => {
|
|
301
|
+
if (closed || dispatchFailed) {
|
|
302
|
+
settle({ status: 'skipped' });
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
try {
|
|
306
|
+
settle({ status: 'fulfilled', value: await deps.dispatchOnce() });
|
|
307
|
+
} catch (reason) {
|
|
308
|
+
settle({ status: 'rejected', reason });
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
for (;;) {
|
|
314
|
+
if (!closed && !dispatchFailed) {
|
|
315
|
+
// A wake grants one indexed probe, including when other slots are
|
|
316
|
+
// still delivering. Keep it pending when full so an empty result
|
|
317
|
+
// cannot consume a notification that arrived after its query began.
|
|
318
|
+
if (requested && pending.size < parallelism) {
|
|
319
|
+
requested = false;
|
|
320
|
+
launch();
|
|
321
|
+
}
|
|
322
|
+
// Productive completion permits immediate use of every free slot.
|
|
323
|
+
// Empty results grant no refill, so idle work cannot spin on scans.
|
|
324
|
+
if (refill) {
|
|
325
|
+
while (pending.size < parallelism) launch();
|
|
326
|
+
refill = false;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
if (pending.size === 0) {
|
|
330
|
+
reportDeliveries();
|
|
331
|
+
if (!closed && !dispatchFailed) await scheduleNextDue();
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
await new Promise<void>((resolve) => {
|
|
336
|
+
// Register before checking queued completions and notifications.
|
|
337
|
+
wakeActiveDrain = resolve;
|
|
338
|
+
if (
|
|
339
|
+
deliveries.length > 0 ||
|
|
340
|
+
(requested &&
|
|
341
|
+
!closed &&
|
|
342
|
+
!dispatchFailed &&
|
|
343
|
+
pending.size < parallelism)
|
|
344
|
+
)
|
|
345
|
+
resolve();
|
|
346
|
+
});
|
|
347
|
+
wakeActiveDrain = null;
|
|
348
|
+
const delivery = deliveries.shift();
|
|
349
|
+
if (!delivery) continue;
|
|
350
|
+
pending.delete(delivery.id);
|
|
351
|
+
if (delivery.result.status !== 'fulfilled') {
|
|
352
|
+
// Stop new claims but settle every already-started delivery before
|
|
353
|
+
// cooldown or close can hand ownership to another drain.
|
|
339
354
|
continue;
|
|
340
355
|
}
|
|
341
|
-
|
|
356
|
+
const result = delivery.result.value;
|
|
357
|
+
completed += 1;
|
|
358
|
+
attempted += result.attempted;
|
|
359
|
+
projected += result.projected;
|
|
360
|
+
retrying += result.retrying;
|
|
361
|
+
blocked += result.failed;
|
|
362
|
+
if (completed >= parallelism) reportDeliveries();
|
|
363
|
+
// Retryable rows own durable retry clocks. The SQL claim keeps their
|
|
364
|
+
// run ordered while successful slots keep unrelated runs moving.
|
|
365
|
+
refill = result.attempted > 0;
|
|
342
366
|
}
|
|
343
367
|
};
|
|
344
368
|
|
|
@@ -353,6 +377,7 @@ export function startRunLedgerOutboxRecovery(
|
|
|
353
377
|
close: async () => {
|
|
354
378
|
if (closed) return;
|
|
355
379
|
closed = true;
|
|
380
|
+
wakeActiveDrain?.();
|
|
356
381
|
clearWakeTimer();
|
|
357
382
|
cooldownUntilMs = null;
|
|
358
383
|
unsubscribeNotify?.();
|