deepline 0.3.89 → 0.3.90
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/contracts/install-commands.json +29 -0
- package/dist/bundling-sources/sdk/src/client.ts +120 -37
- package/dist/bundling-sources/sdk/src/index.ts +4 -0
- package/dist/bundling-sources/sdk/src/pagination.ts +25 -0
- package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +1 -1
- package/dist/bundling-sources/sdk/src/release.ts +16 -9
- package/dist/bundling-sources/sdk/src/types.ts +23 -0
- package/dist/bundling-sources/shared_libs/monitors/analytics-public.ts +10 -0
- package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +3 -0
- package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +4 -4
- package/dist/bundling-sources/shared_libs/monitors/inventory-reconciliation.ts +59 -0
- package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +7 -9
- package/dist/bundling-sources/shared_libs/monitors/package.json +7 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +44 -2
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-consumer-health.ts +2 -2
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +2 -2
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-public-aliases.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-dead-letter.ts +245 -0
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-message.ts +38 -0
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-ack-probe.ts +94 -0
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue-delivery.ts +60 -0
- package/dist/bundling-sources/shared_libs/monitors/signal-radars/inbound-queue.ts +60 -0
- package/dist/bundling-sources/shared_libs/monitors/snitcher-install-validation.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/snitcher-ip2company.ts +2 -2
- package/dist/bundling-sources/shared_libs/monitors/snitcher-radar.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/tracking-provider-integrations.ts +1 -1
- package/dist/bundling-sources/shared_libs/observability/build-context.ts +13 -0
- package/dist/bundling-sources/shared_libs/observability/log-metadata.ts +160 -0
- package/dist/bundling-sources/shared_libs/observability/request-context.ts +68 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +654 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +35 -0
- package/dist/bundling-sources/shared_libs/observability/scheduled-work.ts +5 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/neon-constants.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +272 -0
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +45 -0
- package/dist/bundling-sources/shared_libs/play-runtime/async-operation.ts +66 -1
- package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +0 -1
- package/dist/bundling-sources/shared_libs/play-runtime/bounceban-batching.ts +137 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +779 -140
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +46 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-payload-contract.ts +68 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-janitor.ts +103 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-sandbox-reaper.ts +725 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +29 -0
- package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +23 -0
- package/dist/bundling-sources/shared_libs/play-runtime/execution-gateway-invocation-fence.ts +442 -0
- package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +3 -3
- package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +18 -0
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/contracts.ts +66 -0
- package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/job.ts +145 -0
- package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/ports.ts +21 -0
- package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/postgres-store.ts +170 -0
- package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +1322 -0
- package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/launch-source-policy.ts +112 -0
- package/dist/bundling-sources/shared_libs/play-runtime/map-execution-frame.ts +8 -0
- package/dist/bundling-sources/shared_libs/play-runtime/perf-trace.ts +127 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-artifact-runtime-contract.ts +5 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +24 -1
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/contracts.ts +56 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/index.ts +13 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/job.ts +41 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/ports.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/postgres-adapter.ts +54 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/contracts.ts +114 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/engine-suspension.ts +108 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/index.ts +36 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/job.ts +97 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/ports.ts +104 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/postgres-fence-adapter.ts +263 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/worker-terminal-projection.ts +64 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/contracts.ts +29 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/gateway-adapter.ts +56 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/index.ts +15 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/job.ts +65 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/projection/ports.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/contracts.ts +42 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/index.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/job.ts +142 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/ports.ts +42 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/sandbox-cleanup/postgres-adapter.ts +102 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/contracts.ts +60 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/index.ts +16 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/job.ts +78 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/ports.ts +54 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/postgres-adapter.ts +71 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-batching-registry.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +5 -8
- package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +3 -5
- package/dist/bundling-sources/shared_libs/play-runtime/run-identity.ts +168 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +72 -9
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +6 -12
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +19 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/bundle.ts +0 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +14 -44
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +57 -205
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-authority.ts +201 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +67 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-release-environment.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-sandbox-contract.ts +68 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +14 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-telemetry.ts +108 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-deadline-reconciliation.ts +88 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-deploy-task.ts +124 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-run-task.ts +68 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool.ts +193 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-lifecycle.ts +269 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-queue-suffix.ts +73 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +6642 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +897 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-metrics.ts +120 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +76 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +476 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-heavy-request-admission.ts +47 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-progress-registry.ts +147 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/index.ts +27 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/lazy.ts +50 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/play-run-recovery.ts +98 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-budget-state.ts +260 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +1416 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +1255 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +942 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +14636 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +888 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +355 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-terminal-transition.ts +46 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runner-push.ts +60 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-api-origin.ts +33 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-gateway-health.ts +64 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +835 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-ledger-reconciliation.ts +1218 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-operation.ts +207 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-scheduler-schema.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-capacity.ts +123 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/scheduler-launch-read-observability.ts +78 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/submit-admission.ts +169 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/terminal-contract.ts +20 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-queue-metrics.ts +34 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-resource-metrics.ts +249 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/step-progress.ts +296 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/native-batch.ts +3 -3
- package/dist/bundling-sources/shared_libs/play-runtime/tool-call/runtime-step-receipts-adapter.ts +20 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +60 -15
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execution-outcome.ts +20 -0
- package/dist/bundling-sources/shared_libs/play-runtime/transient-service-error.ts +12 -0
- package/dist/bundling-sources/shared_libs/play-runtime/vercel-protection.ts +14 -1
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-storage-contract.ts +165 -0
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +15 -23
- package/dist/bundling-sources/shared_libs/play-runtime/workflow-executor-auth.ts +169 -0
- package/dist/bundling-sources/shared_libs/play-runtime/zerobounce-batching.ts +122 -0
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +2 -0
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +2 -0
- package/dist/bundling-sources/shared_libs/plays/deployment-status.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/docflow.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/play-grep-search.ts +39 -0
- package/dist/bundling-sources/shared_libs/plays/share/copy.ts +271 -0
- package/dist/bundling-sources/shared_libs/plays/share/metrics.ts +140 -0
- package/dist/bundling-sources/shared_libs/plays/share/public-read-model.ts +86 -0
- package/dist/bundling-sources/shared_libs/plays/share/seo-quality.ts +181 -0
- package/dist/bundling-sources/shared_libs/plays/share/static-pipeline-summary.ts +658 -0
- package/dist/bundling-sources/shared_libs/plays/share/types.ts +197 -0
- package/dist/bundling-sources/shared_libs/plays/slack-hitl-timeout-error.ts +37 -0
- package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +6 -1
- package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +1 -1
- package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +7 -1
- package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +3 -2
- package/dist/bundling-sources/shared_libs/product-notifications/overflow.ts +18 -0
- package/dist/bundling-sources/shared_libs/product-notifications/rolling-limit.ts +24 -0
- package/dist/bundling-sources/shared_libs/product-notifications/slack-delivery.ts +624 -0
- package/dist/bundling-sources/shared_libs/product-notifications/slack-payload.ts +140 -0
- package/dist/bundling-sources/shared_libs/product-notifications/slack-transport.ts +75 -0
- package/dist/bundling-sources/shared_libs/runtime-env.ts +6 -0
- package/dist/bundling-sources/shared_libs/security/email-blacklist.ts +42 -0
- package/dist/bundling-sources/shared_libs/security/header-safe-env.ts +10 -3
- package/dist/bundling-sources/shared_libs/security/slack-sanitize.ts +133 -0
- package/dist/cli/getting-started.d.mts +52 -0
- package/dist/cli/getting-started.d.ts +52 -0
- package/dist/cli/getting-started.js +65 -0
- package/dist/cli/getting-started.mjs +36 -0
- package/dist/cli/index.d.mts +9 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.js +545 -264
- package/dist/cli/index.mjs +543 -271
- package/dist/{compiler-manifest-DsLbQaew.d.mts → compiler-manifest-BaJfE-5H.d.mts} +5 -3
- package/dist/{compiler-manifest-DsLbQaew.d.ts → compiler-manifest-BaJfE-5H.d.ts} +5 -3
- package/dist/index.d.mts +81 -148
- package/dist/index.d.ts +81 -148
- package/dist/index.js +83 -26
- package/dist/index.mjs +83 -26
- package/dist/install-integrity.json +130 -2
- package/dist/monitor-fleet-contract.d.mts +138 -0
- package/dist/monitor-fleet-contract.d.ts +138 -0
- package/dist/monitor-fleet-contract.js +404 -0
- package/dist/monitor-fleet-contract.mjs +367 -0
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/dist/release.d.mts +255 -0
- package/dist/release.d.ts +255 -0
- package/dist/release.js +215 -0
- package/dist/release.mjs +188 -0
- package/package.json +21 -4
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Static analysis turns top-level play statements it cannot attribute to a
|
|
5
5
|
* structured step into `run_javascript` glue substeps whose alias is a
|
|
6
6
|
* machine-generated source line range (`lines_<startLine>_<endLine>`, built in
|
|
7
|
-
* `src/lib/plays/static-analysis.ts` → `createCodeStageForStatements`). The
|
|
7
|
+
* `apps/deepline-api/src/lib/plays/static-analysis.ts` → `createCodeStageForStatements`). The
|
|
8
8
|
* execution plan / runtime node ids namespace every substep by its type
|
|
9
|
-
* (`getStaticSubstepNodeId` in `
|
|
9
|
+
* (`getStaticSubstepNodeId` in `packages/play-runtime/step-progress.ts`), so glue nodes are ALWAYS
|
|
10
10
|
* `run_javascript:<alias>` on the wire (ledger stepsById, snapshot
|
|
11
11
|
* nodeStates, `play.step.*` stream events).
|
|
12
12
|
*
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* reach exactly the same verdict and none of them may drag the others'
|
|
6
6
|
* dependencies in:
|
|
7
7
|
*
|
|
8
|
-
* - the Next.js app (`src/lib/plays/runtime-lanes.ts`, the admin and internal
|
|
8
|
+
* - the Next.js app (`apps/deepline-api/src/lib/plays/runtime-lanes.ts`, the admin and internal
|
|
9
9
|
* lane endpoints), which also talks to Convex;
|
|
10
10
|
* - `scripts/fly-absurd-lane.ts` retire, run by the release controller; and
|
|
11
11
|
* - `apps/absurd-release-scaler/index.ts`, which owns retirement of every lane
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue-admission policy is about *how the run was invoked*, not whether its
|
|
3
|
+
* artifact is published, ad-hoc, or draft. A manual API run can launch a
|
|
4
|
+
* published artifact, while a webhook can launch a draft artifact.
|
|
5
|
+
*/
|
|
6
|
+
export type PlayLaunchTriggerSource =
|
|
7
|
+
| 'api'
|
|
8
|
+
| 'webhook'
|
|
9
|
+
| 'cron'
|
|
10
|
+
| 'sql_listener'
|
|
11
|
+
| 'async_child';
|
|
12
|
+
|
|
13
|
+
export type PlayLaunchQueuePolicy = {
|
|
14
|
+
triggerSource: PlayLaunchTriggerSource;
|
|
15
|
+
/**
|
|
16
|
+
* Relative ordering within one scheduler queue. This only decides which
|
|
17
|
+
* runnable run gets a newly available worker/sandbox slot; it never
|
|
18
|
+
* preempts a running customer sandbox or bypasses cross-org fairness.
|
|
19
|
+
*/
|
|
20
|
+
priority: number;
|
|
21
|
+
/**
|
|
22
|
+
* Absurd's maximum time waiting to be claimed, in seconds. `null` means the
|
|
23
|
+
* accepted launch is allowed to wait durably for capacity.
|
|
24
|
+
*/
|
|
25
|
+
maxDelaySeconds: number | null;
|
|
26
|
+
/**
|
|
27
|
+
* Maximum total time an accepted run may wait for a live sandbox slot. This
|
|
28
|
+
* is evaluated by the worker after a claim, where Absurd's `max_delay`
|
|
29
|
+
* cannot help. Zero gives an interactive caller an immediate, typed
|
|
30
|
+
* capacity-full result instead of a stuck watch.
|
|
31
|
+
*/
|
|
32
|
+
sandboxCapacityMaxWaitSeconds: number | null;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export function shouldTerminalizeSandboxCapacityRejection(input: {
|
|
36
|
+
triggerSource?: PlayLaunchTriggerSource | null;
|
|
37
|
+
submittedAtMs?: number | null;
|
|
38
|
+
nowMs?: number;
|
|
39
|
+
}): boolean {
|
|
40
|
+
const policy = resolvePlayLaunchQueuePolicy(input.triggerSource);
|
|
41
|
+
const maxWaitSeconds = policy.sandboxCapacityMaxWaitSeconds;
|
|
42
|
+
if (maxWaitSeconds === 0) return true;
|
|
43
|
+
if (maxWaitSeconds === null) return false;
|
|
44
|
+
const submittedAtMs = input.submittedAtMs;
|
|
45
|
+
if (
|
|
46
|
+
typeof submittedAtMs !== 'number' ||
|
|
47
|
+
!Number.isFinite(submittedAtMs) ||
|
|
48
|
+
submittedAtMs <= 0
|
|
49
|
+
) {
|
|
50
|
+
// Old launch rows did not persist submit time. Preserve their historical
|
|
51
|
+
// durable behavior rather than making an age guess at execution time.
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return (input.nowMs ?? Date.now()) >= submittedAtMs + maxWaitSeconds * 1_000;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Resolve the single queue-admission policy for every top-level play launch.
|
|
59
|
+
*
|
|
60
|
+
* Missing source is deliberately manual/API for backwards-compatible direct
|
|
61
|
+
* callers of `startPlayRunExecution`; webhook and cron callers must opt into
|
|
62
|
+
* their durable trigger source explicitly.
|
|
63
|
+
*/
|
|
64
|
+
export function resolvePlayLaunchQueuePolicy(
|
|
65
|
+
triggerSource?: PlayLaunchTriggerSource | null,
|
|
66
|
+
): PlayLaunchQueuePolicy {
|
|
67
|
+
switch (triggerSource ?? 'api') {
|
|
68
|
+
case 'api':
|
|
69
|
+
return {
|
|
70
|
+
triggerSource: 'api',
|
|
71
|
+
// A person waiting in the CLI/UI should get the next slot in their
|
|
72
|
+
// own organization rather than sitting behind that org's automation.
|
|
73
|
+
// The bounded deadline gives the caller a typed terminal outcome
|
|
74
|
+
// instead of an indefinite watch.
|
|
75
|
+
priority: 100,
|
|
76
|
+
maxDelaySeconds: 10,
|
|
77
|
+
sandboxCapacityMaxWaitSeconds: 0,
|
|
78
|
+
};
|
|
79
|
+
case 'webhook':
|
|
80
|
+
return {
|
|
81
|
+
triggerSource: 'webhook',
|
|
82
|
+
priority: 0,
|
|
83
|
+
// A 202 webhook response is a durable delivery promise. Capacity is
|
|
84
|
+
// not a delivery failure: retain it until it executes, is explicitly
|
|
85
|
+
// cancelled, or an operator terminalizes it. Interactive API launches
|
|
86
|
+
// remain separately bounded above.
|
|
87
|
+
maxDelaySeconds: null,
|
|
88
|
+
sandboxCapacityMaxWaitSeconds: null,
|
|
89
|
+
};
|
|
90
|
+
case 'cron':
|
|
91
|
+
return {
|
|
92
|
+
triggerSource: 'cron',
|
|
93
|
+
priority: -10,
|
|
94
|
+
maxDelaySeconds: 30 * 60,
|
|
95
|
+
sandboxCapacityMaxWaitSeconds: 30 * 60,
|
|
96
|
+
};
|
|
97
|
+
case 'sql_listener':
|
|
98
|
+
return {
|
|
99
|
+
triggerSource: 'sql_listener',
|
|
100
|
+
priority: -10,
|
|
101
|
+
maxDelaySeconds: 30 * 60,
|
|
102
|
+
sandboxCapacityMaxWaitSeconds: 30 * 60,
|
|
103
|
+
};
|
|
104
|
+
case 'async_child':
|
|
105
|
+
return {
|
|
106
|
+
triggerSource: 'async_child',
|
|
107
|
+
priority: 0,
|
|
108
|
+
maxDelaySeconds: null,
|
|
109
|
+
sandboxCapacityMaxWaitSeconds: null,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -10,6 +10,14 @@ export function cloneMapFrame(frame: MapExecutionFrame): MapExecutionFrame {
|
|
|
10
10
|
...frame,
|
|
11
11
|
completedRowKeys: [...frame.completedRowKeys],
|
|
12
12
|
pendingRowKeys: [...frame.pendingRowKeys],
|
|
13
|
+
...(frame.suspendedInputRows
|
|
14
|
+
? {
|
|
15
|
+
suspendedInputRows: frame.suspendedInputRows.map((row) => ({
|
|
16
|
+
inputIndex: row.inputIndex,
|
|
17
|
+
data: { ...row.data },
|
|
18
|
+
})),
|
|
19
|
+
}
|
|
20
|
+
: {}),
|
|
13
21
|
};
|
|
14
22
|
}
|
|
15
23
|
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured per-run perf trace for play execution.
|
|
3
|
+
*
|
|
4
|
+
* Each call emits a single line JSON object prefixed with `[perf-trace]` to
|
|
5
|
+
* stdout. Server-side callers (Next.js dev server) ALSO append the same JSON
|
|
6
|
+
* object to `logs/perf-<runId>.jsonl` so post-mortem aggregation works even
|
|
7
|
+
* when stdout has been multiplexed across many runs.
|
|
8
|
+
*
|
|
9
|
+
* This is intentionally additive — it does NOT replace the existing
|
|
10
|
+
* `[perf][plays.start_run]` console.info lines that other tooling parses.
|
|
11
|
+
*
|
|
12
|
+
* Benchmark trace map:
|
|
13
|
+
* - `apps/deepline-api/src/app/api/v2/plays/run/route.ts` records start-route and watch/terminal
|
|
14
|
+
* spans, including the old "terminal wait" bucket.
|
|
15
|
+
* - `packages/play-runtime/scheduler-backends/*` and
|
|
16
|
+
* the submit path records scheduler submit
|
|
17
|
+
* and workflow-create spans.
|
|
18
|
+
* - the runner records execution,
|
|
19
|
+
* dataset, ledger, billing, and terminalization spans.
|
|
20
|
+
* - `scripts/analyze-v2-sdk-cli-benchmark.ts` reads these from local
|
|
21
|
+
* `logs/perf-*.jsonl`, dev logs, or exported Axiom JSONL.
|
|
22
|
+
*
|
|
23
|
+
* Design constraints:
|
|
24
|
+
* - Workerd-safe (Cloudflare Workers can't touch the filesystem). When
|
|
25
|
+
* `appendFileSync` isn't available we degrade silently to stdout-only.
|
|
26
|
+
* - No new dependencies; just `node:fs`.
|
|
27
|
+
* - Loud failures are NOT desired here — perf instrumentation must never
|
|
28
|
+
* break a real play run. We swallow FS errors, but never silently drop
|
|
29
|
+
* the stdout copy.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import {
|
|
33
|
+
createTelemetry,
|
|
34
|
+
type TelemetryEvent,
|
|
35
|
+
type TelemetryFields,
|
|
36
|
+
} from '../observability/telemetry';
|
|
37
|
+
|
|
38
|
+
export type PerfTraceEvent = {
|
|
39
|
+
ts?: number;
|
|
40
|
+
source: 'server' | 'coordinator' | 'dynamic_worker' | 'runner';
|
|
41
|
+
runId: string;
|
|
42
|
+
orgId?: string | null;
|
|
43
|
+
phase: string;
|
|
44
|
+
ms: number;
|
|
45
|
+
playName?: string;
|
|
46
|
+
graphHash?: string | null;
|
|
47
|
+
workerUrl?: string | null;
|
|
48
|
+
bytes?: number;
|
|
49
|
+
extra?: Record<string, unknown>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const PERF_TRACE_PREFIX = '[perf-trace]';
|
|
53
|
+
|
|
54
|
+
let cachedAppendFile: ((path: string, data: string) => void) | null | undefined;
|
|
55
|
+
|
|
56
|
+
function getAppendFile(): ((path: string, data: string) => void) | null {
|
|
57
|
+
if (cachedAppendFile !== undefined) return cachedAppendFile;
|
|
58
|
+
try {
|
|
59
|
+
// Avoid bundling this into edge runtime call paths. Synchronous CJS
|
|
60
|
+
// require() is the right tool here: workerd will throw on load and we
|
|
61
|
+
// fall through to the null branch, which keeps the stdout-only path.
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
63
|
+
const fs = require('node:fs') as typeof import('node:fs');
|
|
64
|
+
cachedAppendFile = (path: string, data: string) => {
|
|
65
|
+
try {
|
|
66
|
+
fs.mkdirSync('logs', { recursive: true });
|
|
67
|
+
fs.appendFileSync(path, data);
|
|
68
|
+
} catch {
|
|
69
|
+
// Filesystem unavailable (workerd / read-only FS). Drop the sidecar
|
|
70
|
+
// copy; the stdout JSON line is still emitted by recordPerfTrace.
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
} catch {
|
|
74
|
+
cachedAppendFile = null;
|
|
75
|
+
}
|
|
76
|
+
return cachedAppendFile;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const perfTraceTelemetry = createTelemetry({
|
|
80
|
+
service: 'play-runtime',
|
|
81
|
+
component: 'perf-trace',
|
|
82
|
+
adapter: {
|
|
83
|
+
emit(event: TelemetryEvent) {
|
|
84
|
+
const json = JSON.stringify(event);
|
|
85
|
+
console.log(`${PERF_TRACE_PREFIX} ${json}`);
|
|
86
|
+
if (event.source === 'server' && typeof event.runId === 'string') {
|
|
87
|
+
getAppendFile()?.(
|
|
88
|
+
`logs/perf-${sanitizeRunIdForFilename(event.runId)}.jsonl`,
|
|
89
|
+
`${json}\n`,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
function perfTraceFields(event: PerfTraceEvent): TelemetryFields {
|
|
97
|
+
return {
|
|
98
|
+
ts: typeof event.ts === 'number' ? event.ts : Date.now(),
|
|
99
|
+
source: event.source,
|
|
100
|
+
phase: event.phase,
|
|
101
|
+
ms: event.ms,
|
|
102
|
+
graphHash: event.graphHash ?? null,
|
|
103
|
+
workerUrl: event.workerUrl ?? null,
|
|
104
|
+
bytes: event.bytes,
|
|
105
|
+
...(event.extra ?? {}),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function recordPerfTrace(event: PerfTraceEvent): void {
|
|
110
|
+
const { runId, phase } = event;
|
|
111
|
+
if (!runId || !phase) return;
|
|
112
|
+
const orgId =
|
|
113
|
+
event.orgId ??
|
|
114
|
+
(typeof event.extra?.orgId === 'string' ? event.extra.orgId : null);
|
|
115
|
+
void perfTraceTelemetry
|
|
116
|
+
.child({
|
|
117
|
+
component: event.source,
|
|
118
|
+
context: { runId, orgId, playName: event.playName ?? null },
|
|
119
|
+
})
|
|
120
|
+
.info(phase, perfTraceFields(event), { tag: PERF_TRACE_PREFIX });
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function sanitizeRunIdForFilename(runId: string): string {
|
|
124
|
+
return runId.replace(/[^a-zA-Z0-9._-]+/g, '_');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const PERF_TRACE_LINE_PREFIX = PERF_TRACE_PREFIX;
|
|
@@ -24,6 +24,8 @@ import {
|
|
|
24
24
|
*/
|
|
25
25
|
export type PlayArtifactRuntimeContract = Readonly<{
|
|
26
26
|
semantics: PlayRuntimeSemantics;
|
|
27
|
+
/** Additive artifact fact; missing persisted fields resolve to `park`. */
|
|
28
|
+
slackHitlTimeoutOutcome: 'park' | 'error';
|
|
27
29
|
toolErrorSchemaVersion: ToolExecutionErrorSchemaVersion;
|
|
28
30
|
toolResponseContract: ToolResponseContract;
|
|
29
31
|
toolResponseReceiptRevision?: string;
|
|
@@ -31,6 +33,7 @@ export type PlayArtifactRuntimeContract = Readonly<{
|
|
|
31
33
|
|
|
32
34
|
export type PlayArtifactRuntimeContractInput = {
|
|
33
35
|
authoringContractEdition?: PlayAuthoringContractEdition | null;
|
|
36
|
+
slackHitlTimeoutOutcome?: 'park' | 'error' | null;
|
|
34
37
|
toolResponseContract?: ToolResponseContract | null;
|
|
35
38
|
toolResponseReceiptRevision?: string | null;
|
|
36
39
|
};
|
|
@@ -50,6 +53,8 @@ export function resolvePlayArtifactRuntimeContract(
|
|
|
50
53
|
semantics: resolvePlayRuntimeSemantics(
|
|
51
54
|
input.authoringContractEdition ?? PLAY_AUTHORING_CONTRACT_EDITION,
|
|
52
55
|
),
|
|
56
|
+
slackHitlTimeoutOutcome:
|
|
57
|
+
input.slackHitlTimeoutOutcome === 'error' ? 'error' : 'park',
|
|
53
58
|
// Historic string-only failures are deliberately upgraded at the runtime
|
|
54
59
|
// boundary. Rehydrating an old artifact must not regress a structured
|
|
55
60
|
// durable failure into an unbranchable string.
|
|
@@ -41,6 +41,7 @@ export type PlayRunRecoveryReason =
|
|
|
41
41
|
| 'modal_circuit_open_before_execution'
|
|
42
42
|
| 'modal_sandbox_unavailable_before_execution'
|
|
43
43
|
| 'modal_runner_start_failed_before_execution'
|
|
44
|
+
| 'daytona_sandbox_transition_pending_before_execution'
|
|
44
45
|
| 'runtime_initialization_transport_before_execution'
|
|
45
46
|
| 'runtime_traffic_hold_before_execution'
|
|
46
47
|
| 'runtime_traffic_throttled_before_execution';
|
|
@@ -209,6 +210,27 @@ export function recoveryForRuntimeTrafficPolicy(input: {
|
|
|
209
210
|
});
|
|
210
211
|
}
|
|
211
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Daytona acknowledged a named sandbox but has not finished creating it.
|
|
215
|
+
* Resume that durable provider operation after a bounded defer; another
|
|
216
|
+
* provider or a fresh Daytona create could execute the same Play twice.
|
|
217
|
+
*/
|
|
218
|
+
export function recoveryForDaytonaSandboxTransitionPending(
|
|
219
|
+
error: unknown,
|
|
220
|
+
): PlayRunRecoveryError {
|
|
221
|
+
return new PlayRunRecoveryError({
|
|
222
|
+
decision: {
|
|
223
|
+
stage: 'pre_code',
|
|
224
|
+
action: 'defer',
|
|
225
|
+
reason: 'daytona_sandbox_transition_pending_before_execution',
|
|
226
|
+
dependency: 'runtime',
|
|
227
|
+
},
|
|
228
|
+
message:
|
|
229
|
+
'Daytona is still finishing a named sandbox create before customer execution began.',
|
|
230
|
+
cause: error,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
212
234
|
/**
|
|
213
235
|
* This is constructed only by the detached-runner readiness check. That
|
|
214
236
|
* check has not parked the runner or observed scheduler liveness, so it is a
|
|
@@ -241,7 +263,8 @@ export function recoveryForRuntimeInitializationTransportFailure(
|
|
|
241
263
|
| 'runtime_postgres_connect'
|
|
242
264
|
| 'runtime_api_transport'
|
|
243
265
|
| 'runtime_receipt_gateway_transport'
|
|
244
|
-
| 'daytona_public_status'
|
|
266
|
+
| 'daytona_public_status'
|
|
267
|
+
| 'daytona_runner_startup_transport',
|
|
245
268
|
): PlayRunRecoveryError {
|
|
246
269
|
return new PlayRunRecoveryError({
|
|
247
270
|
decision: {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { PlaySchedulerSubmitInput } from '../../scheduler-backend';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A fully prepared Play Run is ready to cross the one durable admission
|
|
5
|
+
* boundary. Construction, artifact validation, token minting, and provider
|
|
6
|
+
* resolution are intentionally finished before this value exists.
|
|
7
|
+
*/
|
|
8
|
+
export type PlayRunAdmissionInput = {
|
|
9
|
+
launch: PlaySchedulerSubmitInput;
|
|
10
|
+
queueName: string;
|
|
11
|
+
recoverExistingTask?: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/** The durable facts returned by one atomic launch-row + queue-task commit. */
|
|
15
|
+
export type PlayRunAdmissionReceipt = {
|
|
16
|
+
taskId: string | null;
|
|
17
|
+
runCreated: boolean;
|
|
18
|
+
taskCreated: boolean;
|
|
19
|
+
taskRecoveryRequired: boolean;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The outcome makes the three useful cases explicit to callers. A retry may
|
|
24
|
+
* either observe its original queue task or repair the historical row-first
|
|
25
|
+
* crash window; it never creates a second Play Run.
|
|
26
|
+
*/
|
|
27
|
+
export type PlayRunAdmissionOutcome =
|
|
28
|
+
| {
|
|
29
|
+
kind: 'created';
|
|
30
|
+
receipt: PlayRunAdmissionReceipt;
|
|
31
|
+
}
|
|
32
|
+
| {
|
|
33
|
+
kind: 'recovered';
|
|
34
|
+
receipt: PlayRunAdmissionReceipt;
|
|
35
|
+
}
|
|
36
|
+
| {
|
|
37
|
+
kind: 'replayed';
|
|
38
|
+
receipt: PlayRunAdmissionReceipt;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type PlayRunAdmissionJob = {
|
|
42
|
+
admit(input: PlayRunAdmissionInput): Promise<PlayRunAdmissionOutcome>;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** A stable, machine-readable rejection for a reused run id with new intent. */
|
|
46
|
+
export class PlayRunLaunchConflictError extends Error {
|
|
47
|
+
readonly code = 'PLAY_RUN_LAUNCH_CONFLICT';
|
|
48
|
+
|
|
49
|
+
constructor(runId: string, options?: { cause?: unknown }) {
|
|
50
|
+
super(
|
|
51
|
+
`Play run "${runId}" already exists with a different launch.`,
|
|
52
|
+
options,
|
|
53
|
+
);
|
|
54
|
+
this.name = 'PlayRunLaunchConflictError';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { createPlayRunAdmissionJob } from '../../play-runs/admission/job';
|
|
2
|
+
export { createPostgresPlayRunAdmissionPorts } from '../../play-runs/admission/postgres-adapter';
|
|
3
|
+
export { PlayRunLaunchConflictError } from '../../play-runs/admission/contracts';
|
|
4
|
+
export type {
|
|
5
|
+
PlayRunAdmissionInput,
|
|
6
|
+
PlayRunAdmissionJob,
|
|
7
|
+
PlayRunAdmissionOutcome,
|
|
8
|
+
PlayRunAdmissionReceipt,
|
|
9
|
+
} from '../../play-runs/admission/contracts';
|
|
10
|
+
export type {
|
|
11
|
+
AtomicPlayRunQueueSubmitter,
|
|
12
|
+
PlayRunAdmissionPorts,
|
|
13
|
+
} from '../../play-runs/admission/ports';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type PlayRunAdmissionInput,
|
|
3
|
+
type PlayRunAdmissionJob,
|
|
4
|
+
type PlayRunAdmissionOutcome,
|
|
5
|
+
} from '../../play-runs/admission/contracts';
|
|
6
|
+
import type { PlayRunAdmissionPorts } from '../../play-runs/admission/ports';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Play Run Admission owns the idempotency law for the launch boundary:
|
|
10
|
+
*
|
|
11
|
+
* exact launch retry -> original task
|
|
12
|
+
* existing queued row without task -> repair that row
|
|
13
|
+
* same run id + changed launch -> reject
|
|
14
|
+
*
|
|
15
|
+
* The storage Adapter enforces identity and atomicity. This job exposes the
|
|
16
|
+
* result without leaking SQL rows, scheduler queues, or task engine details.
|
|
17
|
+
*/
|
|
18
|
+
export function createPlayRunAdmissionJob(
|
|
19
|
+
ports: PlayRunAdmissionPorts,
|
|
20
|
+
): PlayRunAdmissionJob {
|
|
21
|
+
return {
|
|
22
|
+
async admit(
|
|
23
|
+
input: PlayRunAdmissionInput,
|
|
24
|
+
): Promise<PlayRunAdmissionOutcome> {
|
|
25
|
+
validate(input);
|
|
26
|
+
const receipt = await ports.atomicQueueSubmitter.submit(input);
|
|
27
|
+
if (receipt.runCreated) return { kind: 'created', receipt };
|
|
28
|
+
if (receipt.taskCreated) return { kind: 'recovered', receipt };
|
|
29
|
+
return { kind: 'replayed', receipt };
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function validate(input: PlayRunAdmissionInput): void {
|
|
35
|
+
if (!input.launch.runId.trim()) {
|
|
36
|
+
throw new Error('Play Run Admission requires a non-empty run id.');
|
|
37
|
+
}
|
|
38
|
+
if (!input.queueName.trim()) {
|
|
39
|
+
throw new Error('Play Run Admission requires a non-empty queue name.');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
PlayRunAdmissionInput,
|
|
3
|
+
PlayRunAdmissionReceipt,
|
|
4
|
+
} from '../../play-runs/admission/contracts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* This port is deliberately one operation. Persisting a run and enqueueing
|
|
8
|
+
* it separately creates an unrepairable ambiguity: either can succeed after a
|
|
9
|
+
* lost reply. The implementation must commit both facts atomically.
|
|
10
|
+
*/
|
|
11
|
+
export type AtomicPlayRunQueueSubmitter = {
|
|
12
|
+
submit(input: PlayRunAdmissionInput): Promise<PlayRunAdmissionReceipt>;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type PlayRunAdmissionPorts = {
|
|
16
|
+
atomicQueueSubmitter: AtomicPlayRunQueueSubmitter;
|
|
17
|
+
};
|
package/dist/bundling-sources/shared_libs/play-runtime/play-runs/admission/postgres-adapter.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
submitPostgresAbsurdPlayRun,
|
|
3
|
+
type PostgresSchedulerQueryClient,
|
|
4
|
+
} from '../../scheduler-backends/postgres';
|
|
5
|
+
import {
|
|
6
|
+
PlayRunLaunchConflictError,
|
|
7
|
+
type PlayRunAdmissionInput,
|
|
8
|
+
type PlayRunAdmissionReceipt,
|
|
9
|
+
} from '../../play-runs/admission/contracts';
|
|
10
|
+
import type { PlayRunAdmissionPorts } from '../../play-runs/admission/ports';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* PostgreSQL/Absurd implementation of the admission seam. The delegated
|
|
14
|
+
* statement persists `runs` and invokes `absurd.spawn_task` in one data-
|
|
15
|
+
* modifying CTE; no caller can observe a persisted runnable Play Run without
|
|
16
|
+
* its corresponding queue task.
|
|
17
|
+
*/
|
|
18
|
+
export function createPostgresPlayRunAdmissionPorts(input: {
|
|
19
|
+
client: PostgresSchedulerQueryClient;
|
|
20
|
+
schema?: string;
|
|
21
|
+
}): PlayRunAdmissionPorts {
|
|
22
|
+
const options = input.schema ? { schema: input.schema } : undefined;
|
|
23
|
+
return {
|
|
24
|
+
atomicQueueSubmitter: {
|
|
25
|
+
async submit(
|
|
26
|
+
admission: PlayRunAdmissionInput,
|
|
27
|
+
): Promise<PlayRunAdmissionReceipt> {
|
|
28
|
+
try {
|
|
29
|
+
return await submitPostgresAbsurdPlayRun(
|
|
30
|
+
input.client,
|
|
31
|
+
admission.launch,
|
|
32
|
+
options,
|
|
33
|
+
admission.queueName,
|
|
34
|
+
admission.recoverExistingTask === true,
|
|
35
|
+
);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (isLaunchConflict(error)) {
|
|
38
|
+
throw new PlayRunLaunchConflictError(admission.launch.runId, {
|
|
39
|
+
cause: error,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function isLaunchConflict(error: unknown): boolean {
|
|
50
|
+
return (
|
|
51
|
+
error instanceof Error &&
|
|
52
|
+
/already exists with a different launch/i.test(error.message)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Play Run Attempt is the controller for one fenced execution leg.
|
|
3
|
+
*
|
|
4
|
+
* It deliberately does not know how a sandbox is created, how a runner is
|
|
5
|
+
* started, or how a terminal transaction is committed. Its only policy is
|
|
6
|
+
* the retry boundary: work known not to have crossed into user/provider code
|
|
7
|
+
* may be deferred; once that boundary may have been crossed, this job never
|
|
8
|
+
* asks Sandbox Runs to execute again.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** The already-persisted run details required by this leg. */
|
|
12
|
+
export type PlayRunAttemptLaunch = {
|
|
13
|
+
runId: string;
|
|
14
|
+
/** Opaque to the attempt job; consumed by its execution implementation. */
|
|
15
|
+
launch: unknown;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
import type { PlayExecutionSuspension } from '../../suspension';
|
|
19
|
+
import type { PlayRunRecoveryDecision } from '../../play-run-recovery-policy';
|
|
20
|
+
|
|
21
|
+
/** A scheduler fence granted to exactly one execution leg. */
|
|
22
|
+
export type PlayRunAttemptClaim = {
|
|
23
|
+
runId: string;
|
|
24
|
+
number: number;
|
|
25
|
+
/** Opaque authority used by scheduler/resource/terminal Adapters. */
|
|
26
|
+
fenceId: string;
|
|
27
|
+
checkpoint: unknown;
|
|
28
|
+
/**
|
|
29
|
+
* A detached runner keeps its original attempt-scoped executor token. A
|
|
30
|
+
* heartbeat wake must therefore reuse this claim rather than minting a
|
|
31
|
+
* successor that would fence its still-live runner out of heartbeats and
|
|
32
|
+
* terminal delivery.
|
|
33
|
+
*/
|
|
34
|
+
origin: 'fresh' | 'detached_runner_resume';
|
|
35
|
+
/** Present only for an origin that resumed a detached runner. */
|
|
36
|
+
suspension?: Extract<PlayExecutionSuspension, { kind: 'detached_runner' }>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/** A durable waiting/resumed lifecycle fact ready for read-model projection. */
|
|
40
|
+
export type PlayRunAttemptLifecycle = {
|
|
41
|
+
runId: string;
|
|
42
|
+
eventId: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** Durable truth read before a new attempt may be claimed. */
|
|
46
|
+
export type PlayRunAttemptTerminal = {
|
|
47
|
+
status: 'completed' | 'failed' | 'cancelled';
|
|
48
|
+
output?: unknown;
|
|
49
|
+
error?: string;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type PlayRunAttemptInput = {
|
|
53
|
+
run: PlayRunAttemptLaunch;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Sandbox Runs reports whether user/provider code was crossed. The payload
|
|
58
|
+
* is opaque here because only the terminal job owns interpretation and
|
|
59
|
+
* persistence of a runner result.
|
|
60
|
+
*/
|
|
61
|
+
/**
|
|
62
|
+
* Evidence that no customer or provider code has begun. It is intentionally
|
|
63
|
+
* distinct from an ordinary thrown error: only these outcomes may put a run
|
|
64
|
+
* back into durable admission.
|
|
65
|
+
*/
|
|
66
|
+
export type PlayRunAttemptPreCodeDeferral =
|
|
67
|
+
| { kind: 'capacity'; reason: string }
|
|
68
|
+
| {
|
|
69
|
+
kind: 'recovery';
|
|
70
|
+
reason: string;
|
|
71
|
+
decision: PlayRunRecoveryDecision;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The runner-to-terminal transport envelope. Attempt never interprets this
|
|
76
|
+
* result; Terminal owns first-write-wins persistence and result shaping.
|
|
77
|
+
*/
|
|
78
|
+
export type PlayRunAttemptTerminalEnvelope =
|
|
79
|
+
| { status: 'completed'; output: unknown }
|
|
80
|
+
| { status: 'failed'; error: string };
|
|
81
|
+
|
|
82
|
+
export type PlayRunAttemptSandboxOutcome =
|
|
83
|
+
| { kind: 'pre_code_deferred'; deferral: PlayRunAttemptPreCodeDeferral }
|
|
84
|
+
| {
|
|
85
|
+
kind: 'suspended';
|
|
86
|
+
checkpoint: unknown;
|
|
87
|
+
suspension: PlayExecutionSuspension;
|
|
88
|
+
}
|
|
89
|
+
| { kind: 'terminal'; result: PlayRunAttemptTerminalEnvelope }
|
|
90
|
+
| { kind: 'post_code_unknown'; reason: string };
|
|
91
|
+
|
|
92
|
+
export type PlayRunAttemptTerminalHandoff =
|
|
93
|
+
| { kind: 'committed' }
|
|
94
|
+
| { kind: 'already_terminal' }
|
|
95
|
+
| { kind: 'fence_lost' };
|
|
96
|
+
|
|
97
|
+
/** Outcomes visible to the worker Adapter after one execution leg. */
|
|
98
|
+
export type PlayRunAttemptOutcome =
|
|
99
|
+
| { kind: 'already_terminal'; terminal: PlayRunAttemptTerminal }
|
|
100
|
+
| { kind: 'claim_rejected' }
|
|
101
|
+
| { kind: 'pre_code_deferred'; deferral: PlayRunAttemptPreCodeDeferral }
|
|
102
|
+
| {
|
|
103
|
+
kind: 'parked';
|
|
104
|
+
checkpoint: unknown;
|
|
105
|
+
suspension: PlayExecutionSuspension;
|
|
106
|
+
}
|
|
107
|
+
| { kind: 'post_code_unknown'; reason: string }
|
|
108
|
+
| { kind: 'terminal_committed' }
|
|
109
|
+
| { kind: 'terminal_already_committed' }
|
|
110
|
+
| { kind: 'terminal_fence_lost' };
|
|
111
|
+
|
|
112
|
+
export type PlayRunAttemptJob = {
|
|
113
|
+
execute(input: PlayRunAttemptInput): Promise<PlayRunAttemptOutcome>;
|
|
114
|
+
};
|