@donkeylabs/server 2.0.30 → 2.0.31
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/docs/workflows.md +13 -0
- package/package.json +1 -1
- package/src/core/workflows.ts +14 -0
package/docs/workflows.md
CHANGED
|
@@ -89,6 +89,19 @@ const instanceId = await ctx.core.workflows.start("process-order", {
|
|
|
89
89
|
});
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
+
### Concurrency Guard
|
|
93
|
+
|
|
94
|
+
Limit concurrent instances per workflow name:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
const server = new AppServer({
|
|
98
|
+
db,
|
|
99
|
+
workflows: {
|
|
100
|
+
concurrentWorkflows: 1, // 0 = unlimited
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
92
105
|
### 3. Track Progress
|
|
93
106
|
|
|
94
107
|
```typescript
|
package/package.json
CHANGED
package/src/core/workflows.ts
CHANGED
|
@@ -766,6 +766,8 @@ export interface WorkflowsConfig {
|
|
|
766
766
|
sqlitePragmas?: SqlitePragmaConfig;
|
|
767
767
|
/** Disable in-process watchdog timers (use external watchdog instead) */
|
|
768
768
|
useWatchdog?: boolean;
|
|
769
|
+
/** Max concurrent instances per workflow name (0 = unlimited, default: 0) */
|
|
770
|
+
concurrentWorkflows?: number;
|
|
769
771
|
/** Resume strategy for orphaned workflows (default: "blocking") */
|
|
770
772
|
resumeStrategy?: WorkflowResumeStrategy;
|
|
771
773
|
}
|
|
@@ -871,6 +873,7 @@ class WorkflowsImpl implements Workflows {
|
|
|
871
873
|
private killGraceMs: number;
|
|
872
874
|
private sqlitePragmas?: SqlitePragmaConfig;
|
|
873
875
|
private useWatchdog: boolean;
|
|
876
|
+
private concurrentWorkflows: number;
|
|
874
877
|
private resumeStrategy!: WorkflowResumeStrategy;
|
|
875
878
|
private workflowModulePaths = new Map<string, string>();
|
|
876
879
|
private isolatedProcesses = new Map<string, IsolatedProcessInfo>();
|
|
@@ -908,6 +911,7 @@ class WorkflowsImpl implements Workflows {
|
|
|
908
911
|
this.killGraceMs = config.killGraceMs ?? 5000;
|
|
909
912
|
this.sqlitePragmas = config.sqlitePragmas;
|
|
910
913
|
this.useWatchdog = config.useWatchdog ?? false;
|
|
914
|
+
this.concurrentWorkflows = config.concurrentWorkflows ?? 0;
|
|
911
915
|
this.resumeStrategy = config.resumeStrategy ?? "blocking";
|
|
912
916
|
}
|
|
913
917
|
|
|
@@ -1006,6 +1010,16 @@ class WorkflowsImpl implements Workflows {
|
|
|
1006
1010
|
throw new Error(`Workflow "${workflowName}" is not registered`);
|
|
1007
1011
|
}
|
|
1008
1012
|
|
|
1013
|
+
if (this.concurrentWorkflows > 0) {
|
|
1014
|
+
const running = await this.adapter.getInstancesByWorkflow(workflowName, "running");
|
|
1015
|
+
const pending = await this.adapter.getInstancesByWorkflow(workflowName, "pending");
|
|
1016
|
+
if (running.length + pending.length >= this.concurrentWorkflows) {
|
|
1017
|
+
throw new Error(
|
|
1018
|
+
`Workflow "${workflowName}" has reached its concurrency limit (${this.concurrentWorkflows})`
|
|
1019
|
+
);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1009
1023
|
const instance = await this.adapter.createInstance({
|
|
1010
1024
|
workflowName,
|
|
1011
1025
|
status: "pending",
|