@rivetkit/workflow-engine 0.0.0-main.72cbc7c → 0.0.0-main.78336a1
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/schemas/v1.ts +25 -0
- package/dist/tsup/{chunk-SFJQFMCW.cjs → chunk-32422MOM.cjs} +221 -93
- package/dist/tsup/chunk-32422MOM.cjs.map +1 -0
- package/dist/tsup/{chunk-CIDHCIH7.js → chunk-TVRZA5O5.js} +221 -93
- package/dist/tsup/chunk-TVRZA5O5.js.map +1 -0
- package/dist/tsup/index.cjs +2 -2
- package/dist/tsup/index.cjs.map +1 -1
- package/dist/tsup/index.d.cts +50 -13
- package/dist/tsup/index.d.ts +50 -13
- package/dist/tsup/index.js +1 -1
- package/dist/tsup/testing.cjs +29 -23
- package/dist/tsup/testing.cjs.map +1 -1
- package/dist/tsup/testing.d.cts +1 -0
- package/dist/tsup/testing.d.ts +1 -0
- package/dist/tsup/testing.js +7 -1
- package/dist/tsup/testing.js.map +1 -1
- package/package.json +6 -1
- package/schemas/serde.ts +17 -3
- package/schemas/v1.bare +10 -1
- package/schemas/versioned.ts +1 -0
- package/src/context.ts +140 -49
- package/src/driver.ts +12 -0
- package/src/index.ts +41 -21
- package/src/location.ts +1 -1
- package/src/storage.ts +50 -16
- package/src/testing.ts +7 -0
- package/src/types.ts +20 -3
- package/dist/tsup/chunk-CIDHCIH7.js.map +0 -1
- package/dist/tsup/chunk-SFJQFMCW.cjs.map +0 -1
|
@@ -670,6 +670,16 @@ function writeRemovedEntry(bc, x) {
|
|
|
670
670
|
bare.writeString(bc, x.originalType);
|
|
671
671
|
write1(bc, x.originalName);
|
|
672
672
|
}
|
|
673
|
+
function readVersionCheckEntry(bc) {
|
|
674
|
+
return {
|
|
675
|
+
resolved: bare.readU32(bc),
|
|
676
|
+
latest: bare.readU32(bc)
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
function writeVersionCheckEntry(bc, x) {
|
|
680
|
+
bare.writeU32(bc, x.resolved);
|
|
681
|
+
bare.writeU32(bc, x.latest);
|
|
682
|
+
}
|
|
673
683
|
function readEntryKind(bc) {
|
|
674
684
|
const offset = bc.offset;
|
|
675
685
|
const tag = bare.readU8(bc);
|
|
@@ -690,6 +700,8 @@ function readEntryKind(bc) {
|
|
|
690
700
|
return { tag: "RaceEntry", val: readRaceEntry(bc) };
|
|
691
701
|
case 7:
|
|
692
702
|
return { tag: "RemovedEntry", val: readRemovedEntry(bc) };
|
|
703
|
+
case 8:
|
|
704
|
+
return { tag: "VersionCheckEntry", val: readVersionCheckEntry(bc) };
|
|
693
705
|
default: {
|
|
694
706
|
bc.offset = offset;
|
|
695
707
|
throw new bare.BareError(offset, "invalid tag");
|
|
@@ -738,6 +750,11 @@ function writeEntryKind(bc, x) {
|
|
|
738
750
|
writeRemovedEntry(bc, x.val);
|
|
739
751
|
break;
|
|
740
752
|
}
|
|
753
|
+
case "VersionCheckEntry": {
|
|
754
|
+
bare.writeU8(bc, 8);
|
|
755
|
+
writeVersionCheckEntry(bc, x.val);
|
|
756
|
+
break;
|
|
757
|
+
}
|
|
741
758
|
}
|
|
742
759
|
}
|
|
743
760
|
function readEntry(bc) {
|
|
@@ -1182,6 +1199,14 @@ function entryKindToBare(kind) {
|
|
|
1182
1199
|
originalName: kind.data.originalName ?? null
|
|
1183
1200
|
}
|
|
1184
1201
|
};
|
|
1202
|
+
case "version_check":
|
|
1203
|
+
return {
|
|
1204
|
+
tag: "VersionCheckEntry",
|
|
1205
|
+
val: {
|
|
1206
|
+
resolved: kind.data.resolved,
|
|
1207
|
+
latest: kind.data.latest
|
|
1208
|
+
}
|
|
1209
|
+
};
|
|
1185
1210
|
}
|
|
1186
1211
|
}
|
|
1187
1212
|
function entryKindFromBare(kind) {
|
|
@@ -1263,6 +1288,14 @@ function entryKindFromBare(kind) {
|
|
|
1263
1288
|
originalName: kind.val.originalName ?? void 0
|
|
1264
1289
|
}
|
|
1265
1290
|
};
|
|
1291
|
+
case "VersionCheckEntry":
|
|
1292
|
+
return {
|
|
1293
|
+
type: "version_check",
|
|
1294
|
+
data: {
|
|
1295
|
+
resolved: kind.val.resolved,
|
|
1296
|
+
latest: kind.val.latest
|
|
1297
|
+
}
|
|
1298
|
+
};
|
|
1266
1299
|
default:
|
|
1267
1300
|
throw new Error(
|
|
1268
1301
|
`Unknown entry kind: ${kind.tag}`
|
|
@@ -1404,6 +1437,7 @@ function deserializeName(bytes) {
|
|
|
1404
1437
|
// src/storage.ts
|
|
1405
1438
|
var MAX_KV_BATCH_ENTRIES = 128;
|
|
1406
1439
|
var MAX_KV_BATCH_PAYLOAD_BYTES = 976 * 1024;
|
|
1440
|
+
var MAX_CONCURRENT_DELETES = 64;
|
|
1407
1441
|
function createStorage() {
|
|
1408
1442
|
return {
|
|
1409
1443
|
nameRegistry: [],
|
|
@@ -1574,23 +1608,17 @@ async function flush(storage, driver, onHistoryUpdated, pendingDeletions) {
|
|
|
1574
1608
|
});
|
|
1575
1609
|
}
|
|
1576
1610
|
if (writes.length > 0) {
|
|
1577
|
-
|
|
1578
|
-
await driver.batch(
|
|
1611
|
+
if (driver.atomicBatch) {
|
|
1612
|
+
await driver.batch(writes);
|
|
1613
|
+
} else {
|
|
1614
|
+
for (const chunk of splitBatchWrites(writes)) {
|
|
1615
|
+
await driver.batch(chunk);
|
|
1616
|
+
}
|
|
1579
1617
|
}
|
|
1580
1618
|
}
|
|
1581
1619
|
if (pendingDeletions) {
|
|
1582
|
-
const
|
|
1583
|
-
|
|
1584
|
-
deleteOps.push(driver.deletePrefix(prefix));
|
|
1585
|
-
}
|
|
1586
|
-
for (const range of pendingDeletions.ranges) {
|
|
1587
|
-
deleteOps.push(driver.deleteRange(range.start, range.end));
|
|
1588
|
-
}
|
|
1589
|
-
for (const key of pendingDeletions.keys) {
|
|
1590
|
-
deleteOps.push(driver.delete(key));
|
|
1591
|
-
}
|
|
1592
|
-
if (deleteOps.length > 0) {
|
|
1593
|
-
await Promise.all(deleteOps);
|
|
1620
|
+
const didChange = await runDeletes(driver, pendingDeletions);
|
|
1621
|
+
if (didChange) {
|
|
1594
1622
|
historyUpdated = true;
|
|
1595
1623
|
}
|
|
1596
1624
|
}
|
|
@@ -1632,10 +1660,36 @@ function splitBatchWrites(writes) {
|
|
|
1632
1660
|
}
|
|
1633
1661
|
return chunks;
|
|
1634
1662
|
}
|
|
1663
|
+
function splitBatchDeletes(keys) {
|
|
1664
|
+
const chunks = [];
|
|
1665
|
+
for (let i = 0; i < keys.length; i += MAX_KV_BATCH_ENTRIES) {
|
|
1666
|
+
chunks.push(keys.slice(i, i + MAX_KV_BATCH_ENTRIES));
|
|
1667
|
+
}
|
|
1668
|
+
return chunks;
|
|
1669
|
+
}
|
|
1670
|
+
async function runDeletes(driver, deletions) {
|
|
1671
|
+
const ops = [
|
|
1672
|
+
...deletions.prefixes.map((prefix) => () => driver.deletePrefix(prefix)),
|
|
1673
|
+
...deletions.ranges.map(
|
|
1674
|
+
(range) => () => driver.deleteRange(range.start, range.end)
|
|
1675
|
+
),
|
|
1676
|
+
...splitBatchDeletes(deletions.keys).map(
|
|
1677
|
+
(chunk) => () => driver.batchDelete(chunk)
|
|
1678
|
+
)
|
|
1679
|
+
];
|
|
1680
|
+
if (ops.length === 0) {
|
|
1681
|
+
return false;
|
|
1682
|
+
}
|
|
1683
|
+
for (let i = 0; i < ops.length; i += MAX_CONCURRENT_DELETES) {
|
|
1684
|
+
await Promise.all(
|
|
1685
|
+
ops.slice(i, i + MAX_CONCURRENT_DELETES).map((op) => op())
|
|
1686
|
+
);
|
|
1687
|
+
}
|
|
1688
|
+
return true;
|
|
1689
|
+
}
|
|
1635
1690
|
async function deleteEntriesWithPrefix(storage, driver, prefixLocation, onHistoryUpdated) {
|
|
1636
1691
|
const deletions = collectDeletionsForPrefix(storage, prefixLocation);
|
|
1637
|
-
await driver
|
|
1638
|
-
await Promise.all(deletions.keys.map((key) => driver.delete(key)));
|
|
1692
|
+
await runDeletes(driver, deletions);
|
|
1639
1693
|
if (deletions.keys.length > 0 && onHistoryUpdated) {
|
|
1640
1694
|
onHistoryUpdated();
|
|
1641
1695
|
}
|
|
@@ -1664,30 +1718,6 @@ function setEntry(storage, location, entry) {
|
|
|
1664
1718
|
storage.history.entries.set(key, entry);
|
|
1665
1719
|
}
|
|
1666
1720
|
|
|
1667
|
-
// src/utils.ts
|
|
1668
|
-
function sleep(ms) {
|
|
1669
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1670
|
-
}
|
|
1671
|
-
var TIMEOUT_MAX = 2147483647;
|
|
1672
|
-
function setLongTimeout(listener, after) {
|
|
1673
|
-
let timeout;
|
|
1674
|
-
function start(remaining) {
|
|
1675
|
-
if (remaining <= TIMEOUT_MAX) {
|
|
1676
|
-
timeout = setTimeout(listener, remaining);
|
|
1677
|
-
} else {
|
|
1678
|
-
timeout = setTimeout(() => {
|
|
1679
|
-
start(remaining - TIMEOUT_MAX);
|
|
1680
|
-
}, TIMEOUT_MAX);
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
start(after);
|
|
1684
|
-
return {
|
|
1685
|
-
abort: () => {
|
|
1686
|
-
if (timeout !== void 0) clearTimeout(timeout);
|
|
1687
|
-
}
|
|
1688
|
-
};
|
|
1689
|
-
}
|
|
1690
|
-
|
|
1691
1721
|
// src/context.ts
|
|
1692
1722
|
var DEFAULT_MAX_RETRIES = 3;
|
|
1693
1723
|
var DEFAULT_RETRY_BACKOFF_BASE = 100;
|
|
@@ -1963,7 +1993,7 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
|
|
|
1963
1993
|
* Throws HistoryDivergedError if duplicate detected.
|
|
1964
1994
|
*/
|
|
1965
1995
|
checkDuplicateName(name) {
|
|
1966
|
-
const fullKey = locationToKey(this.storage, this.currentLocation)
|
|
1996
|
+
const fullKey = `${locationToKey(this.storage, this.currentLocation)}/${name}`;
|
|
1967
1997
|
if (this.usedNamesInExecution.has(fullKey)) {
|
|
1968
1998
|
throw new HistoryDivergedError(
|
|
1969
1999
|
`Duplicate entry name "${name}" at location "${locationToKey(this.storage, this.currentLocation)}". Each step/loop/sleep/queue.next/join/race must have a unique name within its scope.`
|
|
@@ -2017,7 +2047,7 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
|
|
|
2017
2047
|
validateComplete() {
|
|
2018
2048
|
const prefix = locationToKey(this.storage, this.currentLocation);
|
|
2019
2049
|
for (const key of this.storage.history.entries.keys()) {
|
|
2020
|
-
const isUnderPrefix = prefix === "" ? true : key.startsWith(prefix
|
|
2050
|
+
const isUnderPrefix = prefix === "" ? true : key.startsWith(`${prefix}/`) || key === prefix;
|
|
2021
2051
|
if (isUnderPrefix) {
|
|
2022
2052
|
if (!this.visitedKeys.has(key)) {
|
|
2023
2053
|
throw new HistoryDivergedError(
|
|
@@ -2034,25 +2064,33 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
|
|
|
2034
2064
|
this.abortController.abort(new EvictedError());
|
|
2035
2065
|
}
|
|
2036
2066
|
/**
|
|
2037
|
-
* Wait for
|
|
2038
|
-
*
|
|
2039
|
-
*
|
|
2040
|
-
*
|
|
2067
|
+
* Wait for `ms`, rejecting early with EvictedError if the workflow is
|
|
2068
|
+
* evicted. Both the timer and the abort listener are torn down on either
|
|
2069
|
+
* outcome, so a completed sleep never leaves a dangling listener on the
|
|
2070
|
+
* long-lived run abort signal.
|
|
2041
2071
|
*/
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2072
|
+
async sleepOrEvict(ms) {
|
|
2073
|
+
if (this.abortSignal.aborted) {
|
|
2074
|
+
throw new EvictedError();
|
|
2075
|
+
}
|
|
2076
|
+
let timer;
|
|
2077
|
+
let onAbort;
|
|
2078
|
+
try {
|
|
2079
|
+
await new Promise((resolve, reject) => {
|
|
2080
|
+
timer = setTimeout(resolve, ms);
|
|
2081
|
+
onAbort = () => reject(new EvictedError());
|
|
2082
|
+
this.abortSignal.addEventListener("abort", onAbort, {
|
|
2083
|
+
once: true
|
|
2084
|
+
});
|
|
2085
|
+
});
|
|
2086
|
+
} finally {
|
|
2087
|
+
if (timer !== void 0) {
|
|
2088
|
+
clearTimeout(timer);
|
|
2047
2089
|
}
|
|
2048
|
-
|
|
2049
|
-
"abort",
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
},
|
|
2053
|
-
{ once: true }
|
|
2054
|
-
);
|
|
2055
|
-
});
|
|
2090
|
+
if (onAbort) {
|
|
2091
|
+
this.abortSignal.removeEventListener("abort", onAbort);
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2056
2094
|
}
|
|
2057
2095
|
// === Step ===
|
|
2058
2096
|
async step(nameOrConfig, run) {
|
|
@@ -2201,7 +2239,7 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
|
|
|
2201
2239
|
}
|
|
2202
2240
|
const maxRetries2 = config2.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
2203
2241
|
if (metadata2.attempts > maxRetries2) {
|
|
2204
|
-
const lastError =
|
|
2242
|
+
const lastError = metadata2.error;
|
|
2205
2243
|
const exhaustedError = new StepExhaustedError(
|
|
2206
2244
|
config2.name,
|
|
2207
2245
|
lastError
|
|
@@ -2290,14 +2328,13 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
|
|
|
2290
2328
|
});
|
|
2291
2329
|
return output;
|
|
2292
2330
|
} catch (error) {
|
|
2293
|
-
if (
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2331
|
+
if (entry.kind.type === "step") {
|
|
2332
|
+
entry.kind.data.error = String(error);
|
|
2333
|
+
}
|
|
2334
|
+
entry.dirty = true;
|
|
2335
|
+
if (error instanceof StepTimeoutError && !config2.retryOnTimeout) {
|
|
2298
2336
|
metadata.status = "exhausted";
|
|
2299
2337
|
metadata.error = String(error);
|
|
2300
|
-
await this.flushStorage();
|
|
2301
2338
|
await this.notifyStepError(config2, metadata.attempts, error, {
|
|
2302
2339
|
willRetry: false
|
|
2303
2340
|
});
|
|
@@ -2311,13 +2348,8 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
|
|
|
2311
2348
|
);
|
|
2312
2349
|
}
|
|
2313
2350
|
if (error instanceof CriticalError || error instanceof RollbackError) {
|
|
2314
|
-
if (entry.kind.type === "step") {
|
|
2315
|
-
entry.kind.data.error = String(error);
|
|
2316
|
-
}
|
|
2317
|
-
entry.dirty = true;
|
|
2318
2351
|
metadata.status = "exhausted";
|
|
2319
2352
|
metadata.error = String(error);
|
|
2320
|
-
await this.flushStorage();
|
|
2321
2353
|
await this.notifyStepError(config2, metadata.attempts, error, {
|
|
2322
2354
|
willRetry: false
|
|
2323
2355
|
});
|
|
@@ -2330,14 +2362,9 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
|
|
|
2330
2362
|
})
|
|
2331
2363
|
);
|
|
2332
2364
|
}
|
|
2333
|
-
if (entry.kind.type === "step") {
|
|
2334
|
-
entry.kind.data.error = String(error);
|
|
2335
|
-
}
|
|
2336
|
-
entry.dirty = true;
|
|
2337
2365
|
const willRetry = metadata.attempts <= maxRetries;
|
|
2338
2366
|
metadata.status = willRetry ? "failed" : "exhausted";
|
|
2339
2367
|
metadata.error = String(error);
|
|
2340
|
-
await this.flushStorage();
|
|
2341
2368
|
if (willRetry) {
|
|
2342
2369
|
const retryDelay = calculateBackoff(
|
|
2343
2370
|
metadata.attempts,
|
|
@@ -2361,7 +2388,7 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
|
|
|
2361
2388
|
attachTryStepFailure(
|
|
2362
2389
|
new StepExhaustedError(config2.name, String(error)),
|
|
2363
2390
|
{
|
|
2364
|
-
kind: "exhausted",
|
|
2391
|
+
kind: error instanceof StepTimeoutError ? "timeout" : "exhausted",
|
|
2365
2392
|
stepName: config2.name,
|
|
2366
2393
|
attempts: metadata.attempts,
|
|
2367
2394
|
error: extractErrorInfo(error)
|
|
@@ -2379,7 +2406,9 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
|
|
|
2379
2406
|
*
|
|
2380
2407
|
* Note: This does NOT cancel the underlying operation. JavaScript Promises
|
|
2381
2408
|
* cannot be cancelled once started. When a timeout occurs:
|
|
2382
|
-
* - The step is
|
|
2409
|
+
* - The step is rejected with StepTimeoutError. By default this is treated
|
|
2410
|
+
* as a critical failure with no retry. Set retryOnTimeout: true on the
|
|
2411
|
+
* step config to retry timeouts like any other error.
|
|
2383
2412
|
* - The underlying async operation continues running in the background
|
|
2384
2413
|
* - Any side effects from the operation may still occur
|
|
2385
2414
|
*
|
|
@@ -2704,7 +2733,7 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
|
|
|
2704
2733
|
return;
|
|
2705
2734
|
}
|
|
2706
2735
|
if (remaining < this.driver.workerPollInterval) {
|
|
2707
|
-
await
|
|
2736
|
+
await this.sleepOrEvict(remaining);
|
|
2708
2737
|
this.checkEvicted();
|
|
2709
2738
|
if (entry.kind.type === "sleep") {
|
|
2710
2739
|
entry.kind.data.state = "completed";
|
|
@@ -3513,8 +3542,91 @@ var WorkflowContextImpl = class _WorkflowContextImpl {
|
|
|
3513
3542
|
setEntry(this.storage, location, entry);
|
|
3514
3543
|
await this.flushStorage();
|
|
3515
3544
|
}
|
|
3545
|
+
// === Version ===
|
|
3546
|
+
async getVersion(name, latest) {
|
|
3547
|
+
this.assertNotInProgress();
|
|
3548
|
+
this.checkEvicted();
|
|
3549
|
+
this.entryInProgress = true;
|
|
3550
|
+
try {
|
|
3551
|
+
return await this.executeGetVersion(name, latest);
|
|
3552
|
+
} finally {
|
|
3553
|
+
this.entryInProgress = false;
|
|
3554
|
+
}
|
|
3555
|
+
}
|
|
3556
|
+
async executeGetVersion(name, latest) {
|
|
3557
|
+
if (!Number.isInteger(latest) || latest < 1) {
|
|
3558
|
+
throw new Error(
|
|
3559
|
+
`getVersion("${name}", ${latest}): latest must be an integer >= 1`
|
|
3560
|
+
);
|
|
3561
|
+
}
|
|
3562
|
+
this.checkDuplicateName(name);
|
|
3563
|
+
const location = appendName(this.storage, this.currentLocation, name);
|
|
3564
|
+
const key = locationToKey(this.storage, location);
|
|
3565
|
+
const existing = this.storage.history.entries.get(key);
|
|
3566
|
+
this.markVisited(key);
|
|
3567
|
+
this.stopRollbackIfMissing(existing);
|
|
3568
|
+
if (existing) {
|
|
3569
|
+
if (existing.kind.type !== "version_check") {
|
|
3570
|
+
throw new HistoryDivergedError(
|
|
3571
|
+
`Expected version_check at ${key}, found ${existing.kind.type}`
|
|
3572
|
+
);
|
|
3573
|
+
}
|
|
3574
|
+
return existing.kind.data.resolved;
|
|
3575
|
+
}
|
|
3576
|
+
const resolved = this.hasUnvisitedUnderCurrentScope(key) ? 1 : latest;
|
|
3577
|
+
const entry = createEntry(location, {
|
|
3578
|
+
type: "version_check",
|
|
3579
|
+
data: { resolved, latest }
|
|
3580
|
+
});
|
|
3581
|
+
setEntry(this.storage, location, entry);
|
|
3582
|
+
await this.flushStorage();
|
|
3583
|
+
return resolved;
|
|
3584
|
+
}
|
|
3585
|
+
/**
|
|
3586
|
+
* Returns true if any history entry under the current location scope
|
|
3587
|
+
* (other than `excludeKey`) has not yet been visited this run. Used by
|
|
3588
|
+
* getVersion to detect an old in-flight instance whose scope was already
|
|
3589
|
+
* executed by code that predates a version gate.
|
|
3590
|
+
*/
|
|
3591
|
+
hasUnvisitedUnderCurrentScope(excludeKey) {
|
|
3592
|
+
const prefix = locationToKey(this.storage, this.currentLocation);
|
|
3593
|
+
for (const key of this.storage.history.entries.keys()) {
|
|
3594
|
+
if (key === excludeKey) {
|
|
3595
|
+
continue;
|
|
3596
|
+
}
|
|
3597
|
+
const isUnderPrefix = prefix === "" ? true : key.startsWith(`${prefix}/`) || key === prefix;
|
|
3598
|
+
if (isUnderPrefix && !this.visitedKeys.has(key)) {
|
|
3599
|
+
return true;
|
|
3600
|
+
}
|
|
3601
|
+
}
|
|
3602
|
+
return false;
|
|
3603
|
+
}
|
|
3516
3604
|
};
|
|
3517
3605
|
|
|
3606
|
+
// src/utils.ts
|
|
3607
|
+
function sleep(ms) {
|
|
3608
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3609
|
+
}
|
|
3610
|
+
var TIMEOUT_MAX = 2147483647;
|
|
3611
|
+
function setLongTimeout(listener, after) {
|
|
3612
|
+
let timeout;
|
|
3613
|
+
function start(remaining) {
|
|
3614
|
+
if (remaining <= TIMEOUT_MAX) {
|
|
3615
|
+
timeout = setTimeout(listener, remaining);
|
|
3616
|
+
} else {
|
|
3617
|
+
timeout = setTimeout(() => {
|
|
3618
|
+
start(remaining - TIMEOUT_MAX);
|
|
3619
|
+
}, TIMEOUT_MAX);
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
start(after);
|
|
3623
|
+
return {
|
|
3624
|
+
abort: () => {
|
|
3625
|
+
if (timeout !== void 0) clearTimeout(timeout);
|
|
3626
|
+
}
|
|
3627
|
+
};
|
|
3628
|
+
}
|
|
3629
|
+
|
|
3518
3630
|
// src/index.ts
|
|
3519
3631
|
var Loop = {
|
|
3520
3632
|
continue: (state) => ({
|
|
@@ -3738,25 +3850,41 @@ async function executeLiveWorkflow(workflowId, workflowFn, input, driver, messag
|
|
|
3738
3850
|
const hasMessages = result.waitingForMessages !== void 0;
|
|
3739
3851
|
const hasDeadline = result.sleepUntil !== void 0;
|
|
3740
3852
|
if (hasMessages && hasDeadline) {
|
|
3853
|
+
const iterationAbort = new AbortController();
|
|
3854
|
+
const onRunAbort = () => iterationAbort.abort();
|
|
3855
|
+
if (abortController.signal.aborted) {
|
|
3856
|
+
iterationAbort.abort();
|
|
3857
|
+
} else {
|
|
3858
|
+
abortController.signal.addEventListener("abort", onRunAbort, {
|
|
3859
|
+
once: true
|
|
3860
|
+
});
|
|
3861
|
+
}
|
|
3862
|
+
const messagePromise = awaitWithEviction(
|
|
3863
|
+
driver.waitForMessages(
|
|
3864
|
+
result.waitingForMessages,
|
|
3865
|
+
iterationAbort.signal
|
|
3866
|
+
),
|
|
3867
|
+
iterationAbort.signal
|
|
3868
|
+
);
|
|
3869
|
+
const sleepPromise = waitForSleep(
|
|
3870
|
+
runtime,
|
|
3871
|
+
result.sleepUntil,
|
|
3872
|
+
iterationAbort.signal
|
|
3873
|
+
);
|
|
3874
|
+
messagePromise.catch(() => {
|
|
3875
|
+
});
|
|
3876
|
+
sleepPromise.catch(() => {
|
|
3877
|
+
});
|
|
3741
3878
|
try {
|
|
3742
|
-
const messagePromise = awaitWithEviction(
|
|
3743
|
-
driver.waitForMessages(
|
|
3744
|
-
result.waitingForMessages,
|
|
3745
|
-
abortController.signal
|
|
3746
|
-
),
|
|
3747
|
-
abortController.signal
|
|
3748
|
-
);
|
|
3749
|
-
const sleepPromise = waitForSleep(
|
|
3750
|
-
runtime,
|
|
3751
|
-
result.sleepUntil,
|
|
3752
|
-
abortController.signal
|
|
3753
|
-
);
|
|
3754
3879
|
await Promise.race([messagePromise, sleepPromise]);
|
|
3755
3880
|
} catch (error) {
|
|
3756
3881
|
if (error instanceof EvictedError) {
|
|
3757
3882
|
return lastResult;
|
|
3758
3883
|
}
|
|
3759
3884
|
throw error;
|
|
3885
|
+
} finally {
|
|
3886
|
+
iterationAbort.abort();
|
|
3887
|
+
abortController.signal.removeEventListener("abort", onRunAbort);
|
|
3760
3888
|
}
|
|
3761
3889
|
continue;
|
|
3762
3890
|
}
|
|
@@ -4199,15 +4327,15 @@ export {
|
|
|
4199
4327
|
deleteEntriesWithPrefix,
|
|
4200
4328
|
getEntry,
|
|
4201
4329
|
setEntry,
|
|
4202
|
-
sleep,
|
|
4203
4330
|
DEFAULT_MAX_RETRIES,
|
|
4204
4331
|
DEFAULT_RETRY_BACKOFF_BASE,
|
|
4205
4332
|
DEFAULT_RETRY_BACKOFF_MAX,
|
|
4206
4333
|
DEFAULT_LOOP_HISTORY_PRUNE_INTERVAL,
|
|
4207
4334
|
DEFAULT_STEP_TIMEOUT,
|
|
4208
4335
|
WorkflowContextImpl,
|
|
4336
|
+
sleep,
|
|
4209
4337
|
Loop,
|
|
4210
4338
|
runWorkflow,
|
|
4211
4339
|
replayWorkflowFromStep
|
|
4212
4340
|
};
|
|
4213
|
-
//# sourceMappingURL=chunk-
|
|
4341
|
+
//# sourceMappingURL=chunk-TVRZA5O5.js.map
|