deepline 0.3.461 → 0.3.463
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-core.ts +7593 -0
- package/dist/bundling-sources/sdk/src/client.ts +8 -7366
- package/dist/bundling-sources/sdk/src/http-core.ts +1239 -0
- package/dist/bundling-sources/sdk/src/http.ts +6 -1231
- package/dist/bundling-sources/sdk/src/index.ts +4 -1
- package/dist/bundling-sources/sdk/src/play.ts +5 -5
- package/dist/bundling-sources/sdk/src/plays/client-core.ts +437 -0
- package/dist/bundling-sources/sdk/src/plays/client.ts +4 -421
- package/dist/bundling-sources/sdk/src/plays/input-example.ts +3 -4
- package/dist/bundling-sources/sdk/src/plays/play-description.ts +1 -1
- package/dist/bundling-sources/sdk/src/plays/run-request.ts +1 -1
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/server.ts +43 -0
- package/dist/bundling-sources/sdk/src/types.ts +15 -5
- package/dist/bundling-sources/shared_libs/integration-contracts/billing-entitlements.ts +15 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/tamradar.ts +17 -17
- package/dist/bundling-sources/shared_libs/monitors/callback-security.ts +0 -307
- package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +3 -0
- package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +3 -2
- package/dist/bundling-sources/shared_libs/monitors/package.json +2 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-callback-verification.ts +34 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +61 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-upstream-identity.ts +122 -2
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +11 -1
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-failure-codes.ts +24 -0
- package/dist/bundling-sources/shared_libs/observability/dlq.ts +32 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +57 -3
- package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +66 -1
- package/dist/bundling-sources/shared_libs/play-data-plane/sheet-column-storage.ts +36 -7
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +250 -11
- package/dist/bundling-sources/shared_libs/play-runtime/array-input-store.ts +319 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +991 -359
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +13 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +110 -0
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +155 -6
- package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-registry.ts +110 -6
- package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +127 -13
- package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +14 -1
- package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +57 -1
- package/dist/bundling-sources/shared_libs/play-runtime/free-company-lookup-batching.ts +218 -0
- package/dist/bundling-sources/shared_libs/play-runtime/gateway-postgres-admission.ts +42 -5
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-budget-state-backend.ts +6 -1
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +92 -31
- package/dist/bundling-sources/shared_libs/play-runtime/governor/block-reserving-budget-state-backend.ts +69 -14
- package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +93 -23
- package/dist/bundling-sources/shared_libs/play-runtime/governor/in-memory-rate-state-backend.ts +15 -4
- package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +22 -18
- package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +5 -0
- package/dist/bundling-sources/shared_libs/play-runtime/launch-identity.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/map-memory-limits.ts +190 -14
- package/dist/bundling-sources/shared_libs/play-runtime/memory-ledger.ts +131 -0
- package/dist/bundling-sources/shared_libs/play-runtime/modal-runtime-config.ts +77 -2
- package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +271 -2
- package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +51 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +27 -1
- package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/provider-text-for-log.ts +63 -0
- package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +19 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-event-transport.ts +112 -16
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +104 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +265 -151
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-gateway-transport.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-progress-push.ts +35 -14
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-sheet-persistence-retry.ts +12 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-control-transport.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-labels.ts +36 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-launch-transport.ts +136 -70
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +237 -36
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +148 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +285 -32
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/modal.ts +251 -56
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +29 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/sandbox-create-outcome.ts +27 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +22 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +1397 -382
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-array-input-receipts.ts +920 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-constants.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-environment.ts +38 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-flow.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-incident-drills.ts +26 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +30 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-store-adapter.ts +14 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-writer.ts +31 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-transition.ts +47 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-compute-usage.ts +20 -7
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +12 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/index.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +1496 -320
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +31 -1
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1389 -129
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +36 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-dispatch-authority.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +162 -23
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +499 -115
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +377 -9
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +117 -8
- package/dist/bundling-sources/shared_libs/play-runtime/secret-resolution-retry-policy.ts +25 -0
- package/dist/bundling-sources/shared_libs/play-runtime/terminal-runtime-performance.ts +391 -0
- package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +40 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/index.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/mapped-calls.ts +171 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/receipt-cohort.ts +16 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +38 -12
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +33 -9
- package/dist/bundling-sources/shared_libs/play-runtime/transport-error-diagnostics.ts +28 -0
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +55 -5
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +41 -1
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +4 -0
- package/dist/bundling-sources/shared_libs/plays/dataset.ts +9 -3
- package/dist/bundling-sources/shared_libs/plays/deploy/manifest-contract.ts +2 -0
- package/dist/bundling-sources/shared_libs/plays/deploy/manifest.ts +3 -2
- package/dist/bundling-sources/shared_libs/plays/deploy/project-serializer.ts +2 -2
- package/dist/bundling-sources/shared_libs/plays/run-output-summary.ts +66 -0
- package/dist/bundling-sources/shared_libs/plays/script-entry.ts +1 -1
- package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +43 -1
- package/dist/bundling-sources/shared_libs/product-notifications/content.ts +9 -0
- package/dist/bundling-sources/shared_libs/product-notifications/email.ts +91 -13
- package/dist/bundling-sources/shared_libs/product-notifications/events.ts +3 -0
- package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +41 -24
- package/dist/bundling-sources/shared_libs/security/attested-client-ip.ts +91 -0
- package/dist/bundling-sources/shared_libs/security/internal-actor.ts +0 -11
- package/dist/cli/{auth-6HJXNWUG.mjs → auth-LZLBR4C3.mjs} +5 -4
- package/dist/cli/auth-XPGKBJKB.js +41 -0
- package/dist/cli/{billing-6P5HO6QG.js → billing-6TJPNJQD.js} +152 -78
- package/dist/cli/{billing-MJ42N7YF.mjs → billing-OTOP5RE4.mjs} +84 -10
- package/dist/cli/{chunk-FCAZQ7WV.js → chunk-2NISBXMN.js} +52 -50
- package/dist/cli/{chunk-PNATXKLP.js → chunk-2ZIRCBYG.js} +6 -6
- package/dist/cli/{chunk-5FDKJQZE.js → chunk-3BOIOCNX.js} +1 -1
- package/dist/cli/chunk-3BVLLJ3H.mjs +1038 -0
- package/dist/cli/{chunk-FJZILBL7.mjs → chunk-3U5EAP6E.mjs} +5 -5
- package/dist/cli/{describe-FRAVCY5F.mjs → chunk-4YZKBBLZ.mjs} +19 -36
- package/dist/cli/{chunk-QWRHGGUH.js → chunk-5DRNNC72.js} +20 -2
- package/dist/cli/{chunk-Z2GUFYT6.js → chunk-5LEAXRHV.js} +11 -11
- package/dist/cli/{chunk-5MDIZX7M.js → chunk-5LHXOIPT.js} +8 -6
- package/dist/cli/{chunk-NMJ4D2WO.js → chunk-6PMCRYDA.js} +216 -91
- package/dist/cli/{chunk-EBU7LQ64.js → chunk-6V7KVRR5.js} +3 -3
- package/dist/cli/{chunk-MGXEUZHL.mjs → chunk-7D6X7IXW.mjs} +7 -5
- package/dist/cli/{chunk-SAZFZQRI.js → chunk-7FCYPAPP.js} +2 -2
- package/dist/cli/{chunk-ACCR7POB.js → chunk-7XYDDCQ2.js} +27 -27
- package/dist/cli/{chunk-5IYOUBFZ.js → chunk-ALZBANZI.js} +28 -54
- package/dist/cli/{chunk-3DNKFH2G.mjs → chunk-BAPTQDLF.mjs} +19 -1
- package/dist/cli/chunk-BGNWI3KH.js +827 -0
- package/dist/cli/{chunk-V7REJRDZ.mjs → chunk-C25QE4CH.mjs} +1 -1
- package/dist/cli/{chunk-FGMX4HUZ.js → chunk-CBZP6J3V.js} +29 -27
- package/dist/cli/{chunk-QEYHTIV4.mjs → chunk-CTQ56DXP.mjs} +10 -1
- package/dist/cli/{chunk-IHHLTHE7.mjs → chunk-CVQ7N5CV.mjs} +267 -38
- package/dist/cli/{chunk-7DH2FD7Y.mjs → chunk-D464JW3N.mjs} +5 -85
- package/dist/cli/{chunk-MEAIOXJL.mjs → chunk-DHXCBITQ.mjs} +7 -5
- package/dist/cli/chunk-F2RHUPVH.mjs +827 -0
- package/dist/cli/chunk-F6QV42MC.mjs +91 -0
- package/dist/cli/{chunk-OZBWRICM.js → chunk-FK2HNDCN.js} +2 -2
- package/dist/cli/{chunk-BGY2PLP7.mjs → chunk-GUT7CLOL.mjs} +23 -49
- package/dist/cli/{chunk-RY4IVOU3.mjs → chunk-I624J4H5.mjs} +16 -806
- package/dist/cli/{chunk-Z2XUZC34.js → chunk-IAYSWZDJ.js} +188 -76
- package/dist/cli/{chunk-FGLKOWSC.mjs → chunk-IKWRUNAP.mjs} +1 -1
- package/dist/cli/{chunk-KCCOQ5G5.js → chunk-JVDKZJUH.js} +511 -282
- package/dist/cli/{chunk-HDFRJ4IT.mjs → chunk-JVHOS3K3.mjs} +177 -65
- package/dist/cli/chunk-LYFKBLJI.mjs +1039 -0
- package/dist/cli/{chunk-SLEUWLJE.mjs → chunk-MSY22NQW.mjs} +5 -5
- package/dist/cli/{chunk-5FY72YOV.js → chunk-NAPTMYTY.js} +8 -8
- package/dist/cli/{chunk-O6QOMHCH.js → chunk-NDHJR2WZ.js} +37 -35
- package/dist/cli/{chunk-KXMNM4AQ.js → chunk-NMU3VR5U.js} +4 -5
- package/dist/cli/chunk-NTLI6P6Y.mjs +19 -0
- package/dist/cli/{chunk-RFONC4WJ.mjs → chunk-O3BJYD6D.mjs} +3 -3
- package/dist/cli/{describe-2WQY7ZCY.js → chunk-PVY4DPPF.js} +27 -44
- package/dist/cli/{chunk-WIYWSYDS.mjs → chunk-Q2EIZKVX.mjs} +3 -3
- package/dist/cli/{chunk-VZBCEA5S.mjs → chunk-RD6IQ2JY.mjs} +223 -92
- package/dist/cli/chunk-RGOUCIIZ.js +1039 -0
- package/dist/cli/{chunk-EIMG75BT.mjs → chunk-S3A4IXBQ.mjs} +4 -5
- package/dist/cli/{chunk-QIW7TVV6.mjs → chunk-S4XQCFES.mjs} +14 -12
- package/dist/cli/chunk-SKU6ECIY.js +19 -0
- package/dist/cli/{chunk-CRYOUPEB.js → chunk-TIRBDQ3W.js} +16 -16
- package/dist/cli/{chunk-G7L27KZB.mjs → chunk-TKAQR3IB.mjs} +31 -21
- package/dist/cli/{chunk-MDJPEGVN.js → chunk-UC4SFYNU.js} +392 -261
- package/dist/cli/{chunk-3BMLICF7.mjs → chunk-UIURR26V.mjs} +13 -8
- package/dist/cli/{chunk-TNMBPMMC.js → chunk-UROQDCVW.js} +13 -4
- package/dist/cli/{chunk-R64BGGRQ.mjs → chunk-VDGTTH7K.mjs} +2 -2
- package/dist/cli/chunk-VLEVVDWG.js +91 -0
- package/dist/cli/{chunk-R2GLGLDR.mjs → chunk-VPHN2HAL.mjs} +216 -91
- package/dist/cli/chunk-VY2GBNTX.js +1038 -0
- package/dist/cli/{chunk-CFUTOWE4.js → chunk-WG3KGAII.js} +8 -88
- package/dist/cli/{chunk-QAJAJPKK.mjs → chunk-WUMIYOXQ.mjs} +4 -2
- package/dist/cli/{chunk-SCIR5JXW.js → chunk-WUZS2HK6.js} +56 -51
- package/dist/cli/{chunk-T3MVIPHG.mjs → chunk-XDWS2JJT.mjs} +1 -1
- package/dist/cli/{chunk-KGQNIA37.js → chunk-XQCTG5OO.js} +44 -34
- package/dist/cli/{chunk-KVJ5VHW5.mjs → chunk-XW2JIYG7.mjs} +2 -2
- package/dist/cli/chunk-YGGIZ3VT.js +920 -0
- package/dist/cli/command-docs.d.mts +5 -0
- package/dist/cli/command-docs.d.ts +5 -0
- package/dist/cli/command-docs.js +2 -2
- package/dist/cli/command-docs.mjs +1 -1
- package/dist/cli/{csv-NX7NO3O6.js → csv-EH5QWR4O.js} +13 -12
- package/dist/cli/{csv-DQ6GW5B5.mjs → csv-OK45Z5XQ.mjs} +4 -3
- package/dist/cli/{db-R72DFMP6.js → db-3ESJKETS.js} +30 -27
- package/dist/cli/{db-2YP33M4K.mjs → db-6Z5E4HKN.mjs} +10 -7
- package/dist/cli/describe-PNDQB7YS.mjs +48 -0
- package/dist/cli/describe-QUF7VTTR.js +48 -0
- package/dist/cli/describe-core.d.mts +153 -5
- package/dist/cli/describe-core.d.ts +153 -5
- package/dist/cli/describe-core.js +9 -5
- package/dist/cli/describe-core.mjs +10 -6
- package/dist/cli/{executions-WFBU7L2Q.mjs → executions-2NTWQFEG.mjs} +7 -5
- package/dist/cli/{executions-ZLHD4QIT.js → executions-KUOBRX5V.js} +9 -7
- package/dist/cli/{feedback-CN3HJFVF.mjs → feedback-7RPRMSGY.mjs} +6 -5
- package/dist/cli/{feedback-NDV6TPHG.js → feedback-UPHAZJ4C.js} +10 -9
- package/dist/cli/getting-started.d.mts +6 -6
- package/dist/cli/getting-started.d.ts +6 -6
- package/dist/cli/getting-started.js +2 -2
- package/dist/cli/getting-started.mjs +1 -1
- package/dist/cli/{git-QAD6E3HW.mjs → git-SCYP6WSZ.mjs} +5 -4
- package/dist/cli/git-UH653WHV.js +25 -0
- package/dist/cli/index.js +152 -142
- package/dist/cli/index.mjs +56 -46
- package/dist/cli/{legacy-noops-KVC5QJ74.js → legacy-noops-7XMFCVRG.js} +8 -7
- package/dist/cli/{legacy-noops-TPTKNBI2.mjs → legacy-noops-A4KYAGI6.mjs} +5 -4
- package/dist/cli/{monitors-SV57JFLO.mjs → monitors-FLC5J7RI.mjs} +19 -6
- package/dist/cli/{monitors-KCROV6PJ.js → monitors-NZV6IX5H.js} +103 -90
- package/dist/cli/{org-NJYX5743.js → org-IZ7UP3XF.js} +70 -67
- package/dist/cli/{org-KX6QIR7A.mjs → org-LUETJ7Z5.mjs} +9 -6
- package/dist/cli/pages-22ML3O7O.js +252 -0
- package/dist/cli/pages-EUX5EAGF.mjs +252 -0
- package/dist/cli/{play-IQQ57L7Z.mjs → play-CDHPAKKM.mjs} +512 -1508
- package/dist/cli/{play-32L7EQN4.js → play-USJBQADG.js} +1090 -2086
- package/dist/cli/{providers-4WEC2EQN.mjs → providers-CCXZ3SQF.mjs} +7 -5
- package/dist/cli/{providers-ZQV6QLVQ.js → providers-WFEUNPGC.js} +10 -8
- package/dist/cli/{quickstart-HKUSFADF.js → quickstart-O4JSUORZ.js} +13 -12
- package/dist/cli/{quickstart-RQ76RIUE.mjs → quickstart-ZUULI635.mjs} +5 -4
- package/dist/cli/run-ISDJYJMU.js +443 -0
- package/dist/cli/run-QJ4NX5F5.mjs +443 -0
- package/dist/cli/{search-ZRAVFBZC.mjs → search-IX3XKZJ3.mjs} +8 -6
- package/dist/cli/search-TIFNLRPM.js +32 -0
- package/dist/cli/{secrets-CMJOVNVH.mjs → secrets-7VUDXTUZ.mjs} +7 -5
- package/dist/cli/{secrets-J3G5Y43U.js → secrets-ELQSNCTR.js} +16 -14
- package/dist/cli/{sessions-WY7VN4AE.js → sessions-A3FG3AZX.js} +6 -5
- package/dist/cli/{sessions-MDQYY5CB.mjs → sessions-VOIQ62GB.mjs} +5 -4
- package/dist/cli/{settings-4RWZPCT5.mjs → settings-S6N6EFBG.mjs} +14 -11
- package/dist/cli/{settings-HTNTFKCE.js → settings-ZTXQEMZI.js} +80 -77
- package/dist/cli/{setup-P3GYYZWG.mjs → setup-AYPIK4JE.mjs} +12 -10
- package/dist/cli/{setup-QGCAP62X.js → setup-Y3WOIFLS.js} +53 -51
- package/dist/cli/{skills-7NAE4ICL.mjs → skills-5SF5QWNI.mjs} +7 -6
- package/dist/cli/skills-MWFRMG3H.js +31 -0
- package/dist/cli/tools-3XNZ4J64.mjs +55 -0
- package/dist/cli/tools-XEC4OD3R.js +55 -0
- package/dist/cli/{update-GODLRKNB.mjs → update-3U4OVX5R.mjs} +9 -8
- package/dist/cli/update-DWYEYTZE.js +33 -0
- package/dist/cli/{workflow-4BXOUVEO.mjs → workflow-2M5JP7SA.mjs} +10 -8
- package/dist/cli/{workflow-AO3A6LXN.js → workflow-RM7H7555.js} +20 -18
- package/dist/client-DS2IWYZF.d.ts +10 -0
- package/dist/client-DTwnz_AW.d.mts +10 -0
- package/dist/{client-CYqG23K1.d.ts → client-core-B_6HAIBy.d.ts} +385 -12
- package/dist/{client-BbU5_j7n.d.mts → client-core-DzBSlY1U.d.mts} +385 -12
- package/dist/{compiler-manifest-CWz_sNOQ.d.ts → compiler-manifest-Dcyd3-Zd.d.mts} +43 -1
- package/dist/{compiler-manifest-CWz_sNOQ.d.mts → compiler-manifest-Dcyd3-Zd.d.ts} +43 -1
- package/dist/errors-d-sTrZhe.d.mts +142 -0
- package/dist/errors-yQwfgrcX.d.ts +142 -0
- package/dist/{index-BF2JB_Ug.d.mts → index-C6oXchjN.d.mts} +1 -1
- package/dist/{index-4NPXDzlD.d.ts → index-P56zy_z5.d.ts} +1 -1
- package/dist/index.d.mts +11 -147
- package/dist/index.d.ts +11 -147
- package/dist/index.js +16 -12
- package/dist/index.mjs +15 -11
- package/dist/install-integrity.json +141 -104
- package/dist/plays/bundle-play-file.d.mts +3 -3
- package/dist/plays/bundle-play-file.d.ts +3 -3
- package/dist/plays/bundle-play-file.mjs +2 -1
- package/dist/plays/play-description.d.mts +2 -2
- package/dist/plays/play-description.d.ts +2 -2
- package/dist/plays/play-description.js +2 -2
- package/dist/plays/play-description.mjs +1 -1
- 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/dist/server.d.mts +17 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.js +76 -0
- package/dist/server.mjs +76 -0
- package/package.json +6 -1
- package/dist/cli/auth-IACERYQH.js +0 -40
- package/dist/cli/chunk-PQUUWFXY.js +0 -95
- package/dist/cli/chunk-YBWAG72P.mjs +0 -95
- package/dist/cli/chunk-YQDUODZW.js +0 -1710
- package/dist/cli/git-JVI36ZFV.js +0 -24
- package/dist/cli/search-75X5LTDE.js +0 -30
- package/dist/cli/skills-BKJ53JOQ.js +0 -30
- package/dist/cli/tools-COWMIEJ6.mjs +0 -45
- package/dist/cli/tools-TASOCE7I.js +0 -45
- package/dist/cli/update-SJIKVME6.js +0 -32
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineBatchStrategyMap,
|
|
3
|
+
type BatchOperationStrategy,
|
|
4
|
+
} from './batching-types';
|
|
5
|
+
|
|
6
|
+
export const FREE_COMPANY_LOOKUP_KEY_TYPES = [
|
|
7
|
+
'domain',
|
|
8
|
+
'linkedin_url',
|
|
9
|
+
'company_name',
|
|
10
|
+
] as const;
|
|
11
|
+
export type FreeCompanyLookupKeyType =
|
|
12
|
+
(typeof FREE_COMPANY_LOOKUP_KEY_TYPES)[number];
|
|
13
|
+
|
|
14
|
+
/** Snowflake bind count stays well inside one statement's limits. */
|
|
15
|
+
export const FREE_COMPANY_BULK_LOOKUP_MAX_KEYS = 1_000;
|
|
16
|
+
/** One SQL statement per batch keeps a row's wait under the query timeout. */
|
|
17
|
+
export const FREE_COMPANY_LOOKUP_MAX_BATCH_SIZE = 100;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The same steps the loader applies to PDL's `website` column, so a lookup
|
|
21
|
+
* matches `normalized_domain` exactly. Subdomains are kept, as they are there.
|
|
22
|
+
*/
|
|
23
|
+
export function normalizeFreeCompanyDomain(value: string): string {
|
|
24
|
+
return value
|
|
25
|
+
.trim()
|
|
26
|
+
.toLowerCase()
|
|
27
|
+
.replace(/^https?:\/\//, '')
|
|
28
|
+
.replace(/^www\./, '')
|
|
29
|
+
.replace(/[/?#].*$/, '')
|
|
30
|
+
.replace(/\.$/, '');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Stored as `linkedin.com/company/<slug>`; LinkedIn slugs ignore case. */
|
|
34
|
+
export function normalizeFreeCompanyLinkedinUrl(value: string): string {
|
|
35
|
+
return value
|
|
36
|
+
.trim()
|
|
37
|
+
.toLowerCase()
|
|
38
|
+
.replace(/^https?:\/\//, '')
|
|
39
|
+
.replace(/^www\./, '')
|
|
40
|
+
.replace(/[?#].*$/, '')
|
|
41
|
+
.replace(/\/+$/, '');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Stored names are trimmed and lowercase, so this is case-insensitive equality. */
|
|
45
|
+
export function normalizeFreeCompanyName(value: string): string {
|
|
46
|
+
return value.trim().toLowerCase();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function normalizeFreeCompanyLookupKey(
|
|
50
|
+
keyType: FreeCompanyLookupKeyType,
|
|
51
|
+
value: string,
|
|
52
|
+
): string {
|
|
53
|
+
switch (keyType) {
|
|
54
|
+
case 'domain':
|
|
55
|
+
return normalizeFreeCompanyDomain(value);
|
|
56
|
+
case 'linkedin_url':
|
|
57
|
+
return normalizeFreeCompanyLinkedinUrl(value);
|
|
58
|
+
case 'company_name':
|
|
59
|
+
return normalizeFreeCompanyName(value);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
type LookupPayload = Record<string, unknown> & {
|
|
64
|
+
domain?: string;
|
|
65
|
+
linkedin_url?: string;
|
|
66
|
+
company_name?: string;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
type BulkLookupPayload = Record<string, unknown> & {
|
|
70
|
+
domains?: string[];
|
|
71
|
+
linkedin_urls?: string[];
|
|
72
|
+
company_names?: string[];
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export type FreeCompanyLookupResult = Record<string, unknown> & {
|
|
76
|
+
key_type: FreeCompanyLookupKeyType;
|
|
77
|
+
key: string;
|
|
78
|
+
matches: Record<string, unknown>[];
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
type BulkLookupResult = Record<string, unknown> & {
|
|
82
|
+
results?: unknown;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const BULK_FIELD: Record<FreeCompanyLookupKeyType, keyof BulkLookupPayload> = {
|
|
86
|
+
domain: 'domains',
|
|
87
|
+
linkedin_url: 'linkedin_urls',
|
|
88
|
+
company_name: 'company_names',
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/** The one usable key a lookup names, or null when it does not name exactly one. */
|
|
92
|
+
function usableFreeCompanyLookupKey(payload: LookupPayload): {
|
|
93
|
+
keyType: FreeCompanyLookupKeyType;
|
|
94
|
+
key: string;
|
|
95
|
+
} | null {
|
|
96
|
+
const present = FREE_COMPANY_LOOKUP_KEY_TYPES.filter(
|
|
97
|
+
(keyType) => typeof payload[keyType] === 'string',
|
|
98
|
+
);
|
|
99
|
+
if (present.length !== 1) return null;
|
|
100
|
+
const keyType = present[0]!;
|
|
101
|
+
const key = normalizeFreeCompanyLookupKey(
|
|
102
|
+
keyType,
|
|
103
|
+
payload[keyType] as string,
|
|
104
|
+
);
|
|
105
|
+
return key ? { keyType, key } : null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** The single key a lookup names. Callers validate the payload first. */
|
|
109
|
+
export function freeCompanyLookupKey(payload: LookupPayload): {
|
|
110
|
+
keyType: FreeCompanyLookupKeyType;
|
|
111
|
+
key: string;
|
|
112
|
+
} {
|
|
113
|
+
const lookupKey = usableFreeCompanyLookupKey(payload);
|
|
114
|
+
if (!lookupKey) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
'free_company_lookup needs exactly one usable domain, linkedin_url or company_name.',
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
return lookupKey;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function isLookupResult(value: unknown): value is FreeCompanyLookupResult {
|
|
123
|
+
const row = value as FreeCompanyLookupResult | null;
|
|
124
|
+
return Boolean(
|
|
125
|
+
row &&
|
|
126
|
+
typeof row === 'object' &&
|
|
127
|
+
FREE_COMPANY_LOOKUP_KEY_TYPES.includes(row.key_type) &&
|
|
128
|
+
typeof row.key === 'string' &&
|
|
129
|
+
Array.isArray(row.matches),
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export const freeCompanyLookupBatchStrategy: BatchOperationStrategy<
|
|
134
|
+
LookupPayload,
|
|
135
|
+
BulkLookupPayload | LookupPayload,
|
|
136
|
+
BulkLookupResult | FreeCompanyLookupResult,
|
|
137
|
+
FreeCompanyLookupResult
|
|
138
|
+
> = {
|
|
139
|
+
sourceOperation: 'free_company_lookup',
|
|
140
|
+
batchOperation: 'free_company_bulk_lookup',
|
|
141
|
+
kind: 'identifier_batch',
|
|
142
|
+
maxBatchSize: FREE_COMPANY_LOOKUP_MAX_BATCH_SIZE,
|
|
143
|
+
// Rows looking up by different keys share a batch; the bulk lookup takes all
|
|
144
|
+
// three lists in one statement.
|
|
145
|
+
canBatchWith() {
|
|
146
|
+
return true;
|
|
147
|
+
},
|
|
148
|
+
// The runtime batches before the app validates anything. A row without one
|
|
149
|
+
// usable key gets a bucket and item key of its own, so it never joins a
|
|
150
|
+
// batch of valid rows. compile sends it to free_company_lookup alone, which
|
|
151
|
+
// refuses it with a 422 for that row only.
|
|
152
|
+
toBucketKey(payload) {
|
|
153
|
+
return usableFreeCompanyLookupKey(payload)
|
|
154
|
+
? 'free_company_bulk_lookup'
|
|
155
|
+
: `invalid:${JSON.stringify(payload)}`;
|
|
156
|
+
},
|
|
157
|
+
toItemKey(payload) {
|
|
158
|
+
const lookupKey = usableFreeCompanyLookupKey(payload);
|
|
159
|
+
return lookupKey
|
|
160
|
+
? JSON.stringify([lookupKey.keyType, lookupKey.key])
|
|
161
|
+
: JSON.stringify(['invalid', payload]);
|
|
162
|
+
},
|
|
163
|
+
compile(payloads) {
|
|
164
|
+
const [only] = payloads;
|
|
165
|
+
if (payloads.length === 1 && only && !usableFreeCompanyLookupKey(only)) {
|
|
166
|
+
return {
|
|
167
|
+
batchOperation: 'free_company_lookup',
|
|
168
|
+
batchPayload: only,
|
|
169
|
+
items: [{ itemKey: JSON.stringify(['invalid', only]), payload: only }],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const batchPayload: BulkLookupPayload = {};
|
|
173
|
+
const items = payloads.map((payload) => {
|
|
174
|
+
const { keyType, key } = freeCompanyLookupKey(payload);
|
|
175
|
+
const field = BULK_FIELD[keyType];
|
|
176
|
+
const list = (batchPayload[field] ??= []) as string[];
|
|
177
|
+
if (!list.includes(key)) list.push(key);
|
|
178
|
+
return { itemKey: JSON.stringify([keyType, key]), payload };
|
|
179
|
+
});
|
|
180
|
+
return {
|
|
181
|
+
batchOperation: 'free_company_bulk_lookup',
|
|
182
|
+
batchPayload,
|
|
183
|
+
items,
|
|
184
|
+
};
|
|
185
|
+
},
|
|
186
|
+
splitResult(fullResult, compiled) {
|
|
187
|
+
if (compiled.batchOperation === 'free_company_lookup') {
|
|
188
|
+
throw new Error(
|
|
189
|
+
'free_company_lookup answered a payload without one usable key; it must refuse it.',
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
const result = ((fullResult as { data?: unknown }).data ??
|
|
193
|
+
fullResult) as BulkLookupResult;
|
|
194
|
+
if (!Array.isArray(result.results)) {
|
|
195
|
+
throw new Error('free_company_bulk_lookup returned no results list.');
|
|
196
|
+
}
|
|
197
|
+
const byKey = new Map<string, FreeCompanyLookupResult>();
|
|
198
|
+
for (const row of result.results) {
|
|
199
|
+
if (!isLookupResult(row)) {
|
|
200
|
+
throw new Error('free_company_bulk_lookup returned a malformed result.');
|
|
201
|
+
}
|
|
202
|
+
byKey.set(JSON.stringify([row.key_type, row.key]), row);
|
|
203
|
+
}
|
|
204
|
+
return compiled.items.map((item) => {
|
|
205
|
+
const row = byKey.get(item.itemKey);
|
|
206
|
+
if (!row) {
|
|
207
|
+
throw new Error(
|
|
208
|
+
`free_company_bulk_lookup omitted the result for ${item.itemKey}.`,
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
return { itemKey: item.itemKey, result: row, rawResult: row };
|
|
212
|
+
});
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
export const freeCompanyLookupBatchStrategies = defineBatchStrategyMap({
|
|
217
|
+
free_company_lookup: freeCompanyLookupBatchStrategy,
|
|
218
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type GatewayPostgresLane = 'ordinary' | 'commit';
|
|
1
|
+
export type GatewayPostgresLane = 'ordinary' | 'commit' | 'heartbeat';
|
|
2
2
|
|
|
3
3
|
export type GatewayPostgresAdmissionTenant = string | null;
|
|
4
4
|
export const GATEWAY_POSTGRES_MACHINE_TENANT: GatewayPostgresAdmissionTenant =
|
|
@@ -89,6 +89,7 @@ export class GatewayPostgresAdmission {
|
|
|
89
89
|
readonly #waiting: Record<GatewayPostgresLane, LaneQueue> = {
|
|
90
90
|
ordinary: { ring: new Map(), size: 0 },
|
|
91
91
|
commit: { ring: new Map(), size: 0 },
|
|
92
|
+
heartbeat: { ring: new Map(), size: 0 },
|
|
92
93
|
};
|
|
93
94
|
readonly #activeByTenant: Record<
|
|
94
95
|
GatewayPostgresLane,
|
|
@@ -96,9 +97,11 @@ export class GatewayPostgresAdmission {
|
|
|
96
97
|
> = {
|
|
97
98
|
ordinary: new Map(),
|
|
98
99
|
commit: new Map(),
|
|
100
|
+
heartbeat: new Map(),
|
|
99
101
|
};
|
|
100
102
|
#ordinaryActive = 0;
|
|
101
103
|
#commitActive = 0;
|
|
104
|
+
#heartbeatActive = 0;
|
|
102
105
|
#cancelled = 0;
|
|
103
106
|
#overloaded = 0;
|
|
104
107
|
#fairShareEvictions = 0;
|
|
@@ -110,8 +113,21 @@ export class GatewayPostgresAdmission {
|
|
|
110
113
|
maxOrdinaryActive?: number;
|
|
111
114
|
maxTotalActive?: number;
|
|
112
115
|
maxWaitingPerLane?: number;
|
|
116
|
+
/** Capacity withheld from bulk work, within maxTotalActive. */
|
|
117
|
+
reservedHeartbeatActive?: number;
|
|
113
118
|
} = {},
|
|
114
119
|
) {
|
|
120
|
+
const reserved = limits.reservedHeartbeatActive ?? 0;
|
|
121
|
+
if (
|
|
122
|
+
!Number.isSafeInteger(reserved) ||
|
|
123
|
+
reserved < 0 ||
|
|
124
|
+
reserved > 1 ||
|
|
125
|
+
reserved >= this.#maxTotalActive()
|
|
126
|
+
) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
'Gateway Postgres heartbeat reservation must be zero or one and leave bulk capacity.',
|
|
129
|
+
);
|
|
130
|
+
}
|
|
115
131
|
if (
|
|
116
132
|
limits.maxWaitingPerLane !== undefined &&
|
|
117
133
|
(!Number.isSafeInteger(limits.maxWaitingPerLane) ||
|
|
@@ -135,7 +151,12 @@ export class GatewayPostgresAdmission {
|
|
|
135
151
|
this.#cancelled += 1;
|
|
136
152
|
throw new GatewayPostgresAdmissionCancelledError();
|
|
137
153
|
}
|
|
138
|
-
if (
|
|
154
|
+
if (
|
|
155
|
+
this.#canGrant(lane) &&
|
|
156
|
+
(lane === 'heartbeat'
|
|
157
|
+
? this.#waiting.heartbeat.size === 0
|
|
158
|
+
: this.#waiting.commit.size === 0)
|
|
159
|
+
) {
|
|
139
160
|
return this.#grant(lane, tenant);
|
|
140
161
|
}
|
|
141
162
|
if (this.#waiting[lane].size >= this.#maxWaitingPerLane()) {
|
|
@@ -172,15 +193,18 @@ export class GatewayPostgresAdmission {
|
|
|
172
193
|
active: {
|
|
173
194
|
ordinary: this.#ordinaryActive,
|
|
174
195
|
commit: this.#commitActive,
|
|
196
|
+
heartbeat: this.#heartbeatActive,
|
|
175
197
|
total: this.#activeTotal(),
|
|
176
198
|
},
|
|
177
199
|
waiting: {
|
|
178
200
|
ordinary: this.#waiting.ordinary.size,
|
|
179
201
|
commit: this.#waiting.commit.size,
|
|
202
|
+
heartbeat: this.#waiting.heartbeat.size,
|
|
180
203
|
},
|
|
181
204
|
waitingTenants: {
|
|
182
205
|
ordinary: this.#waiting.ordinary.ring.size,
|
|
183
206
|
commit: this.#waiting.commit.ring.size,
|
|
207
|
+
heartbeat: this.#waiting.heartbeat.ring.size,
|
|
184
208
|
},
|
|
185
209
|
cancelled: this.#cancelled,
|
|
186
210
|
overloaded: this.#overloaded,
|
|
@@ -190,11 +214,17 @@ export class GatewayPostgresAdmission {
|
|
|
190
214
|
}
|
|
191
215
|
|
|
192
216
|
#activeTotal(): number {
|
|
193
|
-
return this.#ordinaryActive + this.#commitActive;
|
|
217
|
+
return this.#ordinaryActive + this.#commitActive + this.#heartbeatActive;
|
|
194
218
|
}
|
|
195
219
|
|
|
196
220
|
#canGrant(lane: GatewayPostgresLane): boolean {
|
|
197
221
|
if (this.#activeTotal() >= this.#maxTotalActive()) return false;
|
|
222
|
+
if (lane === 'heartbeat') return this.#heartbeatActive < 1;
|
|
223
|
+
if (
|
|
224
|
+
this.#ordinaryActive + this.#commitActive >=
|
|
225
|
+
this.#maxTotalActive() - (this.limits.reservedHeartbeatActive ?? 0)
|
|
226
|
+
)
|
|
227
|
+
return false;
|
|
198
228
|
return (
|
|
199
229
|
lane === 'commit' || this.#ordinaryActive < this.#maxOrdinaryActive()
|
|
200
230
|
);
|
|
@@ -221,7 +251,8 @@ export class GatewayPostgresAdmission {
|
|
|
221
251
|
tenant: GatewayPostgresAdmissionTenant,
|
|
222
252
|
): () => void {
|
|
223
253
|
if (lane === 'ordinary') this.#ordinaryActive += 1;
|
|
224
|
-
else this.#commitActive += 1;
|
|
254
|
+
else if (lane === 'commit') this.#commitActive += 1;
|
|
255
|
+
else this.#heartbeatActive += 1;
|
|
225
256
|
const activeByTenant = this.#activeByTenant[lane];
|
|
226
257
|
activeByTenant.set(tenant, (activeByTenant.get(tenant) ?? 0) + 1);
|
|
227
258
|
let released = false;
|
|
@@ -229,7 +260,8 @@ export class GatewayPostgresAdmission {
|
|
|
229
260
|
if (released) return;
|
|
230
261
|
released = true;
|
|
231
262
|
if (lane === 'ordinary') this.#ordinaryActive -= 1;
|
|
232
|
-
else this.#commitActive -= 1;
|
|
263
|
+
else if (lane === 'commit') this.#commitActive -= 1;
|
|
264
|
+
else this.#heartbeatActive -= 1;
|
|
233
265
|
const remaining = (activeByTenant.get(tenant) ?? 1) - 1;
|
|
234
266
|
if (remaining > 0) activeByTenant.set(tenant, remaining);
|
|
235
267
|
else activeByTenant.delete(tenant);
|
|
@@ -239,6 +271,11 @@ export class GatewayPostgresAdmission {
|
|
|
239
271
|
|
|
240
272
|
#drain(): void {
|
|
241
273
|
while (this.#activeTotal() < this.#maxTotalActive()) {
|
|
274
|
+
if (this.#waiting.heartbeat.size > 0 && this.#canGrant('heartbeat')) {
|
|
275
|
+
this.#resolve(this.#dequeueLeastActiveTenant('heartbeat')!);
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
if (!this.#canGrant('commit')) return;
|
|
242
279
|
const ordinaryCanRun =
|
|
243
280
|
this.#waiting.ordinary.size > 0 &&
|
|
244
281
|
this.#ordinaryActive < this.#maxOrdinaryActive();
|
package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-budget-state-backend.ts
CHANGED
|
@@ -2,12 +2,16 @@ import {
|
|
|
2
2
|
chargeGovernorBudgetViaAppRuntime,
|
|
3
3
|
type WorkerRuntimeApiContext,
|
|
4
4
|
} from '../app-runtime-api';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
BlockReservingBudgetStateBackend,
|
|
7
|
+
type BlockReservingBudgetStateOptions,
|
|
8
|
+
} from './block-reserving-budget-state-backend';
|
|
6
9
|
|
|
7
10
|
export class AppRuntimeBudgetStateBackend extends BlockReservingBudgetStateBackend {
|
|
8
11
|
constructor(
|
|
9
12
|
context: WorkerRuntimeApiContext,
|
|
10
13
|
schedulerSchema?: string | null,
|
|
14
|
+
options?: BlockReservingBudgetStateOptions,
|
|
11
15
|
) {
|
|
12
16
|
super(
|
|
13
17
|
async (input) =>
|
|
@@ -17,6 +21,7 @@ export class AppRuntimeBudgetStateBackend extends BlockReservingBudgetStateBacke
|
|
|
17
21
|
charges: [...input.charges],
|
|
18
22
|
schedulerSchema: schedulerSchema ?? null,
|
|
19
23
|
}),
|
|
24
|
+
options,
|
|
20
25
|
);
|
|
21
26
|
}
|
|
22
27
|
}
|
package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
acquireRateStateViaAppRuntime,
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
AppRuntimeApiTransportError,
|
|
4
|
+
capacityShedRetryAfterMs,
|
|
5
5
|
penalizeRateStateViaAppRuntime,
|
|
6
6
|
releaseRateStateViaAppRuntime,
|
|
7
7
|
RateStateValidationUnavailableError,
|
|
@@ -143,20 +143,15 @@ function sleepWithAbort(
|
|
|
143
143
|
*/
|
|
144
144
|
const RATE_BLOCK_HORIZON_MS = 1_000;
|
|
145
145
|
const STORE_FAILURE_RETRY_DELAYS_MS = [100, 250] as const;
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const retryAfterMs = (error as AppRuntimeApiResponseError).retryAfterMs;
|
|
156
|
-
return retryAfterMs && retryAfterMs > 0
|
|
157
|
-
? retryAfterMs
|
|
158
|
-
: CAPACITY_SHED_DEFAULT_RETRY_AFTER_MS;
|
|
159
|
-
}
|
|
146
|
+
const RELEASE_SHED_BACKOFF_BASE_MS = 1_000;
|
|
147
|
+
const RELEASE_SHED_BACKOFF_MAX_MS = 16_000;
|
|
148
|
+
/**
|
|
149
|
+
* Longest one batch of leases keeps retrying a shed release. The store expires
|
|
150
|
+
* an unreleased lease after five minutes, so retrying only frees its slot
|
|
151
|
+
* sooner. Past this window the lease is left to that TTL.
|
|
152
|
+
*/
|
|
153
|
+
export const RELEASE_SHED_RETRY_WINDOW_MS = 120_000;
|
|
154
|
+
|
|
160
155
|
/**
|
|
161
156
|
* Jitter fraction applied to a server-supplied `waitMs` so a synchronized wave
|
|
162
157
|
* of buckets that all hit granted=0 at the same instant re-probe at slightly
|
|
@@ -316,10 +311,18 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
316
311
|
string,
|
|
317
312
|
number
|
|
318
313
|
>();
|
|
319
|
-
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* The sandbox runner's transport already retries a request that gets no
|
|
317
|
+
* response through a whole network cut, so one more round here would only
|
|
318
|
+
* repeat that wait.
|
|
319
|
+
*/
|
|
320
|
+
private readonly transportRetriesOutages: boolean;
|
|
320
321
|
|
|
321
322
|
constructor(context: WorkerRuntimeApiContext, options: Options = {}) {
|
|
322
323
|
this.port = options.port ?? contextRatePort(context);
|
|
324
|
+
this.transportRetriesOutages =
|
|
325
|
+
context.connectionRetryBudgetMs !== undefined;
|
|
323
326
|
this.schedulerSchema = options.schedulerSchema?.trim() || null;
|
|
324
327
|
this.now = options.now ?? (() => Date.now());
|
|
325
328
|
this.sleep = options.sleep ?? sleepWithAbort;
|
|
@@ -437,9 +440,9 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
437
440
|
}): PacingPermit | null {
|
|
438
441
|
const { bucketId, rules } = input;
|
|
439
442
|
if (rules.length === 0) return noopPacingPermit();
|
|
440
|
-
// A probe reports nothing and repairs nothing:
|
|
441
|
-
//
|
|
442
|
-
if (this.
|
|
443
|
+
// A probe reports nothing and repairs nothing: an exhausted pacer surfaces
|
|
444
|
+
// from the next blocking acquire instead.
|
|
445
|
+
if (this.pacerExhaustion(bucketId)) {
|
|
443
446
|
return null;
|
|
444
447
|
}
|
|
445
448
|
const laneKey = rateLaneKey(
|
|
@@ -535,7 +538,6 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
535
538
|
}): Promise<PacingPermit> {
|
|
536
539
|
const { bucketId, rules, signal } = input;
|
|
537
540
|
if (rules.length === 0) return noopPacingPermit();
|
|
538
|
-
this.throwPendingReleaseFailure();
|
|
539
541
|
// Pre-check: zero round trips when the pacer is already holding past the
|
|
540
542
|
// threshold. Fails fast with a typed PROVIDER_EXHAUSTED before touching the
|
|
541
543
|
// store.
|
|
@@ -1177,9 +1179,14 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
1177
1179
|
consecutiveFailures += 1;
|
|
1178
1180
|
const normalized = normalizeError(error);
|
|
1179
1181
|
this.onStoreFailure({ bucketId, error: normalized.message });
|
|
1180
|
-
if (
|
|
1182
|
+
if (
|
|
1183
|
+
consecutiveFailures > STORE_FAILURE_RETRY_DELAYS_MS.length ||
|
|
1184
|
+
(this.transportRetriesOutages &&
|
|
1185
|
+
error instanceof AppRuntimeApiTransportError)
|
|
1186
|
+
) {
|
|
1181
1187
|
throw new Error(
|
|
1182
1188
|
`Rate-state store unavailable for ${bucketId}; failing closed after ${consecutiveFailures} acquire attempts: ${normalized.message}`,
|
|
1189
|
+
{ cause: error },
|
|
1183
1190
|
);
|
|
1184
1191
|
}
|
|
1185
1192
|
await this.sleep(
|
|
@@ -1983,10 +1990,31 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
1983
1990
|
queueMicrotask(() => void this.flushReleases(key, pending));
|
|
1984
1991
|
}
|
|
1985
1992
|
|
|
1993
|
+
/**
|
|
1994
|
+
* Background write: `permit.release()` has already returned, so a failure
|
|
1995
|
+
* here has no caller, and the next acquire belongs to an unrelated row. An
|
|
1996
|
+
* unreleased lease holds its slot until the store's TTL, which errs toward
|
|
1997
|
+
* fewer provider calls, and the store still owns every grant. That is why a
|
|
1998
|
+
* failed acquire fails closed and a failed release does not.
|
|
1999
|
+
*
|
|
2000
|
+
* A shed comes from a working store, and DELETE by lease id is idempotent, so
|
|
2001
|
+
* it is retried inside a window. Anything else has spent the transport's
|
|
2002
|
+
* retries already. A contract 4xx would only repeat: acquire passes the same
|
|
2003
|
+
* auth and scope checks and fails closed on its own row, while a release-only
|
|
2004
|
+
* bug surfaces as provider admission timeouts once slots pin. Report it and
|
|
2005
|
+
* let the TTL reclaim the slot.
|
|
2006
|
+
*
|
|
2007
|
+
* Unreleased leases keep counting against the store's concurrency cap, so a
|
|
2008
|
+
* shed lane cannot be granted more than that cap per TTL, and the window
|
|
2009
|
+
* drops whatever the batch holds. The batch stays bounded, and this loop ends
|
|
2010
|
+
* once the lane stops releasing.
|
|
2011
|
+
*/
|
|
1986
2012
|
private async flushReleases(
|
|
1987
2013
|
key: string,
|
|
1988
2014
|
pending: PendingRelease,
|
|
1989
2015
|
): Promise<void> {
|
|
2016
|
+
let shedStartedAtMs: number | null = null;
|
|
2017
|
+
let consecutiveSheds = 0;
|
|
1990
2018
|
while (pending.leaseIds.length > 0) {
|
|
1991
2019
|
const leaseIds = pending.leaseIds.splice(0);
|
|
1992
2020
|
try {
|
|
@@ -1997,15 +2025,37 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
1997
2025
|
leaseIds,
|
|
1998
2026
|
schedulerSchema: this.schedulerSchema,
|
|
1999
2027
|
});
|
|
2028
|
+
shedStartedAtMs = null;
|
|
2029
|
+
consecutiveSheds = 0;
|
|
2000
2030
|
this.signalLeaseRelease(pending.bucketId);
|
|
2001
2031
|
} catch (error) {
|
|
2002
2032
|
const normalized = normalizeError(error);
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2033
|
+
const shedRetryAfterMs = capacityShedRetryAfterMs(error);
|
|
2034
|
+
if (shedRetryAfterMs !== null) {
|
|
2035
|
+
consecutiveSheds += 1;
|
|
2036
|
+
shedStartedAtMs ??= this.now();
|
|
2037
|
+
const delayMs = this.releaseShedDelayMs(
|
|
2038
|
+
shedRetryAfterMs,
|
|
2039
|
+
consecutiveSheds,
|
|
2040
|
+
);
|
|
2041
|
+
if (
|
|
2042
|
+
this.now() - shedStartedAtMs + delayMs <
|
|
2043
|
+
RELEASE_SHED_RETRY_WINDOW_MS
|
|
2044
|
+
) {
|
|
2045
|
+
this.onStoreFailure({
|
|
2046
|
+
bucketId: pending.bucketId,
|
|
2047
|
+
error: `Rate-state release shed for ${pending.bucketId}; retrying in ${delayMs}ms: ${normalized.message}`,
|
|
2048
|
+
});
|
|
2049
|
+
pending.leaseIds.unshift(...leaseIds);
|
|
2050
|
+
await this.sleep(delayMs);
|
|
2051
|
+
continue;
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
shedStartedAtMs = null;
|
|
2055
|
+
consecutiveSheds = 0;
|
|
2006
2056
|
this.onStoreFailure({
|
|
2007
2057
|
bucketId: pending.bucketId,
|
|
2008
|
-
error: normalized.message
|
|
2058
|
+
error: `Rate-state release failed for ${pending.bucketId}; leases held until their TTL (${leaseIds.length}): ${normalized.message}`,
|
|
2009
2059
|
});
|
|
2010
2060
|
}
|
|
2011
2061
|
}
|
|
@@ -2020,11 +2070,22 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
2020
2070
|
}
|
|
2021
2071
|
}
|
|
2022
2072
|
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2073
|
+
/**
|
|
2074
|
+
* Capped doubling, never under the shed's Retry-After. Jitter only adds, so a
|
|
2075
|
+
* wave of runners shed together spreads out above the deadline they were given.
|
|
2076
|
+
*/
|
|
2077
|
+
private releaseShedDelayMs(
|
|
2078
|
+
retryAfterMs: number,
|
|
2079
|
+
consecutiveSheds: number,
|
|
2080
|
+
): number {
|
|
2081
|
+
const floorMs = Math.max(
|
|
2082
|
+
retryAfterMs,
|
|
2083
|
+
Math.min(
|
|
2084
|
+
RELEASE_SHED_BACKOFF_BASE_MS * 2 ** (consecutiveSheds - 1),
|
|
2085
|
+
RELEASE_SHED_BACKOFF_MAX_MS,
|
|
2086
|
+
),
|
|
2087
|
+
);
|
|
2088
|
+
return floorMs + Math.round(this.jitter() * floorMs);
|
|
2028
2089
|
}
|
|
2029
2090
|
|
|
2030
2091
|
private signalLeaseRelease(bucketId: string): void {
|