deepline 0.3.289 → 0.3.290
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +30 -10
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +108 -12
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/launch-identity.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/log-provenance.ts +17 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runs/attempts/worker-terminal-projection.ts +6 -5
- 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 +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-event-catalog.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-event-transport.ts +31 -3
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +23 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-log-buffer.ts +30 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +38 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-progress-push.ts +2 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-terminal-push.ts +22 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-pool-options.ts +145 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +1 -5
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +8 -139
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +19 -5
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +37 -15
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +7 -5
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +961 -281
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +55 -25
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-dispatch-authority.ts +97 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-ledger-outbox-recovery.ts +33 -14
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +452 -43
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-value-storage.ts +10 -1
- package/dist/bundling-sources/shared_libs/play-runtime/test-admission-batching.ts +103 -0
- package/dist/bundling-sources/shared_libs/play-runtime/zerobounce-batching.ts +75 -28
- package/dist/cli/index.js +3 -1
- package/dist/cli/index.mjs +3 -1
- package/dist/index.js +3 -1
- package/dist/index.mjs +3 -1
- package/dist/install-integrity.json +3 -0
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts
CHANGED
|
@@ -964,6 +964,51 @@ export function createReceiptGatewayDispatcher(input: {
|
|
|
964
964
|
}
|
|
965
965
|
}
|
|
966
966
|
|
|
967
|
+
// Value preparation can wait on the writer fence or object storage. Finish
|
|
968
|
+
// it before checking out a SQL client, including the legacy single and
|
|
969
|
+
// injected-failure paths, so it cannot hold the pool needed by the fence.
|
|
970
|
+
let preparedCompletion: ReceiptCompletionOutputWithPersistence | null =
|
|
971
|
+
null;
|
|
972
|
+
let preparedCompletions: ReceiptGatewayCompletionEntry[] | null = null;
|
|
973
|
+
if (body.action === 'complete_runtime_step_receipt') {
|
|
974
|
+
const key = receiptKey(body.key);
|
|
975
|
+
if (key instanceof Response) return key;
|
|
976
|
+
completionFaultInjected =
|
|
977
|
+
(await input.consumeReceiptCompleteFault?.(runId)) === true;
|
|
978
|
+
if (!completionFaultInjected) {
|
|
979
|
+
preparedCompletion = await receiptCompletionOutput({
|
|
980
|
+
orgId: scope.orgId,
|
|
981
|
+
key,
|
|
982
|
+
output: body.output,
|
|
983
|
+
inlineFields: body.inlineFields,
|
|
984
|
+
persist: persistReceiptValue,
|
|
985
|
+
});
|
|
986
|
+
observeReceiptValuePersistence(
|
|
987
|
+
[preparedCompletion],
|
|
988
|
+
input.onReceiptValuePersistence,
|
|
989
|
+
);
|
|
990
|
+
}
|
|
991
|
+
} else if (body.action === 'complete_runtime_step_receipts') {
|
|
992
|
+
const sameRunError = requireSameRunReceipts(runId, body.receipts);
|
|
993
|
+
if (sameRunError) return sameRunError;
|
|
994
|
+
const keys = receiptKeys(
|
|
995
|
+
(body.receipts as Array<Record<string, unknown>>).map(
|
|
996
|
+
(receipt) => receipt.key,
|
|
997
|
+
),
|
|
998
|
+
);
|
|
999
|
+
if (keys instanceof Response) return keys;
|
|
1000
|
+
preparedCompletions = await buildReceiptCompletions({
|
|
1001
|
+
orgId: scope.orgId,
|
|
1002
|
+
persist: persistReceiptValue,
|
|
1003
|
+
receipts: body.receipts,
|
|
1004
|
+
keys,
|
|
1005
|
+
runId,
|
|
1006
|
+
onValuePersistence: input.onReceiptValuePersistence,
|
|
1007
|
+
});
|
|
1008
|
+
completionFaultInjected ??=
|
|
1009
|
+
(await input.consumeReceiptCompleteFault?.(runId)) === true;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
967
1012
|
return await input.withClient(async (client) => {
|
|
968
1013
|
switch (body.action) {
|
|
969
1014
|
case 'get_runtime_step_receipt': {
|
|
@@ -1099,7 +1144,7 @@ export function createReceiptGatewayDispatcher(input: {
|
|
|
1099
1144
|
case 'complete_runtime_step_receipt': {
|
|
1100
1145
|
const key = receiptKey(body.key);
|
|
1101
1146
|
if (key instanceof Response) return key;
|
|
1102
|
-
if (
|
|
1147
|
+
if (completionFaultInjected) {
|
|
1103
1148
|
await injectReceiptCompletionFailure({
|
|
1104
1149
|
client,
|
|
1105
1150
|
orgId: scope.orgId,
|
|
@@ -1116,22 +1161,14 @@ export function createReceiptGatewayDispatcher(input: {
|
|
|
1116
1161
|
{ status: 409 },
|
|
1117
1162
|
);
|
|
1118
1163
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
output: body.output,
|
|
1123
|
-
inlineFields: body.inlineFields,
|
|
1124
|
-
persist: persistReceiptValue,
|
|
1125
|
-
});
|
|
1126
|
-
observeReceiptValuePersistence(
|
|
1127
|
-
[completionOutput],
|
|
1128
|
-
input.onReceiptValuePersistence,
|
|
1129
|
-
);
|
|
1164
|
+
if (!preparedCompletion) {
|
|
1165
|
+
throw new Error('Receipt completion value was not prepared.');
|
|
1166
|
+
}
|
|
1130
1167
|
const {
|
|
1131
1168
|
valuePersistMs: _valuePersistMs,
|
|
1132
1169
|
valuePersistedByReference: _valuePersistedByReference,
|
|
1133
1170
|
...storedCompletionOutput
|
|
1134
|
-
} =
|
|
1171
|
+
} = preparedCompletion;
|
|
1135
1172
|
const completed = await completePostgresSchedulerReceipt(
|
|
1136
1173
|
client,
|
|
1137
1174
|
{
|
|
@@ -1165,18 +1202,11 @@ export function createReceiptGatewayDispatcher(input: {
|
|
|
1165
1202
|
),
|
|
1166
1203
|
);
|
|
1167
1204
|
if (keys instanceof Response) return keys;
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
runId,
|
|
1174
|
-
onValuePersistence: input.onReceiptValuePersistence,
|
|
1175
|
-
});
|
|
1176
|
-
if (
|
|
1177
|
-
completionFaultInjected ??
|
|
1178
|
-
(await input.consumeReceiptCompleteFault?.(runId))
|
|
1179
|
-
) {
|
|
1205
|
+
if (!preparedCompletions) {
|
|
1206
|
+
throw new Error('Receipt completion values were not prepared.');
|
|
1207
|
+
}
|
|
1208
|
+
const completions = preparedCompletions;
|
|
1209
|
+
if (completionFaultInjected) {
|
|
1180
1210
|
const [skippedReceipt, ...siblingReceipts] = completions;
|
|
1181
1211
|
if (siblingReceipts.length > 0) {
|
|
1182
1212
|
await completePostgresSchedulerReceipts(
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { PlaySchedulerSubmitInput } from '../scheduler-backend';
|
|
2
|
+
import { PROD_DEFAULT_RUNTIME_SCHEDULER_SCHEMA } from '../runtime-scheduler-topology';
|
|
3
|
+
import { resolveRuntimeSchedulerSchemaEnv } from './runtime-scheduler-schema';
|
|
4
|
+
import type {
|
|
5
|
+
PostgresSchedulerOptions,
|
|
6
|
+
PostgresSchedulerQueryClient,
|
|
7
|
+
} from './postgres';
|
|
8
|
+
|
|
9
|
+
export type RunLedgerDispatchLaunch = Pick<
|
|
10
|
+
PlaySchedulerSubmitInput,
|
|
11
|
+
| 'runId'
|
|
12
|
+
| 'playId'
|
|
13
|
+
| 'playName'
|
|
14
|
+
| 'executorToken'
|
|
15
|
+
| 'baseUrl'
|
|
16
|
+
| 'runtimeApiBaseUrl'
|
|
17
|
+
| 'runtimeTokenOrigin'
|
|
18
|
+
| 'orgId'
|
|
19
|
+
| 'runtimeAuthority'
|
|
20
|
+
| 'vercelProtectionBypassToken'
|
|
21
|
+
>;
|
|
22
|
+
|
|
23
|
+
/** Authority reads never transfer customer input, artifacts or execution graphs. */
|
|
24
|
+
export function runLedgerDispatchLaunchSql(alias: string): string {
|
|
25
|
+
const fields: (keyof RunLedgerDispatchLaunch)[] = [
|
|
26
|
+
'runId',
|
|
27
|
+
'playId',
|
|
28
|
+
'playName',
|
|
29
|
+
'executorToken',
|
|
30
|
+
'baseUrl',
|
|
31
|
+
'runtimeApiBaseUrl',
|
|
32
|
+
'runtimeTokenOrigin',
|
|
33
|
+
'orgId',
|
|
34
|
+
'runtimeAuthority',
|
|
35
|
+
'vercelProtectionBypassToken',
|
|
36
|
+
];
|
|
37
|
+
return `jsonb_build_object(${fields
|
|
38
|
+
.map((field) => `'${field}', ${alias}.launch_json->'${field}'`)
|
|
39
|
+
.join(', ')})`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function dispatchTableName(
|
|
43
|
+
table: string,
|
|
44
|
+
options?: Pick<PostgresSchedulerOptions, 'schema'>,
|
|
45
|
+
): string {
|
|
46
|
+
const schema =
|
|
47
|
+
options?.schema?.trim() ||
|
|
48
|
+
resolveRuntimeSchedulerSchemaEnv() ||
|
|
49
|
+
PROD_DEFAULT_RUNTIME_SCHEDULER_SCHEMA;
|
|
50
|
+
const quote = (name: string) => `"${name.replace(/"/g, '""')}"`;
|
|
51
|
+
return `${quote(schema)}.${quote(table)}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function parseRunLedgerDispatchLaunch(
|
|
55
|
+
value: unknown,
|
|
56
|
+
): RunLedgerDispatchLaunch {
|
|
57
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
58
|
+
throw new Error('Postgres scheduler launch_json is not an object.');
|
|
59
|
+
}
|
|
60
|
+
const launch = value as Partial<PlaySchedulerSubmitInput>;
|
|
61
|
+
if (
|
|
62
|
+
typeof launch.runId !== 'string' ||
|
|
63
|
+
typeof launch.playId !== 'string' ||
|
|
64
|
+
typeof launch.playName !== 'string' ||
|
|
65
|
+
typeof launch.executorToken !== 'string' ||
|
|
66
|
+
typeof launch.baseUrl !== 'string'
|
|
67
|
+
) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
'Postgres scheduler launch_json is missing required fields.',
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
return launch as RunLedgerDispatchLaunch;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Read only the immutable authority/routing fields under the same lease fence. */
|
|
76
|
+
export async function readRunLedgerDispatchAuthorityForLease(
|
|
77
|
+
client: PostgresSchedulerQueryClient,
|
|
78
|
+
input: { runId: string; eventId: string; leaseOwner: string },
|
|
79
|
+
options?: Pick<PostgresSchedulerOptions, 'schema'>,
|
|
80
|
+
): Promise<RunLedgerDispatchLaunch | null> {
|
|
81
|
+
const result = await client.query<{ launch_json: unknown }>(
|
|
82
|
+
`SELECT ${runLedgerDispatchLaunchSql('runs')} AS launch_json
|
|
83
|
+
FROM ${dispatchTableName('outbox', options)} outbox
|
|
84
|
+
JOIN ${dispatchTableName('runs', options)} runs ON runs.run_id = outbox.run_id
|
|
85
|
+
WHERE outbox.event_id = $1
|
|
86
|
+
AND outbox.run_id = $2
|
|
87
|
+
AND outbox.lease_owner = $3
|
|
88
|
+
AND outbox.lease_expires_at > now()
|
|
89
|
+
AND outbox.delivered_at IS NULL
|
|
90
|
+
AND outbox.failed_at IS NULL
|
|
91
|
+
LIMIT 1`,
|
|
92
|
+
[input.eventId, input.runId, input.leaseOwner],
|
|
93
|
+
);
|
|
94
|
+
return result.rows[0]
|
|
95
|
+
? parseRunLedgerDispatchLaunch(result.rows[0].launch_json)
|
|
96
|
+
: null;
|
|
97
|
+
}
|
|
@@ -583,6 +583,12 @@ export function startRunLedgerOutboxRecoveryController(input: {
|
|
|
583
583
|
onDelivered?: (deliveries: readonly RunLedgerOutboxDeliveredRow[]) => void;
|
|
584
584
|
}): RunLedgerOutboxRecoveryController {
|
|
585
585
|
const schedulerOptions = input.schedulerOptions ?? {};
|
|
586
|
+
let dispatchOrdinal = 0;
|
|
587
|
+
let searchInFlight = 0;
|
|
588
|
+
const maxSearchInFlight = Math.max(
|
|
589
|
+
1,
|
|
590
|
+
Math.floor(RUN_LEDGER_OUTBOX_RECOVERY_PRODUCTION_IN_FLIGHT / 2),
|
|
591
|
+
);
|
|
586
592
|
return startRunLedgerOutboxRecovery({
|
|
587
593
|
acquireNotifyHub: () =>
|
|
588
594
|
input.useDirectNotify === false
|
|
@@ -593,20 +599,33 @@ export function startRunLedgerOutboxRecoveryController(input: {
|
|
|
593
599
|
schedulerOptions,
|
|
594
600
|
}),
|
|
595
601
|
),
|
|
596
|
-
dispatchOnce: (headPriority) =>
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
602
|
+
dispatchOnce: async (headPriority) => {
|
|
603
|
+
const searchOnly =
|
|
604
|
+
dispatchOrdinal++ % 2 === 1 && searchInFlight < maxSearchInFlight;
|
|
605
|
+
if (searchOnly) searchInFlight += 1;
|
|
606
|
+
try {
|
|
607
|
+
return await dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
|
|
608
|
+
(operation) =>
|
|
609
|
+
withRuntimeSchedulerClient(input.poolOptions, operation),
|
|
610
|
+
{
|
|
611
|
+
tokenAuthority: 'gateway',
|
|
612
|
+
materializeObservability: true,
|
|
613
|
+
// One durable controller, with half its capacity reserved for
|
|
614
|
+
// lifecycle delivery even when every search operation is blocked.
|
|
615
|
+
searchOnly,
|
|
616
|
+
limit: 8,
|
|
617
|
+
headPriority,
|
|
618
|
+
// The lease holder delivers a run's terminal committed during its
|
|
619
|
+
// append, instead of leaving it for the next wave.
|
|
620
|
+
continueThroughTerminal: true,
|
|
621
|
+
...(input.onDelivered ? { onDelivered: input.onDelivered } : {}),
|
|
622
|
+
},
|
|
623
|
+
schedulerOptions,
|
|
624
|
+
);
|
|
625
|
+
} finally {
|
|
626
|
+
if (searchOnly) searchInFlight -= 1;
|
|
627
|
+
}
|
|
628
|
+
},
|
|
610
629
|
// `dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope` releases each
|
|
611
630
|
// short scheduler checkout before it calls the Vercel gateway. The two
|
|
612
631
|
// replicas therefore drain up to sixteen independent runs concurrently
|