@dudousxd/nestjs-durable-core 0.64.0 → 0.66.0
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/index.cjs +518 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +678 -137
- package/dist/index.d.ts +678 -137
- package/dist/index.js +509 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ __export(index_exports, {
|
|
|
26
26
|
CURRENT_PROTOCOL_VERSION: () => CURRENT_PROTOCOL_VERSION,
|
|
27
27
|
CodecStateStore: () => CodecStateStore,
|
|
28
28
|
ContinueAsNew: () => ContinueAsNew,
|
|
29
|
+
DEFAULT_PARTITION: () => DEFAULT_PARTITION,
|
|
29
30
|
DURABLE_OPTIONS: () => DURABLE_OPTIONS,
|
|
30
31
|
DURABLE_OPTIONS_CANONICAL: () => DURABLE_OPTIONS_CANONICAL,
|
|
31
32
|
DURABLE_STEP_CONFIG: () => DURABLE_STEP_CONFIG,
|
|
@@ -56,25 +57,31 @@ __export(index_exports, {
|
|
|
56
57
|
TERMINAL_RUN_STATUSES: () => TERMINAL_RUN_STATUSES,
|
|
57
58
|
TRANSPORT: () => TRANSPORT,
|
|
58
59
|
TRANSPORT_CANONICAL: () => TRANSPORT_CANONICAL,
|
|
60
|
+
VERSION_UNDECLARED_TAG: () => VERSION_UNDECLARED_TAG,
|
|
59
61
|
WORKFLOW_NAME_KEY: () => WORKFLOW_NAME_KEY,
|
|
60
62
|
WorkflowBlocked: () => WorkflowBlocked,
|
|
61
63
|
WorkflowEngine: () => WorkflowEngine,
|
|
62
64
|
WorkflowSuspended: () => WorkflowSuspended,
|
|
65
|
+
aggregateAnnouncements: () => aggregateAnnouncements,
|
|
66
|
+
announcementsOf: () => announcementsOf,
|
|
63
67
|
applyAttributeQuery: () => applyAttributeQuery,
|
|
64
68
|
attributeColumnFor: () => attributeColumnFor,
|
|
65
69
|
attributeOperand: () => attributeOperand,
|
|
66
70
|
bindWorkflowClass: () => bindWorkflowClass,
|
|
67
71
|
breakpointToken: () => breakpointToken,
|
|
72
|
+
buildWorkflowDirectory: () => buildWorkflowDirectory,
|
|
68
73
|
canRoute: () => canRoute,
|
|
69
74
|
capableWorkers: () => capableWorkers,
|
|
70
75
|
classifyWaiterToken: () => classifyWaiterToken,
|
|
71
76
|
clearDurableExecutionWrappers: () => clearDurableExecutionWrappers,
|
|
72
77
|
collectMetrics: () => collectMetrics,
|
|
73
78
|
controlPlaneDescriptor: () => controlPlaneDescriptor,
|
|
79
|
+
coveredTokens: () => coveredTokens,
|
|
74
80
|
createStepLogger: () => createStepLogger,
|
|
75
81
|
currentStep: () => currentStep,
|
|
76
82
|
currentWorkflowCtx: () => currentWorkflowCtx,
|
|
77
83
|
debug: () => debug,
|
|
84
|
+
describeWorker: () => describeWorker,
|
|
78
85
|
descriptorHash: () => descriptorHash,
|
|
79
86
|
error: () => error,
|
|
80
87
|
eventMatchOf: () => eventMatchOf,
|
|
@@ -95,7 +102,9 @@ __export(index_exports, {
|
|
|
95
102
|
negotiate: () => negotiate,
|
|
96
103
|
normalizeAttributeRows: () => normalizeAttributeRows,
|
|
97
104
|
normalizeDescriptor: () => normalizeDescriptor,
|
|
105
|
+
observedAnnouncements: () => observedAnnouncements,
|
|
98
106
|
parseDuration: () => parseDuration,
|
|
107
|
+
partitionOfToken: () => partitionOfToken,
|
|
99
108
|
planDispatch: () => planDispatch,
|
|
100
109
|
prevCronFireMs: () => prevCronFireMs,
|
|
101
110
|
readSearchAttributes: () => readSearchAttributes,
|
|
@@ -1103,6 +1112,9 @@ function normalizeDescriptor(raw) {
|
|
|
1103
1112
|
],
|
|
1104
1113
|
workflows: raw.workflows ?? [],
|
|
1105
1114
|
steps: raw.steps ?? [],
|
|
1115
|
+
...raw.registrations !== void 0 ? {
|
|
1116
|
+
registrations: raw.registrations
|
|
1117
|
+
} : {},
|
|
1106
1118
|
...raw.partition !== void 0 ? {
|
|
1107
1119
|
partition: raw.partition
|
|
1108
1120
|
} : {},
|
|
@@ -1113,6 +1125,23 @@ function normalizeDescriptor(raw) {
|
|
|
1113
1125
|
};
|
|
1114
1126
|
}
|
|
1115
1127
|
__name(normalizeDescriptor, "normalizeDescriptor");
|
|
1128
|
+
function canonicalizeRegistrations(regs) {
|
|
1129
|
+
const canonical = regs.map((r) => ({
|
|
1130
|
+
name: r.name,
|
|
1131
|
+
version: r.version ?? null,
|
|
1132
|
+
group: r.group ?? null,
|
|
1133
|
+
requires: r.requires ? [
|
|
1134
|
+
...new Set(r.requires)
|
|
1135
|
+
].sort() : null,
|
|
1136
|
+
origin: r.origin ?? null
|
|
1137
|
+
}));
|
|
1138
|
+
const byJson = /* @__PURE__ */ new Map();
|
|
1139
|
+
for (const entry of canonical) byJson.set(JSON.stringify(entry), entry);
|
|
1140
|
+
return [
|
|
1141
|
+
...byJson.keys()
|
|
1142
|
+
].sort().map((k) => byJson.get(k));
|
|
1143
|
+
}
|
|
1144
|
+
__name(canonicalizeRegistrations, "canonicalizeRegistrations");
|
|
1116
1145
|
function canonicalizeForHash(d) {
|
|
1117
1146
|
const set = /* @__PURE__ */ __name((xs) => [
|
|
1118
1147
|
...new Set(xs)
|
|
@@ -1134,6 +1163,9 @@ function canonicalizeForHash(d) {
|
|
|
1134
1163
|
capabilities: set(d.capabilities),
|
|
1135
1164
|
workflows: set(d.workflows),
|
|
1136
1165
|
steps: set(d.steps),
|
|
1166
|
+
...d.registrations !== void 0 ? {
|
|
1167
|
+
registrations: canonicalizeRegistrations(d.registrations)
|
|
1168
|
+
} : {},
|
|
1137
1169
|
partition: d.partition ?? null,
|
|
1138
1170
|
namespace: d.namespace ?? null,
|
|
1139
1171
|
startedAt: d.startedAt
|
|
@@ -1166,6 +1198,276 @@ function heartbeatStatus(descriptor, opts = {}) {
|
|
|
1166
1198
|
};
|
|
1167
1199
|
}
|
|
1168
1200
|
__name(heartbeatStatus, "heartbeatStatus");
|
|
1201
|
+
function describeWorker(opts) {
|
|
1202
|
+
const version = CURRENT_PROTOCOL_VERSION;
|
|
1203
|
+
const registrations = [
|
|
1204
|
+
...opts.registrations ?? []
|
|
1205
|
+
].sort((a, b) => `${a.name}@${a.version ?? ""}`.localeCompare(`${b.name}@${b.version ?? ""}`));
|
|
1206
|
+
return {
|
|
1207
|
+
instanceId: opts.instanceId,
|
|
1208
|
+
runtime: opts.runtime,
|
|
1209
|
+
sdk: {
|
|
1210
|
+
name: opts.sdk.name,
|
|
1211
|
+
version: opts.sdk.version
|
|
1212
|
+
},
|
|
1213
|
+
protocol: {
|
|
1214
|
+
version,
|
|
1215
|
+
range: [
|
|
1216
|
+
version,
|
|
1217
|
+
version
|
|
1218
|
+
]
|
|
1219
|
+
},
|
|
1220
|
+
capabilities: [
|
|
1221
|
+
...LEGACY_V1_CAPABILITIES
|
|
1222
|
+
],
|
|
1223
|
+
workflows: [
|
|
1224
|
+
...opts.workflows ?? []
|
|
1225
|
+
].sort(),
|
|
1226
|
+
steps: [
|
|
1227
|
+
...opts.steps
|
|
1228
|
+
].sort(),
|
|
1229
|
+
...registrations.length > 0 ? {
|
|
1230
|
+
registrations
|
|
1231
|
+
} : {},
|
|
1232
|
+
...opts.partition ? {
|
|
1233
|
+
partition: opts.partition
|
|
1234
|
+
} : {},
|
|
1235
|
+
...opts.namespace && opts.namespace !== "default" ? {
|
|
1236
|
+
namespace: opts.namespace
|
|
1237
|
+
} : {},
|
|
1238
|
+
startedAt: opts.startedAt
|
|
1239
|
+
};
|
|
1240
|
+
}
|
|
1241
|
+
__name(describeWorker, "describeWorker");
|
|
1242
|
+
|
|
1243
|
+
// src/handshake/announced.ts
|
|
1244
|
+
function announcementsOf(raw) {
|
|
1245
|
+
const d = normalizeDescriptor(raw);
|
|
1246
|
+
const identity = {
|
|
1247
|
+
instanceId: d.instanceId,
|
|
1248
|
+
runtime: d.runtime
|
|
1249
|
+
};
|
|
1250
|
+
const announcements = (d.registrations ?? []).map((reg) => ({
|
|
1251
|
+
...reg,
|
|
1252
|
+
...identity
|
|
1253
|
+
}));
|
|
1254
|
+
const covered = new Set(announcements.map((a) => a.name));
|
|
1255
|
+
for (const name of d.workflows) {
|
|
1256
|
+
if (!covered.has(name)) announcements.push({
|
|
1257
|
+
name,
|
|
1258
|
+
...identity
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
return announcements;
|
|
1262
|
+
}
|
|
1263
|
+
__name(announcementsOf, "announcementsOf");
|
|
1264
|
+
function announcementKey(a) {
|
|
1265
|
+
return a.version === void 0 ? a.name : `${a.name}@${a.version}`;
|
|
1266
|
+
}
|
|
1267
|
+
__name(announcementKey, "announcementKey");
|
|
1268
|
+
function stated(values) {
|
|
1269
|
+
return [
|
|
1270
|
+
...new Set(values.filter((v) => v !== void 0))
|
|
1271
|
+
].sort();
|
|
1272
|
+
}
|
|
1273
|
+
__name(stated, "stated");
|
|
1274
|
+
function aggregateAnnouncements(descriptors) {
|
|
1275
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
1276
|
+
for (const descriptor of descriptors) {
|
|
1277
|
+
for (const announcement of announcementsOf(descriptor)) {
|
|
1278
|
+
const key = announcementKey(announcement);
|
|
1279
|
+
const bucket = byKey.get(key);
|
|
1280
|
+
if (bucket) bucket.push(announcement);
|
|
1281
|
+
else byKey.set(key, [
|
|
1282
|
+
announcement
|
|
1283
|
+
]);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
const out = [];
|
|
1287
|
+
for (const [key, announcements] of byKey) {
|
|
1288
|
+
const groups = stated(announcements.map((a) => a.group));
|
|
1289
|
+
const origins = stated(announcements.map((a) => a.origin));
|
|
1290
|
+
const requiresByJson = /* @__PURE__ */ new Map();
|
|
1291
|
+
for (const a of announcements) {
|
|
1292
|
+
if (a.requires === void 0) continue;
|
|
1293
|
+
const canonical = [
|
|
1294
|
+
...new Set(a.requires)
|
|
1295
|
+
].sort();
|
|
1296
|
+
requiresByJson.set(JSON.stringify(canonical), canonical);
|
|
1297
|
+
}
|
|
1298
|
+
const requires = [
|
|
1299
|
+
...requiresByJson.values()
|
|
1300
|
+
].sort((x, y) => x.join(",").localeCompare(y.join(",")));
|
|
1301
|
+
const disagreements = [];
|
|
1302
|
+
if (groups.length > 1) disagreements.push({
|
|
1303
|
+
axis: "group",
|
|
1304
|
+
values: groups
|
|
1305
|
+
});
|
|
1306
|
+
if (origins.length > 1) disagreements.push({
|
|
1307
|
+
axis: "origin",
|
|
1308
|
+
values: origins
|
|
1309
|
+
});
|
|
1310
|
+
if (requires.length > 1) {
|
|
1311
|
+
disagreements.push({
|
|
1312
|
+
axis: "requires",
|
|
1313
|
+
values: requires.map((r) => r.join(","))
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1316
|
+
const first = announcements[0];
|
|
1317
|
+
if (!first) continue;
|
|
1318
|
+
out.push({
|
|
1319
|
+
evidence: "declared",
|
|
1320
|
+
key,
|
|
1321
|
+
name: first.name,
|
|
1322
|
+
...first.version !== void 0 ? {
|
|
1323
|
+
version: first.version
|
|
1324
|
+
} : {},
|
|
1325
|
+
groups,
|
|
1326
|
+
origins,
|
|
1327
|
+
requires,
|
|
1328
|
+
runtimes: [
|
|
1329
|
+
...new Set(announcements.map((a) => a.runtime))
|
|
1330
|
+
].sort(),
|
|
1331
|
+
instances: [
|
|
1332
|
+
...new Set(announcements.map((a) => a.instanceId))
|
|
1333
|
+
].sort(),
|
|
1334
|
+
disagreements
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
return out.sort((a, b) => a.key.localeCompare(b.key));
|
|
1338
|
+
}
|
|
1339
|
+
__name(aggregateAnnouncements, "aggregateAnnouncements");
|
|
1340
|
+
function observedAnnouncements(heartbeats, covered) {
|
|
1341
|
+
const byToken = /* @__PURE__ */ new Map();
|
|
1342
|
+
for (const beat of heartbeats) {
|
|
1343
|
+
if (!beat.group || covered.has(beat.group)) continue;
|
|
1344
|
+
const instances = byToken.get(beat.group);
|
|
1345
|
+
if (instances) instances.add(beat.instanceId);
|
|
1346
|
+
else byToken.set(beat.group, /* @__PURE__ */ new Set([
|
|
1347
|
+
beat.instanceId
|
|
1348
|
+
]));
|
|
1349
|
+
}
|
|
1350
|
+
return [
|
|
1351
|
+
...byToken.entries()
|
|
1352
|
+
].map(([group, instances]) => ({
|
|
1353
|
+
evidence: "observed",
|
|
1354
|
+
key: group,
|
|
1355
|
+
name: group,
|
|
1356
|
+
groups: [
|
|
1357
|
+
group
|
|
1358
|
+
],
|
|
1359
|
+
origins: [],
|
|
1360
|
+
requires: [],
|
|
1361
|
+
runtimes: [],
|
|
1362
|
+
instances: [
|
|
1363
|
+
...instances
|
|
1364
|
+
].sort(),
|
|
1365
|
+
disagreements: []
|
|
1366
|
+
})).sort((a, b) => a.key.localeCompare(b.key));
|
|
1367
|
+
}
|
|
1368
|
+
__name(observedAnnouncements, "observedAnnouncements");
|
|
1369
|
+
function coveredTokens(announced, descriptors, sanitize) {
|
|
1370
|
+
const tokens = /* @__PURE__ */ new Set();
|
|
1371
|
+
for (const entry of announced) {
|
|
1372
|
+
tokens.add(sanitize(entry.name));
|
|
1373
|
+
for (const group of entry.groups) tokens.add(group);
|
|
1374
|
+
}
|
|
1375
|
+
for (const raw of descriptors) {
|
|
1376
|
+
const d = normalizeDescriptor(raw);
|
|
1377
|
+
for (const step of d.steps) {
|
|
1378
|
+
const token = sanitize(step);
|
|
1379
|
+
tokens.add(token);
|
|
1380
|
+
if (d.partition) tokens.add(`${token}@${d.partition}`);
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
return tokens;
|
|
1384
|
+
}
|
|
1385
|
+
__name(coveredTokens, "coveredTokens");
|
|
1386
|
+
|
|
1387
|
+
// src/handshake/directory.ts
|
|
1388
|
+
var DEFAULT_PARTITION = "default";
|
|
1389
|
+
function partitionOfToken(token) {
|
|
1390
|
+
const at = token.lastIndexOf("@");
|
|
1391
|
+
return at === -1 ? DEFAULT_PARTITION : token.slice(at + 1);
|
|
1392
|
+
}
|
|
1393
|
+
__name(partitionOfToken, "partitionOfToken");
|
|
1394
|
+
function buildWorkflowDirectory(input) {
|
|
1395
|
+
const { descriptors, heartbeats, namespace, supported, sanitize } = input;
|
|
1396
|
+
if (!supported) {
|
|
1397
|
+
return {
|
|
1398
|
+
supported: false,
|
|
1399
|
+
workflows: [],
|
|
1400
|
+
otherPartitions: [],
|
|
1401
|
+
detail: "No transport in this process can read what the fleet advertises, so nothing here was asked and this list is empty for that reason alone. Workers may well be running. A workflow can still be called by name."
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
const mine = namespace === void 0 ? void 0 : namespace;
|
|
1405
|
+
const ownDescriptors = mine === void 0 ? descriptors : descriptors.filter((d) => (d.namespace ?? DEFAULT_PARTITION) === mine);
|
|
1406
|
+
const ownBeats = [];
|
|
1407
|
+
const foreign = /* @__PURE__ */ new Map();
|
|
1408
|
+
for (const beat of heartbeats) {
|
|
1409
|
+
if (!beat.group) continue;
|
|
1410
|
+
const partition = partitionOfToken(beat.group);
|
|
1411
|
+
if (mine === void 0 || partition === mine) {
|
|
1412
|
+
ownBeats.push(beat);
|
|
1413
|
+
continue;
|
|
1414
|
+
}
|
|
1415
|
+
const seen = foreign.get(partition);
|
|
1416
|
+
if (seen) {
|
|
1417
|
+
seen.groups.add(beat.group);
|
|
1418
|
+
seen.instances.add(beat.instanceId);
|
|
1419
|
+
} else {
|
|
1420
|
+
foreign.set(partition, {
|
|
1421
|
+
groups: /* @__PURE__ */ new Set([
|
|
1422
|
+
beat.group
|
|
1423
|
+
]),
|
|
1424
|
+
instances: /* @__PURE__ */ new Set([
|
|
1425
|
+
beat.instanceId
|
|
1426
|
+
])
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
const declared = aggregateAnnouncements(ownDescriptors);
|
|
1431
|
+
const observed = observedAnnouncements(ownBeats, coveredTokens(declared, ownDescriptors, sanitize));
|
|
1432
|
+
const workflows = [
|
|
1433
|
+
...declared,
|
|
1434
|
+
...observed
|
|
1435
|
+
].sort((a, b) => a.key.localeCompare(b.key));
|
|
1436
|
+
const otherPartitions = [
|
|
1437
|
+
...foreign.entries()
|
|
1438
|
+
].map(([partition, seen]) => ({
|
|
1439
|
+
partition,
|
|
1440
|
+
groups: [
|
|
1441
|
+
...seen.groups
|
|
1442
|
+
].sort(),
|
|
1443
|
+
instances: [
|
|
1444
|
+
...seen.instances
|
|
1445
|
+
].sort()
|
|
1446
|
+
})).sort((a, b) => a.partition.localeCompare(b.partition));
|
|
1447
|
+
return {
|
|
1448
|
+
supported: true,
|
|
1449
|
+
workflows,
|
|
1450
|
+
otherPartitions,
|
|
1451
|
+
detail: describeDirectory(workflows, otherPartitions, mine)
|
|
1452
|
+
};
|
|
1453
|
+
}
|
|
1454
|
+
__name(buildWorkflowDirectory, "buildWorkflowDirectory");
|
|
1455
|
+
function summarize(names, limit = 3) {
|
|
1456
|
+
if (names.length <= limit) return names.join(", ");
|
|
1457
|
+
return `${names.slice(0, limit).join(", ")} and ${names.length - limit} more`;
|
|
1458
|
+
}
|
|
1459
|
+
__name(summarize, "summarize");
|
|
1460
|
+
function describeDirectory(workflows, otherPartitions, namespace) {
|
|
1461
|
+
const here = namespace === void 0 ? "this deployment" : `partition "${namespace}"`;
|
|
1462
|
+
const elsewhere = otherPartitions.length === 0 ? "" : ` Live workers were seen on ${otherPartitions.map((p) => `"${p.partition}" (${summarize(p.groups)})`).join(", ")}, which ${here} does not route to \u2014 a worker on the wrong partition looks exactly like no worker at all, so it is named here rather than left out.`;
|
|
1463
|
+
if (workflows.length === 0) {
|
|
1464
|
+
return `The fleet was asked just now and nothing is live in ${here}, so this list is empty because the deployment is empty \u2014 not because the question could not be put.${elsewhere}`;
|
|
1465
|
+
}
|
|
1466
|
+
const observed = workflows.filter((w) => w.evidence === "observed").length;
|
|
1467
|
+
const declaredNote = observed === 0 ? "" : ` ${observed} of them ${observed === 1 ? "is" : "are"} known only from a live queue: the worker serving ${observed === 1 ? "it" : "them"} publishes no description, so ${observed === 1 ? "its" : "their"} version, origin and runtime are genuinely unknown and a version pinned against ${observed === 1 ? "it" : "them"} cannot be checked.`;
|
|
1468
|
+
return `Every workflow a live worker in ${here} can execute, read just now. A worker that stops beating drops off this list within about half a minute.${declaredNote}${elsewhere}`;
|
|
1469
|
+
}
|
|
1470
|
+
__name(describeDirectory, "describeDirectory");
|
|
1169
1471
|
|
|
1170
1472
|
// src/handshake/negotiate.ts
|
|
1171
1473
|
var rangesOverlap = /* @__PURE__ */ __name((a, b) => Math.max(a[0], b[0]) <= Math.min(a[1], b[1]), "rangesOverlap");
|
|
@@ -1693,6 +1995,60 @@ var TransportPool = class {
|
|
|
1693
1995
|
}
|
|
1694
1996
|
return descriptors;
|
|
1695
1997
|
}
|
|
1998
|
+
/**
|
|
1999
|
+
* Every live descriptor in the deployment, merged across every transport that can report them and
|
|
2000
|
+
* de-duplicated by `instanceId` — one worker publishes the same descriptor under each token it
|
|
2001
|
+
* consumes, and it must count once. Returns `[]` when no transport implements
|
|
2002
|
+
* {@link Transport.readAllWorkerDescriptors} (a pure in-process pool advertises nothing).
|
|
2003
|
+
*
|
|
2004
|
+
* First writer wins on a duplicate id: the copies are the same bytes by construction (one process,
|
|
2005
|
+
* one descriptor, published N times), so there is nothing to choose between. Two DIFFERENT
|
|
2006
|
+
* processes sharing an `instanceId` would collapse into one here — that is a misconfiguration the
|
|
2007
|
+
* fleet already suffers from (they also share heartbeat and descriptor keys, so they overwrite each
|
|
2008
|
+
* other's advertisement), not something this read can repair.
|
|
2009
|
+
*/
|
|
2010
|
+
async readAllWorkerDescriptors() {
|
|
2011
|
+
const byInstance = /* @__PURE__ */ new Map();
|
|
2012
|
+
for (const { transport } of this.transports) {
|
|
2013
|
+
if (!transport.readAllWorkerDescriptors) continue;
|
|
2014
|
+
for (const descriptor of await transport.readAllWorkerDescriptors()) {
|
|
2015
|
+
if (!byInstance.has(descriptor.instanceId)) byInstance.set(descriptor.instanceId, descriptor);
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
return [
|
|
2019
|
+
...byInstance.values()
|
|
2020
|
+
];
|
|
2021
|
+
}
|
|
2022
|
+
/**
|
|
2023
|
+
* Every live worker heartbeat in the deployment, merged across every transport that can report
|
|
2024
|
+
* them and de-duplicated by `(group, instanceId)` — the same worker is one beat per token, and two
|
|
2025
|
+
* transports scanning the same keyspace must not double-count it.
|
|
2026
|
+
*
|
|
2027
|
+
* Returns `[]` when no transport implements {@link Transport.readAllWorkerHeartbeats}, which is
|
|
2028
|
+
* indistinguishable from "nothing is beating" on its own — {@link introspectsFleet} is what tells
|
|
2029
|
+
* those apart, and the directory reads it rather than guessing from an empty array.
|
|
2030
|
+
*/
|
|
2031
|
+
async readAllWorkerHeartbeats() {
|
|
2032
|
+
const seen = /* @__PURE__ */ new Map();
|
|
2033
|
+
for (const { transport } of this.transports) {
|
|
2034
|
+
if (!transport.readAllWorkerHeartbeats) continue;
|
|
2035
|
+
for (const beat of await transport.readAllWorkerHeartbeats()) {
|
|
2036
|
+
const key = `${beat.group}\0${beat.instanceId}`;
|
|
2037
|
+
if (!seen.has(key)) seen.set(key, beat);
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
return [
|
|
2041
|
+
...seen.values()
|
|
2042
|
+
];
|
|
2043
|
+
}
|
|
2044
|
+
/**
|
|
2045
|
+
* Can ANY transport here introspect the fleet — descriptors or heartbeats? This is the difference
|
|
2046
|
+
* between "the fleet is empty" and "nobody asked", and it is a property of the POOL rather than of
|
|
2047
|
+
* a read's result, so it stays answerable when both reads legitimately come back empty.
|
|
2048
|
+
*/
|
|
2049
|
+
get introspectsFleet() {
|
|
2050
|
+
return this.transports.some(({ transport }) => transport.readAllWorkerDescriptors || transport.readAllWorkerHeartbeats);
|
|
2051
|
+
}
|
|
1696
2052
|
/** Distinct worker groups with a live heartbeat, merged across every transport that can report it. */
|
|
1697
2053
|
async listWorkerGroups() {
|
|
1698
2054
|
const groups = /* @__PURE__ */ new Set();
|
|
@@ -2093,7 +2449,7 @@ function createWorkflowCtx(host, runId, compensations, workflow = "", searchAttr
|
|
|
2093
2449
|
return unwrapCompletion(await waitForSignal(`task:${runId}:${name}`), `task "${name}"`);
|
|
2094
2450
|
}, "task");
|
|
2095
2451
|
const child = /* @__PURE__ */ __name(async (workflow2, input, options) => {
|
|
2096
|
-
const { childId, priority } = normalizeChildOptions(options);
|
|
2452
|
+
const { childId, priority, version } = normalizeChildOptions(options);
|
|
2097
2453
|
const current = pos.next();
|
|
2098
2454
|
const id = childId ?? `${runId}.child.${current}`;
|
|
2099
2455
|
const existing = await readCheckpoint(current);
|
|
@@ -2121,7 +2477,7 @@ function createWorkflowCtx(host, runId, compensations, workflow = "", searchAttr
|
|
|
2121
2477
|
}));
|
|
2122
2478
|
return unwrapCompletion(buffered.payload, `child "${id}"`);
|
|
2123
2479
|
}
|
|
2124
|
-
if (!await store.getRun(id)) host.startChild(workflowName(workflow2), input, id, priority);
|
|
2480
|
+
if (!await store.getRun(id)) host.startChild(workflowName(workflow2), input, id, priority, version);
|
|
2125
2481
|
if (!existing) {
|
|
2126
2482
|
await writeCheckpoint(instantCheckpoint({
|
|
2127
2483
|
runId,
|
|
@@ -2204,12 +2560,12 @@ function createWorkflowCtx(host, runId, compensations, workflow = "", searchAttr
|
|
|
2204
2560
|
return outputs;
|
|
2205
2561
|
}, "all");
|
|
2206
2562
|
const startChild = /* @__PURE__ */ __name(async (workflow2, input, options) => {
|
|
2207
|
-
const { childId, priority } = normalizeChildOptions(options);
|
|
2563
|
+
const { childId, priority, version } = normalizeChildOptions(options);
|
|
2208
2564
|
const current = pos.next();
|
|
2209
2565
|
const id = childId ?? `${runId}.child.${current}`;
|
|
2210
2566
|
const existing = await readCheckpoint(current);
|
|
2211
2567
|
if (existing && existing.status === "completed") return existing.output;
|
|
2212
|
-
if (!await store.getRun(id)) host.startChild(workflowName(workflow2), input, id, priority);
|
|
2568
|
+
if (!await store.getRun(id)) host.startChild(workflowName(workflow2), input, id, priority, version);
|
|
2213
2569
|
await writeCheckpoint(instantCheckpoint({
|
|
2214
2570
|
runId,
|
|
2215
2571
|
seq: current,
|
|
@@ -2457,6 +2813,7 @@ function mergeTags(staticTags, runTags) {
|
|
|
2457
2813
|
__name(mergeTags, "mergeTags");
|
|
2458
2814
|
var BREAKPOINT = "breakpoint";
|
|
2459
2815
|
var isBreakpoint = /* @__PURE__ */ __name((cp) => cp.status === "pending" && cp.name.startsWith(BREAKPOINT), "isBreakpoint");
|
|
2816
|
+
var VERSION_UNDECLARED_TAG = "version:undeclared";
|
|
2460
2817
|
var versionKey = /* @__PURE__ */ __name((name, version) => `${name}@${version}`, "versionKey");
|
|
2461
2818
|
function stepGroup(step, runNamespace) {
|
|
2462
2819
|
return tenantGroup(sanitizeQueueToken(step.name), step.partition ?? runNamespace);
|
|
@@ -2769,6 +3126,15 @@ var WorkflowEngine = class {
|
|
|
2769
3126
|
const reg = this.workflows.get(versionKey(name, version));
|
|
2770
3127
|
return reg?.hasBody ? reg.fn : void 0;
|
|
2771
3128
|
}
|
|
3129
|
+
/** The registered versions of `name`, for the pinned-start error — "2 is not registered" is a
|
|
3130
|
+
* guess-the-typo error without them, and the answer (which versions this deploy actually carries)
|
|
3131
|
+
* is right here. `none` when the name is unknown entirely. */
|
|
3132
|
+
registeredVersions(name) {
|
|
3133
|
+
const versions = [
|
|
3134
|
+
...this.workflows.values()
|
|
3135
|
+
].filter((w) => w.name === name).map((w) => w.version);
|
|
3136
|
+
return versions.length ? versions.join(", ") : "none";
|
|
3137
|
+
}
|
|
2772
3138
|
/**
|
|
2773
3139
|
* Register a workflow whose body runs in another SDK (e.g. Python). The engine owns the run exactly
|
|
2774
3140
|
* as for a TS workflow — it persists checkpoints, recovers, runs timers — but advances it by handing
|
|
@@ -2918,12 +3284,13 @@ var WorkflowEngine = class {
|
|
|
2918
3284
|
}
|
|
2919
3285
|
async start(workflow, input, runId, opts) {
|
|
2920
3286
|
const name = workflowName(workflow);
|
|
2921
|
-
|
|
2922
|
-
|
|
3287
|
+
const pinned = opts?.version;
|
|
3288
|
+
let registered = pinned === void 0 ? this.latest.get(name) : this.workflows.get(versionKey(name, pinned));
|
|
3289
|
+
if (!registered && pinned === void 0) {
|
|
2923
3290
|
const ancestor = await this.findRemoteAncestor(runId);
|
|
2924
3291
|
if (ancestor) registered = this.synthesizeRemoteChild(name, ancestor.version, ancestor);
|
|
2925
3292
|
}
|
|
2926
|
-
if (!registered) {
|
|
3293
|
+
if (!registered && pinned === void 0) {
|
|
2927
3294
|
const conventionRun = {
|
|
2928
3295
|
id: runId,
|
|
2929
3296
|
workflow: name,
|
|
@@ -2938,9 +3305,13 @@ var WorkflowEngine = class {
|
|
|
2938
3305
|
createdAt: /* @__PURE__ */ new Date(),
|
|
2939
3306
|
updatedAt: /* @__PURE__ */ new Date()
|
|
2940
3307
|
};
|
|
2941
|
-
registered = await this.resolveRemoteByConvention(conventionRun
|
|
3308
|
+
registered = await this.resolveRemoteByConvention(conventionRun, {
|
|
3309
|
+
askFleetForVersion: true
|
|
3310
|
+
});
|
|
3311
|
+
}
|
|
3312
|
+
if (!registered) {
|
|
3313
|
+
throw new Error(pinned === void 0 ? `workflow ${name} is not registered` : `workflow ${versionKey(name, pinned)} is not registered \u2014 a pinned start never falls back to the newest version (registered: ${this.registeredVersions(name)})`);
|
|
2942
3314
|
}
|
|
2943
|
-
if (!registered) throw new Error(`workflow ${name} is not registered`);
|
|
2944
3315
|
await registered.validateInput?.(input);
|
|
2945
3316
|
const prior = await this.store.getRun(runId);
|
|
2946
3317
|
if (prior) {
|
|
@@ -2952,10 +3323,16 @@ var WorkflowEngine = class {
|
|
|
2952
3323
|
};
|
|
2953
3324
|
}
|
|
2954
3325
|
const now = /* @__PURE__ */ new Date();
|
|
2955
|
-
const
|
|
3326
|
+
const stampedTags = [
|
|
2956
3327
|
...opts?.tags ?? [],
|
|
2957
|
-
|
|
2958
|
-
|
|
3328
|
+
...registered.singleton ? [
|
|
3329
|
+
this.singletons.tag(registered.singleton, input)
|
|
3330
|
+
] : [],
|
|
3331
|
+
...registered.versionDeclared === false ? [
|
|
3332
|
+
VERSION_UNDECLARED_TAG
|
|
3333
|
+
] : []
|
|
3334
|
+
];
|
|
3335
|
+
const tags = mergeTags(registered.tags, stampedTags);
|
|
2959
3336
|
if (registered.singleton) {
|
|
2960
3337
|
await this.singletons.assertCapacity(name, registered.singleton, input);
|
|
2961
3338
|
}
|
|
@@ -3065,14 +3442,15 @@ var WorkflowEngine = class {
|
|
|
3065
3442
|
* Recomputed per call (never memoized into `this.workflows`) so it stays correct if group
|
|
3066
3443
|
* liveness changes between calls, exactly as {@link synthesizeRemoteChild} does.
|
|
3067
3444
|
*/
|
|
3068
|
-
async resolveRemoteByConvention(run) {
|
|
3445
|
+
async resolveRemoteByConvention(run, opts = {}) {
|
|
3069
3446
|
const group = tenantGroup(sanitizeQueueToken(run.workflow), run.namespace);
|
|
3070
3447
|
const liveTransport = await this.pool.transportWithLiveGroup(group);
|
|
3071
3448
|
if (!liveTransport) return void 0;
|
|
3072
3449
|
const executor = new RemoteWorkflowExecutor(liveTransport, run.workflow, run.namespace);
|
|
3450
|
+
const declared = opts.askFleetForVersion ? await this.declaredVersion(liveTransport, group, run.workflow) : void 0;
|
|
3073
3451
|
return {
|
|
3074
3452
|
name: run.workflow,
|
|
3075
|
-
version: run.workflowVersion,
|
|
3453
|
+
version: declared ?? run.workflowVersion,
|
|
3076
3454
|
fn: /* @__PURE__ */ __name(() => {
|
|
3077
3455
|
throw new Error(`remote workflow ${run.workflow} has no local body`);
|
|
3078
3456
|
}, "fn"),
|
|
@@ -3080,10 +3458,46 @@ var WorkflowEngine = class {
|
|
|
3080
3458
|
remote: {
|
|
3081
3459
|
group,
|
|
3082
3460
|
executor
|
|
3083
|
-
}
|
|
3461
|
+
},
|
|
3462
|
+
...opts.askFleetForVersion ? {
|
|
3463
|
+
versionDeclared: declared !== void 0
|
|
3464
|
+
} : {}
|
|
3084
3465
|
};
|
|
3085
3466
|
}
|
|
3086
3467
|
/**
|
|
3468
|
+
* The version the LIVE fleet declares for `workflow` on `group`, or `undefined` when it declares
|
|
3469
|
+
* none — which is a fact about the fleet, not a failure to read it.
|
|
3470
|
+
*
|
|
3471
|
+
* The read is the descriptor advertisement, scoped to the one group being resolved: the workers on
|
|
3472
|
+
* that queue, their `registrations`, the entry whose `name` matches. That is where a version can
|
|
3473
|
+
* come from at all — a heartbeat has no room for one, so a worker on an SDK too old to publish a
|
|
3474
|
+
* descriptor declares nothing and the caller is told so rather than handed a default.
|
|
3475
|
+
*
|
|
3476
|
+
* `undefined` when the announcers DISAGREE, and deliberately: two live workers claiming different
|
|
3477
|
+
* versions of one name is a deployment in the middle of something, and picking either would stamp
|
|
3478
|
+
* a run with a version half the fleet does not serve. Undeclared is the honest reading of a
|
|
3479
|
+
* contradiction, and it is the reading that refuses to let a pin pass on a coin flip.
|
|
3480
|
+
*/
|
|
3481
|
+
async declaredVersion(transport, group, workflow) {
|
|
3482
|
+
if (!transport.readWorkerDescriptors) return void 0;
|
|
3483
|
+
let descriptors;
|
|
3484
|
+
try {
|
|
3485
|
+
descriptors = await transport.readWorkerDescriptors(group);
|
|
3486
|
+
} catch {
|
|
3487
|
+
return void 0;
|
|
3488
|
+
}
|
|
3489
|
+
const versions = /* @__PURE__ */ new Set();
|
|
3490
|
+
for (const announced of aggregateAnnouncements(descriptors)) {
|
|
3491
|
+
if (announced.name === workflow && announced.version !== void 0) {
|
|
3492
|
+
versions.add(announced.version);
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
const only = [
|
|
3496
|
+
...versions
|
|
3497
|
+
];
|
|
3498
|
+
return only.length === 1 ? only[0] : void 0;
|
|
3499
|
+
}
|
|
3500
|
+
/**
|
|
3087
3501
|
* Walk the parent chain of `childRunId` to the nearest ancestor registered as REMOTE, returning its
|
|
3088
3502
|
* registration (or `undefined` if there is none). The parent of an awaited child is found via its
|
|
3089
3503
|
* live `child:<childId>` signal waiter — present for as long as the parent is suspended awaiting the
|
|
@@ -3147,7 +3561,32 @@ var WorkflowEngine = class {
|
|
|
3147
3561
|
/**
|
|
3148
3562
|
* Cancel in-flight runs that have outlived their workflow's `executionTimeout`. Call it from the
|
|
3149
3563
|
* timer poller alongside {@link resumeDueTimers}. A timed-out run is moved to `cancelled` with an
|
|
3150
|
-
* `execution_timeout` error (terminal, so a late step result can't resurrect it)
|
|
3564
|
+
* `execution_timeout` error (terminal, so a late step result can't resurrect it), AND its children
|
|
3565
|
+
* are cascaded exactly as an explicit {@link cancel} cascades them.
|
|
3566
|
+
*
|
|
3567
|
+
* WHY THE TERMINAL WRITE IS DIRECT, not a call to {@link cancel}. Two reasons, both still standing:
|
|
3568
|
+
* the run must land with the `execution_timeout` error `cancel` knows nothing about (`cancel` writes
|
|
3569
|
+
* a plain `cancelled`, and the code is what a dashboard/alert distinguishes a timeout by), and this
|
|
3570
|
+
* is a SCAN — it walks every in-flight run of every timed workflow on every poller tick, so it must
|
|
3571
|
+
* not pay `cancel`'s per-run re-read and singleton/control-plane work on runs it isn't cancelling.
|
|
3572
|
+
* The cascade below is charged only to the runs that ACTUALLY timed out, which are rare by
|
|
3573
|
+
* construction; the scan itself is unchanged.
|
|
3574
|
+
*
|
|
3575
|
+
* The subtree, though, has no reason to differ, and before this it did: a timed-out parent's
|
|
3576
|
+
* children kept running with the parent gone and nothing pointing at them — a silent orphan you
|
|
3577
|
+
* could only find by reading the runs table by hand. {@link cancelChildren} is the SAME recursive
|
|
3578
|
+
* walk `cancel` uses, so children of children go too, and it inherits that path's two guards:
|
|
3579
|
+
* `cancel` returns early on a run that is already `completed`/`cancelled`/`dead` (a child that beat
|
|
3580
|
+
* the sweep to the finish is never clobbered, and a re-cancel is a no-op), and it writes the
|
|
3581
|
+
* parent's terminal status BEFORE recursing, so a cyclic parent→child graph terminates on the
|
|
3582
|
+
* second visit instead of looping. Two pollers sweeping the same run concurrently therefore write
|
|
3583
|
+
* the same terminal state twice and cascade into already-cancelled children — idempotent, not
|
|
3584
|
+
* corrupting. The one window it does NOT close is the pre-existing check-then-write race an
|
|
3585
|
+
* explicit `cancel` has always had (a child that completes between `cancel`'s read and its write);
|
|
3586
|
+
* closing that needs a compare-and-set in the store contract, not a change here.
|
|
3587
|
+
*
|
|
3588
|
+
* Cascade failures are swallowed per subtree for the same reason `cancelChildren` swallows them per
|
|
3589
|
+
* child: one unreachable child must not abort the sweep and leave every LATER timed-out run alive.
|
|
3151
3590
|
*/
|
|
3152
3591
|
async sweepTimeouts(now = this.clock()) {
|
|
3153
3592
|
for (const reg of new Set(this.latest.values())) {
|
|
@@ -3183,6 +3622,7 @@ var WorkflowEngine = class {
|
|
|
3183
3622
|
namespace: run.namespace,
|
|
3184
3623
|
error: error2
|
|
3185
3624
|
});
|
|
3625
|
+
await this.cancelChildren(run.id).catch(() => void 0);
|
|
3186
3626
|
}
|
|
3187
3627
|
}
|
|
3188
3628
|
}
|
|
@@ -3911,6 +4351,10 @@ var WorkflowEngine = class {
|
|
|
3911
4351
|
* `child:<id>` waiter) and fire-and-forget (`ctx.startChild`, found via its `spawn:<id>`
|
|
3912
4352
|
* checkpoint). Recursive, so a whole subtree is cancelled; the terminal guard in `cancel` stops it
|
|
3913
4353
|
* at finished / already-cancelled runs (no loops, no re-cancel).
|
|
4354
|
+
*
|
|
4355
|
+
* Two callers, deliberately the same walk: an explicit {@link cancel}, and {@link sweepTimeouts}
|
|
4356
|
+
* when a parent hits its `executionTimeout` — a timed-out parent's subtree dies the same way an
|
|
4357
|
+
* explicitly cancelled one's does, or the children are orphans nobody is holding a reference to.
|
|
3914
4358
|
*/
|
|
3915
4359
|
async cancelChildren(parentRunId, opts) {
|
|
3916
4360
|
for (const id of await this.getRunChildren(parentRunId)) {
|
|
@@ -3990,6 +4434,50 @@ var WorkflowEngine = class {
|
|
|
3990
4434
|
return out;
|
|
3991
4435
|
}
|
|
3992
4436
|
/**
|
|
4437
|
+
* What workflows the LIVE fleet announces it can execute — the deployment-wide registry a picker
|
|
4438
|
+
* ("call this existing workflow") needs, and the one question this engine's own registry cannot
|
|
4439
|
+
* answer. {@link workflowBody} answers only for this process, and a missing body is ambiguous: it
|
|
4440
|
+
* means "not registered here", but equally "registered via {@link registerRemote} against another
|
|
4441
|
+
* SDK" or "a group resolved by convention against a worker". An inferred answer would therefore
|
|
4442
|
+
* differ per replica. This one does not: every pod folds the same published announcements.
|
|
4443
|
+
*
|
|
4444
|
+
* Scoped like every other poll surface — an engine WITH a `namespace` sees only workers in it, and
|
|
4445
|
+
* an operator (namespace unset) sees the whole deployment ("ver tudo = ausência de namespace"). A
|
|
4446
|
+
* descriptor that states no namespace is `default`, matching how a single-tenant fleet publishes.
|
|
4447
|
+
*
|
|
4448
|
+
* Cost: one advertisement scan per CALL, on demand. Nothing is added to the poll loop and nothing
|
|
4449
|
+
* is retained — no pod holds a table of the fleet's registrations. Empty when no transport can
|
|
4450
|
+
* introspect the advertisement keyspace (a pure in-process transport advertises nothing).
|
|
4451
|
+
*
|
|
4452
|
+
* Workflows only, and deliberately: see the "steps are out of scope" note in `handshake/announced`.
|
|
4453
|
+
*/
|
|
4454
|
+
async announcedWorkflows() {
|
|
4455
|
+
return (await this.workflowDirectory()).workflows;
|
|
4456
|
+
}
|
|
4457
|
+
/**
|
|
4458
|
+
* {@link announcedWorkflows}, plus the thing a list of workflows can never say: why it is the
|
|
4459
|
+
* length it is. See {@link WorkflowDirectory} for the three states an empty array used to collapse
|
|
4460
|
+
* into one — "nobody asked", "nothing is live", and the partition mismatch that reads exactly like
|
|
4461
|
+
* the second from the caller's side.
|
|
4462
|
+
*
|
|
4463
|
+
* Two live reads, both on demand and neither retained: the descriptor advertisement (what workers
|
|
4464
|
+
* SAY they serve) and the heartbeat keyspace (what is demonstrably consuming a queue right now).
|
|
4465
|
+
* The second is why a worker on an SDK too old to publish a descriptor appears here at all — it
|
|
4466
|
+
* beats and never describes itself, and reading only descriptors reported such a fleet as empty
|
|
4467
|
+
* while `resolveRemoteByConvention`, a few lines away in this same class, was routing calls to it
|
|
4468
|
+
* off those very keys. Two answers out of one Redis, disagreeing. Now they agree, and the entry
|
|
4469
|
+
* says which of the two kinds of evidence it rests on rather than flattening them together.
|
|
4470
|
+
*/
|
|
4471
|
+
async workflowDirectory() {
|
|
4472
|
+
return buildWorkflowDirectory({
|
|
4473
|
+
descriptors: await this.pool.readAllWorkerDescriptors(),
|
|
4474
|
+
heartbeats: await this.pool.readAllWorkerHeartbeats(),
|
|
4475
|
+
namespace: this.namespace,
|
|
4476
|
+
supported: this.pool.introspectsFleet,
|
|
4477
|
+
sanitize: sanitizeQueueToken
|
|
4478
|
+
});
|
|
4479
|
+
}
|
|
4480
|
+
/**
|
|
3993
4481
|
* The routing groups of every in-flight run's still-`pending` remote step — the queues where work is
|
|
3994
4482
|
* dispatched and awaiting a worker. Folded into {@link workerHealth} so a step waiting on a group
|
|
3995
4483
|
* that is NEITHER a registration NOR heartbeating (the exact shape of a run stuck on an offline
|
|
@@ -5068,10 +5556,13 @@ var WorkflowEngine = class {
|
|
|
5068
5556
|
// namespace) is the one executing the parent. Otherwise an operator recovery-resuming a
|
|
5069
5557
|
// `davi-local` pipeline would stamp its `processing` child `default` and it would leak off the
|
|
5070
5558
|
// tenant's worker pool onto the shared/dev workers.
|
|
5071
|
-
startChild: /* @__PURE__ */ __name((workflow, input, id, priority) => {
|
|
5559
|
+
startChild: /* @__PURE__ */ __name((workflow, input, id, priority, version) => {
|
|
5072
5560
|
this.startChildDeferred(workflow, input, id, {
|
|
5073
5561
|
priority,
|
|
5074
|
-
namespace: parentNamespace
|
|
5562
|
+
namespace: parentNamespace,
|
|
5563
|
+
// Absent unless the body pinned one (`ctx.child(ref, input, { version })`) — an omitted
|
|
5564
|
+
// pin must stay omitted, so the child keeps resolving `latest` exactly as before.
|
|
5565
|
+
version
|
|
5075
5566
|
});
|
|
5076
5567
|
}, "startChild"),
|
|
5077
5568
|
// Deferred for the same reentrancy reason as `startChild` above. `cancel()` is already
|
|
@@ -6446,6 +6937,7 @@ var InMemoryTransport = class {
|
|
|
6446
6937
|
CURRENT_PROTOCOL_VERSION,
|
|
6447
6938
|
CodecStateStore,
|
|
6448
6939
|
ContinueAsNew,
|
|
6940
|
+
DEFAULT_PARTITION,
|
|
6449
6941
|
DURABLE_OPTIONS,
|
|
6450
6942
|
DURABLE_OPTIONS_CANONICAL,
|
|
6451
6943
|
DURABLE_STEP_CONFIG,
|
|
@@ -6476,25 +6968,31 @@ var InMemoryTransport = class {
|
|
|
6476
6968
|
TERMINAL_RUN_STATUSES,
|
|
6477
6969
|
TRANSPORT,
|
|
6478
6970
|
TRANSPORT_CANONICAL,
|
|
6971
|
+
VERSION_UNDECLARED_TAG,
|
|
6479
6972
|
WORKFLOW_NAME_KEY,
|
|
6480
6973
|
WorkflowBlocked,
|
|
6481
6974
|
WorkflowEngine,
|
|
6482
6975
|
WorkflowSuspended,
|
|
6976
|
+
aggregateAnnouncements,
|
|
6977
|
+
announcementsOf,
|
|
6483
6978
|
applyAttributeQuery,
|
|
6484
6979
|
attributeColumnFor,
|
|
6485
6980
|
attributeOperand,
|
|
6486
6981
|
bindWorkflowClass,
|
|
6487
6982
|
breakpointToken,
|
|
6983
|
+
buildWorkflowDirectory,
|
|
6488
6984
|
canRoute,
|
|
6489
6985
|
capableWorkers,
|
|
6490
6986
|
classifyWaiterToken,
|
|
6491
6987
|
clearDurableExecutionWrappers,
|
|
6492
6988
|
collectMetrics,
|
|
6493
6989
|
controlPlaneDescriptor,
|
|
6990
|
+
coveredTokens,
|
|
6494
6991
|
createStepLogger,
|
|
6495
6992
|
currentStep,
|
|
6496
6993
|
currentWorkflowCtx,
|
|
6497
6994
|
debug,
|
|
6995
|
+
describeWorker,
|
|
6498
6996
|
descriptorHash,
|
|
6499
6997
|
error,
|
|
6500
6998
|
eventMatchOf,
|
|
@@ -6515,7 +7013,9 @@ var InMemoryTransport = class {
|
|
|
6515
7013
|
negotiate,
|
|
6516
7014
|
normalizeAttributeRows,
|
|
6517
7015
|
normalizeDescriptor,
|
|
7016
|
+
observedAnnouncements,
|
|
6518
7017
|
parseDuration,
|
|
7018
|
+
partitionOfToken,
|
|
6519
7019
|
planDispatch,
|
|
6520
7020
|
prevCronFireMs,
|
|
6521
7021
|
readSearchAttributes,
|