@solidactions/sdk 0.1.1 → 0.2.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.
Files changed (52) hide show
  1. package/README.md +25 -4
  2. package/dist/src/cli/cli.js +0 -0
  3. package/dist/src/testing/index.d.ts +13 -0
  4. package/dist/src/testing/index.d.ts.map +1 -0
  5. package/dist/src/testing/index.js +19 -0
  6. package/dist/src/testing/index.js.map +1 -0
  7. package/dist/src/testing/mock_server.d.ts +134 -0
  8. package/dist/src/testing/mock_server.d.ts.map +1 -0
  9. package/dist/src/testing/mock_server.js +613 -0
  10. package/dist/src/testing/mock_server.js.map +1 -0
  11. package/dist/tsconfig.tsbuildinfo +1 -1
  12. package/docs/sdk-reference.md +1207 -0
  13. package/package.json +6 -1
  14. package/.claude/settings.local.json +0 -7
  15. package/dist/dbos-config.schema.json +0 -132
  16. package/dist/src/cli/commands.d.ts +0 -3
  17. package/dist/src/cli/commands.d.ts.map +0 -1
  18. package/dist/src/cli/commands.js +0 -46
  19. package/dist/src/cli/commands.js.map +0 -1
  20. package/dist/src/datasource.d.ts +0 -109
  21. package/dist/src/datasource.d.ts.map +0 -1
  22. package/dist/src/datasource.js +0 -204
  23. package/dist/src/datasource.js.map +0 -1
  24. package/dist/src/dbos-executor.d.ts +0 -189
  25. package/dist/src/dbos-executor.d.ts.map +0 -1
  26. package/dist/src/dbos-executor.js +0 -817
  27. package/dist/src/dbos-executor.js.map +0 -1
  28. package/dist/src/dbos.d.ts +0 -519
  29. package/dist/src/dbos.d.ts.map +0 -1
  30. package/dist/src/dbos.js +0 -1282
  31. package/dist/src/dbos.js.map +0 -1
  32. package/dist/src/debouncer.d.ts +0 -33
  33. package/dist/src/debouncer.d.ts.map +0 -1
  34. package/dist/src/debouncer.js +0 -170
  35. package/dist/src/debouncer.js.map +0 -1
  36. package/dist/src/scheduler/crontab.d.ts +0 -14
  37. package/dist/src/scheduler/crontab.d.ts.map +0 -1
  38. package/dist/src/scheduler/crontab.js +0 -308
  39. package/dist/src/scheduler/crontab.js.map +0 -1
  40. package/dist/src/scheduler/scheduler.d.ts +0 -41
  41. package/dist/src/scheduler/scheduler.d.ts.map +0 -1
  42. package/dist/src/scheduler/scheduler.js +0 -165
  43. package/dist/src/scheduler/scheduler.js.map +0 -1
  44. package/dist/src/wfqueue.d.ts +0 -64
  45. package/dist/src/wfqueue.d.ts.map +0 -1
  46. package/dist/src/wfqueue.js +0 -147
  47. package/dist/src/wfqueue.js.map +0 -1
  48. package/docs/api-schema.md +0 -1441
  49. package/docs/migration-guide.md +0 -460
  50. package/docs/phase-14-changes.md +0 -156
  51. package/docs/solidsteps-ai-prompt.md +0 -534
  52. package/solidactions-ai-prompt.md +0 -1504
