deepline 0.1.222 → 0.1.224
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/apps/play-runner-workers/src/coordinator-entry.ts +396 -176
- package/dist/bundling-sources/apps/play-runner-workers/src/dedup-do.ts +6 -3
- package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +210 -105
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/shared_libs/observability/node-tracing.ts +125 -0
- package/dist/bundling-sources/shared_libs/observability/redaction.ts +94 -0
- package/dist/bundling-sources/shared_libs/observability/telemetry.ts +414 -0
- package/dist/bundling-sources/shared_libs/observability/tracing.ts +93 -0
- package/dist/bundling-sources/shared_libs/observability/worker-telemetry.ts +119 -0
- package/dist/bundling-sources/shared_libs/play-runtime/secret-redaction.ts +32 -14
- package/dist/cli/index.js +220 -164
- package/dist/cli/index.mjs +220 -164
- package/dist/index.js +72 -56
- package/dist/index.mjs +72 -56
- package/package.json +1 -1
|
@@ -15,6 +15,13 @@ import {
|
|
|
15
15
|
WorkflowEntrypoint,
|
|
16
16
|
exports as workersExports,
|
|
17
17
|
} from 'cloudflare:workers';
|
|
18
|
+
import {
|
|
19
|
+
createWorkerTelemetry,
|
|
20
|
+
type TelemetryEvent,
|
|
21
|
+
type TelemetryFields,
|
|
22
|
+
type TelemetryScalar,
|
|
23
|
+
} from '../../../shared_libs/observability/worker-telemetry';
|
|
24
|
+
import { createSecretRedactionContext } from '../../../shared_libs/play-runtime/secret-redaction';
|
|
18
25
|
import {
|
|
19
26
|
_dispatcherBindingImpl as createDispatcherWorkflowBinding,
|
|
20
27
|
dispatchWorkflow,
|
|
@@ -83,6 +90,59 @@ import {
|
|
|
83
90
|
|
|
84
91
|
export { DynamicWorkflowBinding };
|
|
85
92
|
|
|
93
|
+
const coordinatorTelemetry = createWorkerTelemetry({
|
|
94
|
+
service: 'play-runtime',
|
|
95
|
+
component: 'coordinator',
|
|
96
|
+
});
|
|
97
|
+
const coordinatorStorageRedactor = createSecretRedactionContext();
|
|
98
|
+
const coordinatorPerfTelemetry = createWorkerTelemetry({
|
|
99
|
+
service: 'play-runtime',
|
|
100
|
+
component: 'coordinator',
|
|
101
|
+
adapter: {
|
|
102
|
+
emit(event: TelemetryEvent) {
|
|
103
|
+
console.log(`[perf-trace] ${JSON.stringify(event)}`);
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
function coordinatorTelemetryFields(input: object): TelemetryFields {
|
|
109
|
+
const fields: Record<string, TelemetryScalar> = {};
|
|
110
|
+
for (const [key, value] of Object.entries(input)) {
|
|
111
|
+
if (
|
|
112
|
+
value === undefined ||
|
|
113
|
+
value === null ||
|
|
114
|
+
typeof value === 'string' ||
|
|
115
|
+
typeof value === 'number' ||
|
|
116
|
+
typeof value === 'boolean'
|
|
117
|
+
) {
|
|
118
|
+
fields[key] = value;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return fields;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function recordCoordinatorEvent(
|
|
125
|
+
level: 'info' | 'warn' | 'error',
|
|
126
|
+
event: string,
|
|
127
|
+
tag: string,
|
|
128
|
+
input: Record<string, unknown> = {},
|
|
129
|
+
): void {
|
|
130
|
+
const telemetry = coordinatorTelemetry.child({
|
|
131
|
+
context: {
|
|
132
|
+
runId: typeof input.runId === 'string' ? input.runId : null,
|
|
133
|
+
orgId: typeof input.orgId === 'string' ? input.orgId : null,
|
|
134
|
+
playName: typeof input.playName === 'string' ? input.playName : null,
|
|
135
|
+
requestId: typeof input.requestId === 'string' ? input.requestId : null,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
const fields = coordinatorTelemetryFields(input);
|
|
139
|
+
if (level === 'error') {
|
|
140
|
+
void telemetry.error(event, input.error ?? input.message, fields, { tag });
|
|
141
|
+
} else {
|
|
142
|
+
void telemetry[level](event, fields, { tag });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
86
146
|
export type PlayWorkflowParams = {
|
|
87
147
|
runId: string;
|
|
88
148
|
playId: string;
|
|
@@ -389,7 +449,11 @@ function buildCoordinatorPerfTracePayload(
|
|
|
389
449
|
}
|
|
390
450
|
|
|
391
451
|
function logCoordinatorPerfTrace(payload: CoordinatorPerfTracePayload): void {
|
|
392
|
-
|
|
452
|
+
void coordinatorPerfTelemetry
|
|
453
|
+
.child({ context: { runId: payload.runId } })
|
|
454
|
+
.info(payload.phase, coordinatorTelemetryFields(payload), {
|
|
455
|
+
tag: '[perf-trace]',
|
|
456
|
+
});
|
|
393
457
|
}
|
|
394
458
|
|
|
395
459
|
function recordCoordinatorPerfTrace(event: CoordinatorPerfTraceInput): void {
|
|
@@ -417,7 +481,7 @@ async function appendCoordinatorPerfTrace(
|
|
|
417
481
|
{
|
|
418
482
|
method: 'POST',
|
|
419
483
|
headers: { 'content-type': 'application/json' },
|
|
420
|
-
body: JSON.stringify(payload),
|
|
484
|
+
body: JSON.stringify(coordinatorStorageRedactor.redact(payload)),
|
|
421
485
|
},
|
|
422
486
|
);
|
|
423
487
|
if (!response.ok) {
|
|
@@ -438,11 +502,16 @@ function recordCoordinatorPerfTraceBuffered(
|
|
|
438
502
|
if (!payload) return;
|
|
439
503
|
logCoordinatorPerfTrace(payload);
|
|
440
504
|
const append = appendCoordinatorPerfTrace(env, payload).catch((error) => {
|
|
441
|
-
|
|
442
|
-
runId: payload.runId
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
505
|
+
return coordinatorTelemetry
|
|
506
|
+
.child({ context: { runId: payload.runId } })
|
|
507
|
+
.warn(
|
|
508
|
+
'coordinator.perf_trace.buffer_failed',
|
|
509
|
+
{
|
|
510
|
+
phase: payload.phase,
|
|
511
|
+
error: error instanceof Error ? error.message : String(error),
|
|
512
|
+
},
|
|
513
|
+
{ tag: '[coordinator] failed to buffer perf trace' },
|
|
514
|
+
);
|
|
446
515
|
});
|
|
447
516
|
if (typeof ctx?.waitUntil === 'function') {
|
|
448
517
|
ctx.waitUntil(append);
|
|
@@ -595,7 +664,7 @@ async function writeCoordinatorChildTerminalState(input: {
|
|
|
595
664
|
headers: { 'content-type': 'application/json' },
|
|
596
665
|
body: JSON.stringify({
|
|
597
666
|
eventKey: input.eventKey,
|
|
598
|
-
data: input.data,
|
|
667
|
+
data: coordinatorStorageRedactor.redact(input.data),
|
|
599
668
|
storedAt: Date.now(),
|
|
600
669
|
}),
|
|
601
670
|
},
|
|
@@ -858,12 +927,17 @@ async function callRunScopedControl<T>(
|
|
|
858
927
|
} catch (error) {
|
|
859
928
|
const handoffMessage = durableObjectDeployHandoffMessage(error);
|
|
860
929
|
if (handoffMessage && attempt < maxAttempts) {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
930
|
+
recordCoordinatorEvent(
|
|
931
|
+
'warn',
|
|
932
|
+
'coordinator.run_state.handoff_retry',
|
|
933
|
+
'[coordinator] run state DO deploy handoff retry',
|
|
934
|
+
{
|
|
935
|
+
runId,
|
|
936
|
+
path,
|
|
937
|
+
attempt,
|
|
938
|
+
error: handoffMessage,
|
|
939
|
+
},
|
|
940
|
+
);
|
|
867
941
|
await sleepForDurableObjectDeployHandoffRetry(attempt - 1);
|
|
868
942
|
continue;
|
|
869
943
|
}
|
|
@@ -877,13 +951,18 @@ async function callRunScopedControl<T>(
|
|
|
877
951
|
const responseText = (await response.text().catch(() => '')).slice(0, 400);
|
|
878
952
|
const handoffMessage = durableObjectDeployHandoffMessage(responseText);
|
|
879
953
|
if (handoffMessage && attempt < maxAttempts) {
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
954
|
+
recordCoordinatorEvent(
|
|
955
|
+
'warn',
|
|
956
|
+
'coordinator.run_state.handoff_retry',
|
|
957
|
+
'[coordinator] run state DO deploy handoff retry',
|
|
958
|
+
{
|
|
959
|
+
runId,
|
|
960
|
+
path,
|
|
961
|
+
attempt,
|
|
962
|
+
status: response.status,
|
|
963
|
+
error: handoffMessage,
|
|
964
|
+
},
|
|
965
|
+
);
|
|
887
966
|
await sleepForDurableObjectDeployHandoffRetry(attempt - 1);
|
|
888
967
|
continue;
|
|
889
968
|
}
|
|
@@ -1341,14 +1420,19 @@ async function markWorkflowRuntimeFailure(input: {
|
|
|
1341
1420
|
const response = await fetch(url, { method: 'POST', headers, body });
|
|
1342
1421
|
if (response.ok) {
|
|
1343
1422
|
if (attempt > 0) {
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1423
|
+
recordCoordinatorEvent(
|
|
1424
|
+
'info',
|
|
1425
|
+
'coordinator.runtime_api.retry',
|
|
1426
|
+
'[coordinator.runtime_api.retry]',
|
|
1427
|
+
{
|
|
1428
|
+
action: 'append_run_events',
|
|
1429
|
+
status: 'ok',
|
|
1430
|
+
attempt,
|
|
1431
|
+
runId,
|
|
1432
|
+
requestId,
|
|
1433
|
+
baseOrigin: safeOrigin(baseUrl),
|
|
1434
|
+
},
|
|
1435
|
+
);
|
|
1352
1436
|
}
|
|
1353
1437
|
return;
|
|
1354
1438
|
}
|
|
@@ -1367,26 +1451,37 @@ async function markWorkflowRuntimeFailure(input: {
|
|
|
1367
1451
|
lastError = error;
|
|
1368
1452
|
}
|
|
1369
1453
|
if (attempt < backoffMs.length) {
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1454
|
+
recordCoordinatorEvent(
|
|
1455
|
+
'warn',
|
|
1456
|
+
'coordinator.runtime_api.retry',
|
|
1457
|
+
'[coordinator.runtime_api.retry]',
|
|
1458
|
+
{
|
|
1459
|
+
action: 'append_run_events',
|
|
1460
|
+
status: 'retry',
|
|
1461
|
+
attempt: attempt + 1,
|
|
1462
|
+
retryDelayMs: backoffMs[attempt],
|
|
1463
|
+
runId,
|
|
1464
|
+
requestId,
|
|
1465
|
+
baseOrigin: safeOrigin(baseUrl),
|
|
1466
|
+
error:
|
|
1467
|
+
lastError instanceof Error
|
|
1468
|
+
? lastError.message.slice(0, 300)
|
|
1469
|
+
: String(lastError).slice(0, 300),
|
|
1470
|
+
},
|
|
1471
|
+
);
|
|
1383
1472
|
await new Promise((resolve) => setTimeout(resolve, backoffMs[attempt]));
|
|
1384
1473
|
}
|
|
1385
1474
|
}
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1475
|
+
recordCoordinatorEvent(
|
|
1476
|
+
'error',
|
|
1477
|
+
'coordinator.workflow_runtime_failure.mark_failed',
|
|
1478
|
+
'[coordinator] failed to mark workflow runtime failure',
|
|
1479
|
+
{
|
|
1480
|
+
runId,
|
|
1481
|
+
message:
|
|
1482
|
+
lastError instanceof Error ? lastError.message : String(lastError),
|
|
1483
|
+
},
|
|
1484
|
+
);
|
|
1390
1485
|
}
|
|
1391
1486
|
|
|
1392
1487
|
async function appendWorkflowChildCompletedRunEvent(input: {
|
|
@@ -1767,10 +1862,15 @@ async function restartWorkflowAfterPlatformReset(input: {
|
|
|
1767
1862
|
env: input.env,
|
|
1768
1863
|
runId: input.runId,
|
|
1769
1864
|
}).catch((error) => {
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1865
|
+
recordCoordinatorEvent(
|
|
1866
|
+
'warn',
|
|
1867
|
+
'coordinator.workflow_platform_retry.claim_failed',
|
|
1868
|
+
'[coordinator] workflow platform retry claim failed',
|
|
1869
|
+
{
|
|
1870
|
+
runId: input.runId,
|
|
1871
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1872
|
+
},
|
|
1873
|
+
);
|
|
1774
1874
|
return null;
|
|
1775
1875
|
});
|
|
1776
1876
|
if (!claim?.claimed || !claim.params) {
|
|
@@ -1968,13 +2068,18 @@ async function callRuntimeApiFromCoordinator(input: {
|
|
|
1968
2068
|
'',
|
|
1969
2069
|
) || null
|
|
1970
2070
|
: null;
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
2071
|
+
recordCoordinatorEvent(
|
|
2072
|
+
'info',
|
|
2073
|
+
'coordinator.runtime_api.breadcrumb',
|
|
2074
|
+
'[coordinator.runtime_api.breadcrumb]',
|
|
2075
|
+
{
|
|
2076
|
+
phase: 'request',
|
|
2077
|
+
action,
|
|
2078
|
+
runId,
|
|
2079
|
+
requestId,
|
|
2080
|
+
baseOrigin: safeOrigin(input.baseUrl),
|
|
2081
|
+
},
|
|
2082
|
+
);
|
|
1978
2083
|
const response = await input.env.HARNESS.runtimeApiCall({
|
|
1979
2084
|
contract: PLAY_RUNTIME_CONTRACT,
|
|
1980
2085
|
executorToken: input.executorToken,
|
|
@@ -1987,15 +2092,20 @@ async function callRuntimeApiFromCoordinator(input: {
|
|
|
1987
2092
|
},
|
|
1988
2093
|
});
|
|
1989
2094
|
recordTiming('coordinator.runtime_api.fetch', fetchStartedAt);
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
2095
|
+
recordCoordinatorEvent(
|
|
2096
|
+
'info',
|
|
2097
|
+
'coordinator.runtime_api.breadcrumb',
|
|
2098
|
+
'[coordinator.runtime_api.breadcrumb]',
|
|
2099
|
+
{
|
|
2100
|
+
phase: 'response',
|
|
2101
|
+
action,
|
|
2102
|
+
runId,
|
|
2103
|
+
requestId,
|
|
2104
|
+
status: response.status,
|
|
2105
|
+
ms: Date.now() - fetchStartedAt,
|
|
2106
|
+
baseOrigin: safeOrigin(input.baseUrl),
|
|
2107
|
+
},
|
|
2108
|
+
);
|
|
1999
2109
|
|
|
2000
2110
|
const bodyStartedAt = Date.now();
|
|
2001
2111
|
const responseBody = response.body;
|
|
@@ -3031,7 +3141,9 @@ async function submitChildWorkflowThroughCoordinator(input: {
|
|
|
3031
3141
|
childRunId,
|
|
3032
3142
|
error,
|
|
3033
3143
|
}).catch((markError) => {
|
|
3034
|
-
|
|
3144
|
+
recordCoordinatorEvent(
|
|
3145
|
+
'error',
|
|
3146
|
+
'coordinator.child_workflow_submit.failure_mark_failed',
|
|
3035
3147
|
'[coordinator] child workflow submit failure mark failed',
|
|
3036
3148
|
{
|
|
3037
3149
|
childRunId,
|
|
@@ -3088,11 +3200,16 @@ async function submitChildWorkflowThroughCoordinator(input: {
|
|
|
3088
3200
|
childRunId,
|
|
3089
3201
|
error: `workflow submit returned ${response.status}: ${responseText.slice(0, 800)}`,
|
|
3090
3202
|
}).catch((markError) => {
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3203
|
+
recordCoordinatorEvent(
|
|
3204
|
+
'error',
|
|
3205
|
+
'coordinator.child_workflow_submit.failure_mark_failed',
|
|
3206
|
+
'[coordinator] child workflow submit failure mark failed',
|
|
3207
|
+
{
|
|
3208
|
+
childRunId,
|
|
3209
|
+
error:
|
|
3210
|
+
markError instanceof Error ? markError.message : String(markError),
|
|
3211
|
+
},
|
|
3212
|
+
);
|
|
3096
3213
|
});
|
|
3097
3214
|
}
|
|
3098
3215
|
return {
|
|
@@ -3159,9 +3276,16 @@ export class RuntimeApi extends WorkerEntrypoint<CoordinatorEnv, undefined> {
|
|
|
3159
3276
|
.clone()
|
|
3160
3277
|
.text()
|
|
3161
3278
|
.catch(() => '');
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3279
|
+
recordCoordinatorEvent(
|
|
3280
|
+
'error',
|
|
3281
|
+
'coordinator.runtime_api.proxy_failed',
|
|
3282
|
+
'[RUNTIME_API] request failed',
|
|
3283
|
+
{
|
|
3284
|
+
path: incoming.pathname,
|
|
3285
|
+
status: res.status,
|
|
3286
|
+
targetOrigin: target.origin,
|
|
3287
|
+
body: body.slice(0, 500),
|
|
3288
|
+
},
|
|
3165
3289
|
);
|
|
3166
3290
|
}
|
|
3167
3291
|
return res;
|
|
@@ -3394,10 +3518,15 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
|
|
|
3394
3518
|
status: 'running',
|
|
3395
3519
|
ts: Date.now(),
|
|
3396
3520
|
}).catch((error) => {
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3521
|
+
recordCoordinatorEvent(
|
|
3522
|
+
'warn',
|
|
3523
|
+
'coordinator.workflow_entry.status_event_failed',
|
|
3524
|
+
'[coordinator] workflow entry status event failed',
|
|
3525
|
+
{
|
|
3526
|
+
runId: entryTrace.runId,
|
|
3527
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3528
|
+
},
|
|
3529
|
+
);
|
|
3401
3530
|
}),
|
|
3402
3531
|
);
|
|
3403
3532
|
}
|
|
@@ -3449,7 +3578,9 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
|
|
|
3449
3578
|
event: dispatchedEvent,
|
|
3450
3579
|
error: hydrateError,
|
|
3451
3580
|
}).catch((markError) => {
|
|
3452
|
-
|
|
3581
|
+
recordCoordinatorEvent(
|
|
3582
|
+
'error',
|
|
3583
|
+
'coordinator.db_session_expired.failure_forward_failed',
|
|
3453
3584
|
'[coordinator] failed to forward expired-db-session run failure',
|
|
3454
3585
|
{
|
|
3455
3586
|
runId: entryTrace.runId,
|
|
@@ -3586,7 +3717,9 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
|
|
|
3586
3717
|
});
|
|
3587
3718
|
}
|
|
3588
3719
|
} catch (childTerminalError) {
|
|
3589
|
-
|
|
3720
|
+
recordCoordinatorEvent(
|
|
3721
|
+
'warn',
|
|
3722
|
+
'coordinator.child_terminal.ledger_append_failed',
|
|
3590
3723
|
'[coordinator] child terminal ledger append failed; preserving coordinator terminal cache',
|
|
3591
3724
|
{
|
|
3592
3725
|
runId: runIdForTrace,
|
|
@@ -3624,7 +3757,7 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
|
|
|
3624
3757
|
{
|
|
3625
3758
|
graphHash,
|
|
3626
3759
|
runId: runIdForTrace,
|
|
3627
|
-
|
|
3760
|
+
error:
|
|
3628
3761
|
terminalError instanceof Error
|
|
3629
3762
|
? terminalError.message
|
|
3630
3763
|
: String(terminalError),
|
|
@@ -3641,7 +3774,9 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
|
|
|
3641
3774
|
} catch (innerError) {
|
|
3642
3775
|
const failure =
|
|
3643
3776
|
normalizeCoordinatorWorkflowRuntimeFailure(innerError);
|
|
3644
|
-
|
|
3777
|
+
recordCoordinatorEvent(
|
|
3778
|
+
'error',
|
|
3779
|
+
'coordinator.dynamic_workflow.runner_failed',
|
|
3645
3780
|
'[coordinator] DynamicWorkflow runner.run threw',
|
|
3646
3781
|
{
|
|
3647
3782
|
graphHash,
|
|
@@ -3668,7 +3803,9 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
|
|
|
3668
3803
|
event: innerEvent,
|
|
3669
3804
|
error: innerError,
|
|
3670
3805
|
}).catch((markError) => {
|
|
3671
|
-
|
|
3806
|
+
recordCoordinatorEvent(
|
|
3807
|
+
'error',
|
|
3808
|
+
'coordinator.dynamic_workflow.failure_forward_failed',
|
|
3672
3809
|
'[coordinator] failed to forward DynamicWorkflow runner error',
|
|
3673
3810
|
{
|
|
3674
3811
|
graphHash,
|
|
@@ -3685,7 +3822,9 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
|
|
|
3685
3822
|
error: failure.message,
|
|
3686
3823
|
}).catch(() => undefined);
|
|
3687
3824
|
} else {
|
|
3688
|
-
|
|
3825
|
+
recordCoordinatorEvent(
|
|
3826
|
+
'warn',
|
|
3827
|
+
'coordinator.dynamic_workflow.platform_reset_retrying',
|
|
3689
3828
|
'[coordinator] DynamicWorkflow platform reset will be retried; not publishing durable run.failed',
|
|
3690
3829
|
{
|
|
3691
3830
|
graphHash,
|
|
@@ -4133,11 +4272,16 @@ function coordinatorWorkflowRouteErrorResponse(input: {
|
|
|
4133
4272
|
const message =
|
|
4134
4273
|
input.error instanceof Error ? input.error.message : String(input.error);
|
|
4135
4274
|
const phase = `coordinator.${input.action || 'unknown'}`;
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
error
|
|
4140
|
-
|
|
4275
|
+
recordCoordinatorEvent(
|
|
4276
|
+
'error',
|
|
4277
|
+
'coordinator.workflow_route.error',
|
|
4278
|
+
'[coordinator.workflow_route.error]',
|
|
4279
|
+
{
|
|
4280
|
+
runId: input.runId,
|
|
4281
|
+
action: input.action,
|
|
4282
|
+
error: message,
|
|
4283
|
+
},
|
|
4284
|
+
);
|
|
4141
4285
|
if (
|
|
4142
4286
|
input.action === 'submit' &&
|
|
4143
4287
|
isTenantStorageDegradationError(input.error)
|
|
@@ -4151,12 +4295,17 @@ function coordinatorWorkflowRouteErrorResponse(input: {
|
|
|
4151
4295
|
// actions (status/result/tail/cancel/signal) run against an already-active,
|
|
4152
4296
|
// possibly-billing run, so surfacing "storage not ready, nothing billed,
|
|
4153
4297
|
// run db repair" there would be false and alarming on a healthy run.
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4298
|
+
recordCoordinatorEvent(
|
|
4299
|
+
'error',
|
|
4300
|
+
'coordinator.workflow_route.storage_not_ready',
|
|
4301
|
+
'[coordinator.workflow_route.storage_not_ready]',
|
|
4302
|
+
{
|
|
4303
|
+
runId: input.runId,
|
|
4304
|
+
action: input.action,
|
|
4305
|
+
phase,
|
|
4306
|
+
error: message,
|
|
4307
|
+
},
|
|
4308
|
+
);
|
|
4160
4309
|
return Response.json(
|
|
4161
4310
|
{
|
|
4162
4311
|
error: {
|
|
@@ -4198,7 +4347,7 @@ function coordinatorRouteErrorResponse(input: {
|
|
|
4198
4347
|
}): Response {
|
|
4199
4348
|
const message =
|
|
4200
4349
|
input.error instanceof Error ? input.error.message : String(input.error);
|
|
4201
|
-
|
|
4350
|
+
recordCoordinatorEvent('error', 'coordinator.route.error', input.logTag, {
|
|
4202
4351
|
runId: input.runId,
|
|
4203
4352
|
phase: input.phase,
|
|
4204
4353
|
error: message,
|
|
@@ -4358,7 +4507,9 @@ async function handleWorkflowRoute(input: {
|
|
|
4358
4507
|
// logs. Log the tenant-storage classification loudly so the real
|
|
4359
4508
|
// cause (and the WORKSPACE_STORAGE_NOT_READY repair path) is visible.
|
|
4360
4509
|
if (storageNotReady) {
|
|
4361
|
-
|
|
4510
|
+
recordCoordinatorEvent(
|
|
4511
|
+
'error',
|
|
4512
|
+
'coordinator.harness_prewarm_postgres.storage_not_ready',
|
|
4362
4513
|
'[coordinator.harness_prewarm_postgres.storage_not_ready]',
|
|
4363
4514
|
{
|
|
4364
4515
|
runId: submittedRunId,
|
|
@@ -4414,11 +4565,16 @@ async function handleWorkflowRoute(input: {
|
|
|
4414
4565
|
} catch (error) {
|
|
4415
4566
|
const errorMessage =
|
|
4416
4567
|
error instanceof Error ? error.message : String(error);
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4568
|
+
recordCoordinatorEvent(
|
|
4569
|
+
'error',
|
|
4570
|
+
'coordinator.workflow_retry_state.persistence_failed',
|
|
4571
|
+
'[coordinator] workflow retry state persistence failed',
|
|
4572
|
+
{
|
|
4573
|
+
code: 'WORKFLOW_RETRY_STATE_PERSISTENCE_FAILED',
|
|
4574
|
+
runId: submittedRunId,
|
|
4575
|
+
error: errorMessage,
|
|
4576
|
+
},
|
|
4577
|
+
);
|
|
4422
4578
|
recordSubmitTiming({
|
|
4423
4579
|
phase: 'coordinator.retry_state_persistence',
|
|
4424
4580
|
ms: 0,
|
|
@@ -4561,16 +4717,23 @@ async function handleWorkflowRoute(input: {
|
|
|
4561
4717
|
instanceId: instance.id,
|
|
4562
4718
|
});
|
|
4563
4719
|
} catch (error) {
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4720
|
+
recordCoordinatorEvent(
|
|
4721
|
+
'warn',
|
|
4722
|
+
'coordinator.workflow_instance_id.record_failed',
|
|
4723
|
+
'[coordinator] workflow instance id record failed',
|
|
4724
|
+
{
|
|
4725
|
+
runId: submittedRunId,
|
|
4726
|
+
instanceId: instance?.id ?? null,
|
|
4727
|
+
error: error instanceof Error ? error.message : String(error),
|
|
4728
|
+
},
|
|
4729
|
+
);
|
|
4569
4730
|
await releaseWorkflowSubmitClaim({
|
|
4570
4731
|
env,
|
|
4571
4732
|
runId: submittedRunId,
|
|
4572
4733
|
}).catch((releaseError) => {
|
|
4573
|
-
|
|
4734
|
+
recordCoordinatorEvent(
|
|
4735
|
+
'warn',
|
|
4736
|
+
'coordinator.workflow_submit_claim.release_failed',
|
|
4574
4737
|
'[coordinator] workflow submit claim release after instance record failure failed',
|
|
4575
4738
|
{
|
|
4576
4739
|
runId: submittedRunId,
|
|
@@ -4678,19 +4841,24 @@ async function handleWorkflowRoute(input: {
|
|
|
4678
4841
|
ms: Date.now() - startedAt,
|
|
4679
4842
|
extra: { status: submitResponse.status, childRunId },
|
|
4680
4843
|
});
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
:
|
|
4693
|
-
|
|
4844
|
+
recordCoordinatorEvent(
|
|
4845
|
+
'info',
|
|
4846
|
+
'play.runtime.span',
|
|
4847
|
+
'[play.runtime.span]',
|
|
4848
|
+
{
|
|
4849
|
+
event: 'play.runtime.span',
|
|
4850
|
+
phase: 'coordinator_child_submit',
|
|
4851
|
+
runId,
|
|
4852
|
+
parentRunId: runId,
|
|
4853
|
+
childRunId,
|
|
4854
|
+
playName: childPlayName,
|
|
4855
|
+
ms: Date.now() - startedAt,
|
|
4856
|
+
status: submitResponse.ok ? 'ok' : 'failed',
|
|
4857
|
+
...(submitResponse.ok
|
|
4858
|
+
? {}
|
|
4859
|
+
: { errorCode: 'COORDINATOR_CHILD_SUBMIT_FAILED' }),
|
|
4860
|
+
},
|
|
4861
|
+
);
|
|
4694
4862
|
if (!submitResponse.ok) {
|
|
4695
4863
|
return new Response(responseText, {
|
|
4696
4864
|
status: submitResponse.status,
|
|
@@ -4716,11 +4884,16 @@ async function handleWorkflowRoute(input: {
|
|
|
4716
4884
|
);
|
|
4717
4885
|
} catch (error) {
|
|
4718
4886
|
const message = error instanceof Error ? error.message : String(error);
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
error
|
|
4723
|
-
|
|
4887
|
+
recordCoordinatorEvent(
|
|
4888
|
+
'error',
|
|
4889
|
+
'coordinator.child_submit.error',
|
|
4890
|
+
'[coordinator.child_submit.error]',
|
|
4891
|
+
{
|
|
4892
|
+
runId,
|
|
4893
|
+
ms: Date.now() - startedAt,
|
|
4894
|
+
error: message,
|
|
4895
|
+
},
|
|
4896
|
+
);
|
|
4724
4897
|
return Response.json(
|
|
4725
4898
|
{
|
|
4726
4899
|
error: {
|
|
@@ -4883,10 +5056,15 @@ async function handleWorkflowRoute(input: {
|
|
|
4883
5056
|
).catch((error: unknown) => {
|
|
4884
5057
|
// Tolerated: better to risk a harmless terminal-over-terminal
|
|
4885
5058
|
// overwrite than to skip the cancelled write and hang watchers.
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
5059
|
+
recordCoordinatorEvent(
|
|
5060
|
+
'warn',
|
|
5061
|
+
'coordinator.cancel.terminal_state_read_failed',
|
|
5062
|
+
'[coordinator] terminal state read before cancel failed',
|
|
5063
|
+
{
|
|
5064
|
+
runId,
|
|
5065
|
+
error: error instanceof Error ? error.message : String(error),
|
|
5066
|
+
},
|
|
5067
|
+
);
|
|
4890
5068
|
return null;
|
|
4891
5069
|
});
|
|
4892
5070
|
if (!existingTerminal) {
|
|
@@ -4901,10 +5079,15 @@ async function handleWorkflowRoute(input: {
|
|
|
4901
5079
|
// hang on 'running' forever without the terminal event.
|
|
4902
5080
|
const message =
|
|
4903
5081
|
error instanceof Error ? error.message : String(error);
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
5082
|
+
recordCoordinatorEvent(
|
|
5083
|
+
'error',
|
|
5084
|
+
'coordinator.cancel.terminal_state_write_failed',
|
|
5085
|
+
'[coordinator] cancel terminal state write failed',
|
|
5086
|
+
{
|
|
5087
|
+
runId,
|
|
5088
|
+
error: message,
|
|
5089
|
+
},
|
|
5090
|
+
);
|
|
4908
5091
|
return Response.json(
|
|
4909
5092
|
{
|
|
4910
5093
|
runId,
|
|
@@ -4944,11 +5127,16 @@ async function handleWorkflowRoute(input: {
|
|
|
4944
5127
|
eventKey,
|
|
4945
5128
|
data: body.data ?? body,
|
|
4946
5129
|
}).catch((error: unknown) => {
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
5130
|
+
recordCoordinatorEvent(
|
|
5131
|
+
'warn',
|
|
5132
|
+
'coordinator.child_terminal.cache_write_failed',
|
|
5133
|
+
'[coordinator] child terminal cache write failed',
|
|
5134
|
+
{
|
|
5135
|
+
runId,
|
|
5136
|
+
eventKey,
|
|
5137
|
+
error: error instanceof Error ? error.message : String(error),
|
|
5138
|
+
},
|
|
5139
|
+
);
|
|
4952
5140
|
});
|
|
4953
5141
|
}
|
|
4954
5142
|
await instance.sendEvent({
|
|
@@ -5048,7 +5236,9 @@ async function handleWorkflowRoute(input: {
|
|
|
5048
5236
|
message,
|
|
5049
5237
|
)
|
|
5050
5238
|
) {
|
|
5051
|
-
|
|
5239
|
+
recordCoordinatorEvent(
|
|
5240
|
+
'warn',
|
|
5241
|
+
'coordinator.permanent_error.terminate_failed',
|
|
5052
5242
|
'[coordinator] terminate-after-permanent-error failed',
|
|
5053
5243
|
{
|
|
5054
5244
|
runId,
|
|
@@ -5462,12 +5652,20 @@ export class TenantWorkflow extends WorkflowEntrypoint {
|
|
|
5462
5652
|
})).catch(() => null);
|
|
5463
5653
|
}
|
|
5464
5654
|
console.log("[perf-trace] " + JSON.stringify({
|
|
5655
|
+
telemetrySchemaVersion: 1,
|
|
5656
|
+
timestamp: new Date().toISOString(),
|
|
5657
|
+
service: "play-runtime",
|
|
5658
|
+
component: "coordinator-warmup",
|
|
5659
|
+
event: "dynamic_worker.warmup_run",
|
|
5660
|
+
tag: "[perf-trace]",
|
|
5465
5661
|
ts: Date.now(),
|
|
5466
5662
|
source: "dynamic_worker",
|
|
5467
5663
|
runId,
|
|
5468
5664
|
phase: "dynamic_worker.warmup_run",
|
|
5469
5665
|
ms: Date.now() - startedAt,
|
|
5470
|
-
graphHash: "coordinator-warmup-v1"
|
|
5666
|
+
graphHash: "coordinator-warmup-v1",
|
|
5667
|
+
telemetryKind: "log",
|
|
5668
|
+
telemetryLevel: "info"
|
|
5471
5669
|
}));
|
|
5472
5670
|
return { ok: true, warmup: true };
|
|
5473
5671
|
}
|
|
@@ -5540,15 +5738,20 @@ async function handleStagedFilePut(
|
|
|
5540
5738
|
}
|
|
5541
5739
|
const existing = await headExistingStagedFile(env, key, expectedBytes);
|
|
5542
5740
|
if (existing.exists) {
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5741
|
+
recordCoordinatorEvent(
|
|
5742
|
+
'info',
|
|
5743
|
+
'coordinator.staged_file_put',
|
|
5744
|
+
'[perf][coordinator.staged_file_put]',
|
|
5745
|
+
{
|
|
5746
|
+
key,
|
|
5747
|
+
bytes: expectedBytes,
|
|
5748
|
+
headMs: existing.ms,
|
|
5749
|
+
putMs: 0,
|
|
5750
|
+
ms: existing.ms,
|
|
5751
|
+
transport: 'raw',
|
|
5752
|
+
skipped: true,
|
|
5753
|
+
},
|
|
5754
|
+
);
|
|
5552
5755
|
return Response.json({
|
|
5553
5756
|
ok: true,
|
|
5554
5757
|
key,
|
|
@@ -5571,14 +5774,19 @@ async function handleStagedFilePut(
|
|
|
5571
5774
|
httpMetadata: { contentType },
|
|
5572
5775
|
});
|
|
5573
5776
|
const putMs = Date.now() - putStartedAt;
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5777
|
+
recordCoordinatorEvent(
|
|
5778
|
+
'info',
|
|
5779
|
+
'coordinator.staged_file_put',
|
|
5780
|
+
'[perf][coordinator.staged_file_put]',
|
|
5781
|
+
{
|
|
5782
|
+
key,
|
|
5783
|
+
bytes: bytes.byteLength,
|
|
5784
|
+
readMs,
|
|
5785
|
+
putMs,
|
|
5786
|
+
ms: readMs + putMs,
|
|
5787
|
+
transport: 'raw',
|
|
5788
|
+
},
|
|
5789
|
+
);
|
|
5582
5790
|
return Response.json({
|
|
5583
5791
|
ok: true,
|
|
5584
5792
|
key,
|
|
@@ -5615,15 +5823,20 @@ async function handleStagedFilePut(
|
|
|
5615
5823
|
}
|
|
5616
5824
|
const existing = await headExistingStagedFile(env, key, expectedBytes);
|
|
5617
5825
|
if (existing.exists) {
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5826
|
+
recordCoordinatorEvent(
|
|
5827
|
+
'info',
|
|
5828
|
+
'coordinator.staged_file_put',
|
|
5829
|
+
'[perf][coordinator.staged_file_put]',
|
|
5830
|
+
{
|
|
5831
|
+
key,
|
|
5832
|
+
bytes: expectedBytes,
|
|
5833
|
+
headMs: existing.ms,
|
|
5834
|
+
putMs: 0,
|
|
5835
|
+
ms: existing.ms,
|
|
5836
|
+
transport: 'base64',
|
|
5837
|
+
skipped: true,
|
|
5838
|
+
},
|
|
5839
|
+
);
|
|
5627
5840
|
return Response.json({
|
|
5628
5841
|
ok: true,
|
|
5629
5842
|
key,
|
|
@@ -5646,13 +5859,18 @@ async function handleStagedFilePut(
|
|
|
5646
5859
|
httpMetadata: { contentType },
|
|
5647
5860
|
});
|
|
5648
5861
|
const putMs = Date.now() - putStartedAt;
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5862
|
+
recordCoordinatorEvent(
|
|
5863
|
+
'info',
|
|
5864
|
+
'coordinator.staged_file_put',
|
|
5865
|
+
'[perf][coordinator.staged_file_put]',
|
|
5866
|
+
{
|
|
5867
|
+
key,
|
|
5868
|
+
bytes: bytes.byteLength,
|
|
5869
|
+
decodeMs,
|
|
5870
|
+
putMs,
|
|
5871
|
+
ms: decodeMs + putMs,
|
|
5872
|
+
},
|
|
5873
|
+
);
|
|
5656
5874
|
return Response.json({
|
|
5657
5875
|
ok: true,
|
|
5658
5876
|
key,
|
|
@@ -5931,7 +6149,9 @@ function makeCoordinatorControlBinding():
|
|
|
5931
6149
|
if (typeof ctor !== 'function') {
|
|
5932
6150
|
if (!loggedMissingCoordinatorControlExport) {
|
|
5933
6151
|
loggedMissingCoordinatorControlExport = true;
|
|
5934
|
-
|
|
6152
|
+
recordCoordinatorEvent(
|
|
6153
|
+
'warn',
|
|
6154
|
+
'coordinator.control_export.missing',
|
|
5935
6155
|
'[coordinator] CoordinatorControl is not registered on cloudflare:workers exports; using public coordinator transport.',
|
|
5936
6156
|
);
|
|
5937
6157
|
}
|