deepline 0.3.301 → 0.3.303
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/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/runs/watch-polling.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/live-state-contract.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/gateway-adapter.ts +2 -4
- package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +13 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +16 -5
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-start-admission.ts +7 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-capacity-policy.ts +6 -4
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +229 -98
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +2 -4
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +82 -0
- package/dist/bundling-sources/shared_libs/plays/tool-response-contract.ts +25 -0
- package/dist/cli/{auth-DCN4DA2T.mjs → auth-337SVWQD.mjs} +4 -4
- package/dist/cli/auth-4ME3NANJ.js +31 -0
- package/dist/cli/{billing-OGWOCZOZ.js → billing-CVQURTWQ.js} +71 -71
- package/dist/cli/{billing-VLZNKJ4N.mjs → billing-SVGYQSJI.mjs} +5 -5
- package/dist/cli/{chunk-V7J7U63X.js → chunk-4D5YQETI.js} +6 -6
- package/dist/cli/{chunk-OILZKWKC.mjs → chunk-4LRG6AJZ.mjs} +2 -2
- package/dist/cli/{chunk-JCS5TPNY.mjs → chunk-4NIQA6S7.mjs} +1 -1
- package/dist/cli/{chunk-AKWMFS7H.js → chunk-5NEXN4MZ.js} +2 -2
- package/dist/cli/{chunk-PXJAS6X2.mjs → chunk-BVJSAJKV.mjs} +1 -1
- package/dist/cli/{chunk-SBUIMF2B.mjs → chunk-DH6LEJWD.mjs} +3 -3
- package/dist/cli/{chunk-YFRWD6LM.js → chunk-EAIGGEV5.js} +6 -6
- package/dist/cli/{chunk-6JIXIMC5.js → chunk-GQUI3NYN.js} +57 -57
- package/dist/cli/{chunk-FAQGAPKK.js → chunk-HIXYNASX.js} +4 -4
- package/dist/cli/{chunk-GILGPI67.mjs → chunk-IVT2CZPM.mjs} +10 -3
- package/dist/cli/{chunk-QDFEF4PI.js → chunk-JGEFX6FQ.js} +6 -6
- package/dist/cli/{chunk-AXHRD6ME.mjs → chunk-JWUOPLAR.mjs} +1 -1
- package/dist/cli/{chunk-57J4GHJG.mjs → chunk-LGGR7CGZ.mjs} +4 -4
- package/dist/cli/{chunk-YBYPHZ4I.mjs → chunk-MTICVDNY.mjs} +1 -1
- package/dist/cli/{chunk-M6KBDWGI.js → chunk-NFWFUCGM.js} +19 -12
- package/dist/cli/{chunk-TAPI3QLV.js → chunk-OOQ4IRP4.js} +1 -1
- package/dist/cli/{chunk-7JA3CLD2.js → chunk-P2KELOST.js} +48 -48
- package/dist/cli/{chunk-SHQNCP2G.mjs → chunk-PUKK7SZX.mjs} +1 -1
- package/dist/cli/{chunk-ZNC3KU5O.js → chunk-RY6WID7C.js} +26 -26
- package/dist/cli/{chunk-GONRLVV3.js → chunk-W7INSYJS.js} +9 -9
- package/dist/cli/{chunk-7VBN7TU5.js → chunk-WJGRIDWQ.js} +15 -15
- package/dist/cli/{chunk-RQKAKIVL.mjs → chunk-XKW6HTWO.mjs} +1 -1
- package/dist/cli/{chunk-D7WKHLLF.mjs → chunk-XXQYOQWO.mjs} +2 -2
- package/dist/cli/{chunk-6S2UJUVD.mjs → chunk-YZLPXH7G.mjs} +2 -2
- package/dist/cli/{client-F7LPXBQS.mjs → client-AMSHGQFH.mjs} +4 -4
- package/dist/cli/client-WN33QCMV.js +20 -0
- package/dist/cli/{csv-DTGOY553.js → csv-B2OKPMNX.js} +12 -12
- package/dist/cli/{csv-PFAL3PLE.mjs → csv-F4RPWI4E.mjs} +3 -3
- package/dist/cli/{db-B7JTWZQB.js → db-AJYYK5HH.js} +21 -21
- package/dist/cli/{db-24PTJ6J5.mjs → db-QP4WNVSS.mjs} +5 -5
- package/dist/cli/{executions-3CPX35CQ.js → executions-4LHEJCCY.js} +7 -7
- package/dist/cli/{executions-53BGMOYB.mjs → executions-NY7HYAEH.mjs} +5 -5
- package/dist/cli/{feedback-4JPCFN6F.js → feedback-CXXJJARR.js} +6 -6
- package/dist/cli/{feedback-GA6FF4UP.mjs → feedback-SJYHLVYY.mjs} +3 -3
- package/dist/cli/{git-VXB6ZLJ3.mjs → git-DUODO3NL.mjs} +4 -4
- package/dist/cli/git-K7YPSXLC.js +23 -0
- package/dist/cli/index.d.mts +1 -6
- package/dist/cli/index.d.ts +1 -6
- package/dist/cli/index.js +100 -87
- package/dist/cli/index.mjs +54 -41
- package/dist/cli/{legacy-noops-ANYHW7ER.js → legacy-noops-3UYJVVNW.js} +7 -7
- package/dist/cli/{legacy-noops-7J5WN4M6.mjs → legacy-noops-IUDXZFYO.mjs} +4 -4
- package/dist/cli/{monitors-EAV6KHOK.js → monitors-IEEVACOD.js} +86 -86
- package/dist/cli/{monitors-DXETJ5NX.mjs → monitors-PDWE6BGA.mjs} +5 -5
- package/dist/cli/{org-3IVIYYVM.js → org-NUFEZRY7.js} +61 -61
- package/dist/cli/{org-B57DDLLC.mjs → org-VSPO2YF3.mjs} +5 -5
- package/dist/cli/{play-FXABI2NH.mjs → play-KMHPJVWH.mjs} +21 -19
- package/dist/cli/{play-LNYRYGOT.js → play-MXYK2BRE.js} +229 -227
- package/dist/cli/{providers-LMZBXPLP.mjs → providers-7ENB4EYV.mjs} +5 -5
- package/dist/cli/{providers-SWHCMHUN.js → providers-YE5YRIML.js} +8 -8
- package/dist/cli/{proxy-env-M4ZHXHRL.mjs → proxy-env-NWUIGWS3.mjs} +34 -17
- package/dist/cli/{proxy-env-EBANZHPV.js → proxy-env-ZV2WZFAT.js} +37 -20
- package/dist/cli/{quickstart-PHGLWVGA.mjs → quickstart-GFOOHX2U.mjs} +3 -3
- package/dist/cli/{quickstart-YYKEMF5A.js → quickstart-KXCU2MZ2.js} +5 -5
- package/dist/cli/{search-PHSXMXSV.mjs → search-KESXCJDL.mjs} +6 -6
- package/dist/cli/search-R426JJQW.js +18 -0
- package/dist/cli/{secrets-CWWMAPBB.js → secrets-BRB5SIXG.js} +14 -14
- package/dist/cli/{secrets-ZRVJ6GWI.mjs → secrets-HDR522GC.mjs} +5 -5
- package/dist/cli/{sessions-3HSV7W2M.js → sessions-IK3OSQC6.js} +5 -5
- package/dist/cli/{sessions-IXMB2B5R.mjs → sessions-VOOSWVLS.mjs} +4 -4
- package/dist/cli/{settings-XEM64DRR.mjs → settings-BZKDIHTX.mjs} +8 -8
- package/dist/cli/{settings-PGYWTWJ7.js → settings-OPGEFGXL.js} +75 -75
- package/dist/cli/{setup-MCXGMDIV.mjs → setup-RVPS7AJJ.mjs} +6 -6
- package/dist/cli/{setup-EOTIXFLU.js → setup-TP2VWSCU.js} +41 -41
- package/dist/cli/{skills-4HXO76M7.mjs → skills-7BDD2F4V.mjs} +4 -4
- package/dist/cli/skills-TK2CIWVS.js +28 -0
- package/dist/cli/{tools-FMOJUYVW.js → tools-46ILS57M.js} +51 -51
- package/dist/cli/{tools-P3OULQFZ.mjs → tools-XLGGDBM3.mjs} +6 -6
- package/dist/cli/{update-2QXPDAIV.mjs → update-2JEM7WUF.mjs} +6 -6
- package/dist/cli/update-3JOCQWNF.js +28 -0
- package/dist/cli/{workflow-VAJ3GV2W.mjs → workflow-SSTGMXOQ.mjs} +6 -6
- package/dist/cli/{workflow-P2YQPB7Y.js → workflow-ZKGPY7T4.js} +16 -16
- package/dist/index.js +7 -7
- package/dist/index.mjs +4 -4
- package/dist/install-integrity.json +74 -74
- package/dist/plays/bundle-play-file.mjs +2 -2
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +2 -2
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
- package/dist/cli/auth-G2CKLPSX.js +0 -31
- package/dist/cli/client-WTE3IK53.js +0 -20
- package/dist/cli/git-YTJCZVEL.js +0 -23
- package/dist/cli/search-CEBKSGXX.js +0 -18
- package/dist/cli/skills-3IXQN3KZ.js +0 -28
- package/dist/cli/update-H6I7437Q.js +0 -28
- /package/dist/cli/{chunk-GVUJJJ5G.mjs → chunk-6IKARAYD.mjs} +0 -0
- /package/dist/cli/{chunk-6A3TJUWC.js → chunk-S6R3OX7B.js} +0 -0
|
@@ -200,7 +200,7 @@ export const SDK_RELEASE = {
|
|
|
200
200
|
// getters keep their established compatibility behavior.
|
|
201
201
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
202
202
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
203
|
-
version: '0.3.
|
|
203
|
+
version: '0.3.303',
|
|
204
204
|
updateSummary:
|
|
205
205
|
'Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.',
|
|
206
206
|
packageCapabilities: {
|
|
@@ -95,7 +95,7 @@ async function backfillRotatedLogTail(input: {
|
|
|
95
95
|
}): Promise<PlayRunLiveSnapshot> {
|
|
96
96
|
// A late first attach intentionally shows the retained tail and its gap
|
|
97
97
|
// marker. Backfill only lines that rotated out after this watcher attached.
|
|
98
|
-
if (!input.previous.runSignature) {
|
|
98
|
+
if (!input.previous.runSignature || input.snapshot.logsUnavailable) {
|
|
99
99
|
return input.snapshot;
|
|
100
100
|
}
|
|
101
101
|
const gap = resolvePlayRunLogGap(input.snapshot, input.previous.lastLogSeq);
|
|
@@ -84,6 +84,8 @@ export type PlayRunLiveSnapshot = {
|
|
|
84
84
|
status: PlayRunLiveStatus;
|
|
85
85
|
updatedAt: number | null;
|
|
86
86
|
logs: string[];
|
|
87
|
+
/** Present when an optional canonical log read failed for this snapshot. */
|
|
88
|
+
logsUnavailable?: true;
|
|
87
89
|
activeArtifactTableNamespace: string | null;
|
|
88
90
|
resultTableNamespace: string | null;
|
|
89
91
|
nodeStates: PlayVisualNodeStateSnapshot[];
|
package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/gateway-adapter.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
dispatchRunLedgerOutboxToLedgerThroughEventWithClientScope,
|
|
6
6
|
type PostgresSchedulerOptions,
|
|
7
7
|
type PostgresSchedulerOutboxDrainResult,
|
|
8
|
-
type
|
|
8
|
+
type RunLedgerOutboxWithClient,
|
|
9
9
|
} from '../../scheduler-backends/postgres';
|
|
10
10
|
|
|
11
11
|
import type { RunLedgerProjectionPorts } from '../../play-runs/projection/ports';
|
|
@@ -17,9 +17,7 @@ export type GatewayRunLedgerProjectionAdapterInput = {
|
|
|
17
17
|
* against the active outbox lease while retaining supported transport hooks.
|
|
18
18
|
*/
|
|
19
19
|
runtimeApi: WorkerRuntimeApiContext;
|
|
20
|
-
withClient:
|
|
21
|
-
operation: (client: PostgresSchedulerQueryClient) => Promise<T>,
|
|
22
|
-
) => Promise<T>;
|
|
20
|
+
withClient: RunLedgerOutboxWithClient;
|
|
23
21
|
schedulerOptions?: Pick<PostgresSchedulerOptions, 'schema'>;
|
|
24
22
|
};
|
|
25
23
|
|
|
@@ -99,6 +99,12 @@ export type PlayRunLiveSnapshot = {
|
|
|
99
99
|
* crossed the retention cap (ADR-0009). Additive/optional on the wire.
|
|
100
100
|
*/
|
|
101
101
|
logsTruncated?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* The canonical log store could not be read for this snapshot. The run
|
|
104
|
+
* status remains authoritative; callers should retry logs on the next poll
|
|
105
|
+
* or use the paginated logs endpoint. The log cursor does not advance.
|
|
106
|
+
*/
|
|
107
|
+
logsUnavailable?: true;
|
|
102
108
|
activeArtifactTableNamespace: string | null;
|
|
103
109
|
resultTableNamespace: string | null;
|
|
104
110
|
datasets?: PlayRunLedgerDatasetSnapshot[];
|
|
@@ -573,6 +579,13 @@ function diffLogLines(input: {
|
|
|
573
579
|
lastLogSeq: number;
|
|
574
580
|
}): { lines: string[]; lastLogSeq: number; firstSeq: number | null } {
|
|
575
581
|
const { logs, totalLogCount } = input.snapshot;
|
|
582
|
+
if (input.snapshot.logsUnavailable) {
|
|
583
|
+
return {
|
|
584
|
+
lines: [],
|
|
585
|
+
lastLogSeq: input.lastLogSeq,
|
|
586
|
+
firstSeq: null,
|
|
587
|
+
};
|
|
588
|
+
}
|
|
576
589
|
if (totalLogCount <= input.lastLogSeq) {
|
|
577
590
|
return { lines: [], lastLogSeq: input.lastLogSeq, firstSeq: null };
|
|
578
591
|
}
|
package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts
CHANGED
|
@@ -694,12 +694,22 @@ async function acquireOneShotDaytonaSandbox(input: {
|
|
|
694
694
|
},
|
|
695
695
|
);
|
|
696
696
|
input.emitStage('create:start');
|
|
697
|
+
const admissionRequestedAt = Date.now();
|
|
698
|
+
let admissionWaitMs = 0;
|
|
699
|
+
let admissionQueued = false;
|
|
700
|
+
const create = () => {
|
|
701
|
+
admissionWaitMs = Date.now() - admissionRequestedAt;
|
|
702
|
+
if (admissionQueued) {
|
|
703
|
+
input.emitStage('create:admission_ready', { admissionWaitMs });
|
|
704
|
+
}
|
|
705
|
+
return createRetriedOneShotDaytonaSandbox(input);
|
|
706
|
+
};
|
|
697
707
|
const result = input.startAdmission
|
|
698
|
-
? await input.startAdmission.run(
|
|
699
|
-
|
|
700
|
-
input.
|
|
701
|
-
)
|
|
702
|
-
: await
|
|
708
|
+
? await input.startAdmission.run(create, input.cancellationSignal, () => {
|
|
709
|
+
admissionQueued = true;
|
|
710
|
+
input.emitStage('create:admission_wait');
|
|
711
|
+
})
|
|
712
|
+
: await create();
|
|
703
713
|
// The runner's egress probe measures the sandbox-to-estate round trip; the
|
|
704
714
|
// sandbox's target names the region that round trip crosses.
|
|
705
715
|
console.info('[play-runner.daytona.sandbox_acquired]', {
|
|
@@ -779,6 +789,7 @@ async function acquireOneShotDaytonaSandbox(input: {
|
|
|
779
789
|
sandboxId: sandbox.id,
|
|
780
790
|
attempt: result.attempt,
|
|
781
791
|
elapsedMs: billingStartedAt - input.startedAt,
|
|
792
|
+
admissionWaitMs,
|
|
782
793
|
attemptElapsedMs: result.attemptElapsedMs,
|
|
783
794
|
// Daytona's default snapshot is intentionally provider-managed. Record the
|
|
784
795
|
// resolved immutable snapshot identifier so a slow acquisition can be
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { RUNTIME_CAPACITY_POLICY } from '../../runtime-capacity-policy';
|
|
2
2
|
|
|
3
3
|
export type DaytonaSandboxStartAdmission = {
|
|
4
|
-
run<T>(
|
|
4
|
+
run<T>(
|
|
5
|
+
operation: () => Promise<T>,
|
|
6
|
+
signal?: AbortSignal,
|
|
7
|
+
onQueued?: () => void,
|
|
8
|
+
): Promise<T>;
|
|
5
9
|
};
|
|
6
10
|
|
|
7
11
|
/**
|
|
@@ -45,6 +49,7 @@ export function createDaytonaSandboxStartAdmission(
|
|
|
45
49
|
async run<T>(
|
|
46
50
|
operation: () => Promise<T>,
|
|
47
51
|
signal?: AbortSignal,
|
|
52
|
+
onQueued?: () => void,
|
|
48
53
|
): Promise<T> {
|
|
49
54
|
signal?.throwIfAborted();
|
|
50
55
|
// Preserve eager prepare semantics when capacity is free: the provider
|
|
@@ -57,6 +62,7 @@ export function createDaytonaSandboxStartAdmission(
|
|
|
57
62
|
return createRelease();
|
|
58
63
|
})()
|
|
59
64
|
: await new Promise<() => void>((resolve, reject) => {
|
|
65
|
+
onQueued?.();
|
|
60
66
|
const accept = (release: () => void) => {
|
|
61
67
|
signal?.removeEventListener('abort', abort);
|
|
62
68
|
resolve(release);
|
|
@@ -66,11 +66,13 @@ export const RUNTIME_CAPACITY_POLICY = {
|
|
|
66
66
|
sandboxAcquisition: {
|
|
67
67
|
/**
|
|
68
68
|
* Starting a Daytona sandbox is a provider control-plane transition, not
|
|
69
|
-
* an Absurd execution slot.
|
|
70
|
-
*
|
|
69
|
+
* an Absurd execution slot. Allow up to five concurrent starts within one
|
|
70
|
+
* worker process; the fleet-wide limiter paces lifecycle admissions, and
|
|
71
|
+
* this semaphore bounds concurrent create/retry ladders. A worker has
|
|
72
|
+
* eight execution slots.
|
|
71
73
|
*/
|
|
72
|
-
daytonaConcurrentStartsPerProcess:
|
|
73
|
-
/** Fleet-wide AIMD
|
|
74
|
+
daytonaConcurrentStartsPerProcess: 5,
|
|
75
|
+
/** Fleet-wide AIMD lifecycle-admission pacing. */
|
|
74
76
|
daytonaInitialStartsPerMinute: 120,
|
|
75
77
|
daytonaMaximumStartsPerMinute: 600,
|
|
76
78
|
},
|
package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts
CHANGED
|
@@ -870,8 +870,8 @@ function buildDefaultDeps(absurd: Absurd): AbsurdRuntimeWorkerDeps {
|
|
|
870
870
|
...absurdRuntimeApiFromLaunch(launch),
|
|
871
871
|
...(signal ? { signal } : {}),
|
|
872
872
|
},
|
|
873
|
-
withClient: (operation) =>
|
|
874
|
-
withRuntimeSchedulerClient(getPool(), operation),
|
|
873
|
+
withClient: (operation, trace) =>
|
|
874
|
+
withRuntimeSchedulerClient(getPool(), operation, trace),
|
|
875
875
|
schedulerOptions: options,
|
|
876
876
|
}),
|
|
877
877
|
}).deliver(targetEventId ? { targetEventId } : {}),
|
|
@@ -642,6 +642,8 @@ export type PostgresSchedulerRunStatusSnapshot = {
|
|
|
642
642
|
error: string | null;
|
|
643
643
|
suspension: unknown | null;
|
|
644
644
|
staticPipeline: PlayStaticPipeline | null;
|
|
645
|
+
/** Included only when requested by the admission-projection read path. */
|
|
646
|
+
createdProjectionPending?: boolean;
|
|
645
647
|
};
|
|
646
648
|
|
|
647
649
|
type RunStatusRow = RunRow & {
|
|
@@ -651,6 +653,7 @@ type RunStatusRow = RunRow & {
|
|
|
651
653
|
runtime_profile: string | null;
|
|
652
654
|
launch_json: unknown;
|
|
653
655
|
definition_scope?: string | null;
|
|
656
|
+
created_projection_pending?: boolean;
|
|
654
657
|
suspension_json: unknown | null;
|
|
655
658
|
updated_at: Date | null;
|
|
656
659
|
};
|
|
@@ -17380,11 +17383,23 @@ export async function readPostgresSchedulerRunStatus(
|
|
|
17380
17383
|
options?: Pick<PostgresSchedulerOptions, 'schema'> & {
|
|
17381
17384
|
includeDetails?: boolean;
|
|
17382
17385
|
includeAdmissionScope?: boolean;
|
|
17386
|
+
includeCreatedProjectionPending?: boolean;
|
|
17383
17387
|
},
|
|
17384
17388
|
): Promise<PostgresSchedulerRunStatusSnapshot | null> {
|
|
17385
17389
|
const admissionScopeSelection = options?.includeAdmissionScope
|
|
17386
|
-
? ", launch_json ->> 'definitionScope' AS definition_scope"
|
|
17390
|
+
? ", scheduler_run.launch_json ->> 'definitionScope' AS definition_scope"
|
|
17387
17391
|
: '';
|
|
17392
|
+
const createdProjectionJoin = options?.includeCreatedProjectionPending
|
|
17393
|
+
? `LEFT JOIN ${tableName('outbox', options)} AS created_event
|
|
17394
|
+
ON created_event.run_id = scheduler_run.run_id
|
|
17395
|
+
AND created_event.event_id = $2`
|
|
17396
|
+
: '';
|
|
17397
|
+
const createdProjectionSelection = options?.includeCreatedProjectionPending
|
|
17398
|
+
? ', (created_event.event_id IS NOT NULL AND created_event.delivered_at IS NULL) AS created_projection_pending'
|
|
17399
|
+
: '';
|
|
17400
|
+
const values = options?.includeCreatedProjectionPending
|
|
17401
|
+
? [runId, `run-created:${runId}`]
|
|
17402
|
+
: [runId];
|
|
17388
17403
|
if (options?.includeDetails === false) {
|
|
17389
17404
|
// An admission projection gap needs lifecycle truth only. Launch, result,
|
|
17390
17405
|
// suspension and error JSON may contain row/call-sized detail: never even
|
|
@@ -17403,15 +17418,20 @@ export async function readPostgresSchedulerRunStatus(
|
|
|
17403
17418
|
| 'started_at'
|
|
17404
17419
|
| 'finished_at'
|
|
17405
17420
|
| 'definition_scope'
|
|
17421
|
+
| 'created_projection_pending'
|
|
17406
17422
|
>
|
|
17407
17423
|
>(
|
|
17408
17424
|
`
|
|
17409
|
-
SELECT run_id, org_id, status,
|
|
17410
|
-
|
|
17411
|
-
|
|
17412
|
-
|
|
17425
|
+
SELECT scheduler_run.run_id, scheduler_run.org_id, scheduler_run.status,
|
|
17426
|
+
scheduler_run.play_name, scheduler_run.graph_hash,
|
|
17427
|
+
scheduler_run.runtime_profile, scheduler_run.created_at,
|
|
17428
|
+
scheduler_run.updated_at, scheduler_run.started_at,
|
|
17429
|
+
scheduler_run.finished_at${admissionScopeSelection}${createdProjectionSelection}
|
|
17430
|
+
FROM ${tableName('runs', options)} AS scheduler_run
|
|
17431
|
+
${createdProjectionJoin}
|
|
17432
|
+
WHERE scheduler_run.run_id = $1
|
|
17413
17433
|
`,
|
|
17414
|
-
|
|
17434
|
+
values,
|
|
17415
17435
|
);
|
|
17416
17436
|
const row = result.rows[0];
|
|
17417
17437
|
if (!row) return null;
|
|
@@ -17441,17 +17461,25 @@ export async function readPostgresSchedulerRunStatus(
|
|
|
17441
17461
|
error: null,
|
|
17442
17462
|
suspension: null,
|
|
17443
17463
|
staticPipeline: null,
|
|
17464
|
+
...(options.includeCreatedProjectionPending
|
|
17465
|
+
? { createdProjectionPending: row.created_projection_pending === true }
|
|
17466
|
+
: {}),
|
|
17444
17467
|
};
|
|
17445
17468
|
}
|
|
17446
17469
|
const result = await client.query<RunStatusRow>(
|
|
17447
17470
|
`
|
|
17448
|
-
SELECT run_id, org_id, status,
|
|
17449
|
-
|
|
17450
|
-
|
|
17451
|
-
|
|
17452
|
-
|
|
17471
|
+
SELECT scheduler_run.run_id, scheduler_run.org_id, scheduler_run.status,
|
|
17472
|
+
scheduler_run.play_name, scheduler_run.graph_hash,
|
|
17473
|
+
scheduler_run.runtime_profile, scheduler_run.launch_json,
|
|
17474
|
+
scheduler_run.suspension_json, scheduler_run.terminal_result_json,
|
|
17475
|
+
scheduler_run.terminal_error_json, scheduler_run.runtime_timing_json,
|
|
17476
|
+
scheduler_run.created_at, scheduler_run.updated_at,
|
|
17477
|
+
scheduler_run.started_at, scheduler_run.finished_at${admissionScopeSelection}${createdProjectionSelection}
|
|
17478
|
+
FROM ${tableName('runs', options)} AS scheduler_run
|
|
17479
|
+
${createdProjectionJoin}
|
|
17480
|
+
WHERE scheduler_run.run_id = $1
|
|
17453
17481
|
`,
|
|
17454
|
-
|
|
17482
|
+
values,
|
|
17455
17483
|
);
|
|
17456
17484
|
const row = result.rows[0] ?? null;
|
|
17457
17485
|
if (!row) return null;
|
|
@@ -17487,6 +17515,9 @@ export async function readPostgresSchedulerRunStatus(
|
|
|
17487
17515
|
: null,
|
|
17488
17516
|
suspension: row.suspension_json ?? null,
|
|
17489
17517
|
staticPipeline: staticPipelineFromContractSnapshot(launch.contractSnapshot),
|
|
17518
|
+
...(options?.includeCreatedProjectionPending
|
|
17519
|
+
? { createdProjectionPending: row.created_projection_pending === true }
|
|
17520
|
+
: {}),
|
|
17490
17521
|
};
|
|
17491
17522
|
}
|
|
17492
17523
|
|
|
@@ -19526,6 +19557,40 @@ export type RunLedgerOutboxDeliveredRow = {
|
|
|
19526
19557
|
lagMs: number;
|
|
19527
19558
|
};
|
|
19528
19559
|
|
|
19560
|
+
export type RunLedgerOutboxClientTrace = {
|
|
19561
|
+
runId: string;
|
|
19562
|
+
phase: string;
|
|
19563
|
+
priority?: 'ordinary' | 'critical';
|
|
19564
|
+
};
|
|
19565
|
+
|
|
19566
|
+
export type RunLedgerOutboxWithClient = <T>(
|
|
19567
|
+
operation: (client: PostgresSchedulerQueryClient) => Promise<T>,
|
|
19568
|
+
trace?: RunLedgerOutboxClientTrace,
|
|
19569
|
+
) => Promise<T>;
|
|
19570
|
+
|
|
19571
|
+
function logRunLedgerOutboxSettlementFailure(input: {
|
|
19572
|
+
runId: string;
|
|
19573
|
+
eventIds: readonly string[];
|
|
19574
|
+
stage: 'continuation_release' | 'aborted_release' | 'failure_settlement';
|
|
19575
|
+
settlementError: unknown;
|
|
19576
|
+
deliveryError?: unknown;
|
|
19577
|
+
}): void {
|
|
19578
|
+
const errorMessage = (error: unknown) =>
|
|
19579
|
+
(error instanceof Error ? error.message : String(error)).slice(0, 500);
|
|
19580
|
+
console.error('[run-ledger-outbox.settlement_failed]', {
|
|
19581
|
+
runId: input.runId,
|
|
19582
|
+
stage: input.stage,
|
|
19583
|
+
eventCount: input.eventIds.length,
|
|
19584
|
+
eventIds: input.eventIds.slice(0, 8),
|
|
19585
|
+
settlementError: errorMessage(input.settlementError),
|
|
19586
|
+
deliveryError:
|
|
19587
|
+
input.deliveryError === undefined
|
|
19588
|
+
? null
|
|
19589
|
+
: errorMessage(input.deliveryError),
|
|
19590
|
+
recovery: 'lease_expiry',
|
|
19591
|
+
});
|
|
19592
|
+
}
|
|
19593
|
+
|
|
19529
19594
|
export async function dispatchRunLedgerOutboxToLedgerOnce(
|
|
19530
19595
|
client: PostgresSchedulerQueryClient,
|
|
19531
19596
|
input: RunLedgerOutboxDispatchInput,
|
|
@@ -19570,9 +19635,7 @@ export async function dispatchRunLedgerOutboxToLedgerThroughEvent(
|
|
|
19570
19635
|
* network calls. Each callback owns only the claim or settlement query phase.
|
|
19571
19636
|
*/
|
|
19572
19637
|
export async function dispatchRunLedgerOutboxToLedgerThroughEventWithClientScope(
|
|
19573
|
-
withClient:
|
|
19574
|
-
operation: (client: PostgresSchedulerQueryClient) => Promise<T>,
|
|
19575
|
-
) => Promise<T>,
|
|
19638
|
+
withClient: RunLedgerOutboxWithClient,
|
|
19576
19639
|
input: RunLedgerOutboxDispatchInput & {
|
|
19577
19640
|
targetEventId: string;
|
|
19578
19641
|
maxEvents?: number;
|
|
@@ -19606,9 +19669,7 @@ type RunLedgerOutboxAuthorityScope = {
|
|
|
19606
19669
|
};
|
|
19607
19670
|
|
|
19608
19671
|
async function dispatchRunLedgerOutboxThroughEventWithScope(
|
|
19609
|
-
withClient:
|
|
19610
|
-
operation: (client: PostgresSchedulerQueryClient) => Promise<T>,
|
|
19611
|
-
) => Promise<T>,
|
|
19672
|
+
withClient: RunLedgerOutboxWithClient,
|
|
19612
19673
|
input: RunLedgerOutboxDispatchInput & {
|
|
19613
19674
|
targetEventId: string;
|
|
19614
19675
|
maxEvents?: number;
|
|
@@ -19745,9 +19806,7 @@ async function dispatchRunLedgerOutboxThroughEventWithScope(
|
|
|
19745
19806
|
* background projector use this exact implementation.
|
|
19746
19807
|
*/
|
|
19747
19808
|
export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
|
|
19748
|
-
withClient:
|
|
19749
|
-
operation: (client: PostgresSchedulerQueryClient) => Promise<T>,
|
|
19750
|
-
) => Promise<T>,
|
|
19809
|
+
withClient: RunLedgerOutboxWithClient,
|
|
19751
19810
|
input: RunLedgerOutboxDispatchInput & { waitForRunLock?: boolean },
|
|
19752
19811
|
options?: Pick<PostgresSchedulerOptions, 'schema'>,
|
|
19753
19812
|
): Promise<PostgresSchedulerOutboxProjectionResult> {
|
|
@@ -19761,9 +19820,7 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
|
|
|
19761
19820
|
}
|
|
19762
19821
|
|
|
19763
19822
|
async function dispatchRunLedgerOutboxBatchWithScope(
|
|
19764
|
-
withClient:
|
|
19765
|
-
operation: (client: PostgresSchedulerQueryClient) => Promise<T>,
|
|
19766
|
-
) => Promise<T>,
|
|
19823
|
+
withClient: RunLedgerOutboxWithClient,
|
|
19767
19824
|
input: RunLedgerOutboxDispatchInput & { waitForRunLock?: boolean },
|
|
19768
19825
|
options?: Pick<PostgresSchedulerOptions, 'schema'>,
|
|
19769
19826
|
scope?: RunLedgerOutboxDrainScope,
|
|
@@ -19788,14 +19845,31 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
19788
19845
|
const releasePendingContinuation = async () => {
|
|
19789
19846
|
const nextClaimed = continuation.current?.nextClaimed ?? [];
|
|
19790
19847
|
if (nextClaimed.length === 0) return;
|
|
19791
|
-
|
|
19792
|
-
|
|
19793
|
-
|
|
19794
|
-
|
|
19795
|
-
|
|
19796
|
-
|
|
19797
|
-
|
|
19798
|
-
|
|
19848
|
+
const eventIds = nextClaimed.map((event) => event.eventId);
|
|
19849
|
+
try {
|
|
19850
|
+
await withClient(
|
|
19851
|
+
(client) =>
|
|
19852
|
+
releasePostgresSchedulerOutboxLease(client, eventIds, {
|
|
19853
|
+
...options,
|
|
19854
|
+
leaseOwner,
|
|
19855
|
+
}),
|
|
19856
|
+
{
|
|
19857
|
+
runId: continuation.current?.runId ?? nextClaimed[0]!.runId,
|
|
19858
|
+
phase: 'run_ledger_outbox_lease_release',
|
|
19859
|
+
priority: 'critical',
|
|
19860
|
+
},
|
|
19861
|
+
);
|
|
19862
|
+
nextClaimed.length = 0;
|
|
19863
|
+
} catch (settlementError) {
|
|
19864
|
+
// Keep the in-memory claim visible to this drain and let its durable
|
|
19865
|
+
// lease expire if even critical pool admission cannot settle it.
|
|
19866
|
+
logRunLedgerOutboxSettlementFailure({
|
|
19867
|
+
runId: continuation.current?.runId ?? nextClaimed[0]!.runId,
|
|
19868
|
+
eventIds,
|
|
19869
|
+
stage: 'continuation_release',
|
|
19870
|
+
settlementError,
|
|
19871
|
+
});
|
|
19872
|
+
}
|
|
19799
19873
|
};
|
|
19800
19874
|
const claimEvents = async (client: PostgresSchedulerQueryClient) => {
|
|
19801
19875
|
// The checkout is exclusive. Hold the existing scheduler run's row lock
|
|
@@ -20497,13 +20571,31 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
20497
20571
|
// projection attempt or scheduling backoff, and wake the durable
|
|
20498
20572
|
// projector. If the append already reached the ledger, the projector's
|
|
20499
20573
|
// replay carries the same idempotency key and is a no-op there.
|
|
20500
|
-
const
|
|
20501
|
-
|
|
20502
|
-
|
|
20503
|
-
|
|
20504
|
-
|
|
20505
|
-
|
|
20506
|
-
|
|
20574
|
+
const eventIds = events.map((event) => event.eventId);
|
|
20575
|
+
let released: string[];
|
|
20576
|
+
try {
|
|
20577
|
+
released = await withClient(
|
|
20578
|
+
(client) =>
|
|
20579
|
+
releasePostgresSchedulerOutboxLease(client, eventIds, {
|
|
20580
|
+
...options,
|
|
20581
|
+
leaseOwner,
|
|
20582
|
+
}),
|
|
20583
|
+
{
|
|
20584
|
+
runId: events[0]!.runId,
|
|
20585
|
+
phase: 'run_ledger_outbox_lease_release',
|
|
20586
|
+
priority: 'critical',
|
|
20587
|
+
},
|
|
20588
|
+
);
|
|
20589
|
+
} catch (settlementError) {
|
|
20590
|
+
logRunLedgerOutboxSettlementFailure({
|
|
20591
|
+
runId: events[0]!.runId,
|
|
20592
|
+
eventIds,
|
|
20593
|
+
stage: 'aborted_release',
|
|
20594
|
+
settlementError,
|
|
20595
|
+
deliveryError: error,
|
|
20596
|
+
});
|
|
20597
|
+
released = eventIds;
|
|
20598
|
+
}
|
|
20507
20599
|
return {
|
|
20508
20600
|
attempted: events.length,
|
|
20509
20601
|
projected: 0,
|
|
@@ -20515,22 +20607,34 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
20515
20607
|
};
|
|
20516
20608
|
}
|
|
20517
20609
|
if (error instanceof DeferredRuntimeProjectionInputError) {
|
|
20518
|
-
const outcome = await withClient(
|
|
20519
|
-
|
|
20520
|
-
|
|
20521
|
-
|
|
20522
|
-
|
|
20610
|
+
const outcome = await withClient(
|
|
20611
|
+
(client) =>
|
|
20612
|
+
settlePostgresSchedulerOutboxFailure(client, error.eventId, error, {
|
|
20613
|
+
...options,
|
|
20614
|
+
leaseOwner,
|
|
20615
|
+
}),
|
|
20616
|
+
{
|
|
20617
|
+
runId: events[0]!.runId,
|
|
20618
|
+
phase: 'run_ledger_outbox_failure_settlement',
|
|
20619
|
+
priority: 'critical',
|
|
20620
|
+
},
|
|
20523
20621
|
);
|
|
20524
20622
|
// Earlier facts may already be indexed. Only the invalid immutable row
|
|
20525
20623
|
// is quarantined; valid predecessors remain deliverable in causal order.
|
|
20526
|
-
const released = await withClient(
|
|
20527
|
-
|
|
20528
|
-
|
|
20529
|
-
|
|
20530
|
-
|
|
20531
|
-
|
|
20532
|
-
|
|
20533
|
-
|
|
20624
|
+
const released = await withClient(
|
|
20625
|
+
(client) =>
|
|
20626
|
+
releasePostgresSchedulerOutboxLease(
|
|
20627
|
+
client,
|
|
20628
|
+
events
|
|
20629
|
+
.filter((event) => event.eventId !== error.eventId)
|
|
20630
|
+
.map((event) => event.eventId),
|
|
20631
|
+
{ ...options, leaseOwner },
|
|
20632
|
+
),
|
|
20633
|
+
{
|
|
20634
|
+
runId: events[0]!.runId,
|
|
20635
|
+
phase: 'run_ledger_outbox_lease_release',
|
|
20636
|
+
priority: 'critical',
|
|
20637
|
+
},
|
|
20534
20638
|
);
|
|
20535
20639
|
const failed = outcome === 'blocked' ? [error.eventId] : [];
|
|
20536
20640
|
const retrying =
|
|
@@ -20550,52 +20654,79 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
20550
20654
|
retryingEventIds: retrying,
|
|
20551
20655
|
};
|
|
20552
20656
|
}
|
|
20553
|
-
|
|
20554
|
-
|
|
20555
|
-
|
|
20556
|
-
|
|
20557
|
-
|
|
20558
|
-
|
|
20559
|
-
|
|
20560
|
-
|
|
20561
|
-
|
|
20562
|
-
event
|
|
20563
|
-
|
|
20564
|
-
|
|
20565
|
-
|
|
20566
|
-
|
|
20567
|
-
|
|
20568
|
-
|
|
20569
|
-
|
|
20570
|
-
|
|
20571
|
-
|
|
20572
|
-
|
|
20573
|
-
|
|
20574
|
-
|
|
20575
|
-
|
|
20576
|
-
|
|
20577
|
-
|
|
20578
|
-
|
|
20579
|
-
|
|
20580
|
-
|
|
20581
|
-
|
|
20582
|
-
|
|
20583
|
-
|
|
20584
|
-
|
|
20585
|
-
|
|
20586
|
-
|
|
20587
|
-
|
|
20588
|
-
|
|
20589
|
-
|
|
20590
|
-
|
|
20591
|
-
|
|
20592
|
-
|
|
20593
|
-
|
|
20594
|
-
|
|
20595
|
-
|
|
20596
|
-
|
|
20597
|
-
|
|
20598
|
-
|
|
20657
|
+
let settlement: { blocked: string[]; retrying: string[] };
|
|
20658
|
+
try {
|
|
20659
|
+
settlement = await withClient(
|
|
20660
|
+
async (client) => {
|
|
20661
|
+
await client.query('BEGIN');
|
|
20662
|
+
try {
|
|
20663
|
+
const blocked: string[] = [];
|
|
20664
|
+
const retrying: string[] = [];
|
|
20665
|
+
const ownedRetrying: string[] = [];
|
|
20666
|
+
for (const event of events) {
|
|
20667
|
+
const outcome = await settlePostgresSchedulerOutboxFailure(
|
|
20668
|
+
client,
|
|
20669
|
+
event.eventId,
|
|
20670
|
+
error,
|
|
20671
|
+
{ ...options, leaseOwner },
|
|
20672
|
+
);
|
|
20673
|
+
if (outcome === 'blocked') blocked.push(event.eventId);
|
|
20674
|
+
else retrying.push(event.eventId);
|
|
20675
|
+
if (outcome === 'retrying') ownedRetrying.push(event.eventId);
|
|
20676
|
+
}
|
|
20677
|
+
// Keep every member of a failed append on the same retry deadline.
|
|
20678
|
+
if (ownedRetrying.length > 1) {
|
|
20679
|
+
await client.query(
|
|
20680
|
+
`
|
|
20681
|
+
WITH retry AS (
|
|
20682
|
+
SELECT max(next_attempt_at) AS retry_at
|
|
20683
|
+
FROM ${tableName('outbox', options)}
|
|
20684
|
+
WHERE event_id = ANY($1::text[])
|
|
20685
|
+
AND delivered_at IS NULL AND failed_at IS NULL
|
|
20686
|
+
)
|
|
20687
|
+
UPDATE ${tableName('outbox', options)} AS outbox
|
|
20688
|
+
SET next_attempt_at = retry.retry_at
|
|
20689
|
+
FROM retry
|
|
20690
|
+
WHERE outbox.event_id = ANY($1::text[])
|
|
20691
|
+
AND outbox.delivered_at IS NULL AND outbox.failed_at IS NULL
|
|
20692
|
+
AND retry.retry_at IS NOT NULL
|
|
20693
|
+
`,
|
|
20694
|
+
[ownedRetrying],
|
|
20695
|
+
);
|
|
20696
|
+
}
|
|
20697
|
+
await client.query('COMMIT');
|
|
20698
|
+
return { blocked, retrying };
|
|
20699
|
+
} catch (settlementError) {
|
|
20700
|
+
await client.query('ROLLBACK');
|
|
20701
|
+
throw settlementError;
|
|
20702
|
+
}
|
|
20703
|
+
},
|
|
20704
|
+
{
|
|
20705
|
+
runId: events[0]!.runId,
|
|
20706
|
+
phase: 'run_ledger_outbox_failure_settlement',
|
|
20707
|
+
priority: 'critical',
|
|
20708
|
+
},
|
|
20709
|
+
);
|
|
20710
|
+
} catch (settlementError) {
|
|
20711
|
+
// The delivery error is already known. If the critical settlement
|
|
20712
|
+
// retry also fails, durable lease expiry remains the recovery path.
|
|
20713
|
+
logRunLedgerOutboxSettlementFailure({
|
|
20714
|
+
runId: events[0]!.runId,
|
|
20715
|
+
eventIds: events.map((event) => event.eventId),
|
|
20716
|
+
stage: 'failure_settlement',
|
|
20717
|
+
settlementError,
|
|
20718
|
+
deliveryError: error,
|
|
20719
|
+
});
|
|
20720
|
+
return {
|
|
20721
|
+
attempted: events.length,
|
|
20722
|
+
projected: 0,
|
|
20723
|
+
eventIds: [],
|
|
20724
|
+
failed: 0,
|
|
20725
|
+
failedEventIds: [],
|
|
20726
|
+
retrying: events.length,
|
|
20727
|
+
retryingEventIds: events.map((event) => event.eventId),
|
|
20728
|
+
};
|
|
20729
|
+
}
|
|
20599
20730
|
const failure = runLedgerDeliveryFailure({ error });
|
|
20600
20731
|
console.warn('[run-ledger-outbox.batch_dispatch_failed]', {
|
|
20601
20732
|
runId: input.runId ?? null,
|
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
readPostgresSchedulerOutboxNextDueAt,
|
|
16
16
|
type PostgresSchedulerOptions,
|
|
17
17
|
type PostgresSchedulerOutboxProjectionResult,
|
|
18
|
-
type PostgresSchedulerQueryClient,
|
|
19
18
|
type RunLedgerOutboxDeliveredRow,
|
|
20
19
|
type RunLedgerOutboxHeadPriority,
|
|
21
20
|
type RunLedgerOutboxTokenAuthority,
|
|
21
|
+
type RunLedgerOutboxWithClient,
|
|
22
22
|
} from './postgres';
|
|
23
23
|
import {
|
|
24
24
|
acquirePgNotifyHub,
|
|
@@ -561,9 +561,7 @@ export type RunCreatedInlineDeliveryOutcome =
|
|
|
561
561
|
*/
|
|
562
562
|
export async function deliverRunCreatedOutboxEventInline(input: {
|
|
563
563
|
runId: string;
|
|
564
|
-
withClient:
|
|
565
|
-
operation: (client: PostgresSchedulerQueryClient) => Promise<T>,
|
|
566
|
-
) => Promise<T>;
|
|
564
|
+
withClient: RunLedgerOutboxWithClient;
|
|
567
565
|
schedulerOptions?: Pick<PostgresSchedulerOptions, 'schema'>;
|
|
568
566
|
tokenAuthority: RunLedgerOutboxTokenAuthority;
|
|
569
567
|
deadlineMs?: number;
|