@@ -1,41 +0,0 @@
1
- import { DBOSLifecycleCallback, FunctionName } from '../decorators';
2
- /**
3
- * Choices for scheduler mode for `@DBOS.scheduled` workflows
4
- */
5
- export declare enum SchedulerMode {
6
- /**
7
- * Using `ExactlyOncePerInterval` causes the scheduler to add "make-up work" for any
8
- * schedule slots that occurred when the app was not running
9
- */
10
- ExactlyOncePerInterval = "ExactlyOncePerInterval",
11
- /**
12
- * Using `ExactlyOncePerIntervalWhenActive` causes the scheduler to run the workflow once
13
- * per interval when the application is active. If the app is not running at a time
14
- * otherwise indicated by the schedule, no workflow will be run.
15
- */
16
- ExactlyOncePerIntervalWhenActive = "ExactlyOncePerIntervalWhenActive"
17
- }
18
- /**
19
- * Configuration for a `@DBOS.scheduled` workflow
20
- */
21
- export interface SchedulerConfig {
22
- /** Schedule, in 5- or 6-spot crontab format */
23
- crontab: string;
24
- /**
25
- * Indicates whether or not to retroactively start workflows that were scheduled during
26
- * times when the app was not running. @see `SchedulerMode`.
27
- */
28
- mode?: SchedulerMode;
29
- /** If set, workflows will be enqueued on the named queue, rather than being started immediately */
30
- queueName?: string;
31
- }
32
- export type ScheduledArgs = [Date, Date];
33
- export declare class ScheduledReceiver implements DBOSLifecycleCallback {
34
- #private;
35
- constructor();
36
- initialize(): Promise<void>;
37
- destroy(): Promise<void>;
38
- logRegisteredEndpoints(): void;
39
- static registerScheduled<This, Return>(func: (this: This, ...args: ScheduledArgs) => Promise<Return>, config: SchedulerConfig & FunctionName): void;
40
- }
41
- //# sourceMappingURL=scheduler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/scheduler/scheduler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAA0B,MAAM,eAAe,CAAC;AAQ5F;;GAEG;AACH,oBAAY,aAAa;IACvB;;;OAGG;IACH,sBAAsB,2BAA2B;IACjD;;;;OAIG;IACH,gCAAgC,qCAAqC;CACtE;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,mGAAmG;IACnG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAOD,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AASzC,qBAAa,iBAAkB,YAAW,qBAAqB;;;IASvD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA6B3B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAM9B,sBAAsB,IAAI,IAAI;IA+G9B,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EACnC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,MAAM,CAAC,EAC7D,MAAM,EAAE,eAAe,GAAG,YAAY;CAazC"}
@@ -1,165 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ScheduledReceiver = exports.SchedulerMode = void 0;
4
- const __1 = require("..");
5
- const utils_1 = require("../utils");
6
- const crontab_1 = require("./crontab");
7
- ////
8
- // Configuration
9
- ////
10
- /**
11
- * Choices for scheduler mode for `@DBOS.scheduled` workflows
12
- */
13
- var SchedulerMode;
14
- (function (SchedulerMode) {
15
- /**
16
- * Using `ExactlyOncePerInterval` causes the scheduler to add "make-up work" for any
17
- * schedule slots that occurred when the app was not running
18
- */
19
- SchedulerMode["ExactlyOncePerInterval"] = "ExactlyOncePerInterval";
20
- /**
21
- * Using `ExactlyOncePerIntervalWhenActive` causes the scheduler to run the workflow once
22
- * per interval when the application is active. If the app is not running at a time
23
- * otherwise indicated by the schedule, no workflow will be run.
24
- */
25
- SchedulerMode["ExactlyOncePerIntervalWhenActive"] = "ExactlyOncePerIntervalWhenActive";
26
- })(SchedulerMode || (exports.SchedulerMode = SchedulerMode = {}));
27
- ///////////////////////////
28
- // Scheduler Management
29
- ///////////////////////////
30
- const SCHEDULER_EVENT_SERVICE_NAME = 'dbos.scheduler';
31
- class ScheduledReceiver {
32
- #controller = new AbortController();
33
- #disposables = new Array();
34
- constructor() {
35
- __1.DBOS.registerLifecycleCallback(this);
36
- }
37
- // eslint-disable-next-line @typescript-eslint/require-await
38
- async initialize() {
39
- for (const regOp of __1.DBOS.getAssociatedInfo(SCHEDULER_EVENT_SERVICE_NAME)) {
40
- if (regOp.methodReg.registeredFunction === undefined) {
41
- __1.DBOS.logger.warn(`Scheduled workflow ${regOp.methodReg.className}.${regOp.methodReg.name} is missing registered function; skipping`);
42
- continue;
43
- }
44
- const { crontab, mode, queueName } = regOp.methodConfig;
45
- if (!crontab) {
46
- __1.DBOS.logger.warn(`Scheduled workflow ${regOp.methodReg.className}.${regOp.methodReg.name} is missing crontab; skipping`);
47
- continue;
48
- }
49
- const timeMatcher = new crontab_1.TimeMatcher(crontab);
50
- const promise = ScheduledReceiver.#schedulerLoop(regOp.methodReg, timeMatcher, mode ?? SchedulerMode.ExactlyOncePerIntervalWhenActive, queueName, this.#controller.signal);
51
- this.#disposables.push(promise);
52
- }
53
- }
54
- async destroy() {
55
- this.#controller.abort();
56
- const promises = this.#disposables.splice(0);
57
- await Promise.allSettled(promises);
58
- }
59
- logRegisteredEndpoints() {
60
- __1.DBOS.logger.info('Scheduled endpoints:');
61
- for (const regOp of __1.DBOS.getAssociatedInfo(SCHEDULER_EVENT_SERVICE_NAME)) {
62
- const name = `${regOp.methodReg.className}.${regOp.methodReg.name}`;
63
- const { crontab, mode } = regOp.methodConfig;
64
- if (crontab) {
65
- __1.DBOS.logger.info(` ${name} @ ${crontab}; ${mode ?? SchedulerMode.ExactlyOncePerIntervalWhenActive}`);
66
- }
67
- else {
68
- __1.DBOS.logger.info(` ${name} is missing crontab; skipping`);
69
- }
70
- }
71
- }
72
- static async #schedulerLoop(methodReg, timeMatcher, mode, queueName, signal) {
73
- const name = `${methodReg.className}.${methodReg.name}`;
74
- let lastExec = new Date().setMilliseconds(0);
75
- if (mode === SchedulerMode.ExactlyOncePerInterval) {
76
- const lastState = await __1.DBOS.getEventDispatchState(SCHEDULER_EVENT_SERVICE_NAME, name, 'lastState');
77
- if (lastState?.value) {
78
- lastExec = parseFloat(lastState.value);
79
- }
80
- }
81
- while (!signal.aborted) {
82
- const nextExec = timeMatcher.nextWakeupTime(lastExec).getTime();
83
- const sleepTime = nextExec - Date.now();
84
- if (sleepTime > 0) {
85
- await new Promise((resolve, reject) => {
86
- // eslint-disable-next-line prefer-const
87
- let timeoutID;
88
- const onAbort = () => {
89
- clearTimeout(timeoutID);
90
- reject(new Error('Abort signal received'));
91
- };
92
- signal.addEventListener('abort', onAbort, { once: true });
93
- if (signal.aborted) {
94
- signal.removeEventListener('abort', onAbort);
95
- reject(new Error('Abort signal received'));
96
- }
97
- timeoutID = setTimeout(() => {
98
- signal.removeEventListener('abort', onAbort);
99
- resolve();
100
- }, sleepTime);
101
- });
102
- }
103
- if (signal.aborted) {
104
- break;
105
- }
106
- if (!timeMatcher.match(nextExec)) {
107
- lastExec = nextExec;
108
- continue;
109
- }
110
- const date = new Date(nextExec);
111
- if (methodReg.workflowConfig && methodReg.registeredFunction) {
112
- const workflowID = `sched-${name}-${date.toISOString()}`;
113
- const wfParams = { workflowID, queueName: queueName ?? utils_1.INTERNAL_QUEUE_NAME };
114
- __1.DBOS.logger.debug(`Executing scheduled workflow ${workflowID}`);
115
- await __1.DBOS.startWorkflow(methodReg.registeredFunction, wfParams)(date, new Date());
116
- }
117
- else {
118
- __1.DBOS.logger.error(`${name} is @scheduled but not a workflow`);
119
- }
120
- lastExec = await ScheduledReceiver.#setLastExecTime(name, nextExec);
121
- }
122
- }
123
- static async #setLastExecTime(name, time) {
124
- // Record the time of the wf kicked off
125
- try {
126
- const state = {
127
- service: SCHEDULER_EVENT_SERVICE_NAME,
128
- workflowFnName: name,
129
- key: 'lastState',
130
- value: `${time}`,
131
- updateTime: time,
132
- };
133
- const newState = await __1.DBOS.upsertEventDispatchState(state);
134
- const dbTime = parseFloat(newState.value);
135
- if (dbTime && dbTime > time) {
136
- return dbTime;
137
- }
138
- }
139
- catch (e) {
140
- // This write is not strictly essential and the scheduler is often the "canary in the coal mine"
141
- // We will simply continue after giving full details.
142
- const err = e;
143
- __1.DBOS.logger.warn(`Scheduler caught an error writing to system DB: ${err.message}`);
144
- __1.DBOS.logger.error(e);
145
- }
146
- return time;
147
- }
148
- // registerScheduled is static so it can be called before an instance is created during DBOS.launch.
149
- // This means we can't use the instance as the external info key for associateFunctionWithInfo below
150
- // or in getAssociatedInfo above...which means we can only have one scheduled receiver instance.
151
- // However, since this is an internal receiver, it's safe to assume there is ever only one instnace.
152
- static registerScheduled(func, config) {
153
- const { regInfo } = __1.DBOS.associateFunctionWithInfo(SCHEDULER_EVENT_SERVICE_NAME, func, {
154
- ctorOrProto: config.ctorOrProto,
155
- className: config.className,
156
- name: config.name ?? func.name,
157
- });
158
- const schedRegInfo = regInfo;
159
- schedRegInfo.crontab = config.crontab;
160
- schedRegInfo.mode = config.mode;
161
- schedRegInfo.queueName = config.queueName;
162
- }
163
- }
164
- exports.ScheduledReceiver = ScheduledReceiver;
165
- //# sourceMappingURL=scheduler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/scheduler/scheduler.ts"],"names":[],"mappings":";;;AAAA,0BAA6C;AAE7C,oCAA+C;AAC/C,uCAAwC;AAExC,IAAI;AACJ,gBAAgB;AAChB,IAAI;AAEJ;;GAEG;AACH,IAAY,aAYX;AAZD,WAAY,aAAa;IACvB;;;OAGG;IACH,kEAAiD,CAAA;IACjD;;;;OAIG;IACH,sFAAqE,CAAA;AACvE,CAAC,EAZW,aAAa,6BAAb,aAAa,QAYxB;AAyBD,2BAA2B;AAC3B,uBAAuB;AACvB,2BAA2B;AAE3B,MAAM,4BAA4B,GAAG,gBAAgB,CAAC;AAEtD,MAAa,iBAAiB;IACnB,WAAW,GAAG,IAAI,eAAe,EAAE,CAAC;IACpC,YAAY,GAAG,IAAI,KAAK,EAAiB,CAAC;IAEnD;QACE,QAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,UAAU;QACd,KAAK,MAAM,KAAK,IAAI,QAAI,CAAC,iBAAiB,CAAC,4BAA4B,CAAC,EAAE,CAAC;YACzE,IAAI,KAAK,CAAC,SAAS,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;gBACrD,QAAI,CAAC,MAAM,CAAC,IAAI,CACd,sBAAsB,KAAK,CAAC,SAAS,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,2CAA2C,CACnH,CAAC;gBACF,SAAS;YACX,CAAC;YAED,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,YAAwC,CAAC;YACpF,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,QAAI,CAAC,MAAM,CAAC,IAAI,CACd,sBAAsB,KAAK,CAAC,SAAS,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,+BAA+B,CACvG,CAAC;gBACF,SAAS;YACX,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,qBAAW,CAAC,OAAO,CAAC,CAAC;YAC7C,MAAM,OAAO,GAAG,iBAAiB,CAAC,cAAc,CAC9C,KAAK,CAAC,SAAS,EACf,WAAW,EACX,IAAI,IAAI,aAAa,CAAC,gCAAgC,EACtD,SAAS,EACT,IAAI,CAAC,WAAW,CAAC,MAAM,CACxB,CAAC;YACF,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,sBAAsB;QACpB,QAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACzC,KAAK,MAAM,KAAK,IAAI,QAAI,CAAC,iBAAiB,CAAC,4BAA4B,CAAC,EAAE,CAAC;YACzE,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YACpE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,YAAwC,CAAC;YACzE,IAAI,OAAO,EAAE,CAAC;gBACZ,QAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,MAAM,OAAO,KAAK,IAAI,IAAI,aAAa,CAAC,gCAAgC,EAAE,CAAC,CAAC;YAC1G,CAAC;iBAAM,CAAC;gBACN,QAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,+BAA+B,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,cAAc,CACzB,SAAiC,EACjC,WAAwB,EACxB,IAAmB,EACnB,SAA6B,EAC7B,MAAmB;QAEnB,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;QAExD,IAAI,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,IAAI,KAAK,aAAa,CAAC,sBAAsB,EAAE,CAAC;YAClD,MAAM,SAAS,GAAG,MAAM,QAAI,CAAC,qBAAqB,CAAC,4BAA4B,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;YACpG,IAAI,SAAS,EAAE,KAAK,EAAE,CAAC;gBACrB,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,WAAW,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;YAChE,MAAM,SAAS,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAExC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBAClB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBAC1C,wCAAwC;oBACxC,IAAI,SAAyB,CAAC;oBAE9B,MAAM,OAAO,GAAG,GAAG,EAAE;wBACnB,YAAY,CAAC,SAAS,CAAC,CAAC;wBACxB,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;oBAC7C,CAAC,CAAC;oBAEF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;oBAE1D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;wBACnB,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;wBAC7C,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;oBAC7C,CAAC;oBAED,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;wBAC1B,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;wBAC7C,OAAO,EAAE,CAAC;oBACZ,CAAC,EAAE,SAAS,CAAC,CAAC;gBAChB,CAAC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,MAAM;YACR,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjC,QAAQ,GAAG,QAAQ,CAAC;gBACpB,SAAS;YACX,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChC,IAAI,SAAS,CAAC,cAAc,IAAI,SAAS,CAAC,kBAAkB,EAAE,CAAC;gBAC7D,MAAM,UAAU,GAAG,SAAS,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACzD,MAAM,QAAQ,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,IAAI,2BAAmB,EAAE,CAAC;gBAC7E,QAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,UAAU,EAAE,CAAC,CAAC;gBAChE,MAAM,QAAI,CAAC,aAAa,CAAC,SAAS,CAAC,kBAA+C,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;YAClH,CAAC;iBAAM,CAAC;gBACN,QAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,mCAAmC,CAAC,CAAC;YAChE,CAAC;YAED,QAAQ,GAAG,MAAM,iBAAiB,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,IAAY;QACtD,uCAAuC;QACvC,IAAI,CAAC;YACH,MAAM,KAAK,GAAsB;gBAC/B,OAAO,EAAE,4BAA4B;gBACrC,cAAc,EAAE,IAAI;gBACpB,GAAG,EAAE,WAAW;gBAChB,KAAK,EAAE,GAAG,IAAI,EAAE;gBAChB,UAAU,EAAE,IAAI;aACjB,CAAC;YACF,MAAM,QAAQ,GAAG,MAAM,QAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;YAC5D,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAM,CAAC,CAAC;YAC3C,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,EAAE,CAAC;gBAC5B,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,gGAAgG;YAChG,sDAAsD;YACtD,MAAM,GAAG,GAAG,CAAU,CAAC;YACvB,QAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mDAAmD,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACnF,QAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,oGAAoG;IACpG,oGAAoG;IACpG,gGAAgG;IAChG,oGAAoG;IAEpG,MAAM,CAAC,iBAAiB,CACtB,IAA6D,EAC7D,MAAsC;QAEtC,MAAM,EAAE,OAAO,EAAE,GAAG,QAAI,CAAC,yBAAyB,CAAC,4BAA4B,EAAE,IAAI,EAAE;YACrF,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI;SAC/B,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,OAA0B,CAAC;QAChD,YAAY,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QACtC,YAAY,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QAChC,YAAY,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IAC5C,CAAC;CACF;AA1KD,8CA0KC"}
@@ -1,64 +0,0 @@
1
- import { DBOSExecutor } from './dbos-executor';
2
- /**
3
- * Limit the maximum number of functions started from a `WorkflowQueue`
4
- * per given time period.
5
- * If the limit is 5 and the period is 10, no more than 5 functions can be
6
- * started per 10 seconds.
7
- */
8
- interface QueueRateLimit {
9
- /** Number of queue dispateches per `periodSec` */
10
- limitPerPeriod: number;
11
- /** Period of time during which `limitPerPeriod` queued workflows may be dispatched */
12
- periodSec: number;
13
- }
14
- /**
15
- * Limit the number of concurrent workflows running for a queue.
16
- * This limit may be per worker or global
17
- */
18
- export interface QueueParameters {
19
- /** If defined, this limits the number of running workflows for a single DBOS process */
20
- workerConcurrency?: number;
21
- /** If defined, this limits the number of running workflows globally in the app */
22
- concurrency?: number;
23
- /** If set, this limits the rate at which queued workflows are started */
24
- rateLimit?: QueueRateLimit;
25
- /** If set, this queue supports priority */
26
- priorityEnabled?: boolean;
27
- /** If set, this queue supports partitioning */
28
- partitionQueue?: boolean;
29
- }
30
- /**
31
- * Settings structure for a named workflow queue.
32
- * Workflow queues limit the rate and concurrency at which DBOS executes workflows.
33
- * Queue policies apply to workflows started by `DBOS.startWorkflow`,
34
- * `DBOS.withWorkflowQueue`, etc.
35
- */
36
- export declare class WorkflowQueue {
37
- readonly name: string;
38
- readonly concurrency?: number;
39
- readonly rateLimit?: QueueRateLimit;
40
- readonly workerConcurrency?: number;
41
- readonly priorityEnabled: boolean;
42
- readonly partitionQueue: boolean;
43
- constructor(name: string);
44
- /**
45
- *
46
- * @param name - Name to give the `WorkflowQueue`, accepted by `DBOS.startWorkflow`
47
- * @param queueParameters - Policy for limiting workflow initiation rate and execution concurrency
48
- */
49
- constructor(name: string, queueParameters: QueueParameters);
50
- }
51
- declare class WFQueueRunner {
52
- readonly wfQueuesByName: Map<string, WorkflowQueue>;
53
- private isRunning;
54
- private interruptResolve?;
55
- private pollingIntervalMs;
56
- private readonly minPollingIntervalMs;
57
- private readonly maxPollingIntervalMs;
58
- stop(): void;
59
- dispatchLoop(exec: DBOSExecutor, listenQueuesArg: WorkflowQueue[] | null): Promise<void>;
60
- logRegisteredEndpoints(exec: DBOSExecutor): void;
61
- }
62
- export declare const wfQueueRunner: WFQueueRunner;
63
- export {};
64
- //# sourceMappingURL=wfqueue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wfqueue.d.ts","sourceRoot":"","sources":["../../src/wfqueue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAK/C;;;;;GAKG;AACH,UAAU,cAAc;IACtB,kDAAkD;IAClD,cAAc,EAAE,MAAM,CAAC;IACvB,sFAAsF;IACtF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,wFAAwF;IACxF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,2CAA2C;IAC3C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+CAA+C;IAC/C,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAS;IAC1C,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAS;gBAE7B,IAAI,EAAE,MAAM;IAExB;;;;OAIG;gBACS,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe;CA6B3D;AAED,cAAM,aAAa;IACjB,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAa;IAEhE,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,gBAAgB,CAAC,CAAa;IACtC,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAgB;IACrD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAkB;IAEvD,IAAI;IAQE,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA0F9F,sBAAsB,CAAC,IAAI,EAAE,YAAY;CAc1C;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC"}
@@ -1,147 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.wfQueueRunner = exports.WorkflowQueue = void 0;
4
- const dbos_1 = require("./dbos");
5
- const debugpoint_1 = require("./debugpoint");
6
- const utils_1 = require("./utils");
7
- /**
8
- * Settings structure for a named workflow queue.
9
- * Workflow queues limit the rate and concurrency at which DBOS executes workflows.
10
- * Queue policies apply to workflows started by `DBOS.startWorkflow`,
11
- * `DBOS.withWorkflowQueue`, etc.
12
- */
13
- class WorkflowQueue {
14
- name;
15
- concurrency;
16
- rateLimit;
17
- workerConcurrency;
18
- priorityEnabled = false;
19
- partitionQueue = false;
20
- constructor(name, arg2, rateLimit) {
21
- this.name = name;
22
- if (dbos_1.DBOS.isInitialized()) {
23
- dbos_1.DBOS.logger.warn(`Workflow queue '${name}' is being created after DBOS initialization and will not be considered for dequeue.`);
24
- }
25
- if (typeof arg2 === 'object' && arg2 !== null) {
26
- // Handle the case where the second argument is QueueParameters
27
- this.concurrency = arg2.concurrency;
28
- this.rateLimit = arg2.rateLimit;
29
- this.workerConcurrency = arg2.workerConcurrency;
30
- this.priorityEnabled = arg2.priorityEnabled ?? false;
31
- this.partitionQueue = arg2.partitionQueue ?? false;
32
- }
33
- else {
34
- // Handle the case where the second argument is a number
35
- this.concurrency = arg2;
36
- this.rateLimit = rateLimit;
37
- }
38
- if (exports.wfQueueRunner.wfQueuesByName.has(name)) {
39
- throw Error(`Workflow Queue '${name}' defined multiple times`);
40
- }
41
- exports.wfQueueRunner.wfQueuesByName.set(name, this);
42
- }
43
- }
44
- exports.WorkflowQueue = WorkflowQueue;
45
- class WFQueueRunner {
46
- wfQueuesByName = new Map();
47
- isRunning = false;
48
- interruptResolve;
49
- pollingIntervalMs = 1000;
50
- minPollingIntervalMs = 1000;
51
- maxPollingIntervalMs = 120000;
52
- stop() {
53
- if (!this.isRunning)
54
- return;
55
- this.isRunning = false;
56
- if (this.interruptResolve) {
57
- this.interruptResolve();
58
- }
59
- }
60
- async dispatchLoop(exec, listenQueuesArg) {
61
- this.isRunning = true;
62
- while (this.isRunning) {
63
- // Wait for either the timeout or an interruption
64
- let timer;
65
- const timeoutPromise = new Promise((resolve) => {
66
- timer = setTimeout(() => {
67
- resolve();
68
- }, this.pollingIntervalMs);
69
- });
70
- await Promise.race([timeoutPromise, new Promise((_, reject) => (this.interruptResolve = reject))]).catch(() => {
71
- exec.logger.debug('Workflow queue loop interrupted!');
72
- }); // Interrupt sleep throws
73
- clearTimeout(timer);
74
- if (!this.isRunning) {
75
- break;
76
- }
77
- let listenQueues;
78
- if (listenQueuesArg !== null) {
79
- // If explicitly listening for queues, use only those queues plus the internal queue
80
- listenQueues = [...listenQueuesArg, this.wfQueuesByName.get(utils_1.INTERNAL_QUEUE_NAME)];
81
- }
82
- else {
83
- // Else, listen to all declared queues
84
- listenQueues = Array.from(this.wfQueuesByName.values());
85
- }
86
- // Check queues
87
- for (const q of listenQueues) {
88
- let wfids = [];
89
- try {
90
- if (q.partitionQueue) {
91
- // For partitioned queues, get all partition keys and dequeue from each partition separately
92
- const partitionKeys = await exec.systemDatabase.getQueuePartitions(q.name);
93
- for (const partitionKey of partitionKeys) {
94
- const partitionWfids = await exec.systemDatabase.findAndMarkStartableWorkflows(q, exec.executorID, utils_1.globalParams.appVersion, partitionKey);
95
- wfids.push(...partitionWfids);
96
- }
97
- }
98
- else {
99
- // For non-partitioned queues, pass null to match workflows with queue_partition_key IS NULL
100
- wfids = await exec.systemDatabase.findAndMarkStartableWorkflows(q, exec.executorID, utils_1.globalParams.appVersion, undefined);
101
- }
102
- }
103
- catch (e) {
104
- const err = e;
105
- // Handle serialization errors and lock contention with backoff
106
- if ('code' in err && (err.code === '40001' || err.code === '55P03')) {
107
- // 40001: serialization_failure, 55P03: lock_not_available
108
- // Increase the polling interval on contention
109
- this.pollingIntervalMs = Math.min(this.maxPollingIntervalMs, this.pollingIntervalMs * 2.0);
110
- exec.logger.warn(`Contention detected in queue thread for ${q.name}. Increasing polling interval to ${(this.pollingIntervalMs / 1000).toFixed(2)}s.`);
111
- }
112
- else {
113
- exec.logger.warn(`Error getting startable workflows: ${err.message}`);
114
- }
115
- wfids = [];
116
- }
117
- if (wfids.length > 0) {
118
- await (0, debugpoint_1.debugTriggerPoint)(debugpoint_1.DEBUG_TRIGGER_WORKFLOW_QUEUE_START);
119
- }
120
- for (const wfid of wfids) {
121
- try {
122
- const _wfh = await exec.executeWorkflowId(wfid, { isQueueDispatch: true });
123
- }
124
- catch (e) {
125
- exec.logger.warn(`Could not execute workflow with id ${wfid}: ${e.message}`);
126
- }
127
- }
128
- }
129
- // Gradually decrease the polling interval when there's no contention
130
- this.pollingIntervalMs = Math.max(this.minPollingIntervalMs, this.pollingIntervalMs * 0.9);
131
- }
132
- }
133
- logRegisteredEndpoints(exec) {
134
- const logger = exec.logger;
135
- logger.info('Workflow queues:');
136
- for (const [qn, q] of this.wfQueuesByName) {
137
- const conc = q.concurrency !== undefined ? `global concurrency limit: ${q.concurrency}` : 'No concurrency limit set';
138
- logger.info(` ${qn}: ${conc}`);
139
- const workerconc = q.workerConcurrency !== undefined
140
- ? `worker concurrency limit: ${q.workerConcurrency}`
141
- : 'No worker concurrency limit set';
142
- logger.info(` ${qn}: ${workerconc}`);
143
- }
144
- }
145
- }
146
- exports.wfQueueRunner = new WFQueueRunner();
147
- //# sourceMappingURL=wfqueue.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wfqueue.js","sourceRoot":"","sources":["../../src/wfqueue.ts"],"names":[],"mappings":"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"}