@dbos-inc/dbos-sdk 3.0.27-preview → 3.0.35-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/datasource.d.ts +11 -6
- package/dist/src/datasource.d.ts.map +1 -1
- package/dist/src/datasource.js +9 -6
- package/dist/src/datasource.js.map +1 -1
- package/dist/src/dbos-executor.d.ts +51 -89
- package/dist/src/dbos-executor.d.ts.map +1 -1
- package/dist/src/dbos-executor.js +61 -284
- package/dist/src/dbos-executor.js.map +1 -1
- package/dist/src/dbos-runtime/config.d.ts +6 -4
- package/dist/src/dbos-runtime/config.d.ts.map +1 -1
- package/dist/src/dbos-runtime/config.js +59 -28
- package/dist/src/dbos-runtime/config.js.map +1 -1
- package/dist/src/dbos-runtime/migrate.js +3 -3
- package/dist/src/dbos-runtime/migrate.js.map +1 -1
- package/dist/src/dbos-runtime/runtime.d.ts +1 -1
- package/dist/src/dbos-runtime/runtime.d.ts.map +1 -1
- package/dist/src/dbos-runtime/runtime.js +4 -14
- package/dist/src/dbos-runtime/runtime.js.map +1 -1
- package/dist/src/dbos.d.ts +27 -65
- package/dist/src/dbos.d.ts.map +1 -1
- package/dist/src/dbos.js +107 -122
- package/dist/src/dbos.js.map +1 -1
- package/dist/src/decorators.d.ts +51 -57
- package/dist/src/decorators.d.ts.map +1 -1
- package/dist/src/decorators.js +234 -200
- package/dist/src/decorators.js.map +1 -1
- package/dist/src/httpServer/handler.d.ts +1 -1
- package/dist/src/httpServer/handler.d.ts.map +1 -1
- package/dist/src/httpServer/handler.js +1 -1
- package/dist/src/httpServer/handler.js.map +1 -1
- package/dist/src/httpServer/middleware.d.ts +0 -1
- package/dist/src/httpServer/middleware.d.ts.map +1 -1
- package/dist/src/httpServer/middleware.js.map +1 -1
- package/dist/src/httpServer/server.d.ts.map +1 -1
- package/dist/src/httpServer/server.js +4 -6
- package/dist/src/httpServer/server.js.map +1 -1
- package/dist/src/index.d.ts +3 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -12
- package/dist/src/index.js.map +1 -1
- package/dist/src/paramdecorators.d.ts +6 -6
- package/dist/src/paramdecorators.d.ts.map +1 -1
- package/dist/src/paramdecorators.js.map +1 -1
- package/dist/src/scheduler/crontab.d.ts +3 -8
- package/dist/src/scheduler/crontab.d.ts.map +1 -1
- package/dist/src/scheduler/crontab.js +24 -23
- package/dist/src/scheduler/crontab.js.map +1 -1
- package/dist/src/scheduler/scheduler.d.ts +10 -31
- package/dist/src/scheduler/scheduler.d.ts.map +1 -1
- package/dist/src/scheduler/scheduler.js +100 -135
- package/dist/src/scheduler/scheduler.js.map +1 -1
- package/dist/src/system_database.d.ts +5 -6
- package/dist/src/system_database.d.ts.map +1 -1
- package/dist/src/system_database.js +14 -1
- package/dist/src/system_database.js.map +1 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +14 -4
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/eslint.config.cjs +6 -1
- package/package.json +1 -1
- package/dist/src/eventreceiver.d.ts +0 -152
- package/dist/src/eventreceiver.d.ts.map +0 -1
- package/dist/src/eventreceiver.js +0 -3
- package/dist/src/eventreceiver.js.map +0 -1
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
27
27
|
};
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
29
|
-
exports.DBOSExecutor = exports.TempWorkflowType = exports.OperationType = exports.
|
29
|
+
exports.DBOSExecutor = exports.TempWorkflowType = exports.OperationType = exports.DBOS_QUEUE_MAX_PRIORITY = exports.DBOS_QUEUE_MIN_PRIORITY = exports.dbosNull = void 0;
|
30
30
|
const error_1 = require("./error");
|
31
31
|
const workflow_1 = require("./workflow");
|
32
32
|
const transaction_1 = require("./transaction");
|
@@ -46,7 +46,6 @@ const serialize_error_1 = require("serialize-error");
|
|
46
46
|
const utils_1 = require("./utils");
|
47
47
|
const node_path_1 = __importDefault(require("node:path"));
|
48
48
|
const _1 = require(".");
|
49
|
-
const lodash_1 = require("lodash");
|
50
49
|
const wfqueue_1 = require("./wfqueue");
|
51
50
|
const debugpoint_1 = require("./debugpoint");
|
52
51
|
const scheduler_1 = require("./scheduler/scheduler");
|
@@ -55,16 +54,6 @@ const workflow_management_1 = require("./dbos-runtime/workflow_management");
|
|
55
54
|
exports.dbosNull = {};
|
56
55
|
exports.DBOS_QUEUE_MIN_PRIORITY = 1;
|
57
56
|
exports.DBOS_QUEUE_MAX_PRIORITY = 2 ** 31 - 1; // 2,147,483,647
|
58
|
-
function isDeprecatedDBOSConfig(config) {
|
59
|
-
const isDeprecated = config.poolConfig !== undefined ||
|
60
|
-
config.telemetry !== undefined ||
|
61
|
-
config.system_database !== undefined ||
|
62
|
-
config.env !== undefined ||
|
63
|
-
config.application !== undefined ||
|
64
|
-
config.http !== undefined;
|
65
|
-
return isDeprecated;
|
66
|
-
}
|
67
|
-
exports.isDeprecatedDBOSConfig = isDeprecatedDBOSConfig;
|
68
57
|
exports.OperationType = {
|
69
58
|
HANDLER: 'handler',
|
70
59
|
WORKFLOW: 'workflow',
|
@@ -88,27 +77,6 @@ class DBOSExecutor {
|
|
88
77
|
procedurePool;
|
89
78
|
// Temporary workflows are created by calling transaction/send/recv directly from the executor class
|
90
79
|
static tempWorkflowName = 'temp_workflow';
|
91
|
-
workflowInfoMap = new Map([
|
92
|
-
// We initialize the map with an entry for temporary workflows.
|
93
|
-
[
|
94
|
-
DBOSExecutor.tempWorkflowName,
|
95
|
-
{
|
96
|
-
workflow: async () => {
|
97
|
-
this.logger.error('UNREACHABLE: Indirect invoke of temp workflow');
|
98
|
-
return Promise.resolve();
|
99
|
-
},
|
100
|
-
workflowOrigFunction: async () => {
|
101
|
-
this.logger.error('UNREACHABLE: Indirect invoke of temp workflow');
|
102
|
-
return Promise.resolve();
|
103
|
-
},
|
104
|
-
config: {},
|
105
|
-
},
|
106
|
-
],
|
107
|
-
]);
|
108
|
-
transactionInfoMap = new Map();
|
109
|
-
stepInfoMap = new Map();
|
110
|
-
procedureInfoMap = new Map();
|
111
|
-
registeredOperations = [];
|
112
80
|
telemetryCollector;
|
113
81
|
static defaultNotificationTimeoutSec = 60;
|
114
82
|
debugMode;
|
@@ -119,8 +87,7 @@ class DBOSExecutor {
|
|
119
87
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
120
88
|
typeormEntities = [];
|
121
89
|
drizzleEntities = {};
|
122
|
-
|
123
|
-
scheduler = undefined;
|
90
|
+
scheduler = new scheduler_1.ScheduledReceiver();
|
124
91
|
wfqEnded = undefined;
|
125
92
|
executorID = utils_1.globalParams.executorID;
|
126
93
|
static globalInstance = undefined;
|
@@ -128,17 +95,6 @@ class DBOSExecutor {
|
|
128
95
|
constructor(config, { systemDatabase, debugMode } = {}) {
|
129
96
|
this.config = config;
|
130
97
|
this.debugMode = debugMode ?? false;
|
131
|
-
// Set configured environment variables
|
132
|
-
if (config.env) {
|
133
|
-
for (const [key, value] of Object.entries(config.env)) {
|
134
|
-
if (typeof value === 'string') {
|
135
|
-
process.env[key] = value;
|
136
|
-
}
|
137
|
-
else {
|
138
|
-
console.warn(`Invalid value type for environment variable ${key}: ${typeof value}`);
|
139
|
-
}
|
140
|
-
}
|
141
|
-
}
|
142
98
|
if (config.telemetry.OTLPExporter) {
|
143
99
|
const OTLPExporter = new exporters_1.TelemetryExporter(config.telemetry.OTLPExporter);
|
144
100
|
this.telemetryCollector = new collector_1.TelemetryCollector(OTLPExporter);
|
@@ -233,39 +189,6 @@ class DBOSExecutor {
|
|
233
189
|
this.logger.debug('Loaded Postgres user database');
|
234
190
|
}
|
235
191
|
}
|
236
|
-
#registerClass(clsname) {
|
237
|
-
const registeredClassOperations = (0, decorators_1.getRegisteredOperationsByClassname)(clsname);
|
238
|
-
this.registeredOperations.push(...registeredClassOperations);
|
239
|
-
for (const ro of registeredClassOperations) {
|
240
|
-
if (ro.workflowConfig) {
|
241
|
-
this.#registerWorkflow(ro);
|
242
|
-
}
|
243
|
-
else if (ro.txnConfig) {
|
244
|
-
this.#registerTransaction(ro);
|
245
|
-
}
|
246
|
-
else if (ro.stepConfig) {
|
247
|
-
this.#registerStep(ro);
|
248
|
-
}
|
249
|
-
else if (ro.procConfig) {
|
250
|
-
this.#registerProcedure(ro);
|
251
|
-
}
|
252
|
-
for (const [evtRcvr, _cfg] of ro.eventReceiverInfo) {
|
253
|
-
if (!this.eventReceivers.includes(evtRcvr))
|
254
|
-
this.eventReceivers.push(evtRcvr);
|
255
|
-
}
|
256
|
-
}
|
257
|
-
}
|
258
|
-
getRegistrationsFor(obj) {
|
259
|
-
const res = [];
|
260
|
-
for (const r of this.registeredOperations) {
|
261
|
-
if (!r.eventReceiverInfo.has(obj))
|
262
|
-
continue;
|
263
|
-
const methodConfig = r.eventReceiverInfo.get(obj);
|
264
|
-
const classConfig = r.defaults?.eventReceiverInfo.get(obj) ?? {};
|
265
|
-
res.push({ methodReg: r, methodConfig, classConfig });
|
266
|
-
}
|
267
|
-
return res;
|
268
|
-
}
|
269
192
|
async init(classes) {
|
270
193
|
if (this.initialized) {
|
271
194
|
this.logger.error('Workflow executor already initialized!');
|
@@ -306,9 +229,6 @@ class DBOSExecutor {
|
|
306
229
|
this.logger.error('No user database configured!');
|
307
230
|
throw new error_1.DBOSInitializationError('No user database configured!');
|
308
231
|
}
|
309
|
-
for (const cls of classnames) {
|
310
|
-
this.#registerClass(cls);
|
311
|
-
}
|
312
232
|
// Debug mode doesn't need to initialize the DBs. Everything should appear to be read-only.
|
313
233
|
await this.userDatabase.init(this.debugMode);
|
314
234
|
if (!this.debugMode) {
|
@@ -342,7 +262,7 @@ class DBOSExecutor {
|
|
342
262
|
await cfg.initialize(new _1.InitContext());
|
343
263
|
}
|
344
264
|
}
|
345
|
-
for (const v of
|
265
|
+
for (const v of (0, decorators_1.getAllRegisteredFunctions)()) {
|
346
266
|
const m = v;
|
347
267
|
if (m.init === true) {
|
348
268
|
this.logger.debug('Executing init method: ' + m.name);
|
@@ -402,109 +322,11 @@ class DBOSExecutor {
|
|
402
322
|
throw err;
|
403
323
|
}
|
404
324
|
}
|
405
|
-
|
406
|
-
#
|
407
|
-
const
|
408
|
-
|
409
|
-
throw new error_1.DBOSError(`Unexpected use of reserved workflow name: ${wf.name}`);
|
410
|
-
}
|
411
|
-
const wfn = ro.className + '.' + ro.name;
|
412
|
-
if (this.workflowInfoMap.has(wfn)) {
|
413
|
-
throw new error_1.DBOSError(`Repeated workflow name: ${wfn}`);
|
414
|
-
}
|
415
|
-
const workflowInfo = {
|
416
|
-
workflow: wf,
|
417
|
-
workflowOrigFunction: ro.origFunction,
|
418
|
-
config: { ...ro.workflowConfig },
|
419
|
-
registration: ro,
|
420
|
-
};
|
421
|
-
this.workflowInfoMap.set(wfn, workflowInfo);
|
422
|
-
this.logger.debug(`Registered workflow ${wfn}`);
|
423
|
-
}
|
424
|
-
#registerTransaction(ro) {
|
425
|
-
const txf = ro.registeredFunction;
|
426
|
-
const tfn = ro.className + '.' + ro.name;
|
427
|
-
if (this.transactionInfoMap.has(tfn)) {
|
428
|
-
throw new error_1.DBOSError(`Repeated Transaction name: ${tfn}`);
|
429
|
-
}
|
430
|
-
const txnInfo = {
|
431
|
-
transaction: txf,
|
432
|
-
config: { ...ro.txnConfig },
|
433
|
-
registration: ro,
|
434
|
-
};
|
435
|
-
this.transactionInfoMap.set(tfn, txnInfo);
|
436
|
-
this.logger.debug(`Registered transaction ${tfn}`);
|
437
|
-
}
|
438
|
-
#registerStep(ro) {
|
439
|
-
const comm = ro.registeredFunction;
|
440
|
-
const cfn = ro.className + '.' + ro.name;
|
441
|
-
if (this.stepInfoMap.has(cfn)) {
|
442
|
-
throw new error_1.DBOSError(`Repeated Commmunicator name: ${cfn}`);
|
443
|
-
}
|
444
|
-
const stepInfo = {
|
445
|
-
step: comm,
|
446
|
-
config: { ...ro.stepConfig },
|
447
|
-
registration: ro,
|
448
|
-
};
|
449
|
-
this.stepInfoMap.set(cfn, stepInfo);
|
450
|
-
this.logger.debug(`Registered step ${cfn}`);
|
451
|
-
}
|
452
|
-
#registerProcedure(ro) {
|
453
|
-
const proc = ro.registeredFunction;
|
454
|
-
const cfn = ro.className + '.' + ro.name;
|
455
|
-
if (this.procedureInfoMap.has(cfn)) {
|
456
|
-
throw new error_1.DBOSError(`Repeated Procedure name: ${cfn}`);
|
457
|
-
}
|
458
|
-
const procInfo = {
|
459
|
-
procedure: proc,
|
460
|
-
config: { ...ro.procConfig },
|
461
|
-
registration: ro,
|
462
|
-
};
|
463
|
-
this.procedureInfoMap.set(cfn, procInfo);
|
464
|
-
this.logger.debug(`Registered stored proc ${cfn}`);
|
465
|
-
}
|
466
|
-
getWorkflowInfo(wf) {
|
467
|
-
const wfname = wf.name === DBOSExecutor.tempWorkflowName ? wf.name : (0, decorators_1.getRegisteredMethodClassName)(wf) + '.' + wf.name;
|
468
|
-
return this.workflowInfoMap.get(wfname);
|
469
|
-
}
|
470
|
-
getWorkflowInfoByStatus(wf) {
|
471
|
-
const wfname = wf.workflowClassName + '.' + wf.workflowName;
|
472
|
-
const wfInfo = this.workflowInfoMap.get(wfname);
|
473
|
-
// wfInfo may be undefined here, if this is a temp workflow
|
474
|
-
return { wfInfo, configuredInst: (0, decorators_1.getConfiguredInstance)(wf.workflowClassName, wf.workflowConfigName) };
|
475
|
-
}
|
476
|
-
getTransactionInfo(tf) {
|
477
|
-
const tfname = (0, decorators_1.getRegisteredMethodClassName)(tf) + '.' + tf.name;
|
478
|
-
return this.transactionInfoMap.get(tfname);
|
479
|
-
}
|
480
|
-
getTransactionInfoByNames(className, functionName, cfgName) {
|
481
|
-
const tfname = className + '.' + functionName;
|
482
|
-
const txnInfo = this.transactionInfoMap.get(tfname);
|
483
|
-
if (!txnInfo) {
|
484
|
-
throw new error_1.DBOSNotRegisteredError(tfname, `Transaction function name '${tfname}' is not registered.`);
|
485
|
-
}
|
486
|
-
return { txnInfo, clsInst: (0, decorators_1.getConfiguredInstance)(className, cfgName) };
|
325
|
+
// This could return WF, or the function underlying a temp wf
|
326
|
+
#getFunctionInfoFromWFStatus(wf) {
|
327
|
+
const methReg = (0, decorators_1.getFunctionRegistrationByName)(wf.workflowClassName, wf.workflowName);
|
328
|
+
return { methReg, configuredInst: (0, decorators_1.getConfiguredInstance)(wf.workflowClassName, wf.workflowConfigName) };
|
487
329
|
}
|
488
|
-
getStepInfo(cf) {
|
489
|
-
const cfname = (0, decorators_1.getRegisteredMethodClassName)(cf) + '.' + cf.name;
|
490
|
-
return this.stepInfoMap.get(cfname);
|
491
|
-
}
|
492
|
-
getStepInfoByNames(className, functionName, cfgName) {
|
493
|
-
const cfname = className + '.' + functionName;
|
494
|
-
const stepInfo = this.stepInfoMap.get(cfname);
|
495
|
-
if (!stepInfo) {
|
496
|
-
throw new error_1.DBOSNotRegisteredError(cfname, `Step function name '${cfname}' is not registered.`);
|
497
|
-
}
|
498
|
-
return { commInfo: stepInfo, clsInst: (0, decorators_1.getConfiguredInstance)(className, cfgName) };
|
499
|
-
}
|
500
|
-
getProcedureClassName(pf) {
|
501
|
-
return (0, decorators_1.getRegisteredMethodClassName)(pf);
|
502
|
-
}
|
503
|
-
getProcedureInfo(pf) {
|
504
|
-
const pfName = (0, decorators_1.getRegisteredMethodClassName)(pf) + '.' + pf.name;
|
505
|
-
return this.procedureInfoMap.get(pfName);
|
506
|
-
}
|
507
|
-
// TODO: getProcedureInfoByNames??
|
508
330
|
static reviveResultOrError(r, success) {
|
509
331
|
if (success === true || !r.error) {
|
510
332
|
return utils_1.DBOSJSON.parse(r.output ?? null);
|
@@ -541,18 +363,21 @@ class DBOSExecutor {
|
|
541
363
|
}
|
542
364
|
}
|
543
365
|
const pctx = (0, context_1.getCurrentContextStore)();
|
544
|
-
|
545
|
-
|
546
|
-
|
366
|
+
let wConfig = {};
|
367
|
+
const wInfo = (0, decorators_1.getFunctionRegistration)(wf);
|
368
|
+
if (wf.name !== DBOSExecutor.tempWorkflowName) {
|
369
|
+
if (!wInfo || !wInfo.workflowConfig) {
|
370
|
+
throw new error_1.DBOSNotRegisteredError(wf.name);
|
371
|
+
}
|
372
|
+
wConfig = wInfo.workflowConfig;
|
547
373
|
}
|
548
|
-
const wConfig = wInfo.config;
|
549
374
|
const maxRecoveryAttempts = wConfig.maxRecoveryAttempts ? wConfig.maxRecoveryAttempts : 50;
|
550
375
|
const wfname = wf.name; // TODO: Should be what was registered in wfInfo...
|
551
376
|
const span = this.tracer.startSpan(wfname, {
|
552
377
|
status: workflow_1.StatusString.PENDING,
|
553
378
|
operationUUID: workflowID,
|
554
379
|
operationType: exports.OperationType.WORKFLOW,
|
555
|
-
operationName: wInfo
|
380
|
+
operationName: wInfo?.name ?? wf.name,
|
556
381
|
authenticatedUser: pctx?.authenticatedUser ?? '',
|
557
382
|
authenticatedRoles: pctx?.authenticatedRoles ?? [],
|
558
383
|
assumedRole: pctx?.assumedRole ?? '',
|
@@ -561,8 +386,8 @@ class DBOSExecutor {
|
|
561
386
|
const internalStatus = {
|
562
387
|
workflowUUID: workflowID,
|
563
388
|
status: params.queueName !== undefined ? workflow_1.StatusString.ENQUEUED : workflow_1.StatusString.PENDING,
|
564
|
-
workflowName:
|
565
|
-
workflowClassName: isTempWorkflow ? '' : (0, decorators_1.
|
389
|
+
workflowName: (0, decorators_1.getRegisteredFunctionName)(wf),
|
390
|
+
workflowClassName: isTempWorkflow ? '' : (0, decorators_1.getRegisteredFunctionClassName)(wf),
|
566
391
|
workflowConfigName: params.configuredInstance?.name || '',
|
567
392
|
queueName: params.queueName,
|
568
393
|
output: null,
|
@@ -837,7 +662,7 @@ class DBOSExecutor {
|
|
837
662
|
}
|
838
663
|
return rows;
|
839
664
|
}
|
840
|
-
async
|
665
|
+
async runTransactionTempWF(txn, params, ...args) {
|
841
666
|
return await (await this.startTransactionTempWF(txn, params, undefined, undefined, ...args)).getResult();
|
842
667
|
}
|
843
668
|
async startTransactionTempWF(txn, params, callerWFID, callerFunctionID, ...args) {
|
@@ -848,13 +673,13 @@ class DBOSExecutor {
|
|
848
673
|
return await this.internalWorkflow(temp_workflow, {
|
849
674
|
...params,
|
850
675
|
tempWfType: exports.TempWorkflowType.transaction,
|
851
|
-
tempWfName: (0, decorators_1.
|
852
|
-
tempWfClass: (0, decorators_1.
|
676
|
+
tempWfName: (0, decorators_1.getRegisteredFunctionName)(txn),
|
677
|
+
tempWfClass: (0, decorators_1.getRegisteredFunctionClassName)(txn),
|
853
678
|
}, callerWFID, callerFunctionID, ...args);
|
854
679
|
}
|
855
680
|
async callTransactionFunction(txn, clsinst, ...args) {
|
856
|
-
const
|
857
|
-
if (
|
681
|
+
const txnReg = (0, decorators_1.getFunctionRegistration)(txn);
|
682
|
+
if (!txnReg || !txnReg.txnConfig) {
|
858
683
|
throw new error_1.DBOSNotRegisteredError(txn.name);
|
859
684
|
}
|
860
685
|
const pctx = (0, context_1.getCurrentContextStore)();
|
@@ -871,7 +696,7 @@ class DBOSExecutor {
|
|
871
696
|
authenticatedUser: pctx.authenticatedUser ?? '',
|
872
697
|
assumedRole: pctx.assumedRole ?? '',
|
873
698
|
authenticatedRoles: pctx.authenticatedRoles ?? [],
|
874
|
-
isolationLevel:
|
699
|
+
isolationLevel: txnReg.txnConfig.isolationLevel,
|
875
700
|
}, pctx.span);
|
876
701
|
while (true) {
|
877
702
|
await this.systemDatabase.checkIfCanceled(wfid);
|
@@ -959,7 +784,7 @@ class DBOSExecutor {
|
|
959
784
|
return result;
|
960
785
|
};
|
961
786
|
try {
|
962
|
-
const result = await this.userDatabase.transaction(wrappedTransaction,
|
787
|
+
const result = await this.userDatabase.transaction(wrappedTransaction, txnReg.txnConfig);
|
963
788
|
span.setStatus({ code: api_1.SpanStatusCode.OK });
|
964
789
|
this.tracer.endSpan(span);
|
965
790
|
return result;
|
@@ -989,7 +814,7 @@ class DBOSExecutor {
|
|
989
814
|
}
|
990
815
|
}
|
991
816
|
}
|
992
|
-
async
|
817
|
+
async runProcedureTempWF(proc, params, ...args) {
|
993
818
|
// Create a workflow and call procedure.
|
994
819
|
const temp_workflow = async (...args) => {
|
995
820
|
return this.callProcedureFunction(proc, ...args);
|
@@ -997,19 +822,20 @@ class DBOSExecutor {
|
|
997
822
|
return await (await this.workflow(temp_workflow, {
|
998
823
|
...params,
|
999
824
|
tempWfType: exports.TempWorkflowType.procedure,
|
1000
|
-
tempWfName: (0, decorators_1.
|
1001
|
-
tempWfClass: (0, decorators_1.
|
825
|
+
tempWfName: (0, decorators_1.getRegisteredFunctionName)(proc),
|
826
|
+
tempWfClass: (0, decorators_1.getRegisteredFunctionClassName)(proc),
|
1002
827
|
}, ...args)).getResult();
|
1003
828
|
}
|
1004
829
|
async callProcedureFunction(proc, ...args) {
|
1005
|
-
const procInfo =
|
1006
|
-
if (procInfo
|
830
|
+
const procInfo = (0, decorators_1.getFunctionRegistration)(proc);
|
831
|
+
if (!procInfo || !procInfo.procConfig) {
|
1007
832
|
throw new error_1.DBOSNotRegisteredError(proc.name);
|
1008
833
|
}
|
834
|
+
const procConfig = procInfo.procConfig;
|
1009
835
|
const pctx = (0, context_1.getCurrentContextStore)();
|
1010
836
|
const wfid = pctx.workflowId;
|
1011
837
|
await this.systemDatabase.checkIfCanceled(wfid);
|
1012
|
-
const executeLocally = this.debugMode || (
|
838
|
+
const executeLocally = this.debugMode || (procConfig.executeLocally ?? false);
|
1013
839
|
const funcId = (0, context_1.functionIDGetIncrement)();
|
1014
840
|
const span = this.tracer.startSpan(proc.name, {
|
1015
841
|
operationUUID: wfid,
|
@@ -1018,13 +844,13 @@ class DBOSExecutor {
|
|
1018
844
|
authenticatedUser: pctx.authenticatedUser ?? '',
|
1019
845
|
assumedRole: pctx.assumedRole ?? '',
|
1020
846
|
authenticatedRoles: pctx.authenticatedRoles ?? [],
|
1021
|
-
isolationLevel: procInfo.
|
847
|
+
isolationLevel: procInfo.procConfig.isolationLevel,
|
1022
848
|
executeLocally,
|
1023
849
|
}, pctx.span);
|
1024
850
|
try {
|
1025
851
|
const result = executeLocally
|
1026
852
|
? await this.#callProcedureFunctionLocal(proc, args, span, procInfo, funcId)
|
1027
|
-
: await this.#callProcedureFunctionRemote(proc, args, span,
|
853
|
+
: await this.#callProcedureFunctionRemote(proc, args, span, procConfig, funcId);
|
1028
854
|
span.setStatus({ code: api_1.SpanStatusCode.OK });
|
1029
855
|
return result;
|
1030
856
|
}
|
@@ -1120,7 +946,7 @@ class DBOSExecutor {
|
|
1120
946
|
};
|
1121
947
|
try {
|
1122
948
|
const result = await this.invokeStoredProcFunction(wrappedProcedure, {
|
1123
|
-
isolationLevel: procInfo.
|
949
|
+
isolationLevel: procInfo.procConfig.isolationLevel,
|
1124
950
|
});
|
1125
951
|
span.setStatus({ code: api_1.SpanStatusCode.OK });
|
1126
952
|
return result;
|
@@ -1188,8 +1014,8 @@ class DBOSExecutor {
|
|
1188
1014
|
async #invokeStoredProc(proc, args) {
|
1189
1015
|
const client = await this.procedurePool.connect();
|
1190
1016
|
const log = (msg) => this.#logNotice(msg);
|
1191
|
-
const
|
1192
|
-
const plainProcName = `${
|
1017
|
+
const procname = (0, decorators_1.getRegisteredFunctionFullName)(proc);
|
1018
|
+
const plainProcName = `${procname.className}_${procname.name}_p`;
|
1193
1019
|
const procName = utils_1.globalParams.wasComputed ? plainProcName : `v${utils_1.globalParams.appVersion}_${plainProcName}`;
|
1194
1020
|
const sql = `CALL "${procName}"(${args.map((_v, i) => `$${i + 1}`).join()});`;
|
1195
1021
|
try {
|
@@ -1222,7 +1048,7 @@ class DBOSExecutor {
|
|
1222
1048
|
client.release();
|
1223
1049
|
}
|
1224
1050
|
}
|
1225
|
-
async
|
1051
|
+
async runStepTempWF(stepFn, params, ...args) {
|
1226
1052
|
return await (await this.startStepTempWF(stepFn, params, undefined, undefined, ...args)).getResult();
|
1227
1053
|
}
|
1228
1054
|
async startStepTempWF(stepFn, params, callerWFID, callerFunctionID, ...args) {
|
@@ -1233,8 +1059,8 @@ class DBOSExecutor {
|
|
1233
1059
|
return await this.internalWorkflow(temp_workflow, {
|
1234
1060
|
...params,
|
1235
1061
|
tempWfType: exports.TempWorkflowType.step,
|
1236
|
-
tempWfName: (0, decorators_1.
|
1237
|
-
tempWfClass: (0, decorators_1.
|
1062
|
+
tempWfName: (0, decorators_1.getRegisteredFunctionName)(stepFn),
|
1063
|
+
tempWfClass: (0, decorators_1.getRegisteredFunctionClassName)(stepFn),
|
1238
1064
|
}, callerWFID, callerFunctionID, ...args);
|
1239
1065
|
}
|
1240
1066
|
/**
|
@@ -1245,8 +1071,8 @@ class DBOSExecutor {
|
|
1245
1071
|
async callStepFunction(stepFn, stepFnName, stepConfig, clsInst, ...args) {
|
1246
1072
|
stepFnName = stepFnName ?? stepFn.name ?? '<unnamed>';
|
1247
1073
|
if (!stepConfig) {
|
1248
|
-
const stepReg =
|
1249
|
-
stepConfig = stepReg?.
|
1074
|
+
const stepReg = (0, decorators_1.getFunctionRegistration)(stepFn);
|
1075
|
+
stepConfig = stepReg?.stepConfig;
|
1250
1076
|
}
|
1251
1077
|
if (stepConfig === undefined) {
|
1252
1078
|
throw new error_1.DBOSNotRegisteredError(stepFnName);
|
@@ -1354,7 +1180,7 @@ class DBOSExecutor {
|
|
1354
1180
|
return result;
|
1355
1181
|
}
|
1356
1182
|
}
|
1357
|
-
async
|
1183
|
+
async runSendTempWF(destinationId, message, topic, idempotencyKey) {
|
1358
1184
|
// Create a workflow and call send.
|
1359
1185
|
const temp_workflow = async (destinationId, message, topic) => {
|
1360
1186
|
const ctx = (0, context_1.getCurrentContextStore)();
|
@@ -1434,26 +1260,6 @@ class DBOSExecutor {
|
|
1434
1260
|
return await this.userDatabase.query(sql);
|
1435
1261
|
}
|
1436
1262
|
}
|
1437
|
-
async userDBListen(channels, callback) {
|
1438
|
-
const notificationsClient = await this.procedurePool.connect();
|
1439
|
-
for (const nname of channels) {
|
1440
|
-
await notificationsClient.query(`LISTEN ${nname};`);
|
1441
|
-
}
|
1442
|
-
notificationsClient.on('notification', callback);
|
1443
|
-
return {
|
1444
|
-
close: async () => {
|
1445
|
-
for (const nname of channels) {
|
1446
|
-
try {
|
1447
|
-
await notificationsClient.query(`UNLISTEN ${nname};`);
|
1448
|
-
}
|
1449
|
-
catch (e) {
|
1450
|
-
this.logger.warn(e);
|
1451
|
-
}
|
1452
|
-
notificationsClient.release();
|
1453
|
-
}
|
1454
|
-
},
|
1455
|
-
};
|
1456
|
-
}
|
1457
1263
|
/* INTERNAL HELPERS */
|
1458
1264
|
/**
|
1459
1265
|
* A recovery process that by default runs during executor init time.
|
@@ -1498,12 +1304,7 @@ class DBOSExecutor {
|
|
1498
1304
|
return handlerArray;
|
1499
1305
|
}
|
1500
1306
|
async initEventReceivers() {
|
1501
|
-
this.scheduler = new scheduler_1.DBOSScheduler(this);
|
1502
|
-
this.scheduler.initScheduler();
|
1503
1307
|
this.wfqEnded = wfqueue_1.wfQueueRunner.dispatchLoop(this);
|
1504
|
-
for (const evtRcvr of this.eventReceivers) {
|
1505
|
-
await evtRcvr.initialize(this);
|
1506
|
-
}
|
1507
1308
|
for (const lcl of (0, decorators_1.getLifecycleListeners)()) {
|
1508
1309
|
await lcl.initialize?.();
|
1509
1310
|
}
|
@@ -1519,23 +1320,7 @@ class DBOSExecutor {
|
|
1519
1320
|
this.logger.warn(`Error destroying lifecycle listener: ${e.message}`);
|
1520
1321
|
}
|
1521
1322
|
}
|
1522
|
-
this.logger.debug('Deactivating
|
1523
|
-
for (const evtRcvr of this.eventReceivers || []) {
|
1524
|
-
try {
|
1525
|
-
await evtRcvr.destroy();
|
1526
|
-
}
|
1527
|
-
catch (err) {
|
1528
|
-
const e = err;
|
1529
|
-
this.logger.warn(`Error destroying event receiver: ${e.message}`);
|
1530
|
-
}
|
1531
|
-
}
|
1532
|
-
try {
|
1533
|
-
await this.scheduler?.destroyScheduler();
|
1534
|
-
}
|
1535
|
-
catch (err) {
|
1536
|
-
const e = err;
|
1537
|
-
this.logger.warn(`Error destroying scheduler: ${e.message}`);
|
1538
|
-
}
|
1323
|
+
this.logger.debug('Deactivating queue runner');
|
1539
1324
|
if (stopQueueThread) {
|
1540
1325
|
try {
|
1541
1326
|
wfqueue_1.wfQueueRunner.stop();
|
@@ -1559,12 +1344,12 @@ class DBOSExecutor {
|
|
1559
1344
|
}
|
1560
1345
|
const inputs = utils_1.DBOSJSON.parse(wfStatus.input);
|
1561
1346
|
const recoverCtx = this.#getRecoveryContext(workflowID, wfStatus);
|
1562
|
-
const {
|
1347
|
+
const { methReg, configuredInst } = this.#getFunctionInfoFromWFStatus(wfStatus);
|
1563
1348
|
// If starting a new workflow, assign a new UUID. Otherwise, use the workflow's original UUID.
|
1564
1349
|
const workflowStartID = startNewWorkflow ? undefined : workflowID;
|
1565
|
-
if (
|
1350
|
+
if (methReg?.workflowConfig) {
|
1566
1351
|
return await (0, context_1.runWithTopContext)(recoverCtx, async () => {
|
1567
|
-
return await this.workflow(
|
1352
|
+
return await this.workflow(methReg.registeredFunction, {
|
1568
1353
|
workflowUUID: workflowStartID,
|
1569
1354
|
configuredInstance: configuredInst,
|
1570
1355
|
queueName: wfStatus.queueName,
|
@@ -1577,34 +1362,33 @@ class DBOSExecutor {
|
|
1577
1362
|
const wfName = wfStatus.workflowName;
|
1578
1363
|
const nameArr = wfName.split('-');
|
1579
1364
|
if (!nameArr[0].startsWith(DBOSExecutor.tempWorkflowName)) {
|
1580
|
-
|
1581
|
-
throw new error_1.DBOSError(`This should never happen! Cannot find workflow info for a non-temporary workflow! UUID ${workflowID}, name ${wfName}`);
|
1365
|
+
throw new error_1.DBOSError(`Cannot find workflow function for a non-temporary workflow, ID ${workflowID}, class '${wfStatus.workflowClassName}', function '${wfName}'; did you change your code?`);
|
1582
1366
|
}
|
1583
1367
|
if (nameArr[1] === exports.TempWorkflowType.transaction) {
|
1584
|
-
const
|
1585
|
-
if (!
|
1586
|
-
this.logger.error(`Cannot find transaction info for
|
1368
|
+
const txnReg = (0, decorators_1.getFunctionRegistrationByName)(wfStatus.workflowClassName, nameArr[2]);
|
1369
|
+
if (!txnReg?.txnConfig) {
|
1370
|
+
this.logger.error(`Cannot find transaction info for ID ${workflowID}, name ${nameArr[2]}`);
|
1587
1371
|
throw new error_1.DBOSNotRegisteredError(nameArr[2]);
|
1588
1372
|
}
|
1589
1373
|
return await (0, context_1.runWithTopContext)(recoverCtx, async () => {
|
1590
|
-
return await this.startTransactionTempWF(
|
1374
|
+
return await this.startTransactionTempWF(txnReg.registeredFunction, {
|
1591
1375
|
workflowUUID: workflowStartID,
|
1592
|
-
configuredInstance:
|
1376
|
+
configuredInstance: configuredInst,
|
1593
1377
|
queueName: wfStatus.queueName,
|
1594
1378
|
executeWorkflow: true,
|
1595
1379
|
}, undefined, undefined, ...inputs);
|
1596
1380
|
});
|
1597
1381
|
}
|
1598
1382
|
else if (nameArr[1] === exports.TempWorkflowType.step) {
|
1599
|
-
const
|
1600
|
-
if (!
|
1601
|
-
this.logger.error(`Cannot find step info for
|
1383
|
+
const stepReg = (0, decorators_1.getFunctionRegistrationByName)(wfStatus.workflowClassName, nameArr[2]);
|
1384
|
+
if (!stepReg?.stepConfig) {
|
1385
|
+
this.logger.error(`Cannot find step info for ID ${workflowID}, name ${nameArr[2]}`);
|
1602
1386
|
throw new error_1.DBOSNotRegisteredError(nameArr[2]);
|
1603
1387
|
}
|
1604
1388
|
return await (0, context_1.runWithTopContext)(recoverCtx, async () => {
|
1605
|
-
return await this.startStepTempWF(
|
1389
|
+
return await this.startStepTempWF(stepReg.registeredFunction, {
|
1606
1390
|
workflowUUID: workflowStartID,
|
1607
|
-
configuredInstance:
|
1391
|
+
configuredInstance: configuredInst,
|
1608
1392
|
queueName: wfStatus.queueName, // Probably null
|
1609
1393
|
executeWorkflow: true,
|
1610
1394
|
}, undefined, undefined, ...inputs);
|
@@ -1667,7 +1451,7 @@ class DBOSExecutor {
|
|
1667
1451
|
}
|
1668
1452
|
logRegisteredHTTPUrls() {
|
1669
1453
|
this.logger.info('HTTP endpoints supported:');
|
1670
|
-
|
1454
|
+
(0, decorators_1.getAllRegisteredFunctions)().forEach((registeredOperation) => {
|
1671
1455
|
const ro = registeredOperation;
|
1672
1456
|
if (ro.apiURL) {
|
1673
1457
|
this.logger.info(' ' + ro.apiType.padEnd(6) + ' : ' + ro.apiURL);
|
@@ -1678,14 +1462,6 @@ class DBOSExecutor {
|
|
1678
1462
|
}
|
1679
1463
|
});
|
1680
1464
|
}
|
1681
|
-
getConfig(key, defaultValue) {
|
1682
|
-
const value = (0, lodash_1.get)(this.config.application, key, defaultValue);
|
1683
|
-
// If the key is found and the default value is provided, check whether the value is of the same type.
|
1684
|
-
if (value && defaultValue && typeof value !== typeof defaultValue) {
|
1685
|
-
throw new error_1.DBOSConfigKeyTypeError(key, typeof defaultValue, typeof value);
|
1686
|
-
}
|
1687
|
-
return value;
|
1688
|
-
}
|
1689
1465
|
/**
|
1690
1466
|
An application's version is computed from a hash of the source of its workflows.
|
1691
1467
|
This is guaranteed to be stable given identical source code because it uses an MD5 hash
|
@@ -1695,8 +1471,9 @@ class DBOSExecutor {
|
|
1695
1471
|
*/
|
1696
1472
|
computeAppVersion() {
|
1697
1473
|
const hasher = crypto.createHash('md5');
|
1698
|
-
const sortedWorkflowSource = Array.from(
|
1699
|
-
.
|
1474
|
+
const sortedWorkflowSource = Array.from((0, decorators_1.getAllRegisteredFunctions)())
|
1475
|
+
.filter((e) => e.workflowConfig)
|
1476
|
+
.map((i) => i.origFunction.toString())
|
1700
1477
|
.sort();
|
1701
1478
|
// Different DBOS versions should produce different hashes.
|
1702
1479
|
sortedWorkflowSource.push(utils_1.globalParams.dbosVersion);
|