@dbos-inc/dbos-sdk 4.20.3-preview → 4.20.5-preview
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/src/client.d.ts +3 -3
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +8 -5
- package/dist/src/client.js.map +1 -1
- package/dist/src/dbos-executor.d.ts +1 -1
- package/dist/src/dbos-executor.d.ts.map +1 -1
- package/dist/src/dbos-executor.js +2 -2
- package/dist/src/dbos-executor.js.map +1 -1
- package/dist/src/dbos.d.ts +32 -6
- package/dist/src/dbos.d.ts.map +1 -1
- package/dist/src/dbos.js +27 -10
- package/dist/src/dbos.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/system_database.d.ts +4 -4
- package/dist/src/system_database.d.ts.map +1 -1
- package/dist/src/system_database.js +53 -24
- package/dist/src/system_database.js.map +1 -1
- package/dist/src/workflow.d.ts +5 -4
- package/dist/src/workflow.d.ts.map +1 -1
- package/dist/src/workflow.js +7 -3
- package/dist/src/workflow.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -517,9 +517,7 @@ class SystemDatabase {
|
|
|
517
517
|
async recordWorkflowOutput(workflowID, status) {
|
|
518
518
|
const client = await this.pool.connect();
|
|
519
519
|
try {
|
|
520
|
-
await this
|
|
521
|
-
update: { output: status.output, resetDeduplicationID: true, setCompletedAt: true },
|
|
522
|
-
});
|
|
520
|
+
await this.#recordWorkflowOutcome(client, workflowID, workflow_1.StatusString.SUCCESS, { output: status.output });
|
|
523
521
|
}
|
|
524
522
|
finally {
|
|
525
523
|
client.release();
|
|
@@ -528,14 +526,37 @@ class SystemDatabase {
|
|
|
528
526
|
async recordWorkflowError(workflowID, status) {
|
|
529
527
|
const client = await this.pool.connect();
|
|
530
528
|
try {
|
|
531
|
-
await this
|
|
532
|
-
update: { error: status.error, resetDeduplicationID: true, setCompletedAt: true },
|
|
533
|
-
});
|
|
529
|
+
await this.#recordWorkflowOutcome(client, workflowID, workflow_1.StatusString.ERROR, { error: status.error });
|
|
534
530
|
}
|
|
535
531
|
finally {
|
|
536
532
|
client.release();
|
|
537
533
|
}
|
|
538
534
|
}
|
|
535
|
+
// Record a workflow's terminal outcome (SUCCESS or ERROR), but never overwrite
|
|
536
|
+
// the terminal CANCELLED status: a workflow can be cancelled during its final
|
|
537
|
+
// step, and if so it must not be able to subsequently complete. If the
|
|
538
|
+
// workflow is cancelled, abort the function so it does not complete. This
|
|
539
|
+
// mirrors the cancellation check done before each step.
|
|
540
|
+
async #recordWorkflowOutcome(client, workflowID, status, outcome) {
|
|
541
|
+
let cancelled = false;
|
|
542
|
+
try {
|
|
543
|
+
await client.query('BEGIN');
|
|
544
|
+
await this.updateWorkflowStatus(client, workflowID, status, {
|
|
545
|
+
update: { ...outcome, resetDeduplicationID: true, setCompletedAt: true },
|
|
546
|
+
where: { notStatus: workflow_1.StatusString.CANCELLED },
|
|
547
|
+
throwOnFailure: false,
|
|
548
|
+
});
|
|
549
|
+
cancelled = (await this.getWorkflowStatusValue(client, workflowID)) === workflow_1.StatusString.CANCELLED;
|
|
550
|
+
await client.query('COMMIT');
|
|
551
|
+
}
|
|
552
|
+
catch (e) {
|
|
553
|
+
await client.query('ROLLBACK');
|
|
554
|
+
throw e;
|
|
555
|
+
}
|
|
556
|
+
if (cancelled) {
|
|
557
|
+
throw new error_1.DBOSWorkflowCancelledError(workflowID);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
539
560
|
async getPendingWorkflows(executorID, appVersion) {
|
|
540
561
|
const getWorkflows = await this.pool.query(`SELECT workflow_uuid, queue_name
|
|
541
562
|
FROM "${this.schemaName}".workflow_status
|
|
@@ -1164,9 +1185,10 @@ class SystemDatabase {
|
|
|
1164
1185
|
//throw new Error('Message notification map is not empty - shutdown is not clean.');
|
|
1165
1186
|
}
|
|
1166
1187
|
}
|
|
1167
|
-
async awaitWorkflowResult(workflowID, timeoutSeconds, callerID, timerFuncID) {
|
|
1188
|
+
async awaitWorkflowResult(workflowID, timeoutSeconds, callerID, timerFuncID, pollingIntervalMs) {
|
|
1168
1189
|
const timeoutms = timeoutSeconds !== undefined ? timeoutSeconds * 1000 : undefined;
|
|
1169
1190
|
let finishTime = timeoutms !== undefined ? Date.now() + timeoutms : undefined;
|
|
1191
|
+
const pollIntervalMs = pollingIntervalMs ?? this.dbPollingIntervalResultMs;
|
|
1170
1192
|
while (true) {
|
|
1171
1193
|
let resolveNotification;
|
|
1172
1194
|
const statusPromise = new Promise((resolve) => {
|
|
@@ -1216,14 +1238,14 @@ class SystemDatabase {
|
|
|
1216
1238
|
let timeoutPromise = Promise.resolve();
|
|
1217
1239
|
let timeoutCancel = () => { };
|
|
1218
1240
|
if (timerFuncID !== undefined && callerID !== undefined && timeoutms !== undefined) {
|
|
1219
|
-
const { promise, cancel, endTime } = await this.#durableSleep(callerID, timerFuncID, timeoutms,
|
|
1241
|
+
const { promise, cancel, endTime } = await this.#durableSleep(callerID, timerFuncID, timeoutms, pollIntervalMs);
|
|
1220
1242
|
finishTime = endTime;
|
|
1221
1243
|
timeoutPromise = promise;
|
|
1222
1244
|
timeoutCancel = cancel;
|
|
1223
1245
|
}
|
|
1224
1246
|
else {
|
|
1225
|
-
let poll = finishTime ? finishTime - ct :
|
|
1226
|
-
poll = Math.min(
|
|
1247
|
+
let poll = finishTime ? finishTime - ct : pollIntervalMs;
|
|
1248
|
+
poll = Math.min(pollIntervalMs, poll);
|
|
1227
1249
|
const { promise, cancel } = (0, utils_1.cancellableSleep)(poll);
|
|
1228
1250
|
timeoutPromise = promise;
|
|
1229
1251
|
timeoutCancel = cancel;
|
|
@@ -1242,8 +1264,9 @@ class SystemDatabase {
|
|
|
1242
1264
|
}
|
|
1243
1265
|
}
|
|
1244
1266
|
}
|
|
1245
|
-
async awaitFirstWorkflowId(workflowIds, callerID) {
|
|
1267
|
+
async awaitFirstWorkflowId(workflowIds, callerID, pollingIntervalMs) {
|
|
1246
1268
|
const placeholders = workflowIds.map((_, i) => `$${i + 1}`).join(', ');
|
|
1269
|
+
const pollIntervalMs = pollingIntervalMs ?? this.dbPollingIntervalResultMs;
|
|
1247
1270
|
while (true) {
|
|
1248
1271
|
let resolveNotification;
|
|
1249
1272
|
const wakeupPromise = new Promise((resolve) => {
|
|
@@ -1264,7 +1287,7 @@ class SystemDatabase {
|
|
|
1264
1287
|
if (rows.length > 0) {
|
|
1265
1288
|
return rows[0].workflow_uuid;
|
|
1266
1289
|
}
|
|
1267
|
-
const { promise: sleepPromise, cancel: sleepCancel } = (0, utils_1.cancellableSleep)(
|
|
1290
|
+
const { promise: sleepPromise, cancel: sleepCancel } = (0, utils_1.cancellableSleep)(pollIntervalMs);
|
|
1268
1291
|
try {
|
|
1269
1292
|
await Promise.race([wakeupPromise, sleepPromise]);
|
|
1270
1293
|
}
|
|
@@ -1357,7 +1380,7 @@ class SystemDatabase {
|
|
|
1357
1380
|
throw err;
|
|
1358
1381
|
}
|
|
1359
1382
|
}
|
|
1360
|
-
async recv(workflowID, functionID, timeoutFunctionID, topic, timeoutSeconds = dbos_executor_1.DBOSExecutor.defaultNotificationTimeoutSec) {
|
|
1383
|
+
async recv(workflowID, functionID, timeoutFunctionID, topic, timeoutSeconds = dbos_executor_1.DBOSExecutor.defaultNotificationTimeoutSec, pollingIntervalMs) {
|
|
1361
1384
|
topic = topic ?? this.nullTopic;
|
|
1362
1385
|
const startTime = Date.now();
|
|
1363
1386
|
// First, check for previous executions.
|
|
@@ -1370,6 +1393,7 @@ class SystemDatabase {
|
|
|
1370
1393
|
}
|
|
1371
1394
|
const timeoutms = timeoutSeconds !== undefined ? timeoutSeconds * 1000 : undefined;
|
|
1372
1395
|
let finishTime = timeoutms !== undefined ? Date.now() + timeoutms : undefined;
|
|
1396
|
+
const pollIntervalMs = pollingIntervalMs ?? this.dbPollingIntervalEventMs;
|
|
1373
1397
|
while (true) {
|
|
1374
1398
|
// register the key with the global notifications listener.
|
|
1375
1399
|
let resolveNotification;
|
|
@@ -1393,14 +1417,14 @@ class SystemDatabase {
|
|
|
1393
1417
|
let timeoutPromise = Promise.resolve();
|
|
1394
1418
|
let timeoutCancel = () => { };
|
|
1395
1419
|
if (timeoutms) {
|
|
1396
|
-
const { promise, cancel, endTime } = await this.#durableSleep(workflowID, timeoutFunctionID, timeoutms,
|
|
1420
|
+
const { promise, cancel, endTime } = await this.#durableSleep(workflowID, timeoutFunctionID, timeoutms, pollIntervalMs);
|
|
1397
1421
|
timeoutPromise = promise;
|
|
1398
1422
|
timeoutCancel = cancel;
|
|
1399
1423
|
finishTime = endTime;
|
|
1400
1424
|
}
|
|
1401
1425
|
else {
|
|
1402
|
-
let poll = finishTime ? finishTime - ct :
|
|
1403
|
-
poll = Math.min(
|
|
1426
|
+
let poll = finishTime ? finishTime - ct : pollIntervalMs;
|
|
1427
|
+
poll = Math.min(pollIntervalMs, poll);
|
|
1404
1428
|
const { promise, cancel } = (0, utils_1.cancellableSleep)(poll);
|
|
1405
1429
|
timeoutPromise = promise;
|
|
1406
1430
|
timeoutCancel = cancel;
|
|
@@ -1488,7 +1512,7 @@ class SystemDatabase {
|
|
|
1488
1512
|
client.release();
|
|
1489
1513
|
}
|
|
1490
1514
|
}
|
|
1491
|
-
async getEvent(workflowID, key, timeoutSeconds, callerWorkflow) {
|
|
1515
|
+
async getEvent(workflowID, key, timeoutSeconds, callerWorkflow, pollingIntervalMs) {
|
|
1492
1516
|
const startTime = Date.now();
|
|
1493
1517
|
// Check if the operation has been done before for OAOO (only do this inside a workflow).
|
|
1494
1518
|
if (callerWorkflow) {
|
|
@@ -1506,6 +1530,7 @@ class SystemDatabase {
|
|
|
1506
1530
|
const payloadKey = `${workflowID}::${key}`;
|
|
1507
1531
|
const timeoutms = timeoutSeconds !== undefined ? timeoutSeconds * 1000 : undefined;
|
|
1508
1532
|
let finishTime = timeoutms !== undefined ? Date.now() + timeoutms : undefined;
|
|
1533
|
+
const pollIntervalMs = pollingIntervalMs ?? this.dbPollingIntervalEventMs;
|
|
1509
1534
|
// Register the key with the global notifications listener first... we do not want to look in the DB first
|
|
1510
1535
|
// or that would cause a timing hole.
|
|
1511
1536
|
while (true) {
|
|
@@ -1538,14 +1563,14 @@ class SystemDatabase {
|
|
|
1538
1563
|
let timeoutPromise = Promise.resolve();
|
|
1539
1564
|
let timeoutCancel = () => { };
|
|
1540
1565
|
if (callerWorkflow && timeoutms) {
|
|
1541
|
-
const { promise, cancel, endTime } = await this.#durableSleep(callerWorkflow.workflowID, callerWorkflow.timeoutFunctionID ?? -1, timeoutms,
|
|
1566
|
+
const { promise, cancel, endTime } = await this.#durableSleep(callerWorkflow.workflowID, callerWorkflow.timeoutFunctionID ?? -1, timeoutms, pollIntervalMs);
|
|
1542
1567
|
timeoutPromise = promise;
|
|
1543
1568
|
timeoutCancel = cancel;
|
|
1544
1569
|
finishTime = endTime;
|
|
1545
1570
|
}
|
|
1546
1571
|
else {
|
|
1547
|
-
let poll = finishTime ? finishTime - ct :
|
|
1548
|
-
poll = Math.min(
|
|
1572
|
+
let poll = finishTime ? finishTime - ct : pollIntervalMs;
|
|
1573
|
+
poll = Math.min(pollIntervalMs, poll);
|
|
1549
1574
|
const { promise, cancel } = (0, utils_1.cancellableSleep)(poll);
|
|
1550
1575
|
timeoutPromise = promise;
|
|
1551
1576
|
timeoutCancel = cancel;
|
|
@@ -2758,6 +2783,10 @@ class SystemDatabase {
|
|
|
2758
2783
|
const param = args.push(where.status);
|
|
2759
2784
|
whereClause += ` AND status=$${param}`;
|
|
2760
2785
|
}
|
|
2786
|
+
if (where.notStatus) {
|
|
2787
|
+
const param = args.push(where.notStatus);
|
|
2788
|
+
whereClause += ` AND status!=$${param}`;
|
|
2789
|
+
}
|
|
2761
2790
|
const result = await client.query(`UPDATE "${this.schemaName}".workflow_status ${setClause} ${whereClause}`, args);
|
|
2762
2791
|
const throwOnFailure = options.throwOnFailure ?? true;
|
|
2763
2792
|
if (throwOnFailure && result.rowCount !== 1) {
|
|
@@ -3013,13 +3042,13 @@ __decorate([
|
|
|
3013
3042
|
__decorate([
|
|
3014
3043
|
dbRetry(),
|
|
3015
3044
|
__metadata("design:type", Function),
|
|
3016
|
-
__metadata("design:paramtypes", [String, Number, String, Number]),
|
|
3045
|
+
__metadata("design:paramtypes", [String, Number, String, Number, Number]),
|
|
3017
3046
|
__metadata("design:returntype", Promise)
|
|
3018
3047
|
], SystemDatabase.prototype, "awaitWorkflowResult", null);
|
|
3019
3048
|
__decorate([
|
|
3020
3049
|
dbRetry(),
|
|
3021
3050
|
__metadata("design:type", Function),
|
|
3022
|
-
__metadata("design:paramtypes", [Array, String]),
|
|
3051
|
+
__metadata("design:paramtypes", [Array, String, Number]),
|
|
3023
3052
|
__metadata("design:returntype", Promise)
|
|
3024
3053
|
], SystemDatabase.prototype, "awaitFirstWorkflowId", null);
|
|
3025
3054
|
__decorate([
|
|
@@ -3043,7 +3072,7 @@ __decorate([
|
|
|
3043
3072
|
__decorate([
|
|
3044
3073
|
dbRetry(),
|
|
3045
3074
|
__metadata("design:type", Function),
|
|
3046
|
-
__metadata("design:paramtypes", [String, Number, Number, String, Number]),
|
|
3075
|
+
__metadata("design:paramtypes", [String, Number, Number, String, Number, Number]),
|
|
3047
3076
|
__metadata("design:returntype", Promise)
|
|
3048
3077
|
], SystemDatabase.prototype, "recv", null);
|
|
3049
3078
|
__decorate([
|
|
@@ -3055,7 +3084,7 @@ __decorate([
|
|
|
3055
3084
|
__decorate([
|
|
3056
3085
|
dbRetry(),
|
|
3057
3086
|
__metadata("design:type", Function),
|
|
3058
|
-
__metadata("design:paramtypes", [String, String, Number, Object]),
|
|
3087
|
+
__metadata("design:paramtypes", [String, String, Number, Object, Number]),
|
|
3059
3088
|
__metadata("design:returntype", Promise)
|
|
3060
3089
|
], SystemDatabase.prototype, "getEvent", null);
|
|
3061
3090
|
__decorate([
|