deepline 0.3.406 → 0.3.408
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 +56 -57
- package/dist/bundling-sources/sdk/src/play.ts +21 -5
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +27 -3
- package/dist/bundling-sources/shared_libs/play-runtime/admission-timings.ts +64 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +11 -1
- package/dist/bundling-sources/shared_libs/play-runtime/modal-runtime-config.ts +1 -4
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/gateway-adapter.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/local-process.ts +15 -6
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +275 -73
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +22 -4
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +10 -4
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +72 -0
- package/dist/bundling-sources/shared_libs/play-runtime/webhook-receipt-source-commit-retry.ts +90 -0
- package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +5 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +6 -1
- package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +6 -0
- package/dist/cli/auth-3GB2K636.js +40 -0
- package/dist/cli/{auth-U7LIMXIS.mjs → auth-UVD3CUBB.mjs} +4 -4
- package/dist/cli/{billing-KGGS3444.mjs → billing-BZVTXXLM.mjs} +23 -16
- package/dist/cli/{billing-5ABVIJFU.js → billing-BZVYAF6T.js} +92 -85
- package/dist/cli/{chunk-KPU53YBB.js → chunk-2XXXFPTD.js} +67 -67
- package/dist/cli/{chunk-FQBKK5DG.js → chunk-3ZB6IIA7.js} +26 -26
- package/dist/cli/{chunk-5IGBBYXH.mjs → chunk-4CFULMRB.mjs} +73 -4
- package/dist/cli/{chunk-OPHLT4TM.mjs → chunk-4QFT5LGV.mjs} +2 -2
- package/dist/cli/{chunk-W2BAO4OR.js → chunk-4RNDKFNQ.js} +2 -2
- package/dist/cli/{chunk-GAMFK2ZP.mjs → chunk-67RWR34T.mjs} +10 -3
- package/dist/cli/{chunk-APLRSERF.js → chunk-AUMD2VXP.js} +60 -63
- package/dist/cli/{chunk-N6DJQQ2S.js → chunk-BRJUESQV.js} +50 -50
- package/dist/cli/{chunk-W3ZNQE5Y.js → chunk-D6FFBSM5.js} +1 -1
- package/dist/cli/{chunk-AYHLUHE5.js → chunk-E3PJF6YP.js} +6 -2
- package/dist/cli/{chunk-IE6IKRQA.js → chunk-ECVLPS67.js} +15 -15
- package/dist/cli/{chunk-QJBJZVG6.js → chunk-HQY2SG3K.js} +15 -8
- package/dist/cli/{chunk-2OFPPAUY.mjs → chunk-I3DHIXVJ.mjs} +4 -4
- package/dist/cli/{chunk-RXDJKAM2.mjs → chunk-IOHRWLQE.mjs} +6 -6
- package/dist/cli/{chunk-2MLY2ZBT.mjs → chunk-IWBXJDZA.mjs} +2 -2
- package/dist/cli/{chunk-URWF7NGQ.js → chunk-J5PTX66Y.js} +28 -14
- package/dist/cli/{chunk-7ZMVAV2B.mjs → chunk-LOYISF7S.mjs} +55 -58
- package/dist/cli/{chunk-T7YF4MQH.mjs → chunk-MJELBQBU.mjs} +4 -4
- package/dist/cli/{chunk-WJYPBHTE.js → chunk-OSFWFV72.js} +11 -4
- package/dist/cli/{chunk-ZI2ZNDJK.mjs → chunk-PYZZMAJQ.mjs} +28 -14
- package/dist/cli/{chunk-N43PX2CA.js → chunk-Q3LFI3VH.js} +8 -8
- package/dist/cli/{chunk-NYDRX6JJ.js → chunk-Q3PUHXOY.js} +99 -30
- package/dist/cli/{chunk-YSAZVLJD.js → chunk-QUAQX3FQ.js} +4 -4
- package/dist/cli/{chunk-4REBZQNK.js → chunk-RWCY6YI2.js} +53 -53
- package/dist/cli/{chunk-CGX4NSS3.mjs → chunk-SD7MXAJA.mjs} +1 -1
- package/dist/cli/{chunk-UFS752TU.mjs → chunk-SJVVBWRL.mjs} +5 -1
- package/dist/cli/{chunk-V3OTRWVK.mjs → chunk-URACNNLO.mjs} +2 -2
- package/dist/cli/{chunk-WXLOW623.mjs → chunk-WPAB4DCU.mjs} +14 -7
- package/dist/cli/{chunk-42RUJLQI.mjs → chunk-WTT6CLED.mjs} +1 -1
- package/dist/cli/{chunk-YLV6PT6B.mjs → chunk-XXLXOUUU.mjs} +1 -1
- package/dist/cli/{chunk-77UGRG6X.mjs → chunk-YMOFWHGO.mjs} +3 -3
- package/dist/cli/{chunk-EKS2FXL5.js → chunk-ZBABPK6Y.js} +8 -8
- package/dist/cli/command-docs.js +2 -2
- package/dist/cli/command-docs.mjs +1 -1
- package/dist/cli/{csv-HXJAAW3H.mjs → csv-WPSXG6ZZ.mjs} +3 -3
- package/dist/cli/{csv-U36TIOKU.js → csv-XLGLHJ6P.js} +12 -12
- package/dist/cli/{db-T5MLQQWJ.js → db-5PTNJG4X.js} +25 -25
- package/dist/cli/{db-GRWD3JAC.mjs → db-ABS57ABJ.mjs} +4 -4
- package/dist/cli/{describe-NFX6THJE.js → describe-EZS6PQXA.js} +11 -11
- package/dist/cli/{describe-HXFEIZFO.mjs → describe-PVWQJ2PB.mjs} +7 -7
- package/dist/cli/describe-core.d.mts +2 -2
- package/dist/cli/describe-core.d.ts +2 -2
- package/dist/cli/{executions-KBHTDL3A.js → executions-FNTAFQ7Y.js} +6 -6
- package/dist/cli/{executions-YGOS5E44.mjs → executions-OKJGATQZ.mjs} +4 -4
- package/dist/cli/{feedback-VP3GWJIH.js → feedback-6YBOMSUA.js} +7 -7
- package/dist/cli/{feedback-NEQGCSHB.mjs → feedback-W27HDMRR.mjs} +3 -3
- package/dist/cli/git-YKUXXJOR.js +24 -0
- package/dist/cli/{git-JJ3CHOTL.mjs → git-YOOUEL6M.mjs} +4 -4
- package/dist/cli/index.js +204 -127
- package/dist/cli/index.mjs +124 -47
- package/dist/cli/{legacy-noops-ITTD33ZN.js → legacy-noops-2VZ7XT6C.js} +7 -7
- package/dist/cli/{legacy-noops-A6KGBODU.mjs → legacy-noops-V6OKW7VR.mjs} +4 -4
- package/dist/cli/{monitors-DXVP5YFC.js → monitors-FBWGVIUS.js} +84 -84
- package/dist/cli/{monitors-NGEXCUEY.mjs → monitors-P2YYWTWT.mjs} +4 -4
- package/dist/cli/{org-C4ZTOSQC.js → org-3XUSVX5T.js} +64 -64
- package/dist/cli/{org-34DBJSFP.mjs → org-DVMG6H3C.mjs} +4 -4
- package/dist/cli/{play-SVLQKZBG.mjs → play-GNC5CQAS.mjs} +70 -18
- package/dist/cli/{play-5FWTZCHN.js → play-YG5L4BWQ.js} +345 -293
- package/dist/cli/{providers-QWR2HRNY.js → providers-7PSWG2OV.js} +7 -7
- package/dist/cli/{providers-RQTSGYE4.mjs → providers-JR33SLWL.mjs} +4 -4
- package/dist/cli/{quickstart-DHFNEMGY.js → quickstart-FDVZ5BL3.js} +5 -5
- package/dist/cli/{quickstart-W5UHZAEU.mjs → quickstart-VUOBQYIQ.mjs} +3 -3
- package/dist/cli/{search-U4AJC3FH.mjs → search-JZYLO33K.mjs} +5 -5
- package/dist/cli/search-PPPYC5OZ.js +30 -0
- package/dist/cli/{secrets-YSMQ7CVZ.mjs → secrets-3MCYBT4I.mjs} +4 -4
- package/dist/cli/{secrets-HH4H7BLE.js → secrets-VS266FVA.js} +13 -13
- package/dist/cli/{sessions-URONRCTV.mjs → sessions-ELLLT23E.mjs} +4 -4
- package/dist/cli/{sessions-AJZXYUCJ.js → sessions-TEHEWW7O.js} +5 -5
- package/dist/cli/{settings-QAW62BH4.js → settings-7364NMMA.js} +75 -75
- package/dist/cli/{settings-KGAMW4MN.mjs → settings-PZCKAFII.mjs} +8 -8
- package/dist/cli/{setup-P54DPBFO.mjs → setup-A7GQ4KIA.mjs} +7 -7
- package/dist/cli/{setup-KAMFU5VE.js → setup-PMWYLCT6.js} +42 -42
- package/dist/cli/skills-SYS7VRRK.js +29 -0
- package/dist/cli/{skills-UMWRJ6TL.mjs → skills-WS6BIFPQ.mjs} +5 -5
- package/dist/cli/{tools-HN4EFVY7.mjs → tools-BR4DOZA2.mjs} +7 -7
- package/dist/cli/{tools-HX3BHT55.js → tools-KK4BKVQR.js} +8 -8
- package/dist/cli/update-2IV5JTX2.js +29 -0
- package/dist/cli/{update-7AFQCJ75.mjs → update-D2B7UNFT.mjs} +7 -7
- package/dist/cli/{workflow-7EHU5ZPX.js → workflow-6ODTCYXU.js} +15 -15
- package/dist/cli/{workflow-ARDO4VHU.mjs → workflow-PQXC2R47.mjs} +5 -5
- package/dist/{client-Db1jFLpF.d.ts → client-BcvhDfJJ.d.ts} +80 -58
- package/dist/{client-Buv1_ktG.d.mts → client-Z9Pye1Wm.d.mts} +80 -58
- package/dist/{compiler-manifest-N77W75Py.d.ts → compiler-manifest-Ycx-hoAr.d.mts} +8 -1
- package/dist/{compiler-manifest-N77W75Py.d.mts → compiler-manifest-Ycx-hoAr.d.ts} +8 -1
- package/dist/{index-3WOfyVhW.d.mts → index-CZXgiN3E.d.mts} +1 -1
- package/dist/{index-CtIJFTCl.d.ts → index-NPG5pqxQ.d.ts} +1 -1
- package/dist/index.d.mts +13 -10
- package/dist/index.d.ts +13 -10
- package/dist/index.js +28 -11
- package/dist/index.mjs +25 -8
- package/dist/install-integrity.json +86 -84
- package/dist/plays/bundle-play-file.d.mts +3 -3
- package/dist/plays/bundle-play-file.d.ts +3 -3
- package/dist/plays/play-description.d.mts +2 -2
- package/dist/plays/play-description.d.ts +2 -2
- package/dist/plays/run-request.d.mts +2 -2
- package/dist/plays/run-request.d.ts +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-K5QAZH42.js +0 -40
- package/dist/cli/git-63RYCZSI.js +0 -24
- package/dist/cli/search-YAYYU3WD.js +0 -30
- package/dist/cli/skills-M2GGHYJU.js +0 -29
- package/dist/cli/update-I23NN5QI.js +0 -29
|
@@ -18598,8 +18598,8 @@ function runLedgerOutboxPrefixClaimSql(
|
|
|
18598
18598
|
const lockFence = fence
|
|
18599
18599
|
? `current_setting('deepline.run_ledger_outbox_lock', true) = ${escapeLiteral(fence.runId)}`
|
|
18600
18600
|
: undefined;
|
|
18601
|
-
const pending = (alias: string) =>
|
|
18602
|
-
`${alias}.delivered_at IS NULL${
|
|
18601
|
+
const pending = (alias: string, primaryKeyLookup = false) =>
|
|
18602
|
+
`${primaryKeyLookup ? `coalesce(${alias}.delivered_at IS NULL, false)` : `${alias}.delivered_at IS NULL`}${
|
|
18603
18603
|
acknowledgement ? ` AND NOT (${alias}.event_id = ANY($5::text[]))` : ''
|
|
18604
18604
|
}`;
|
|
18605
18605
|
// The dispatcher already chose this run. Seek its oldest pending fact
|
|
@@ -18628,11 +18628,20 @@ function runLedgerOutboxPrefixClaimSql(
|
|
|
18628
18628
|
? `(head.event_type = ${RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL.runEvents})`
|
|
18629
18629
|
: 'false';
|
|
18630
18630
|
const findSearchBlockersOnce = seekRunHead && input.searchOnly === true;
|
|
18631
|
-
|
|
18631
|
+
// Only ordinary scoped lifecycle enumeration changes. Its existing limit
|
|
18632
|
+
// bounds candidate keys before the original eligibility/fence predicates;
|
|
18633
|
+
// a frozen terminal in that window retains complete receipt membership.
|
|
18634
|
+
// Carry the locked event type instead of fetching it again by primary key.
|
|
18635
|
+
// Recheck pending/run identity without inviting stale partial-index scans.
|
|
18636
|
+
// Predecessor checks share snapshot metadata; bounded keys own live row access.
|
|
18637
|
+
const inspectLifecycleCandidates = seekRunHead && input.searchOnly !== true;
|
|
18638
|
+
const claimFactColumnsSql = (alias: string) =>
|
|
18632
18639
|
`${alias}.event_id, ${alias}.run_id, ${alias}.event_type,
|
|
18633
18640
|
${alias}.created_at, ${alias}.failed_at, ${alias}.next_attempt_at,
|
|
18634
18641
|
${alias}.lease_owner, ${alias}.lease_expires_at,
|
|
18635
18642
|
${supportsTerminalBatchMarker ? `${alias}.delivery_batch_started_at` : 'NULL::timestamptz AS delivery_batch_started_at'}`;
|
|
18643
|
+
const lifecycleFactColumnsSql = (alias: string) =>
|
|
18644
|
+
`${claimFactColumnsSql(alias)}, ${alias}.delivered_at`;
|
|
18636
18645
|
const blockingPredecessorSql = (alias: string) => `(
|
|
18637
18646
|
(${alias}.event_type = ${RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL.runEvents}
|
|
18638
18647
|
AND NOT (${ingressPrefixSql}))
|
|
@@ -18646,6 +18655,27 @@ function runLedgerOutboxPrefixClaimSql(
|
|
|
18646
18655
|
AND ${alias}.lease_owner IS DISTINCT FROM $3::text
|
|
18647
18656
|
)
|
|
18648
18657
|
)`;
|
|
18658
|
+
// A modern frozen head cannot cross an unmarked predecessor. A witness in
|
|
18659
|
+
// this snapshot's window therefore blocks every later key, even if a live
|
|
18660
|
+
// candidate is rejected after locking. Keep full membership without that
|
|
18661
|
+
// witness: an all-marked window can refill after a concurrent ACK.
|
|
18662
|
+
const lifecycleRequiresFullMembershipSql = inspectLifecycleCandidates
|
|
18663
|
+
? `EXISTS (
|
|
18664
|
+
SELECT 1 FROM lifecycle_window AS terminal
|
|
18665
|
+
WHERE terminal.delivery_batch_started_at IS NOT NULL
|
|
18666
|
+
AND terminal.event_type IN (${RUN_EVENT_KIND_SQL_LITERAL.runCompleted}, ${RUN_EVENT_KIND_SQL_LITERAL.runFailed}, ${RUN_EVENT_KIND_SQL_LITERAL.runCancelled})${
|
|
18667
|
+
supportsTerminalBatchMarker && input.allowIngressPrefix === true
|
|
18668
|
+
? `
|
|
18669
|
+
AND NOT EXISTS (
|
|
18670
|
+
SELECT 1 FROM head AS frozen_head
|
|
18671
|
+
CROSS JOIN lifecycle_window AS unmarked
|
|
18672
|
+
WHERE frozen_head.delivery_batch_started_at IS NOT NULL
|
|
18673
|
+
AND unmarked.delivery_batch_started_at IS NULL
|
|
18674
|
+
)`
|
|
18675
|
+
: ''
|
|
18676
|
+
}
|
|
18677
|
+
)`
|
|
18678
|
+
: 'false';
|
|
18649
18679
|
return `
|
|
18650
18680
|
WITH ${
|
|
18651
18681
|
acknowledgement
|
|
@@ -18681,9 +18711,8 @@ function runLedgerOutboxPrefixClaimSql(
|
|
|
18681
18711
|
${findSearchBlockersOnce ? 'candidate.created_at,' : ''}
|
|
18682
18712
|
${supportsTerminalBatchMarker ? 'candidate.delivery_batch_started_at' : 'NULL::timestamptz'} AS delivery_batch_started_at
|
|
18683
18713
|
FROM ${tableName('outbox', options)} AS candidate
|
|
18684
|
-
${seekRunHead ? 'JOIN
|
|
18685
|
-
${
|
|
18686
|
-
WHERE ${pending('candidate')}
|
|
18714
|
+
${seekRunHead ? '' : '\n '}${input.extendOwnedHead ? 'JOIN owned_run ON owned_run.run_id = candidate.run_id' : ''}
|
|
18715
|
+
WHERE ${seekRunHead ? `candidate.event_id = (SELECT event_id FROM pending_head) AND ${pending('candidate')}` : pending('candidate')}
|
|
18687
18716
|
${lockFence ? `AND (${lockFence})` : ''}
|
|
18688
18717
|
${fence?.expectedHeadEventId ? `AND candidate.event_id = ${escapeLiteral(fence.expectedHeadEventId)}` : ''}
|
|
18689
18718
|
AND ${searchLaneSql('candidate')} = ${input.searchOnly === true ? 'true' : 'false'}
|
|
@@ -18766,14 +18795,16 @@ function runLedgerOutboxPrefixClaimSql(
|
|
|
18766
18795
|
), ${
|
|
18767
18796
|
findSearchBlockersOnce
|
|
18768
18797
|
? `search_prefix AS MATERIALIZED (
|
|
18769
|
-
SELECT
|
|
18798
|
+
SELECT prefix.* FROM head
|
|
18799
|
+
CROSS JOIN LATERAL (
|
|
18800
|
+
SELECT ${claimFactColumnsSql('pending')}
|
|
18770
18801
|
FROM ${tableName('outbox', options)} AS pending
|
|
18771
|
-
|
|
18772
|
-
WHERE pending.run_id = $2::text
|
|
18802
|
+
WHERE pending.run_id = head.run_id
|
|
18773
18803
|
AND ${pending('pending')}
|
|
18774
18804
|
AND ${searchLaneSql('pending')} = true
|
|
18775
18805
|
ORDER BY ${runLedgerOrderSql('pending')}
|
|
18776
18806
|
LIMIT $1
|
|
18807
|
+
) AS prefix
|
|
18777
18808
|
), frozen_search_prefix AS MATERIALIZED (
|
|
18778
18809
|
SELECT EXISTS (
|
|
18779
18810
|
SELECT 1 FROM search_prefix AS fact
|
|
@@ -18791,7 +18822,7 @@ function runLedgerOutboxPrefixClaimSql(
|
|
|
18791
18822
|
-- A frozen terminal receipt can contain marked facts beyond newer
|
|
18792
18823
|
-- unmarked rows. Retain that full membership scan only for this case;
|
|
18793
18824
|
-- limiting its raw window would strand an already attempted receipt.
|
|
18794
|
-
SELECT ${
|
|
18825
|
+
SELECT ${claimFactColumnsSql('pending')}
|
|
18795
18826
|
FROM ${tableName('outbox', options)} AS pending
|
|
18796
18827
|
JOIN head ON head.run_id = pending.run_id
|
|
18797
18828
|
WHERE (SELECT has_terminal FROM frozen_search_prefix)
|
|
@@ -18826,13 +18857,49 @@ function runLedgerOutboxPrefixClaimSql(
|
|
|
18826
18857
|
LIMIT 1
|
|
18827
18858
|
),`
|
|
18828
18859
|
: ''
|
|
18860
|
+
}${
|
|
18861
|
+
inspectLifecycleCandidates
|
|
18862
|
+
? `lifecycle_window AS MATERIALIZED (
|
|
18863
|
+
SELECT prefix.* FROM head
|
|
18864
|
+
CROSS JOIN LATERAL (
|
|
18865
|
+
SELECT ${lifecycleFactColumnsSql('pending')}
|
|
18866
|
+
FROM ${tableName('outbox', options)} AS pending
|
|
18867
|
+
WHERE pending.run_id = head.run_id
|
|
18868
|
+
AND pending.run_id = $2::text
|
|
18869
|
+
AND ${pending('pending')}
|
|
18870
|
+
AND ${searchLaneSql('pending')} = false
|
|
18871
|
+
ORDER BY ${runLedgerOrderSql('pending')}
|
|
18872
|
+
LIMIT $1
|
|
18873
|
+
) AS prefix
|
|
18874
|
+
), lifecycle_facts AS MATERIALIZED (
|
|
18875
|
+
SELECT prefix.* FROM lifecycle_window AS prefix
|
|
18876
|
+
WHERE NOT ${lifecycleRequiresFullMembershipSql}
|
|
18877
|
+
UNION ALL
|
|
18878
|
+
SELECT ${lifecycleFactColumnsSql('pending')}
|
|
18879
|
+
FROM ${tableName('outbox', options)} AS pending
|
|
18880
|
+
JOIN head ON head.run_id = pending.run_id
|
|
18881
|
+
WHERE ${lifecycleRequiresFullMembershipSql}
|
|
18882
|
+
AND pending.run_id = $2::text
|
|
18883
|
+
AND ${pending('pending')}
|
|
18884
|
+
AND ${searchLaneSql('pending')} = false
|
|
18885
|
+
), `
|
|
18886
|
+
: ''
|
|
18829
18887
|
}candidates AS MATERIALIZED (
|
|
18830
|
-
|
|
18888
|
+
${
|
|
18889
|
+
runId !== null
|
|
18890
|
+
? `SELECT candidate.event_id${inspectLifecycleCandidates ? ', candidate.event_type' : ''} FROM head
|
|
18891
|
+
CROSS JOIN LATERAL (
|
|
18892
|
+
SELECT outbox.event_id${inspectLifecycleCandidates ? ', outbox.event_type' : ''}
|
|
18893
|
+
FROM ${tableName('outbox', options)} AS outbox
|
|
18894
|
+
WHERE ${pending('outbox', inspectLifecycleCandidates)}
|
|
18895
|
+
AND ${inspectLifecycleCandidates ? 'coalesce(outbox.run_id = head.run_id, false)' : 'outbox.run_id = head.run_id'}`
|
|
18896
|
+
: `SELECT outbox.event_id
|
|
18831
18897
|
FROM ${tableName('outbox', options)} AS outbox
|
|
18832
18898
|
JOIN head ON head.run_id = outbox.run_id
|
|
18833
18899
|
WHERE ${pending('outbox')}
|
|
18834
|
-
|
|
18835
|
-
|
|
18900
|
+
`
|
|
18901
|
+
}
|
|
18902
|
+
${findSearchBlockersOnce ? 'AND outbox.event_id = ANY(ARRAY(SELECT event_id FROM search_facts))' : ''}${inspectLifecycleCandidates ? '\n AND outbox.event_id = ANY(ARRAY(SELECT event_id FROM lifecycle_facts))' : ''}
|
|
18836
18903
|
AND ${searchLaneSql('outbox')} = ${input.searchOnly === true ? 'true' : 'false'}
|
|
18837
18904
|
AND ${outboxNotFailedSql('outbox')}
|
|
18838
18905
|
-- Admission is causally first and must be projected alone. A later
|
|
@@ -18881,8 +18948,8 @@ function runLedgerOutboxPrefixClaimSql(
|
|
|
18881
18948
|
)`
|
|
18882
18949
|
: ` AND NOT EXISTS (
|
|
18883
18950
|
SELECT 1
|
|
18884
|
-
FROM ${tableName('outbox', options)} AS terminal_predecessor
|
|
18885
|
-
WHERE terminal_predecessor.run_id = outbox.run_id
|
|
18951
|
+
FROM ${inspectLifecycleCandidates ? 'lifecycle_facts' : tableName('outbox', options)} AS terminal_predecessor
|
|
18952
|
+
WHERE terminal_predecessor.run_id = outbox.run_id${inspectLifecycleCandidates ? '\n AND terminal_predecessor.run_id = $2::text' : ''}
|
|
18886
18953
|
AND ${pending('terminal_predecessor')}
|
|
18887
18954
|
AND ${
|
|
18888
18955
|
supportsTerminalBatchMarker
|
|
@@ -18897,16 +18964,16 @@ function runLedgerOutboxPrefixClaimSql(
|
|
|
18897
18964
|
AND terminal_predecessor.event_type IN (
|
|
18898
18965
|
${RUN_EVENT_KIND_SQL_LITERAL.runCompleted}, ${RUN_EVENT_KIND_SQL_LITERAL.runFailed}, ${RUN_EVENT_KIND_SQL_LITERAL.runCancelled}
|
|
18899
18966
|
)
|
|
18900
|
-
AND ${runLedgerPrecedesSql('terminal_predecessor', 'outbox', false, input.searchOnly === true)}
|
|
18967
|
+
AND ${inspectLifecycleCandidates ? `${runLedgerPositionSql('terminal_predecessor')} < ${runLedgerPositionSql('outbox')}` : runLedgerPrecedesSql('terminal_predecessor', 'outbox', false, input.searchOnly === true)}
|
|
18901
18968
|
)
|
|
18902
18969
|
-- Claim only the contiguous due prefix. A delayed, leased, or failed
|
|
18903
18970
|
-- predecessor retains ownership of everything that follows it.
|
|
18904
18971
|
AND NOT EXISTS (
|
|
18905
18972
|
SELECT 1
|
|
18906
|
-
FROM ${tableName('outbox', options)} AS predecessor
|
|
18907
|
-
WHERE predecessor.run_id = outbox.run_id
|
|
18973
|
+
FROM ${inspectLifecycleCandidates ? 'lifecycle_facts' : tableName('outbox', options)} AS predecessor
|
|
18974
|
+
WHERE predecessor.run_id = outbox.run_id${inspectLifecycleCandidates ? '\n AND predecessor.run_id = $2::text' : ''}
|
|
18908
18975
|
AND ${pending('predecessor')}
|
|
18909
|
-
AND ${runLedgerPrecedesSql('predecessor', 'outbox', false, input.searchOnly === true)}
|
|
18976
|
+
AND ${inspectLifecycleCandidates ? `${runLedgerPositionSql('predecessor')} < ${runLedgerPositionSql('outbox')}` : runLedgerPrecedesSql('predecessor', 'outbox', false, input.searchOnly === true)}
|
|
18910
18977
|
AND ${blockingPredecessorSql('predecessor')}
|
|
18911
18978
|
)
|
|
18912
18979
|
`
|
|
@@ -18914,14 +18981,18 @@ function runLedgerOutboxPrefixClaimSql(
|
|
|
18914
18981
|
ORDER BY ${runLedgerOrderSql('outbox')}
|
|
18915
18982
|
FOR UPDATE OF outbox
|
|
18916
18983
|
LIMIT $1
|
|
18917
|
-
)
|
|
18984
|
+
${runId !== null ? ' ) AS candidate\n ' : ''}), ${
|
|
18985
|
+
inspectLifecycleCandidates
|
|
18986
|
+
? ''
|
|
18987
|
+
: `terminal_batch AS (
|
|
18918
18988
|
SELECT EXISTS (
|
|
18919
18989
|
SELECT 1
|
|
18920
18990
|
FROM ${tableName('outbox', options)} AS candidate
|
|
18921
18991
|
JOIN candidates ON candidates.event_id = candidate.event_id
|
|
18922
18992
|
WHERE candidate.event_type IN (${RUN_EVENT_KIND_SQL_LITERAL.runCompleted}, ${RUN_EVENT_KIND_SQL_LITERAL.runFailed}, ${RUN_EVENT_KIND_SQL_LITERAL.runCancelled})
|
|
18923
18993
|
) AS has_terminal
|
|
18924
|
-
),
|
|
18994
|
+
), `
|
|
18995
|
+
}claimed AS (
|
|
18925
18996
|
UPDATE ${tableName('outbox', options)} outbox
|
|
18926
18997
|
SET lease_owner = $3,
|
|
18927
18998
|
lease_expires_at = CASE
|
|
@@ -18931,14 +19002,14 @@ function runLedgerOutboxPrefixClaimSql(
|
|
|
18931
19002
|
${
|
|
18932
19003
|
supportsTerminalBatchMarker
|
|
18933
19004
|
? `, delivery_batch_started_at = CASE
|
|
18934
|
-
WHEN terminal_batch.has_terminal ${input.allowIngressPrefix === true ? `OR ${urgentLifecyclePendingSql('outbox')} OR EXISTS (SELECT 1 FROM head WHERE head.event_type = ${RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL.runEvents})` : ''}
|
|
19005
|
+
WHEN ${inspectLifecycleCandidates ? `EXISTS (SELECT 1 FROM candidates AS terminal_candidate WHERE terminal_candidate.event_type IN (${RUN_EVENT_KIND_SQL_LITERAL.runCompleted}, ${RUN_EVENT_KIND_SQL_LITERAL.runFailed}, ${RUN_EVENT_KIND_SQL_LITERAL.runCancelled}))` : 'terminal_batch.has_terminal'} ${input.allowIngressPrefix === true ? `OR ${urgentLifecyclePendingSql('outbox')} OR EXISTS (SELECT 1 FROM head WHERE head.event_type = ${RUN_SCHEDULER_OUTBOX_EVENT_TYPE_SQL_LITERAL.runEvents})` : ''}
|
|
18935
19006
|
THEN COALESCE(outbox.delivery_batch_started_at, statement_timestamp())
|
|
18936
19007
|
ELSE outbox.delivery_batch_started_at
|
|
18937
19008
|
END`
|
|
18938
19009
|
: ''
|
|
18939
19010
|
}
|
|
18940
19011
|
FROM candidates
|
|
18941
|
-
CROSS JOIN terminal_batch
|
|
19012
|
+
${inspectLifecycleCandidates ? '' : 'CROSS JOIN terminal_batch'}
|
|
18942
19013
|
WHERE outbox.event_id = candidates.event_id
|
|
18943
19014
|
RETURNING outbox.event_id, outbox.run_id, outbox.event_type,
|
|
18944
19015
|
outbox.payload_json, outbox.created_at, outbox.lease_owner,
|
|
@@ -19002,9 +19073,34 @@ function runLedgerOutboxPrefixClaimBatchSql(input: {
|
|
|
19002
19073
|
lockStrength?: 'no_key_update';
|
|
19003
19074
|
transportHeadSql?: string;
|
|
19004
19075
|
}): string {
|
|
19005
|
-
|
|
19076
|
+
// Ordinary claims have four bounded primitive arguments. Give PostgreSQL
|
|
19077
|
+
// constants instead of a scalar InitPlan for every repeated argument. Keep
|
|
19078
|
+
// the JSON renderer for ACK arrays, transport/extension claims and values
|
|
19079
|
+
// whose existing JSON conversion or cast failure must remain unchanged.
|
|
19080
|
+
const directScalars =
|
|
19081
|
+
input.params.length === 4 &&
|
|
19082
|
+
!input.transportHeadSql &&
|
|
19083
|
+
input.params.every((value, index) =>
|
|
19084
|
+
index === 0 || index === 3
|
|
19085
|
+
? typeof value === 'number' &&
|
|
19086
|
+
Number.isInteger(value) &&
|
|
19087
|
+
value >= -2_147_483_648 &&
|
|
19088
|
+
value <= 2_147_483_647
|
|
19089
|
+
: value === null ||
|
|
19090
|
+
(typeof value === 'string' &&
|
|
19091
|
+
/^(?:[\u0001-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF])*$/.test(
|
|
19092
|
+
value,
|
|
19093
|
+
)),
|
|
19094
|
+
);
|
|
19095
|
+
const encoded = directScalars
|
|
19096
|
+
? undefined
|
|
19097
|
+
: escapeLiteral(JSON.stringify(input.params));
|
|
19006
19098
|
const parameter = (index: number) => {
|
|
19007
19099
|
const value = input.params[index - 1];
|
|
19100
|
+
if (directScalars) {
|
|
19101
|
+
const type = typeof value === 'number' ? 'integer' : 'text';
|
|
19102
|
+
return `(${value === null ? 'NULL' : escapeLiteral(String(value))}::${type})`;
|
|
19103
|
+
}
|
|
19008
19104
|
if (Array.isArray(value)) {
|
|
19009
19105
|
return `(SELECT ARRAY(SELECT jsonb_array_elements_text(values_json->${index - 1})) FROM run_ledger_parameters)`;
|
|
19010
19106
|
}
|
|
@@ -19022,9 +19118,11 @@ function runLedgerOutboxPrefixClaimBatchSql(input: {
|
|
|
19022
19118
|
(match, index: string | undefined) =>
|
|
19023
19119
|
index ? parameter(Number(index)) : match,
|
|
19024
19120
|
)
|
|
19025
|
-
.
|
|
19026
|
-
|
|
19027
|
-
|
|
19121
|
+
// Use a callback so replacement metacharacters inside generated IDs stay literal.
|
|
19122
|
+
.replace(/^\s*WITH\s/, (match) =>
|
|
19123
|
+
directScalars
|
|
19124
|
+
? match
|
|
19125
|
+
: `WITH run_ledger_parameters AS MATERIALIZED (SELECT ${encoded}::jsonb AS values_json), `,
|
|
19028
19126
|
);
|
|
19029
19127
|
return `BEGIN;
|
|
19030
19128
|
SELECT set_config('lock_timeout', '${RUNTIME_SCHEDULER_CANCEL_LOCK_TIMEOUT_MS}ms', true),
|
|
@@ -19053,6 +19151,8 @@ async function claimRunLedgerOutboxPrefixInBatch(
|
|
|
19053
19151
|
expectedHeadEventId?: string;
|
|
19054
19152
|
lockStrength?: 'no_key_update';
|
|
19055
19153
|
transportCandidate?: RunLedgerTransportCandidate;
|
|
19154
|
+
/** Discover the zero-effect transport head under this transaction's run lock. */
|
|
19155
|
+
discoverTransportHead?: boolean;
|
|
19056
19156
|
recoverTransportDelivery?: boolean;
|
|
19057
19157
|
},
|
|
19058
19158
|
options?: Pick<PostgresSchedulerOptions, 'schema'>,
|
|
@@ -19093,8 +19193,22 @@ async function claimRunLedgerOutboxPrefixInBatch(
|
|
|
19093
19193
|
// run/head locks a never-leased, never-frozen carrier may be acknowledged
|
|
19094
19194
|
// locally before the next READ COMMITTED statement claims its successor.
|
|
19095
19195
|
// Keep the successor's existing run.events-first receipt shape unchanged.
|
|
19196
|
+
const recoverTransportDelivery = input.recoverTransportDelivery === true;
|
|
19197
|
+
// An ACK and successor claim commit in the same transaction. For a discovered
|
|
19198
|
+
// carrier whose response was lost, xmin plus the still-live successor owner
|
|
19199
|
+
// proves exactly which delivery consumed this drain's allowance.
|
|
19200
|
+
const ownedTransportSql = (alias: string) => `
|
|
19201
|
+
to_jsonb(${alias})->>'delivery_batch_started_at' IS NULL AND EXISTS (
|
|
19202
|
+
SELECT 1 FROM ${tableName('outbox', options)} AS successor
|
|
19203
|
+
WHERE successor.run_id = ${alias}.run_id AND successor.delivered_at IS NULL
|
|
19204
|
+
AND successor.lease_owner = ${escapeLiteral(leaseOwner!)}
|
|
19205
|
+
AND successor.lease_expires_at > clock_timestamp()
|
|
19206
|
+
AND successor.xmin = ${alias}.xmin
|
|
19207
|
+
AND NOT ${searchLaneSql('successor')}
|
|
19208
|
+
)`;
|
|
19096
19209
|
const transportHeadSql =
|
|
19097
|
-
input.transportCandidate !== undefined
|
|
19210
|
+
(input.transportCandidate !== undefined ||
|
|
19211
|
+
input.discoverTransportHead === true) &&
|
|
19098
19212
|
input.allowIngressPrefix === true &&
|
|
19099
19213
|
!input.searchOnly &&
|
|
19100
19214
|
!input.extendOwnedHead &&
|
|
@@ -19112,8 +19226,12 @@ async function claimRunLedgerOutboxPrefixInBatch(
|
|
|
19112
19226
|
), eligible_transport_head AS MATERIALIZED (
|
|
19113
19227
|
SELECT head.* FROM transport_head AS head
|
|
19114
19228
|
WHERE current_setting('deepline.run_ledger_outbox_lock', true) = ${escapeLiteral(input.runId)}
|
|
19115
|
-
|
|
19116
|
-
|
|
19229
|
+
${
|
|
19230
|
+
input.transportCandidate
|
|
19231
|
+
? `AND head.event_id = ${escapeLiteral(input.transportCandidate.eventId)}
|
|
19232
|
+
AND head.delivery_key = ${escapeLiteral(input.transportCandidate.deliveryKey)}`
|
|
19233
|
+
: ''
|
|
19234
|
+
}
|
|
19117
19235
|
AND ${runLedgerZeroEffectTransportSql('head')}
|
|
19118
19236
|
AND ${runLedgerTerminalPendingSql('head', options)}
|
|
19119
19237
|
AND EXISTS (
|
|
@@ -19142,24 +19260,22 @@ async function claimRunLedgerOutboxPrefixInBatch(
|
|
|
19142
19260
|
escapeLiteral(input.runId),
|
|
19143
19261
|
)}
|
|
19144
19262
|
)${
|
|
19145
|
-
|
|
19263
|
+
recoverTransportDelivery
|
|
19146
19264
|
? `, prior_transport AS MATERIALIZED (
|
|
19147
19265
|
SELECT prior.event_id, prior.run_id, prior.event_type, prior.delivery_key,
|
|
19148
19266
|
(extract(epoch FROM (prior.delivered_at-prior.created_at))*1000)::float8 AS lag_ms,
|
|
19149
|
-
|
|
19150
|
-
SELECT 1 FROM ${tableName('outbox', options)} AS successor
|
|
19151
|
-
WHERE successor.run_id = prior.run_id AND successor.delivered_at IS NULL
|
|
19152
|
-
AND successor.lease_owner = ${escapeLiteral(leaseOwner!)}
|
|
19153
|
-
AND successor.lease_expires_at > clock_timestamp()
|
|
19154
|
-
AND successor.xmin = prior.xmin
|
|
19155
|
-
AND NOT ${searchLaneSql('successor')}
|
|
19156
|
-
) AS owned
|
|
19267
|
+
${ownedTransportSql('prior')} AS owned
|
|
19157
19268
|
FROM ${tableName('outbox', options)} AS prior
|
|
19158
19269
|
WHERE current_setting('deepline.run_ledger_outbox_lock', true) = ${escapeLiteral(input.runId)}
|
|
19159
19270
|
AND prior.run_id = ${escapeLiteral(input.runId)}
|
|
19160
|
-
|
|
19161
|
-
|
|
19162
|
-
|
|
19271
|
+
${
|
|
19272
|
+
input.transportCandidate
|
|
19273
|
+
? `AND prior.event_id = ${escapeLiteral(input.transportCandidate.eventId)}
|
|
19274
|
+
AND prior.delivery_key = ${escapeLiteral(input.transportCandidate.deliveryKey)}
|
|
19275
|
+
AND prior.event_type = ${escapeLiteral(input.transportCandidate.eventType)}`
|
|
19276
|
+
: `AND ${runLedgerZeroEffectTransportSql('prior')}
|
|
19277
|
+
AND ${ownedTransportSql('prior')}`
|
|
19278
|
+
}
|
|
19163
19279
|
AND prior.delivered_at IS NOT NULL
|
|
19164
19280
|
AND NOT EXISTS (SELECT 1 FROM delivered)
|
|
19165
19281
|
)`
|
|
@@ -19168,7 +19284,7 @@ async function claimRunLedgerOutboxPrefixInBatch(
|
|
|
19168
19284
|
SELECT delivered.event_id, head.run_id, delivered.event_type, head.delivery_key, delivered.lag_ms
|
|
19169
19285
|
FROM delivered JOIN eligible_transport_head AS head ON head.event_id = delivered.event_id
|
|
19170
19286
|
${
|
|
19171
|
-
|
|
19287
|
+
recoverTransportDelivery
|
|
19172
19288
|
? `UNION ALL
|
|
19173
19289
|
SELECT event_id,run_id,event_type,delivery_key,lag_ms FROM prior_transport WHERE owned`
|
|
19174
19290
|
: ''
|
|
@@ -19185,13 +19301,28 @@ async function claimRunLedgerOutboxPrefixInBatch(
|
|
|
19185
19301
|
json_build_object('eventId', delivered.event_id, 'kind', 'outbox_delivered')::text)::text
|
|
19186
19302
|
FROM transport_deliveries AS delivered
|
|
19187
19303
|
${
|
|
19188
|
-
|
|
19304
|
+
recoverTransportDelivery
|
|
19189
19305
|
? `UNION ALL
|
|
19190
19306
|
SELECT 'transport_unconfirmed'::text,event_id,run_id,event_type,NULL::jsonb,NULL::timestamptz,
|
|
19191
19307
|
NULL::text,delivery_key,lag_ms,false,NULL::float8,NULL::text,NULL::text
|
|
19192
19308
|
FROM prior_transport WHERE NOT owned`
|
|
19193
19309
|
: ''
|
|
19194
|
-
}`
|
|
19310
|
+
}` +
|
|
19311
|
+
(recoverTransportDelivery && !input.transportCandidate
|
|
19312
|
+
? `
|
|
19313
|
+
UNION ALL
|
|
19314
|
+
SELECT 'transport_unconfirmed'::text,pending.event_id,pending.run_id,pending.event_type,NULL::jsonb,NULL::timestamptz,
|
|
19315
|
+
NULL::text,pending.delivery_key,0::float8,false,NULL::float8,NULL::text,NULL::text
|
|
19316
|
+
FROM ${tableName('outbox', options)} AS pending
|
|
19317
|
+
WHERE current_setting('deepline.run_ledger_outbox_lock', true) = ${escapeLiteral(input.runId)}
|
|
19318
|
+
AND pending.run_id = ${escapeLiteral(input.runId)} AND pending.delivered_at IS NULL
|
|
19319
|
+
AND pending.lease_owner = ${escapeLiteral(leaseOwner!)}
|
|
19320
|
+
AND NOT ${searchLaneSql('pending')}
|
|
19321
|
+
AND NOT EXISTS (SELECT 1 FROM transport_deliveries)
|
|
19322
|
+
-- A renewal may have replaced the transaction proof. Hand back the
|
|
19323
|
+
-- prefix instead of guessing whether a carrier spent its allowance.
|
|
19324
|
+
`
|
|
19325
|
+
: '')
|
|
19195
19326
|
: undefined;
|
|
19196
19327
|
let result: QueryResult<RunLedgerOutboxPrefixClaimRow>;
|
|
19197
19328
|
try {
|
|
@@ -19992,8 +20123,9 @@ export async function markPostgresSchedulerOutboxDelivered(
|
|
|
19992
20123
|
|
|
19993
20124
|
/**
|
|
19994
20125
|
* Shared lease-fenced ACK, including the canonical retained-payload cleanup.
|
|
19995
|
-
* Known-run callers
|
|
19996
|
-
*
|
|
20126
|
+
* Known-run callers recheck scope and pending state without offering a second
|
|
20127
|
+
* index access path beside their exact IDs. Stale statistics otherwise favor a
|
|
20128
|
+
* full run bitmap or pending partial-index scan before filtering those IDs.
|
|
19997
20129
|
*/
|
|
19998
20130
|
function runLedgerAcknowledgeSql(
|
|
19999
20131
|
options: Pick<PostgresSchedulerOptions, 'schema'> | undefined,
|
|
@@ -20014,9 +20146,9 @@ function runLedgerAcknowledgeSql(
|
|
|
20014
20146
|
AND run.run_event_store = 'planet_scale'
|
|
20015
20147
|
) THEN '{}'::jsonb ELSE outbox.payload_json END
|
|
20016
20148
|
WHERE outbox.event_id = ANY(${eventIdsParameter}::text[])
|
|
20017
|
-
${runIdParameter ? `AND outbox.run_id = ${runIdParameter}::text` : ''}
|
|
20149
|
+
${runIdParameter ? `AND coalesce(outbox.run_id = ${runIdParameter}::text, false)` : ''}
|
|
20018
20150
|
${lockFence ? `AND (${lockFence})` : ''}
|
|
20019
|
-
AND outbox.delivered_at IS NULL
|
|
20151
|
+
AND ${runIdParameter ? 'coalesce(outbox.delivered_at IS NULL, false)' : 'outbox.delivered_at IS NULL'}
|
|
20020
20152
|
AND (${leaseOwnerParameter}::text IS NULL OR outbox.lease_owner = ${leaseOwnerParameter})
|
|
20021
20153
|
RETURNING outbox.event_id,
|
|
20022
20154
|
outbox.event_type,
|
|
@@ -20587,6 +20719,12 @@ export type RunLedgerOutboxDispatchInput = {
|
|
|
20587
20719
|
* explicit context as before.
|
|
20588
20720
|
*/
|
|
20589
20721
|
runtimeApi?: WorkerRuntimeApiContext | null;
|
|
20722
|
+
/**
|
|
20723
|
+
* Immutable launch already held by a terminal producer. Reuse requires the
|
|
20724
|
+
* same run and the existing qualified projection token; claims and receiver
|
|
20725
|
+
* ownership proofs still read durable state. Other dispatches read SQL.
|
|
20726
|
+
*/
|
|
20727
|
+
dispatchLaunch?: RunLedgerDispatchLaunch;
|
|
20590
20728
|
limit?: number;
|
|
20591
20729
|
runId?: string | null;
|
|
20592
20730
|
leaseOwner?: string | null;
|
|
@@ -21160,19 +21298,38 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
21160
21298
|
)
|
|
21161
21299
|
return null;
|
|
21162
21300
|
const targetRunId = input.runId?.trim() || null;
|
|
21301
|
+
const producerLaunch =
|
|
21302
|
+
terminalRunId === targetRunId &&
|
|
21303
|
+
!input.headEventId &&
|
|
21304
|
+
tokenAuthority === 'gateway' &&
|
|
21305
|
+
input.dispatchLaunch?.runId === targetRunId &&
|
|
21306
|
+
usableRunLedgerExecutorToken(input.dispatchLaunch, reuseMarginMs, options)
|
|
21307
|
+
?.runLedgerIngressPrefixBatching === true
|
|
21308
|
+
? input.dispatchLaunch
|
|
21309
|
+
: null;
|
|
21163
21310
|
const selected =
|
|
21164
21311
|
selectedFastRun ??
|
|
21165
|
-
(
|
|
21166
|
-
?
|
|
21167
|
-
|
|
21168
|
-
|
|
21169
|
-
|
|
21170
|
-
|
|
21171
|
-
|
|
21312
|
+
(producerLaunch
|
|
21313
|
+
? {
|
|
21314
|
+
rows: [
|
|
21315
|
+
{
|
|
21316
|
+
run_id: producerLaunch.runId,
|
|
21317
|
+
dispatch_launch_json: producerLaunch,
|
|
21318
|
+
transport_head: undefined,
|
|
21319
|
+
},
|
|
21320
|
+
],
|
|
21321
|
+
}
|
|
21322
|
+
: input.waitForRunLock && targetRunId
|
|
21323
|
+
? await client.query<{
|
|
21324
|
+
run_id: string;
|
|
21325
|
+
dispatch_launch_json: unknown;
|
|
21326
|
+
transport_head?: RunLedgerTransportCandidate | null;
|
|
21327
|
+
}>(
|
|
21328
|
+
`SELECT runs.run_id, ${needsLaunch ? runLedgerDispatchLaunchSql('runs') : 'NULL::jsonb'} AS dispatch_launch_json, ${transportHeadSelection} AS transport_head
|
|
21172
21329
|
FROM ${tableName('runs', options)} AS runs WHERE runs.run_id = $1`,
|
|
21173
|
-
|
|
21174
|
-
|
|
21175
|
-
|
|
21330
|
+
[targetRunId],
|
|
21331
|
+
)
|
|
21332
|
+
: await selectRunForClaim(client, targetRunId));
|
|
21176
21333
|
const runId = selected.rows[0]?.run_id;
|
|
21177
21334
|
if (!runId)
|
|
21178
21335
|
return {
|
|
@@ -21201,6 +21358,7 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
21201
21358
|
!input.headEventId && ingressPrefixClaimed
|
|
21202
21359
|
? (selected.rows[0]?.transport_head ?? undefined)
|
|
21203
21360
|
: undefined,
|
|
21361
|
+
discoverTransportHead: producerLaunch !== null && ingressPrefixClaimed,
|
|
21204
21362
|
recoverTransportDelivery: claimInvocations > 1,
|
|
21205
21363
|
},
|
|
21206
21364
|
options,
|
|
@@ -21393,6 +21551,14 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
21393
21551
|
}
|
|
21394
21552
|
}
|
|
21395
21553
|
let events = claimed.events;
|
|
21554
|
+
const searchOnlyTerminalLogCarrier =
|
|
21555
|
+
input.searchOnly === true &&
|
|
21556
|
+
events.some(
|
|
21557
|
+
(event) =>
|
|
21558
|
+
event.eventType === RUN_SCHEDULER_OUTBOX_EVENT_TYPE.runnerLogs &&
|
|
21559
|
+
(event.eventId.startsWith('runner-terminal-logs:') ||
|
|
21560
|
+
event.eventId.startsWith('terminal-log-chunk:')),
|
|
21561
|
+
);
|
|
21396
21562
|
const unconfirmedTransportError = claimed.transportOwnershipUnconfirmed
|
|
21397
21563
|
? new RunLedgerProjectionLeaseLostError('delivery_lease_not_current')
|
|
21398
21564
|
: null;
|
|
@@ -21462,6 +21628,10 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
21462
21628
|
const appendAttempt: { transportAttemptId: string | null } = {
|
|
21463
21629
|
transportAttemptId: null,
|
|
21464
21630
|
};
|
|
21631
|
+
// Fixed-shape diagnostic timings for the search-only terminal-log carrier.
|
|
21632
|
+
// These are process-local observations and never enter durable run state.
|
|
21633
|
+
let terminalLogMaterializeTransactionCommitMs: number | null = null;
|
|
21634
|
+
let terminalLogAcknowledgeMs: number | null = null;
|
|
21465
21635
|
const callerOnRequestAttempt = input.runtimeApi?.onRequestAttempt;
|
|
21466
21636
|
const materializeDeferredObservability = async () => {
|
|
21467
21637
|
if (
|
|
@@ -21520,6 +21690,7 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
21520
21690
|
},
|
|
21521
21691
|
),
|
|
21522
21692
|
);
|
|
21693
|
+
const materializeStartedAtMs = performance.now();
|
|
21523
21694
|
const checkoutStartedAtMs = performance.now();
|
|
21524
21695
|
let materializeEnteredAtMs: number | null = null;
|
|
21525
21696
|
try {
|
|
@@ -21580,6 +21751,14 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
21580
21751
|
(searchPhaseTimingsMs.materializeAcquireAndRetry ?? 0) +
|
|
21581
21752
|
(materializeEnteredAtMs ?? performance.now()) -
|
|
21582
21753
|
checkoutStartedAtMs;
|
|
21754
|
+
if (searchOnlyTerminalLogCarrier) {
|
|
21755
|
+
const elapsedMs = Math.max(
|
|
21756
|
+
0,
|
|
21757
|
+
performance.now() - materializeStartedAtMs,
|
|
21758
|
+
);
|
|
21759
|
+
terminalLogMaterializeTransactionCommitMs =
|
|
21760
|
+
(terminalLogMaterializeTransactionCommitMs ?? 0) + elapsedMs;
|
|
21761
|
+
}
|
|
21583
21762
|
}
|
|
21584
21763
|
};
|
|
21585
21764
|
try {
|
|
@@ -21642,20 +21821,31 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
21642
21821
|
)
|
|
21643
21822
|
)
|
|
21644
21823
|
throw new Error('Search lease includes a lifecycle fact.');
|
|
21645
|
-
const
|
|
21646
|
-
|
|
21647
|
-
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
|
|
21658
|
-
|
|
21824
|
+
const acknowledgeStartedAtMs = performance.now();
|
|
21825
|
+
let delivered: RunLedgerOutboxDeliveredRow[];
|
|
21826
|
+
try {
|
|
21827
|
+
delivered = await observeSearchPhase('acknowledge', () =>
|
|
21828
|
+
withClient(
|
|
21829
|
+
(client) =>
|
|
21830
|
+
markPostgresSchedulerOutboxDeliveredRows(
|
|
21831
|
+
client,
|
|
21832
|
+
events.map((event) => event.eventId),
|
|
21833
|
+
{ ...options, leaseOwner },
|
|
21834
|
+
),
|
|
21835
|
+
{
|
|
21836
|
+
runId: events[0]!.runId,
|
|
21837
|
+
phase: 'run_ledger_outbox_search_acknowledge',
|
|
21838
|
+
},
|
|
21839
|
+
),
|
|
21840
|
+
);
|
|
21841
|
+
} finally {
|
|
21842
|
+
if (searchOnlyTerminalLogCarrier) {
|
|
21843
|
+
terminalLogAcknowledgeMs = Math.max(
|
|
21844
|
+
0,
|
|
21845
|
+
performance.now() - acknowledgeStartedAtMs,
|
|
21846
|
+
);
|
|
21847
|
+
}
|
|
21848
|
+
}
|
|
21659
21849
|
if (delivered.length !== events.length)
|
|
21660
21850
|
throw new RunLedgerProjectionLeaseLostError(
|
|
21661
21851
|
'delivery_lease_not_current',
|
|
@@ -22382,6 +22572,18 @@ async function dispatchRunLedgerOutboxBatchWithScope(
|
|
|
22382
22572
|
continuationMs:
|
|
22383
22573
|
acknowledgedAtMs === null ? null : settledAtMs - acknowledgedAtMs,
|
|
22384
22574
|
durationMs: settledAtMs - dispatchStartedAtMs,
|
|
22575
|
+
...(searchOnlyTerminalLogCarrier
|
|
22576
|
+
? {
|
|
22577
|
+
// Keep this fixed-shape scalar packet on the existing diagnostic;
|
|
22578
|
+
// no per-event payload, rows, or durable fields are added.
|
|
22579
|
+
searchOnlyTerminalLogPhaseTimingsMs: {
|
|
22580
|
+
claim: Math.max(0, claimElapsedMs),
|
|
22581
|
+
materializeTransactionCommit:
|
|
22582
|
+
terminalLogMaterializeTransactionCommitMs,
|
|
22583
|
+
acknowledge: terminalLogAcknowledgeMs,
|
|
22584
|
+
},
|
|
22585
|
+
}
|
|
22586
|
+
: {}),
|
|
22385
22587
|
...(input.searchOnly ? { searchPhaseTimingsMs } : {}),
|
|
22386
22588
|
// Which platform requests served the two app hops, so a slow
|
|
22387
22589
|
// authority or append stage can be found in the app's request log.
|
|
@@ -119,6 +119,21 @@ export type RunLedgerOutboxRecoveryDeps = {
|
|
|
119
119
|
logger?: RunLedgerOutboxRecoveryLogger;
|
|
120
120
|
};
|
|
121
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Production runs two projector replicas at eight deliveries each. An
|
|
124
|
+
* isolated Preview estate has one replica, so use the existing bounded
|
|
125
|
+
* 32-delivery ceiling there to keep fixture admission and its catalog
|
|
126
|
+
* projection inside the same latency budget. This does not change Production
|
|
127
|
+
* capacity or the controller's hard maximum.
|
|
128
|
+
*/
|
|
129
|
+
export function runLedgerOutboxRecoveryParallelism(
|
|
130
|
+
environment: 'preview' | 'production',
|
|
131
|
+
): number {
|
|
132
|
+
return environment === 'preview'
|
|
133
|
+
? RUN_LEDGER_OUTBOX_RECOVERY_MAX_IN_FLIGHT
|
|
134
|
+
: RUN_LEDGER_OUTBOX_RECOVERY_PRODUCTION_IN_FLIGHT;
|
|
135
|
+
}
|
|
136
|
+
|
|
122
137
|
export type RunLedgerOutboxRecoveryController = {
|
|
123
138
|
/**
|
|
124
139
|
* Ask the singleton projector to re-read durable outbox work. This is
|
|
@@ -1011,6 +1026,7 @@ export async function deliverRunCreatedOutboxEventInline(input: {
|
|
|
1011
1026
|
export function startRunLedgerOutboxRecoveryController(input: {
|
|
1012
1027
|
poolOptions: RuntimeSchedulerPoolOptions;
|
|
1013
1028
|
schedulerOptions?: Pick<PostgresSchedulerOptions, 'schema'>;
|
|
1029
|
+
environment?: 'preview' | 'production';
|
|
1014
1030
|
/** Direct LISTEN is a latency hint and may be disabled for isolated schemas. */
|
|
1015
1031
|
useDirectNotify?: boolean;
|
|
1016
1032
|
/** Observation hook for acknowledged rows (lag metrics). */
|
|
@@ -1071,10 +1087,12 @@ export function startRunLedgerOutboxRecoveryController(input: {
|
|
|
1071
1087
|
dispatchObservabilityOnce: (runId) => dispatch('oldest_ready', true, runId),
|
|
1072
1088
|
observabilityParallelism: RUN_LEDGER_OUTBOX_RECOVERY_INDEX_IN_FLIGHT,
|
|
1073
1089
|
// `dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope` releases each
|
|
1074
|
-
// short scheduler checkout before it calls the Vercel gateway.
|
|
1075
|
-
// replicas
|
|
1076
|
-
//
|
|
1077
|
-
parallelism:
|
|
1090
|
+
// short scheduler checkout before it calls the Vercel gateway. Production
|
|
1091
|
+
// retains two replicas at eight slots each; one isolated Preview replica
|
|
1092
|
+
// uses the same controller's existing hard ceiling of 32.
|
|
1093
|
+
parallelism: runLedgerOutboxRecoveryParallelism(
|
|
1094
|
+
input.environment ?? 'production',
|
|
1095
|
+
),
|
|
1078
1096
|
notifyUnavailableSafetyWakeMs: runLedgerOutboxNotifySafetyWakeMs(
|
|
1079
1097
|
schedulerOptions.schema,
|
|
1080
1098
|
),
|