comfyui-node 1.6.1 → 1.6.2

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 (88) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/call-wrapper.js +856 -856
  3. package/dist/index.d.ts +13 -13
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +7 -7
  6. package/dist/index.js.map +1 -1
  7. package/dist/multipool/client-registry.d.ts +32 -11
  8. package/dist/multipool/client-registry.d.ts.map +1 -1
  9. package/dist/multipool/client-registry.js +152 -25
  10. package/dist/multipool/client-registry.js.map +1 -1
  11. package/dist/multipool/helpers.d.ts +5 -0
  12. package/dist/multipool/helpers.d.ts.map +1 -0
  13. package/dist/multipool/helpers.js +53 -0
  14. package/dist/multipool/helpers.js.map +1 -0
  15. package/dist/multipool/index.d.ts +2 -1
  16. package/dist/multipool/index.d.ts.map +1 -1
  17. package/dist/multipool/index.js +2 -1
  18. package/dist/multipool/index.js.map +1 -1
  19. package/dist/multipool/interfaces.d.ts +12 -4
  20. package/dist/multipool/interfaces.d.ts.map +1 -1
  21. package/dist/multipool/interfaces.js +1 -1
  22. package/dist/multipool/job-profiler.d.ts +128 -0
  23. package/dist/multipool/job-profiler.d.ts.map +1 -0
  24. package/dist/multipool/job-profiler.js +222 -0
  25. package/dist/multipool/job-profiler.js.map +1 -0
  26. package/dist/multipool/job-queue-processor.d.ts +27 -11
  27. package/dist/multipool/job-queue-processor.d.ts.map +1 -1
  28. package/dist/multipool/job-queue-processor.js +196 -9
  29. package/dist/multipool/job-queue-processor.js.map +1 -1
  30. package/dist/multipool/job-state-registry.d.ts +67 -0
  31. package/dist/multipool/job-state-registry.d.ts.map +1 -0
  32. package/dist/multipool/job-state-registry.js +283 -0
  33. package/dist/multipool/job-state-registry.js.map +1 -0
  34. package/dist/multipool/logger.d.ts +30 -0
  35. package/dist/multipool/logger.d.ts.map +1 -0
  36. package/dist/multipool/logger.js +75 -0
  37. package/dist/multipool/logger.js.map +1 -0
  38. package/dist/multipool/multi-workflow-pool.d.ts +42 -23
  39. package/dist/multipool/multi-workflow-pool.d.ts.map +1 -1
  40. package/dist/multipool/multi-workflow-pool.js +313 -72
  41. package/dist/multipool/multi-workflow-pool.js.map +1 -1
  42. package/dist/multipool/pool-event-manager.d.ts +10 -10
  43. package/dist/multipool/pool-event-manager.js +27 -27
  44. package/dist/multipool/tests/error-classification-tests.d.ts +2 -0
  45. package/dist/multipool/tests/error-classification-tests.d.ts.map +1 -0
  46. package/dist/multipool/tests/error-classification-tests.js +374 -0
  47. package/dist/multipool/tests/error-classification-tests.js.map +1 -0
  48. package/dist/multipool/tests/job-state-registry.d.ts +16 -16
  49. package/dist/multipool/tests/job-state-registry.js +23 -23
  50. package/dist/multipool/tests/multipool-basic.d.ts +11 -1
  51. package/dist/multipool/tests/multipool-basic.d.ts.map +1 -1
  52. package/dist/multipool/tests/multipool-basic.js +141 -3
  53. package/dist/multipool/tests/multipool-basic.js.map +1 -1
  54. package/dist/multipool/tests/profiling-demo.d.ts +7 -0
  55. package/dist/multipool/tests/profiling-demo.d.ts.map +1 -0
  56. package/dist/multipool/tests/profiling-demo.js +88 -0
  57. package/dist/multipool/tests/profiling-demo.js.map +1 -0
  58. package/dist/multipool/tests/prompt-generator.d.ts +10 -0
  59. package/dist/multipool/tests/prompt-generator.d.ts.map +1 -0
  60. package/dist/multipool/tests/prompt-generator.js +26 -0
  61. package/dist/multipool/tests/prompt-generator.js.map +1 -0
  62. package/dist/multipool/tests/test-helpers.d.ts +4 -0
  63. package/dist/multipool/tests/test-helpers.d.ts.map +1 -0
  64. package/dist/multipool/tests/test-helpers.js +10 -0
  65. package/dist/multipool/tests/test-helpers.js.map +1 -0
  66. package/dist/multipool/tests/two-stage-edit-simulation.d.ts +32 -0
  67. package/dist/multipool/tests/two-stage-edit-simulation.d.ts.map +1 -0
  68. package/dist/multipool/tests/two-stage-edit-simulation.js +299 -0
  69. package/dist/multipool/tests/two-stage-edit-simulation.js.map +1 -0
  70. package/dist/multipool/workflow.d.ts +178 -173
  71. package/dist/multipool/workflow.d.ts.map +1 -1
  72. package/dist/multipool/workflow.js +333 -271
  73. package/dist/multipool/workflow.js.map +1 -1
  74. package/dist/pool/SmartPool.d.ts +143 -143
  75. package/dist/pool/SmartPool.js +676 -676
  76. package/dist/pool/SmartPoolV2.d.ts +119 -119
  77. package/dist/pool/SmartPoolV2.js +586 -586
  78. package/dist/pool/WorkflowPool.d.ts +202 -202
  79. package/dist/pool/WorkflowPool.d.ts.map +1 -1
  80. package/dist/pool/WorkflowPool.js +845 -840
  81. package/dist/pool/WorkflowPool.js.map +1 -1
  82. package/dist/pool/client/ClientManager.d.ts +86 -86
  83. package/dist/pool/client/ClientManager.js +215 -215
  84. package/dist/pool/index.d.ts +9 -11
  85. package/dist/pool/index.d.ts.map +1 -1
  86. package/dist/pool/index.js +3 -5
  87. package/dist/pool/index.js.map +1 -1
  88. package/package.json +1 -1
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Job Profiler for MultiWorkflowPool - Automatic per-node execution profiling
3
+ * ===========================================================================
4
+ *
5
+ * Captures detailed execution metrics for workflow jobs automatically:
6
+ * - Per-node execution timing
7
+ * - Progress tracking for nodes that emit progress events
8
+ * - Execution order and dependencies
9
+ * - Node types and metadata
10
+ *
11
+ * Usage:
12
+ * ```ts
13
+ * const pool = new MultiWorkflowPool({ enableProfiling: true });
14
+ * const jobId = await pool.submitJob(workflow);
15
+ *
16
+ * const results = await pool.waitForJobCompletion(jobId);
17
+ * console.log(results.profileStats);
18
+ * ```
19
+ */
20
+ /**
21
+ * JobProfiler tracks execution metrics for a single workflow job.
22
+ */
23
+ export class JobProfiler {
24
+ queuedAt;
25
+ startedAt;
26
+ completedAt;
27
+ promptId;
28
+ nodeProfiles = new Map();
29
+ lastExecutingNode = null;
30
+ constructor(queuedAt, workflowJson) {
31
+ this.queuedAt = queuedAt;
32
+ // Initialize node profiles from workflow structure
33
+ if (workflowJson) {
34
+ for (const [nodeId, nodeData] of Object.entries(workflowJson)) {
35
+ const node = nodeData;
36
+ if (node && typeof node === 'object' && node.class_type) {
37
+ this.nodeProfiles.set(nodeId, {
38
+ nodeId,
39
+ type: node.class_type,
40
+ title: node._meta?.title,
41
+ cached: false,
42
+ status: 'pending'
43
+ });
44
+ }
45
+ }
46
+ }
47
+ }
48
+ /**
49
+ * Record execution start event
50
+ */
51
+ onExecutionStart(promptId) {
52
+ this.promptId = promptId;
53
+ if (!this.startedAt) {
54
+ this.startedAt = Date.now();
55
+ }
56
+ }
57
+ /**
58
+ * Record cached nodes
59
+ */
60
+ onCachedNodes(nodeIds) {
61
+ const now = Date.now();
62
+ for (const nodeId of nodeIds) {
63
+ let profile = this.nodeProfiles.get(nodeId);
64
+ if (!profile) {
65
+ profile = {
66
+ nodeId,
67
+ cached: true,
68
+ status: 'cached'
69
+ };
70
+ this.nodeProfiles.set(nodeId, profile);
71
+ }
72
+ profile.cached = true;
73
+ profile.status = 'cached';
74
+ profile.startedAt = now;
75
+ profile.completedAt = now;
76
+ profile.duration = 0;
77
+ }
78
+ }
79
+ /**
80
+ * Record node execution start
81
+ */
82
+ onNodeExecuting(nodeId) {
83
+ // Complete previous node if any
84
+ if (this.lastExecutingNode && this.lastExecutingNode !== nodeId) {
85
+ this.completeNode(this.lastExecutingNode);
86
+ }
87
+ // Start tracking new node
88
+ let profile = this.nodeProfiles.get(nodeId);
89
+ if (!profile) {
90
+ profile = {
91
+ nodeId,
92
+ cached: false,
93
+ status: 'executing'
94
+ };
95
+ this.nodeProfiles.set(nodeId, profile);
96
+ }
97
+ if (!profile.startedAt) {
98
+ profile.startedAt = Date.now();
99
+ profile.status = 'executing';
100
+ }
101
+ this.lastExecutingNode = nodeId;
102
+ }
103
+ /**
104
+ * Record node completion (when next node starts or execution ends)
105
+ */
106
+ completeNode(nodeId) {
107
+ const profile = this.nodeProfiles.get(nodeId);
108
+ if (profile && !profile.completedAt && profile.startedAt) {
109
+ profile.completedAt = Date.now();
110
+ profile.duration = profile.completedAt - profile.startedAt;
111
+ profile.status = 'completed';
112
+ }
113
+ }
114
+ /**
115
+ * Record execution end (node: null event)
116
+ */
117
+ onExecutionComplete() {
118
+ // Complete last executing node
119
+ if (this.lastExecutingNode) {
120
+ this.completeNode(this.lastExecutingNode);
121
+ this.lastExecutingNode = null;
122
+ }
123
+ // Mark any nodes still in "executing" state as completed
124
+ for (const profile of Array.from(this.nodeProfiles.values())) {
125
+ if (profile.status === 'executing' && !profile.completedAt && profile.startedAt) {
126
+ profile.completedAt = Date.now();
127
+ profile.duration = profile.completedAt - profile.startedAt;
128
+ profile.status = 'completed';
129
+ }
130
+ }
131
+ this.completedAt = Date.now();
132
+ }
133
+ /**
134
+ * Record progress event for a node
135
+ */
136
+ onProgress(nodeId, value, max) {
137
+ const nodeIdStr = String(nodeId);
138
+ let profile = this.nodeProfiles.get(nodeIdStr);
139
+ if (!profile) {
140
+ profile = {
141
+ nodeId: nodeIdStr,
142
+ cached: false,
143
+ status: 'executing',
144
+ progressEvents: []
145
+ };
146
+ this.nodeProfiles.set(nodeIdStr, profile);
147
+ }
148
+ if (!profile.progressEvents) {
149
+ profile.progressEvents = [];
150
+ }
151
+ profile.progressEvents.push({
152
+ timestamp: Date.now(),
153
+ value,
154
+ max
155
+ });
156
+ }
157
+ /**
158
+ * Record node execution error
159
+ */
160
+ onNodeError(nodeId, error) {
161
+ let profile = this.nodeProfiles.get(nodeId);
162
+ if (!profile) {
163
+ profile = {
164
+ nodeId,
165
+ cached: false,
166
+ status: 'failed'
167
+ };
168
+ this.nodeProfiles.set(nodeId, profile);
169
+ }
170
+ profile.status = 'failed';
171
+ profile.error = error;
172
+ profile.completedAt = Date.now();
173
+ if (profile.startedAt) {
174
+ profile.duration = profile.completedAt - profile.startedAt;
175
+ }
176
+ }
177
+ /**
178
+ * Generate final profile statistics
179
+ */
180
+ getStats() {
181
+ const now = Date.now();
182
+ const completedAt = this.completedAt || now;
183
+ const startedAt = this.startedAt || this.queuedAt;
184
+ const nodes = Array.from(this.nodeProfiles.values());
185
+ // Calculate summary statistics
186
+ const executedNodes = nodes.filter(n => n.status === 'completed').length;
187
+ const cachedNodes = nodes.filter(n => n.cached).length;
188
+ const failedNodes = nodes.filter(n => n.status === 'failed').length;
189
+ const slowestNodes = nodes
190
+ .filter(n => n.duration && n.duration > 0)
191
+ .sort((a, b) => (b.duration || 0) - (a.duration || 0))
192
+ .slice(0, 5)
193
+ .map(n => ({
194
+ nodeId: n.nodeId,
195
+ type: n.type,
196
+ title: n.title,
197
+ duration: n.duration
198
+ }));
199
+ const progressNodes = nodes
200
+ .filter(n => n.progressEvents && n.progressEvents.length > 0)
201
+ .map(n => n.nodeId);
202
+ return {
203
+ promptId: this.promptId,
204
+ totalDuration: completedAt - this.queuedAt,
205
+ queueTime: startedAt - this.queuedAt,
206
+ executionTime: completedAt - startedAt,
207
+ queuedAt: this.queuedAt,
208
+ startedAt: this.startedAt,
209
+ completedAt,
210
+ nodes,
211
+ summary: {
212
+ totalNodes: nodes.length,
213
+ executedNodes,
214
+ cachedNodes,
215
+ failedNodes,
216
+ slowestNodes,
217
+ progressNodes
218
+ }
219
+ };
220
+ }
221
+ }
222
+ //# sourceMappingURL=job-profiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-profiler.js","sourceRoot":"","sources":["../../src/multipool/job-profiler.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,28 @@
1
- import { MultiWorkflowPool } from "src/multipool/multi-workflow-pool.js";
2
- import { Workflow } from "src/multipool/workflow.js";
3
- export declare class JobQueueProcessor {
4
- pool: MultiWorkflowPool;
5
- queue: Array<{
6
- jobId: string;
7
- workflow: Workflow;
8
- }>;
9
- constructor(pool: MultiWorkflowPool);
10
- enqueueJob(newJobId: string, workflow: Workflow): void;
11
- }
1
+ import { Workflow } from "./workflow.js";
2
+ import { JobStateRegistry } from "./job-state-registry.js";
3
+ import { ClientRegistry } from "./client-registry.js";
4
+ import { Logger } from "./logger.js";
5
+ export interface QueueJob {
6
+ jobId: string;
7
+ workflow: Workflow;
8
+ attempts: number;
9
+ }
10
+ export declare class JobQueueProcessor {
11
+ private jobs;
12
+ private clientRegistry;
13
+ private logger;
14
+ queue: Array<QueueJob>;
15
+ workflowHash: string;
16
+ isProcessing: boolean;
17
+ maxAttempts: number;
18
+ constructor(stateRegistry: JobStateRegistry, clientRegistry: ClientRegistry, workflowHash: string, logger: Logger);
19
+ enqueueJob(newJobId: string, workflow: Workflow): Promise<void>;
20
+ processQueue(): Promise<void>;
21
+ private applyAutoSeed;
22
+ private runJobOnClient;
23
+ dequeueJob(jobId: string): void;
24
+ private handleFailure;
25
+ private retryOrMarkFailed;
26
+ private processAttachedMedia;
27
+ }
12
28
  //# sourceMappingURL=job-queue-processor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"job-queue-processor.d.ts","sourceRoot":"","sources":["../../src/multipool/job-queue-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,qBAAa,iBAAiB;IAE5B,IAAI,EAAE,iBAAiB,CAAC;IAExB,KAAK,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,QAAQ,CAAA;KAAC,CAAC,CAAM;gBAE3C,IAAI,EAAE,iBAAiB;IAInC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;CAGhD"}
