@dbos-inc/dbos-sdk 2.8.46-preview.g30b0e27ed1 → 2.9.9-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/dbos-config.schema.json +28 -19
- package/dist/dbos-config.schema.json +28 -19
- package/dist/schemas/system_db_schema.d.ts +0 -4
- package/dist/schemas/system_db_schema.d.ts.map +1 -1
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +5 -7
- package/dist/src/client.js.map +1 -1
- package/dist/src/conductor/conductor.d.ts.map +1 -1
- package/dist/src/conductor/conductor.js +6 -12
- package/dist/src/conductor/conductor.js.map +1 -1
- package/dist/src/conductor/protocol.d.ts +2 -2
- package/dist/src/conductor/protocol.d.ts.map +1 -1
- package/dist/src/conductor/protocol.js +2 -2
- package/dist/src/conductor/protocol.js.map +1 -1
- package/dist/src/dbos-executor.d.ts +22 -7
- package/dist/src/dbos-executor.d.ts.map +1 -1
- package/dist/src/dbos-executor.js +154 -36
- package/dist/src/dbos-executor.js.map +1 -1
- package/dist/src/dbos-runtime/cli.d.ts.map +1 -1
- package/dist/src/dbos-runtime/cli.js +2 -0
- package/dist/src/dbos-runtime/cli.js.map +1 -1
- package/dist/src/dbos-runtime/config.js +3 -3
- package/dist/src/dbos-runtime/config.js.map +1 -1
- package/dist/src/dbos-runtime/workflow_management.d.ts +6 -13
- package/dist/src/dbos-runtime/workflow_management.d.ts.map +1 -1
- package/dist/src/dbos-runtime/workflow_management.js +23 -36
- package/dist/src/dbos-runtime/workflow_management.js.map +1 -1
- package/dist/src/dbos.d.ts +17 -11
- package/dist/src/dbos.d.ts.map +1 -1
- package/dist/src/dbos.js +47 -33
- package/dist/src/dbos.js.map +1 -1
- package/dist/src/error.d.ts +11 -9
- package/dist/src/error.d.ts.map +1 -1
- package/dist/src/error.js +26 -23
- package/dist/src/error.js.map +1 -1
- package/dist/src/eventreceiver.d.ts +7 -3
- package/dist/src/eventreceiver.d.ts.map +1 -1
- package/dist/src/httpServer/handler.d.ts.map +1 -1
- package/dist/src/httpServer/handler.js +2 -1
- package/dist/src/httpServer/handler.js.map +1 -1
- package/dist/src/httpServer/middleware.js +2 -2
- package/dist/src/httpServer/middleware.js.map +1 -1
- package/dist/src/httpServer/server.d.ts +6 -0
- package/dist/src/httpServer/server.d.ts.map +1 -1
- package/dist/src/httpServer/server.js +40 -2
- package/dist/src/httpServer/server.js.map +1 -1
- package/dist/src/scheduler/scheduler.js +1 -1
- package/dist/src/scheduler/scheduler.js.map +1 -1
- package/dist/src/system_database.d.ts +28 -52
- package/dist/src/system_database.d.ts.map +1 -1
- package/dist/src/system_database.js +261 -390
- package/dist/src/system_database.js.map +1 -1
- package/dist/src/testing/testing_runtime.d.ts.map +1 -1
- package/dist/src/testing/testing_runtime.js +2 -1
- package/dist/src/testing/testing_runtime.js.map +1 -1
- package/dist/src/utils.d.ts +1 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +3 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/src/wfqueue.d.ts.map +1 -1
- package/dist/src/wfqueue.js +1 -2
- package/dist/src/wfqueue.js.map +1 -1
- package/dist/src/workflow.d.ts +16 -6
- package/dist/src/workflow.d.ts.map +1 -1
- package/dist/src/workflow.js +38 -7
- package/dist/src/workflow.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -3
- package/migrations/20250421000000_workflowcancel.js +0 -15
- package/migrations/20250421100000_triggers_wfcancel.js +0 -35
@@ -37,7 +37,7 @@ const logs_1 = require("./telemetry/logs");
|
|
37
37
|
const exporters_1 = require("./telemetry/exporters");
|
38
38
|
const pg_1 = require("pg");
|
39
39
|
const system_database_1 = require("./system_database");
|
40
|
-
const
|
40
|
+
const node_crypto_1 = require("node:crypto");
|
41
41
|
const user_database_1 = require("./user_database");
|
42
42
|
const decorators_1 = require("./decorators");
|
43
43
|
const api_1 = require("@opentelemetry/api");
|
@@ -55,12 +55,13 @@ const scheduler_1 = require("./scheduler/scheduler");
|
|
55
55
|
const crypto = __importStar(require("crypto"));
|
56
56
|
exports.dbosNull = {};
|
57
57
|
function isDeprecatedDBOSConfig(config) {
|
58
|
-
|
58
|
+
const isDeprecated = config.poolConfig !== undefined ||
|
59
59
|
config.telemetry !== undefined ||
|
60
60
|
config.system_database !== undefined ||
|
61
61
|
config.env !== undefined ||
|
62
62
|
config.application !== undefined ||
|
63
|
-
config.http !== undefined
|
63
|
+
config.http !== undefined;
|
64
|
+
return isDeprecated;
|
64
65
|
}
|
65
66
|
exports.isDeprecatedDBOSConfig = isDeprecatedDBOSConfig;
|
66
67
|
var DebugMode;
|
@@ -113,6 +114,8 @@ class DBOSExecutor {
|
|
113
114
|
stepInfoMap = new Map();
|
114
115
|
procedureInfoMap = new Map();
|
115
116
|
registeredOperations = [];
|
117
|
+
pendingWorkflowMap = new Map(); // Map from workflowUUID to workflow promise
|
118
|
+
workflowCancellationMap = new Map(); // Map from workflowUUID to its cancellation status.
|
116
119
|
telemetryCollector;
|
117
120
|
static defaultNotificationTimeoutSec = 60;
|
118
121
|
debugMode;
|
@@ -395,7 +398,10 @@ class DBOSExecutor {
|
|
395
398
|
}
|
396
399
|
async destroy() {
|
397
400
|
try {
|
398
|
-
|
401
|
+
if (this.pendingWorkflowMap.size > 0) {
|
402
|
+
this.logger.info('Waiting for pending workflows to finish.');
|
403
|
+
await Promise.allSettled(this.pendingWorkflowMap.values());
|
404
|
+
}
|
399
405
|
await this.systemDatabase.destroy();
|
400
406
|
if (this.userDatabase) {
|
401
407
|
await this.userDatabase.destroy();
|
@@ -554,7 +560,6 @@ class DBOSExecutor {
|
|
554
560
|
applicationVersion: utils_1.globalParams.appVersion,
|
555
561
|
applicationID: wCtxt.applicationID,
|
556
562
|
createdAt: Date.now(), // Remember the start time of this workflow
|
557
|
-
maxRetries: wCtxt.maxRecoveryAttempts,
|
558
563
|
};
|
559
564
|
if (wCtxt.isTempWorkflow) {
|
560
565
|
internalStatus.workflowName = `${DBOSExecutor.tempWorkflowName}-${wCtxt.tempWfOperationType}-${wCtxt.tempWfOperationName}`;
|
@@ -564,14 +569,15 @@ class DBOSExecutor {
|
|
564
569
|
// Synchronously set the workflow's status to PENDING and record workflow inputs.
|
565
570
|
// We have to do it for all types of workflows because operation_outputs table has a foreign key constraint on workflow status table.
|
566
571
|
if (this.isDebugging) {
|
572
|
+
// TODO: remove call to getWorkflowInputs after #871 is merged
|
567
573
|
const wfStatus = await this.systemDatabase.getWorkflowStatus(workflowID);
|
568
574
|
const wfInputs = await this.systemDatabase.getWorkflowInputs(workflowID);
|
569
575
|
if (!wfStatus || !wfInputs) {
|
570
576
|
throw new error_1.DBOSDebuggerError(`Failed to find inputs for workflow UUID ${workflowID}`);
|
571
577
|
}
|
572
578
|
// Make sure we use the same input.
|
573
|
-
if (utils_1.DBOSJSON.stringify(args) !== wfInputs) {
|
574
|
-
throw new error_1.DBOSDebuggerError(`Detected different inputs for workflow UUID ${workflowID}.\n Received: ${utils_1.DBOSJSON.stringify(args)}\n Original: ${wfInputs}`);
|
579
|
+
if (utils_1.DBOSJSON.stringify(args) !== utils_1.DBOSJSON.stringify(wfInputs)) {
|
580
|
+
throw new error_1.DBOSDebuggerError(`Detected different inputs for workflow UUID ${workflowID}.\n Received: ${utils_1.DBOSJSON.stringify(args)}\n Original: ${utils_1.DBOSJSON.stringify(wfInputs)}`);
|
575
581
|
}
|
576
582
|
status = wfStatus.status;
|
577
583
|
}
|
@@ -583,14 +589,14 @@ class DBOSExecutor {
|
|
583
589
|
return new workflow_1.RetrievedHandle(this.systemDatabase, cr.res.child, callerID, callerFunctionID);
|
584
590
|
}
|
585
591
|
}
|
586
|
-
const ires = await this.systemDatabase.initWorkflowStatus(internalStatus,
|
592
|
+
const ires = await this.systemDatabase.initWorkflowStatus(internalStatus, args, wCtxt.maxRecoveryAttempts);
|
587
593
|
if (callerFunctionID !== undefined && callerID !== undefined) {
|
588
594
|
await this.systemDatabase.recordOperationResult(callerID, callerFunctionID, {
|
589
595
|
childWfId: workflowID,
|
590
596
|
functionName: internalStatus.workflowName,
|
591
597
|
}, true);
|
592
598
|
}
|
593
|
-
args =
|
599
|
+
args = ires.args;
|
594
600
|
status = ires.status;
|
595
601
|
await (0, debugpoint_1.debugTriggerPoint)(debugpoint_1.DEBUG_TRIGGER_WORKFLOW_ENQUEUE);
|
596
602
|
}
|
@@ -631,7 +637,7 @@ class DBOSExecutor {
|
|
631
637
|
wCtxt.span.setStatus({ code: api_1.SpanStatusCode.OK });
|
632
638
|
}
|
633
639
|
catch (err) {
|
634
|
-
if (err instanceof error_1.
|
640
|
+
if (err instanceof error_1.DBOSWorkflowConflictUUIDError) {
|
635
641
|
// Retrieve the handle and wait for the result.
|
636
642
|
const retrievedHandle = this.retrieveWorkflow(workflowID);
|
637
643
|
result = await retrievedHandle.getResult();
|
@@ -677,7 +683,16 @@ class DBOSExecutor {
|
|
677
683
|
if (this.isDebugging ||
|
678
684
|
(status !== 'SUCCESS' && status !== 'ERROR' && (params.queueName === undefined || params.executeWorkflow))) {
|
679
685
|
const workflowPromise = runWorkflow();
|
680
|
-
|
686
|
+
// Need to await for the workflow and capture errors.
|
687
|
+
const awaitWorkflowPromise = workflowPromise
|
688
|
+
.catch((error) => {
|
689
|
+
this.logger.debug('Captured error in awaitWorkflowPromise: ' + error);
|
690
|
+
})
|
691
|
+
.finally(() => {
|
692
|
+
// Remove itself from pending workflow map.
|
693
|
+
this.pendingWorkflowMap.delete(workflowID);
|
694
|
+
});
|
695
|
+
this.pendingWorkflowMap.set(workflowID, awaitWorkflowPromise);
|
681
696
|
// Return the normal handle that doesn't capture errors.
|
682
697
|
return new workflow_1.InvokedHandle(this.systemDatabase, workflowPromise, workflowID, wf.name, callerID, callerFunctionID);
|
683
698
|
}
|
@@ -754,7 +769,7 @@ class DBOSExecutor {
|
|
754
769
|
catch (error) {
|
755
770
|
if (isKeyConflict(error)) {
|
756
771
|
// Serialization and primary key conflict (Postgres).
|
757
|
-
throw new error_1.
|
772
|
+
throw new error_1.DBOSWorkflowConflictUUIDError(workflowUUID);
|
758
773
|
}
|
759
774
|
else {
|
760
775
|
throw error;
|
@@ -775,7 +790,7 @@ class DBOSExecutor {
|
|
775
790
|
catch (error) {
|
776
791
|
if (isKeyConflict(error)) {
|
777
792
|
// Serialization and primary key conflict (Postgres).
|
778
|
-
throw new error_1.
|
793
|
+
throw new error_1.DBOSWorkflowConflictUUIDError(workflowUUID);
|
779
794
|
}
|
780
795
|
else {
|
781
796
|
throw error;
|
@@ -811,7 +826,9 @@ class DBOSExecutor {
|
|
811
826
|
if (txnInfo === undefined) {
|
812
827
|
throw new error_1.DBOSNotRegisteredError(txn.name);
|
813
828
|
}
|
814
|
-
|
829
|
+
if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
|
830
|
+
throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
|
831
|
+
}
|
815
832
|
let retryWaitMillis = 1;
|
816
833
|
const backoffFactor = 1.5;
|
817
834
|
const maxRetryWaitMs = 2000; // Maximum wait 2 seconds.
|
@@ -825,7 +842,9 @@ class DBOSExecutor {
|
|
825
842
|
isolationLevel: txnInfo.config.isolationLevel,
|
826
843
|
}, wfCtx.span);
|
827
844
|
while (true) {
|
828
|
-
|
845
|
+
if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
|
846
|
+
throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
|
847
|
+
}
|
829
848
|
let txn_snapshot = 'invalid';
|
830
849
|
const workflowUUID = wfCtx.workflowUUID;
|
831
850
|
const wrappedTransaction = async (client) => {
|
@@ -959,7 +978,9 @@ class DBOSExecutor {
|
|
959
978
|
if (procInfo === undefined) {
|
960
979
|
throw new error_1.DBOSNotRegisteredError(proc.name);
|
961
980
|
}
|
962
|
-
|
981
|
+
if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
|
982
|
+
throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
|
983
|
+
}
|
963
984
|
const executeLocally = this.isDebugging || (procInfo.config.executeLocally ?? false);
|
964
985
|
const funcId = wfCtx.functionIDGetIncrement();
|
965
986
|
const span = this.tracer.startSpan(proc.name, {
|
@@ -992,7 +1013,9 @@ class DBOSExecutor {
|
|
992
1013
|
const backoffFactor = 1.5;
|
993
1014
|
const maxRetryWaitMs = 2000; // Maximum wait 2 seconds.
|
994
1015
|
while (true) {
|
995
|
-
|
1016
|
+
if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
|
1017
|
+
throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
|
1018
|
+
}
|
996
1019
|
let txn_snapshot = 'invalid';
|
997
1020
|
const wrappedProcedure = async (client) => {
|
998
1021
|
const ctxt = new procedure_1.StoredProcedureContextImpl(client, wfCtx, span, this.logger, funcId, proc.name);
|
@@ -1101,7 +1124,9 @@ class DBOSExecutor {
|
|
1101
1124
|
if (this.isDebugging) {
|
1102
1125
|
throw new error_1.DBOSDebuggerError("Can't invoke stored procedure in debug mode.");
|
1103
1126
|
}
|
1104
|
-
|
1127
|
+
if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
|
1128
|
+
throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
|
1129
|
+
}
|
1105
1130
|
const $jsonCtx = {
|
1106
1131
|
request: wfCtx.request,
|
1107
1132
|
authenticatedUser: wfCtx.authenticatedUser,
|
@@ -1192,7 +1217,9 @@ class DBOSExecutor {
|
|
1192
1217
|
if (commInfo === undefined) {
|
1193
1218
|
throw new error_1.DBOSNotRegisteredError(stepFn.name);
|
1194
1219
|
}
|
1195
|
-
|
1220
|
+
if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
|
1221
|
+
throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
|
1222
|
+
}
|
1196
1223
|
const funcID = wfCtx.functionIDGetIncrement();
|
1197
1224
|
const maxRetryIntervalSec = 3600; // Maximum retry interval: 1 hour
|
1198
1225
|
const span = this.tracer.startSpan(stepFn.name, {
|
@@ -1235,7 +1262,9 @@ class DBOSExecutor {
|
|
1235
1262
|
}
|
1236
1263
|
while (result === exports.dbosNull && numAttempts++ < ctxt.maxAttempts) {
|
1237
1264
|
try {
|
1238
|
-
|
1265
|
+
if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
|
1266
|
+
throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
|
1267
|
+
}
|
1239
1268
|
let cresult;
|
1240
1269
|
if (commInfo.registration.passContext) {
|
1241
1270
|
await (0, context_1.runWithStepContext)(ctxt, numAttempts, async () => {
|
@@ -1326,13 +1355,57 @@ class DBOSExecutor {
|
|
1326
1355
|
async getEvent(workflowUUID, key, timeoutSeconds = DBOSExecutor.defaultNotificationTimeoutSec) {
|
1327
1356
|
return utils_1.DBOSJSON.parse(await this.systemDatabase.getEvent(workflowUUID, key, timeoutSeconds));
|
1328
1357
|
}
|
1358
|
+
async getMaxFunctionID(workflowID) {
|
1359
|
+
const rows = await this.userDatabase.query(`SELECT max(function_id) as max_function_id FROM ${DBOSExecutor.systemDBSchemaName}.transaction_outputs WHERE workflow_uuid=$1`, workflowID);
|
1360
|
+
if (rows.length === 0) {
|
1361
|
+
return 0;
|
1362
|
+
}
|
1363
|
+
else {
|
1364
|
+
return rows[0].max_function_id;
|
1365
|
+
}
|
1366
|
+
}
|
1367
|
+
async cloneWorkflowTransactions(workflowID, forkedWorkflowUUID, startStep) {
|
1368
|
+
const query = `
|
1369
|
+
INSERT INTO dbos.transaction_outputs
|
1370
|
+
(workflow_uuid,
|
1371
|
+
function_id,
|
1372
|
+
output,
|
1373
|
+
error,
|
1374
|
+
txn_id,
|
1375
|
+
txn_snapshot,
|
1376
|
+
function_name)
|
1377
|
+
SELECT $1 AS workflow_uuid,
|
1378
|
+
function_id,
|
1379
|
+
output,
|
1380
|
+
error,
|
1381
|
+
txn_id,
|
1382
|
+
txn_snapshot,
|
1383
|
+
function_name
|
1384
|
+
FROM dbos.transaction_outputs WHERE workflow_uuid= $2 AND function_id < $3`;
|
1385
|
+
await this.userDatabase.query(query, forkedWorkflowUUID, workflowID, startStep);
|
1386
|
+
}
|
1387
|
+
async getMaxStepID(workflowID) {
|
1388
|
+
const maxAppFunctionID = await this.getMaxFunctionID(workflowID);
|
1389
|
+
const maxSystemFunctionID = await this.systemDatabase.getMaxFunctionID(workflowID);
|
1390
|
+
return Math.max(maxAppFunctionID, maxSystemFunctionID);
|
1391
|
+
}
|
1392
|
+
/**
|
1393
|
+
* Fork a workflow.
|
1394
|
+
* The forked workflow will be assigned a new ID.
|
1395
|
+
*/
|
1396
|
+
async forkWorkflow(workflowID, startStep = 0) {
|
1397
|
+
const forkedWorkflowID = this.#generateUUID();
|
1398
|
+
await this.cloneWorkflowTransactions(workflowID, forkedWorkflowID, startStep);
|
1399
|
+
await this.systemDatabase.forkWorkflow(workflowID, forkedWorkflowID, startStep);
|
1400
|
+
return forkedWorkflowID;
|
1401
|
+
}
|
1329
1402
|
/**
|
1330
1403
|
* Retrieve a handle for a workflow UUID.
|
1331
1404
|
*/
|
1332
1405
|
retrieveWorkflow(workflowID) {
|
1333
1406
|
return new workflow_1.RetrievedHandle(this.systemDatabase, workflowID);
|
1334
1407
|
}
|
1335
|
-
async runAsStep(callback, functionName, workflowID, functionID
|
1408
|
+
async runAsStep(callback, functionName, workflowID, functionID) {
|
1336
1409
|
if (workflowID !== undefined && functionID !== undefined) {
|
1337
1410
|
const res = await this.systemDatabase.getOperationResult(workflowID, functionID);
|
1338
1411
|
if (res.res !== undefined) {
|
@@ -1345,22 +1418,28 @@ class DBOSExecutor {
|
|
1345
1418
|
try {
|
1346
1419
|
const output = await callback();
|
1347
1420
|
if (workflowID !== undefined && functionID !== undefined) {
|
1348
|
-
await this.systemDatabase.recordOperationResult(workflowID, functionID, { serialOutput: utils_1.DBOSJSON.stringify(output), functionName
|
1421
|
+
await this.systemDatabase.recordOperationResult(workflowID, functionID, { serialOutput: utils_1.DBOSJSON.stringify(output), functionName }, true);
|
1349
1422
|
}
|
1350
1423
|
return output;
|
1351
1424
|
}
|
1352
1425
|
catch (e) {
|
1353
1426
|
if (workflowID !== undefined && functionID !== undefined) {
|
1354
|
-
await this.systemDatabase.recordOperationResult(workflowID, functionID, { serialError: utils_1.DBOSJSON.stringify((0, serialize_error_1.serializeError)(e)), functionName
|
1427
|
+
await this.systemDatabase.recordOperationResult(workflowID, functionID, { serialError: utils_1.DBOSJSON.stringify((0, serialize_error_1.serializeError)(e)), functionName }, false);
|
1355
1428
|
}
|
1356
1429
|
throw e;
|
1357
1430
|
}
|
1358
1431
|
}
|
1359
|
-
getWorkflowStatus(workflowID, callerID, callerFN) {
|
1360
|
-
|
1432
|
+
async getWorkflowStatus(workflowID, callerID, callerFN) {
|
1433
|
+
const status = await this.systemDatabase.getWorkflowStatus(workflowID, callerID, callerFN);
|
1434
|
+
return status ? DBOSExecutor.toWorkflowStatus(status, true) : null;
|
1435
|
+
}
|
1436
|
+
async listWorkflows(input) {
|
1437
|
+
const wfs = await this.systemDatabase.listWorkflows(input);
|
1438
|
+
return wfs.map((wf) => DBOSExecutor.toWorkflowStatus(wf, true));
|
1361
1439
|
}
|
1362
|
-
|
1363
|
-
|
1440
|
+
async listQueuedWorkflows(input) {
|
1441
|
+
const wfs = await this.systemDatabase.listQueuedWorkflows(input);
|
1442
|
+
return wfs.map((wf) => DBOSExecutor.toWorkflowStatus(wf, true));
|
1364
1443
|
}
|
1365
1444
|
getWorkflowQueue(input) {
|
1366
1445
|
return this.systemDatabase.getWorkflowQueue(input);
|
@@ -1395,7 +1474,7 @@ class DBOSExecutor {
|
|
1395
1474
|
}
|
1396
1475
|
/* INTERNAL HELPERS */
|
1397
1476
|
#generateUUID() {
|
1398
|
-
return (0,
|
1477
|
+
return (0, node_crypto_1.randomUUID)();
|
1399
1478
|
}
|
1400
1479
|
/**
|
1401
1480
|
* A recovery process that by default runs during executor init time.
|
@@ -1475,13 +1554,13 @@ class DBOSExecutor {
|
|
1475
1554
|
}
|
1476
1555
|
}
|
1477
1556
|
async executeWorkflowUUID(workflowID, startNewWorkflow = false) {
|
1557
|
+
// TODO: remove call to getWorkflowInputs after #871 is merged
|
1478
1558
|
const wfStatus = await this.systemDatabase.getWorkflowStatus(workflowID);
|
1479
|
-
const
|
1480
|
-
if (!
|
1559
|
+
const inputs = await this.systemDatabase.getWorkflowInputs(workflowID);
|
1560
|
+
if (!inputs || !wfStatus) {
|
1481
1561
|
this.logger.error(`Failed to find inputs for workflowUUID: ${workflowID}`);
|
1482
1562
|
throw new error_1.DBOSError(`Failed to find inputs for workflow UUID: ${workflowID}`);
|
1483
1563
|
}
|
1484
|
-
const inputs = utils_1.DBOSJSON.parse(sInputs);
|
1485
1564
|
const parentCtx = this.#getRecoveryContext(workflowID, wfStatus);
|
1486
1565
|
const { wfInfo, configuredInst } = this.getWorkflowInfoByStatus(wfStatus);
|
1487
1566
|
// If starting a new workflow, assign a new UUID. Otherwise, use the workflow's original UUID.
|
@@ -1493,7 +1572,9 @@ class DBOSExecutor {
|
|
1493
1572
|
configuredInstance: configuredInst,
|
1494
1573
|
queueName: wfStatus.queueName,
|
1495
1574
|
executeWorkflow: true,
|
1496
|
-
},
|
1575
|
+
},
|
1576
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
1577
|
+
...inputs);
|
1497
1578
|
}
|
1498
1579
|
// Should be temporary workflows. Parse the name of the workflow.
|
1499
1580
|
const wfName = wfStatus.workflowName;
|
@@ -1515,7 +1596,9 @@ class DBOSExecutor {
|
|
1515
1596
|
configuredInstance: clsInst,
|
1516
1597
|
queueName: wfStatus.queueName,
|
1517
1598
|
executeWorkflow: true,
|
1518
|
-
}, undefined, undefined,
|
1599
|
+
}, undefined, undefined,
|
1600
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
1601
|
+
...inputs);
|
1519
1602
|
}
|
1520
1603
|
else if (nameArr[1] === exports.TempWorkflowType.step) {
|
1521
1604
|
const { commInfo, clsInst } = this.getStepInfoByNames(wfStatus.workflowClassName, nameArr[2], wfStatus.workflowConfigName);
|
@@ -1529,7 +1612,9 @@ class DBOSExecutor {
|
|
1529
1612
|
configuredInstance: clsInst,
|
1530
1613
|
queueName: wfStatus.queueName, // Probably null
|
1531
1614
|
executeWorkflow: true,
|
1532
|
-
}, undefined, undefined,
|
1615
|
+
}, undefined, undefined,
|
1616
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
1617
|
+
...inputs);
|
1533
1618
|
}
|
1534
1619
|
else if (nameArr[1] === exports.TempWorkflowType.send) {
|
1535
1620
|
temp_workflow = async (ctxt, ...args) => {
|
@@ -1541,7 +1626,9 @@ class DBOSExecutor {
|
|
1541
1626
|
tempWfType: exports.TempWorkflowType.send,
|
1542
1627
|
queueName: wfStatus.queueName,
|
1543
1628
|
executeWorkflow: true,
|
1544
|
-
},
|
1629
|
+
},
|
1630
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
1631
|
+
...inputs);
|
1545
1632
|
}
|
1546
1633
|
else {
|
1547
1634
|
this.logger.error(`Unrecognized temporary workflow! UUID ${workflowID}, name ${wfName}`);
|
@@ -1567,6 +1654,7 @@ class DBOSExecutor {
|
|
1567
1654
|
async cancelWorkflow(workflowID) {
|
1568
1655
|
await this.systemDatabase.cancelWorkflow(workflowID);
|
1569
1656
|
this.logger.info(`Cancelling workflow ${workflowID}`);
|
1657
|
+
this.workflowCancellationMap.set(workflowID, true);
|
1570
1658
|
}
|
1571
1659
|
async getWorkflowSteps(workflowID) {
|
1572
1660
|
const outputs = await this.systemDatabase.getAllOperationResults(workflowID);
|
@@ -1588,8 +1676,8 @@ class DBOSExecutor {
|
|
1588
1676
|
return merged;
|
1589
1677
|
}
|
1590
1678
|
async resumeWorkflow(workflowID) {
|
1679
|
+
this.workflowCancellationMap.delete(workflowID);
|
1591
1680
|
await this.systemDatabase.resumeWorkflow(workflowID);
|
1592
|
-
return await this.executeWorkflowUUID(workflowID, false);
|
1593
1681
|
}
|
1594
1682
|
logRegisteredHTTPUrls() {
|
1595
1683
|
this.logger.info('HTTP endpoints supported:');
|
@@ -1629,6 +1717,36 @@ class DBOSExecutor {
|
|
1629
1717
|
}
|
1630
1718
|
return hasher.digest('hex');
|
1631
1719
|
}
|
1720
|
+
static internalQueue = undefined;
|
1721
|
+
static createInternalQueue() {
|
1722
|
+
if (DBOSExecutor.internalQueue !== undefined) {
|
1723
|
+
return;
|
1724
|
+
}
|
1725
|
+
DBOSExecutor.internalQueue = new wfqueue_1.WorkflowQueue(utils_1.INTERNAL_QUEUE_NAME);
|
1726
|
+
}
|
1727
|
+
static toWorkflowStatus(internal, getRequest = true) {
|
1728
|
+
return {
|
1729
|
+
workflowID: internal.workflowUUID,
|
1730
|
+
status: internal.status,
|
1731
|
+
workflowName: internal.workflowName,
|
1732
|
+
workflowClassName: internal.workflowClassName,
|
1733
|
+
workflowConfigName: internal.workflowConfigName,
|
1734
|
+
queueName: internal.queueName,
|
1735
|
+
authenticatedUser: internal.authenticatedUser,
|
1736
|
+
assumedRole: internal.assumedRole,
|
1737
|
+
authenticatedRoles: internal.authenticatedRoles,
|
1738
|
+
input: internal.input ? utils_1.DBOSJSON.parse(internal.input) : undefined,
|
1739
|
+
output: internal.output ? utils_1.DBOSJSON.parse(internal.output ?? null) : undefined,
|
1740
|
+
error: internal.error ? (0, serialize_error_1.deserializeError)(utils_1.DBOSJSON.parse(internal.error)) : undefined,
|
1741
|
+
request: getRequest ? internal.request : undefined,
|
1742
|
+
executorId: internal.executorId,
|
1743
|
+
applicationVersion: internal.applicationVersion,
|
1744
|
+
applicationID: internal.applicationID,
|
1745
|
+
recoveryAttempts: internal.recoveryAttempts,
|
1746
|
+
createdAt: internal.createdAt,
|
1747
|
+
updatedAt: internal.updatedAt,
|
1748
|
+
};
|
1749
|
+
}
|
1632
1750
|
}
|
1633
1751
|
exports.DBOSExecutor = DBOSExecutor;
|
1634
1752
|
//# sourceMappingURL=dbos-executor.js.map
|