1
+ {"version":3,"file":"job-queue-processor.d.ts","sourceRoot":"","sources":["../../src/multipool/job-queue-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAkB,MAAM,sBAAsB,CAAC;AAGtE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,iBAAiB;IAE5B,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,MAAM,CAAS;IACvB,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAM;IAC5B,YAAY,EAAE,MAAM,CAAM;IAC1B,YAAY,EAAE,OAAO,CAAS;IAC9B,WAAW,EAAE,MAAM,CAAK;gBAEZ,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAQ3G,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;IAY/C,YAAY;IAyDlB,OAAO,CAAC,aAAa;YAeP,cAAc;IAkD5B,UAAU,CAAC,KAAK,EAAE,MAAM;IAIxB,OAAO,CAAC,aAAa;IAiCrB,OAAO,CAAC,iBAAiB;YAuBX,oBAAoB;CAGnC"}
@@ -1,10 +1,197 @@
1
- export class JobQueueProcessor {
2
- pool;
3
- queue = [];
4
- constructor(pool) {
5
- this.pool = pool;
6
- }
7
- enqueueJob(newJobId, workflow) {
8
- }
9
- }
1
+ import { classifyFailure } from "src/multipool/helpers.js";
2
+ export class JobQueueProcessor {
3
+ jobs;
4
+ clientRegistry;
5
+ logger;
6
+ queue = [];
7
+ workflowHash = "";
8
+ isProcessing = false;
9
+ maxAttempts = 3;
10
+ constructor(stateRegistry, clientRegistry, workflowHash, logger) {
11
+ this.logger = logger;
12
+ this.logger.debug(`Creating JobQueueProcessor for workflow hash: '${workflowHash}'`);
13
+ this.clientRegistry = clientRegistry;
14
+ this.jobs = stateRegistry;
15
+ this.workflowHash = workflowHash;
16
+ }
17
+ async enqueueJob(newJobId, workflow) {
18
+ // validate job state on registry
19
+ const jobStatus = this.jobs.getJobStatus(newJobId);
20
+ if (jobStatus !== "pending") {
21
+ throw new Error(`Cannot enqueue job ${newJobId} with status ${jobStatus}`);
22
+ }
23
+ this.queue.push({ jobId: newJobId, workflow, attempts: 1 });
24
+ this.processQueue().catch(reason => {
25
+ this.logger.error(`Error processing job queue for workflow hash ${this.workflowHash}:`, reason);
26
+ });
27
+ }
28
+ async processQueue() {
29
+ if (this.isProcessing) {
30
+ this.logger.debug(`Job queue for workflow hash ${this.workflowHash} is already being processed, skipping.`);
31
+ return;
32
+ }
33
+ this.isProcessing = true;
34
+ // Get the next job in the queue
35
+ const nextJob = this.queue.shift();
36
+ if (nextJob) {
37
+ this.logger.debug(`Processing job ${nextJob.jobId}`);
38
+ let preferredClient;
39
+ // If this processor is for the general queue, try to find a preferred client
40
+ if (this.workflowHash === "general") {
41
+ preferredClient = await this.clientRegistry.getOptimalIdleClient(nextJob.workflow);
42
+ }
43
+ else {
44
+ preferredClient = this.clientRegistry.getOptimalClient(nextJob.workflow);
45
+ }
46
+ if (!preferredClient) {
47
+ this.logger.debug(`No idle clients available for job ${nextJob.jobId}.`);
48
+ // Mark as pending again
49
+ this.jobs.setJobStatus(nextJob.jobId, "pending");
50
+ // Re-add the job to the front of the queue for later processing
51
+ this.queue.unshift(nextJob);
52
+ this.isProcessing = false;
53
+ return;
54
+ }
55
+ else {
56
+ this.logger.info(`Assigning job ${nextJob.jobId} to client ${preferredClient.nodeName}`);
57
+ this.jobs.setJobStatus(nextJob.jobId, "assigned", preferredClient.url);
58
+ await this.runJobOnClient(nextJob, preferredClient);
59
+ }
60
+ }
61
+ this.isProcessing = false;
62
+ // Recursively process the next job if we have idle clients to handle them
63
+ if (this.queue.length > 0) {
64
+ let idleCount = 0;
65
+ for (const client of this.clientRegistry.clients.values()) {
66
+ this.logger.debug(`Client ${client.nodeName} state: ${client.state}`);
67
+ if (client.state === "idle") {
68
+ idleCount++;
69
+ }
70
+ }
71
+ if (idleCount > 0) {
72
+ this.logger.debug(`Continuing to process next job in queue for workflow hash ${this.workflowHash}.`);
73
+ try {
74
+ await this.processQueue();
75
+ }
76
+ catch (e) {
77
+ this.logger.error(`Error processing job queue for workflow hash ${this.workflowHash}:`, e);
78
+ }
79
+ }
80
+ }
81
+ }
82
+ applyAutoSeed(workflow) {
83
+ const autoSeeds = {};
84
+ for (const [nodeId, nodeValue] of Object.entries(workflow)) {
85
+ if (!nodeValue || typeof nodeValue !== "object")
86
+ continue;
87
+ const inputs = nodeValue.inputs;
88
+ if (!inputs || typeof inputs !== "object")
89
+ continue;
90
+ if (typeof inputs.seed === "number" && inputs.seed === -1) {
91
+ const val = Math.floor(Math.random() * 2_147_483_647);
92
+ inputs.seed = val;
93
+ autoSeeds[nodeId] = val;
94
+ }
95
+ }
96
+ return autoSeeds;
97
+ }
98
+ async runJobOnClient(nextJob, preferredClient) {
99
+ try {
100
+ const api = preferredClient.api;
101
+ // Check if client is idle before sending job
102
+ const queueStatus = await api.getQueue();
103
+ if (queueStatus.queue_running.length !== 0 || queueStatus.queue_pending.length !== 0) {
104
+ this.logger.debug(`Client ${preferredClient.nodeName} is busy, re-adding job ${nextJob.jobId} to queue.`);
105
+ this.jobs.setJobStatus(nextJob.jobId, "pending");
106
+ this.queue.unshift(nextJob);
107
+ return;
108
+ }
109
+ await this.processAttachedMedia(nextJob.workflow, api);
110
+ const workflowJson = nextJob.workflow.toJSON();
111
+ const autoSeeds = this.applyAutoSeed(workflowJson);
112
+ if (Object.keys(autoSeeds).length > 0) {
113
+ this.logger.queue(this.workflowHash, `Applied auto seeds for job ${nextJob.jobId}: ${JSON.stringify(autoSeeds)}`);
114
+ this.jobs.updateJobAutoSeeds(nextJob.jobId, autoSeeds);
115
+ // Update the workflow json with the new seeds before sending
116
+ const nodeIds = Object.keys(autoSeeds);
117
+ for (const nodeId of nodeIds) {
118
+ workflowJson[nodeId].inputs.seed = autoSeeds[nodeId];
119
+ }
120
+ }
121
+ this.logger.queue(this.workflowHash, `Starting job ${nextJob.jobId} on client ${preferredClient.nodeName}`);
122
+ const result = await api.ext.queue.queuePrompt(null, workflowJson);
123
+ // at this point we have the prompt_id assigned by comfyui, we can mark the job as running
124
+ if (result.prompt_id) {
125
+ this.jobs.setPromptId(nextJob.jobId, result.prompt_id);
126
+ this.jobs.setJobStatus(nextJob.jobId, "running");
127
+ this.logger.queue(this.workflowHash, `Job ${nextJob.jobId} is now queued on client ${preferredClient.nodeName} with prompt ID ${result.prompt_id}`);
128
+ // we also mark the client as busy, to prevent new jobs being assigned until we detect completion
129
+ preferredClient.state = "busy";
130
+ this.logger.debug(Array.from(this.clientRegistry.clients.values()).map((c) => `${c.nodeName}: ${c.state}`).join(", "));
131
+ }
132
+ else {
133
+ this.logger.error(`Failed to enqueue job ${nextJob.jobId} on client ${preferredClient.nodeName}: No prompt_id returned.`);
134
+ this.jobs.setJobStatus(nextJob.jobId, "failed");
135
+ }
136
+ }
137
+ catch (e) {
138
+ this.logger.error(`Failed to run job ${nextJob.jobId} on client ${preferredClient.nodeName}`);
139
+ this.handleFailure(preferredClient, nextJob, e);
140
+ }
141
+ }
142
+ dequeueJob(jobId) {
143
+ this.queue = this.queue.filter(job => job.jobId !== jobId);
144
+ }
145
+ handleFailure(preferredClient, nextJob, e) {
146
+ const { type, message } = classifyFailure(e);
147
+ this.logger.queue(this.workflowHash, `Job ${nextJob.jobId} failed on ${preferredClient.nodeName}. Failure type: ${type}. Reason: ${message}`);
148
+ switch (type) {
149
+ case "connection":
150
+ preferredClient.state = "offline"; // Mark as offline to be re-checked later
151
+ this.logger.queue(this.workflowHash, `Re-queuing job ${nextJob.jobId} due to connection error.`);
152
+ this.jobs.setJobStatus(nextJob.jobId, "pending");
153
+ this.queue.unshift(nextJob); // Re-queue without incrementing attempts
154
+ break;
155
+ case "workflow_incompatibility":
156
+ preferredClient.state = "idle";
157
+ this.logger.queue(this.workflowHash, `Marking client ${preferredClient.nodeName} as incompatible with workflow ${nextJob.workflow.structureHash}.`);
158
+ this.clientRegistry.markClientIncompatibleWithWorkflow(preferredClient.url, nextJob.workflow.structureHash);
159
+ this.retryOrMarkFailed(nextJob, e);
160
+ break;
161
+ case "transient":
162
+ preferredClient.state = "idle";
163
+ this.logger.queue(this.workflowHash, `Job ${nextJob.jobId} failed with a transient error. It will not be retried.`);
164
+ this.jobs.setJobFailure(nextJob.jobId, { error: message, details: e.bodyJSON });
165
+ break;
166
+ }
167
+ // Trigger processing for the next job in the queue
168
+ this.processQueue().catch(reason => {
169
+ this.logger.error(`Error processing job queue for workflow hash ${this.workflowHash}:`, reason);
170
+ });
171
+ }
172
+ retryOrMarkFailed(nextJob, originalError) {
173
+ // Check if the job has exceeded its max attempts
174
+ if (nextJob.attempts >= this.maxAttempts) {
175
+ this.logger.queue(this.workflowHash, `Job ${nextJob.jobId} has reached max attempts (${this.maxAttempts}). Marking as failed.`);
176
+ this.jobs.setJobFailure(nextJob.jobId, originalError.bodyJSON);
177
+ return;
178
+ }
179
+ // Confirm if we should re-queue or fail the job
180
+ const eligibleClients = this.clientRegistry.getAllEligibleClientsForWorkflow(nextJob.workflow);
181
+ if (eligibleClients.length > 0) {
182
+ this.logger.queue(this.workflowHash, `Re-queuing job ${nextJob.jobId} (attempt ${nextJob.attempts + 1}) as there are other eligible clients available.`);
183
+ this.jobs.setJobStatus(nextJob.jobId, "pending");
184
+ // Increment attempts and re-add to the front of the queue
185
+ nextJob.attempts++;
186
+ this.queue.unshift(nextJob);
187
+ }
188
+ else {
189
+ this.logger.queue(this.workflowHash, `No other eligible clients for job ${nextJob.jobId}, marking as failed.`);
190
+ this.jobs.setJobFailure(nextJob.jobId, originalError.bodyJSON);
191
+ }
192
+ }
193
+ async processAttachedMedia(workflow, api) {
194
+ await workflow.uploadAssets(api);
195
+ }
196
+ }
10
197
  //# sourceMappingURL=job-queue-processor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"job-queue-processor.js","sourceRoot":"","sources":["../../src/multipool/job-queue-processor.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,iBAAiB;IAE5B,IAAI,CAAoB;IAExB,KAAK,GAA+C,EAAE,CAAC;IAEvD,YAAY,IAAuB;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,UAAU,CAAC,QAAgB,EAAE,QAAkB;IAE/C,CAAC;CACF"}
1
+ {"version":3,"file":"job-queue-processor.js","sourceRoot":"","sources":["../../src/multipool/job-queue-processor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { MultiWorkflowPool } from "src/multipool/multi-workflow-pool.js";
2
+ import { Workflow } from "src/multipool/workflow.js";
3
+ import { ImageInfo } from "src/types/api.js";
4
+ import { ClientRegistry } from "src/multipool/client-registry.js";
5
+ import { JobProfiler, JobProfileStats } from "./job-profiler.js";
6
+ export type JobStatus = "pending" | "assigned" | "running" | "completed" | "failed" | "canceled" | "no_clients";
7
+ export type JobResultStatus = "completed" | "failed" | "canceled";
8
+ export interface JobState {
9
+ jobId: string;
10
+ prompt_id?: string;
11
+ assignedClientUrl?: string;
12
+ workflow: Workflow;
13
+ status: JobStatus;
14
+ autoSeeds?: Record<string, number>;
15
+ resolver: ((results: JobResults) => void) | null;
16
+ resultsPromise?: Promise<JobResults>;
17
+ images?: ImageInfo[];
18
+ onProgress?: (progress: any) => void;
19
+ onPreview?: (preview: any) => void;
20
+ profiler?: JobProfiler;
21
+ }
22
+ export interface JobResults {
23
+ status: JobResultStatus;
24
+ jobId: string;
25
+ prompt_id: string;
26
+ images: string[];
27
+ error?: any;
28
+ profileStats?: JobProfileStats;
29
+ }
30
+ export declare class JobStateRegistry {
31
+ pool: MultiWorkflowPool;
32
+ clients: ClientRegistry;
33
+ jobs: Map<string, JobState>;
34
+ promptIdToJobId: Map<string, string>;
35
+ constructor(pool: MultiWorkflowPool, clients: ClientRegistry);
36
+ addJob(workflow: Workflow): string;
37
+ getJobStatus(jobId: string): JobStatus;
38
+ cancelJob(jobId: string): Promise<void>;
39
+ setJobStatus(jobId: string, newStatus: JobStatus, assignedClientUrl?: string): void;
40
+ updateJobAutoSeeds(jobId: string, autoSeeds: Record<string, number>): void;
41
+ setPromptId(jobId: string, prompt_id: string): void;
42
+ completeJob(prompt_id: string): void;
43
+ private processQueue;
44
+ waitForResults(jobId: string): Promise<JobResults>;
45
+ addJobImages(prompt_id: string, images: ImageInfo[]): void;
46
+ private removeJobFromQueue;
47
+ attachJobProgressListener(jobId: string, progressListener: (progress: {
48
+ value: number;
49
+ max: number;
50
+ }) => void): void;
51
+ attachJobPreviewListener(jobId: string, previewListener: (preview: {
52
+ metadata: any;
53
+ blob: Blob;
54
+ }) => void): void;
55
+ updateJobProgress(prompt_id: string, value: number, max: number, nodeId?: string | number): void;
56
+ updateJobPreviewMetadata(prompt_id: any, metadata: any, blob: Blob): void;
57
+ setJobFailure(jobId: string, bodyJSON: any): void;
58
+ /**
59
+ * Track node execution start for profiling
60
+ */
61
+ onNodeExecuting(prompt_id: string, nodeId: string): void;
62
+ /**
63
+ * Track cached nodes for profiling
64
+ */
65
+ onCachedNodes(prompt_id: string, nodeIds: string[]): void;
66
+ }
67
+ //# sourceMappingURL=job-state-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-state-registry.d.ts","sourceRoot":"","sources":["../../src/multipool/job-state-registry.ts"],"names":[],"mappings":"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"}