comfyui-node 1.6.1 → 1.6.3
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/.tsbuildinfo +1 -1
- package/dist/call-wrapper.js +856 -856
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/multipool/client-registry.d.ts +32 -11
- package/dist/multipool/client-registry.d.ts.map +1 -1
- package/dist/multipool/client-registry.js +135 -8
- package/dist/multipool/client-registry.js.map +1 -1
- package/dist/multipool/helpers.d.ts +5 -0
- package/dist/multipool/helpers.d.ts.map +1 -0
- package/dist/multipool/helpers.js +53 -0
- package/dist/multipool/helpers.js.map +1 -0
- package/dist/multipool/index.d.ts +2 -1
- package/dist/multipool/index.d.ts.map +1 -1
- package/dist/multipool/index.js +2 -1
- package/dist/multipool/index.js.map +1 -1
- package/dist/multipool/interfaces.d.ts +25 -0
- package/dist/multipool/interfaces.d.ts.map +1 -1
- package/dist/multipool/job-profiler.d.ts +128 -0
- package/dist/multipool/job-profiler.d.ts.map +1 -0
- package/dist/multipool/job-profiler.js +222 -0
- package/dist/multipool/job-profiler.js.map +1 -0
- package/dist/multipool/job-queue-processor.d.ts +27 -11
- package/dist/multipool/job-queue-processor.d.ts.map +1 -1
- package/dist/multipool/job-queue-processor.js +196 -9
- package/dist/multipool/job-queue-processor.js.map +1 -1
- package/dist/multipool/job-state-registry.d.ts +67 -0
- package/dist/multipool/job-state-registry.d.ts.map +1 -0
- package/dist/multipool/job-state-registry.js +283 -0
- package/dist/multipool/job-state-registry.js.map +1 -0
- package/dist/multipool/logger.d.ts +30 -0
- package/dist/multipool/logger.d.ts.map +1 -0
- package/dist/multipool/logger.js +75 -0
- package/dist/multipool/logger.js.map +1 -0
- package/dist/multipool/multi-workflow-pool.d.ts +86 -7
- package/dist/multipool/multi-workflow-pool.d.ts.map +1 -1
- package/dist/multipool/multi-workflow-pool.js +365 -13
- package/dist/multipool/multi-workflow-pool.js.map +1 -1
- package/dist/multipool/pool-event-manager.d.ts +10 -10
- package/dist/multipool/tests/client-registry-api-demo.d.ts +7 -0
- package/dist/multipool/tests/client-registry-api-demo.d.ts.map +1 -0
- package/dist/multipool/tests/client-registry-api-demo.js +136 -0
- package/dist/multipool/tests/client-registry-api-demo.js.map +1 -0
- package/dist/multipool/tests/client-registry.spec.d.ts +2 -0
- package/dist/multipool/tests/client-registry.spec.d.ts.map +1 -0
- package/dist/multipool/tests/client-registry.spec.js +191 -0
- package/dist/multipool/tests/client-registry.spec.js.map +1 -0
- package/dist/multipool/tests/error-classification-tests.d.ts +2 -0
- package/dist/multipool/tests/error-classification-tests.d.ts.map +1 -0
- package/dist/multipool/tests/error-classification-tests.js +374 -0
- package/dist/multipool/tests/error-classification-tests.js.map +1 -0
- package/dist/multipool/tests/event-forwarding-demo.d.ts +7 -0
- package/dist/multipool/tests/event-forwarding-demo.d.ts.map +1 -0
- package/dist/multipool/tests/event-forwarding-demo.js +88 -0
- package/dist/multipool/tests/event-forwarding-demo.js.map +1 -0
- package/dist/multipool/tests/helpers.spec.d.ts +2 -0
- package/dist/multipool/tests/helpers.spec.d.ts.map +1 -0
- package/dist/multipool/tests/helpers.spec.js +100 -0
- package/dist/multipool/tests/helpers.spec.js.map +1 -0
- package/dist/multipool/tests/job-queue-processor.spec.d.ts +2 -0
- package/dist/multipool/tests/job-queue-processor.spec.d.ts.map +1 -0
- package/dist/multipool/tests/job-queue-processor.spec.js +89 -0
- package/dist/multipool/tests/job-queue-processor.spec.js.map +1 -0
- package/dist/multipool/tests/job-state-registry.d.ts +16 -16
- package/dist/multipool/tests/job-state-registry.js +23 -23
- package/dist/multipool/tests/job-state-registry.spec.d.ts +2 -0
- package/dist/multipool/tests/job-state-registry.spec.d.ts.map +1 -0
- package/dist/multipool/tests/job-state-registry.spec.js +143 -0
- package/dist/multipool/tests/job-state-registry.spec.js.map +1 -0
- package/dist/multipool/tests/multipool-basic.d.ts +11 -1
- package/dist/multipool/tests/multipool-basic.d.ts.map +1 -1
- package/dist/multipool/tests/multipool-basic.js +140 -2
- package/dist/multipool/tests/multipool-basic.js.map +1 -1
- package/dist/multipool/tests/profiling-demo.d.ts +7 -0
- package/dist/multipool/tests/profiling-demo.d.ts.map +1 -0
- package/dist/multipool/tests/profiling-demo.js +88 -0
- package/dist/multipool/tests/profiling-demo.js.map +1 -0
- package/dist/multipool/tests/prompt-generator.d.ts +10 -0
- package/dist/multipool/tests/prompt-generator.d.ts.map +1 -0
- package/dist/multipool/tests/prompt-generator.js +26 -0
- package/dist/multipool/tests/prompt-generator.js.map +1 -0
- package/dist/multipool/tests/test-helpers.d.ts +4 -0
- package/dist/multipool/tests/test-helpers.d.ts.map +1 -0
- package/dist/multipool/tests/test-helpers.js +10 -0
- package/dist/multipool/tests/test-helpers.js.map +1 -0
- package/dist/multipool/tests/two-stage-edit-simulation.d.ts +32 -0
- package/dist/multipool/tests/two-stage-edit-simulation.d.ts.map +1 -0
- package/dist/multipool/tests/two-stage-edit-simulation.js +299 -0
- package/dist/multipool/tests/two-stage-edit-simulation.js.map +1 -0
- package/dist/multipool/workflow.d.ts +178 -173
- package/dist/multipool/workflow.d.ts.map +1 -1
- package/dist/multipool/workflow.js +333 -271
- package/dist/multipool/workflow.js.map +1 -1
- package/dist/pool/SmartPool.d.ts +143 -143
- package/dist/pool/SmartPool.js +676 -676
- package/dist/pool/SmartPoolV2.d.ts +119 -119
- package/dist/pool/SmartPoolV2.js +586 -586
- package/dist/pool/WorkflowPool.d.ts +202 -202
- package/dist/pool/WorkflowPool.d.ts.map +1 -1
- package/dist/pool/WorkflowPool.js +845 -840
- package/dist/pool/WorkflowPool.js.map +1 -1
- package/dist/pool/client/ClientManager.d.ts +86 -86
- package/dist/pool/client/ClientManager.js +215 -215
- package/dist/pool/index.d.ts +9 -11
- package/dist/pool/index.d.ts.map +1 -1
- package/dist/pool/index.js +3 -5
- package/dist/pool/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event Forwarding Demo for MultiWorkflowPool
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates that all ComfyUI client events are forwarded through PoolEventManager
|
|
5
|
+
*/
|
|
6
|
+
import { MultiWorkflowPool } from "../multi-workflow-pool.js";
|
|
7
|
+
import { Workflow } from "../workflow.js";
|
|
8
|
+
import GenerationGraph from "../../../scripts/workflows/T2I-one-obsession.json" with { type: "json" };
|
|
9
|
+
const GEN_HOST = "http://localhost:8188";
|
|
10
|
+
// Create pool
|
|
11
|
+
const pool = new MultiWorkflowPool({
|
|
12
|
+
logLevel: "warn" // Keep logs minimal to see events clearly
|
|
13
|
+
});
|
|
14
|
+
const genWorkflow = Workflow.fromAugmented(GenerationGraph);
|
|
15
|
+
pool.addClient(GEN_HOST, {
|
|
16
|
+
workflowAffinity: [genWorkflow],
|
|
17
|
+
priority: 1
|
|
18
|
+
});
|
|
19
|
+
console.log("\n" + "=".repeat(80));
|
|
20
|
+
console.log("EVENT FORWARDING DEMO - MultiWorkflowPool");
|
|
21
|
+
console.log("=".repeat(80));
|
|
22
|
+
console.log(`Generation Host: ${GEN_HOST}`);
|
|
23
|
+
console.log("Testing: All client events forwarded through PoolEventManager");
|
|
24
|
+
console.log("=".repeat(80) + "\n");
|
|
25
|
+
// Track all events received
|
|
26
|
+
const eventLog = [];
|
|
27
|
+
// Attach event hooks for various client events
|
|
28
|
+
const trackedEvents = [
|
|
29
|
+
"client:status",
|
|
30
|
+
"client:progress",
|
|
31
|
+
"client:executing",
|
|
32
|
+
"client:execution_cached",
|
|
33
|
+
"client:executed",
|
|
34
|
+
"client:execution_success",
|
|
35
|
+
"client:b_preview_meta"
|
|
36
|
+
];
|
|
37
|
+
trackedEvents.forEach(eventType => {
|
|
38
|
+
pool.attachEventHook(eventType, (event) => {
|
|
39
|
+
eventLog.push({
|
|
40
|
+
type: event.type,
|
|
41
|
+
clientName: event.payload.clientName,
|
|
42
|
+
eventType: event.payload.eventType
|
|
43
|
+
});
|
|
44
|
+
console.log(`[Event Hook] ${event.type} from ${event.payload.clientName}`);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
console.log(`✅ Attached event hooks for: ${trackedEvents.join(", ")}\n`);
|
|
48
|
+
await pool.init();
|
|
49
|
+
console.log("\n📤 Submitting job to trigger events...\n");
|
|
50
|
+
// Run a simple generation job
|
|
51
|
+
const workflow = Workflow.fromAugmented(GenerationGraph)
|
|
52
|
+
.input("1", "value", "test image, simple")
|
|
53
|
+
.input("10", "steps", 5) // Low steps for faster execution
|
|
54
|
+
.input("10", "seed", 42);
|
|
55
|
+
const jobId = await pool.submitJob(workflow);
|
|
56
|
+
await pool.waitForJobCompletion(jobId);
|
|
57
|
+
console.log("\n" + "=".repeat(80));
|
|
58
|
+
console.log("JOB COMPLETED - EVENT LOG SUMMARY");
|
|
59
|
+
console.log("=".repeat(80));
|
|
60
|
+
console.log(`\n📊 Total Events Captured: ${eventLog.length}\n`);
|
|
61
|
+
// Group events by type
|
|
62
|
+
const eventsByType = new Map();
|
|
63
|
+
eventLog.forEach(log => {
|
|
64
|
+
eventsByType.set(log.type, (eventsByType.get(log.type) || 0) + 1);
|
|
65
|
+
});
|
|
66
|
+
console.log("Event Type Breakdown:");
|
|
67
|
+
eventsByType.forEach((count, type) => {
|
|
68
|
+
console.log(` ${type}: ${count} events`);
|
|
69
|
+
});
|
|
70
|
+
// Verify critical events were captured
|
|
71
|
+
const criticalEvents = ["client:status", "client:execution_success"];
|
|
72
|
+
const missingEvents = criticalEvents.filter(e => !eventsByType.has(e));
|
|
73
|
+
if (missingEvents.length > 0) {
|
|
74
|
+
console.log(`\n⚠️ WARNING: Missing critical events: ${missingEvents.join(", ")}`);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
console.log("\n✅ All critical events were forwarded successfully!");
|
|
78
|
+
}
|
|
79
|
+
// Show detailed event timeline
|
|
80
|
+
console.log("\n📅 Event Timeline:");
|
|
81
|
+
eventLog.forEach((log, i) => {
|
|
82
|
+
console.log(` ${i + 1}. ${log.type} (${log.eventType}) from ${log.clientName}`);
|
|
83
|
+
});
|
|
84
|
+
console.log("\n" + "=".repeat(80));
|
|
85
|
+
await pool.shutdown();
|
|
86
|
+
console.log("\n✅ Event forwarding demo completed, exiting...");
|
|
87
|
+
process.exit(0);
|
|
88
|
+
//# sourceMappingURL=event-forwarding-demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-forwarding-demo.js","sourceRoot":"","sources":["../../../src/multipool/tests/event-forwarding-demo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.spec.d.ts","sourceRoot":"","sources":["../../../src/multipool/tests/helpers.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { classifyFailure } from "../helpers.js";
|
|
3
|
+
describe("classifyFailure", () => {
|
|
4
|
+
// Test for Connection Failure
|
|
5
|
+
it("should classify connection errors", () => {
|
|
6
|
+
const connectionError = new Error("Connection timed out");
|
|
7
|
+
expect(classifyFailure(connectionError)).toEqual({
|
|
8
|
+
type: "connection",
|
|
9
|
+
message: "Connection timed out",
|
|
10
|
+
});
|
|
11
|
+
const anotherConnectionError = { message: "connect ECONNREFUSED 127.0.0.1:8188" };
|
|
12
|
+
expect(classifyFailure(anotherConnectionError)).toEqual({
|
|
13
|
+
type: "connection",
|
|
14
|
+
message: "connect ECONNREFUSED 127.0.0.1:8188",
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
// Test for Workflow Incompatibility - Missing Model
|
|
18
|
+
it("should classify missing model errors as workflow_incompatibility", () => {
|
|
19
|
+
const missingModelError = {
|
|
20
|
+
bodyJSON: {
|
|
21
|
+
node_errors: {
|
|
22
|
+
"2": {
|
|
23
|
+
errors: [
|
|
24
|
+
{
|
|
25
|
+
type: "value_not_in_list",
|
|
26
|
+
details: "Value not in list: ckpt_name 'this_model_does_not_exist.safetensors' not in [...]",
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
const classification = classifyFailure(missingModelError);
|
|
34
|
+
expect(classification.type).toBe("workflow_incompatibility");
|
|
35
|
+
expect(classification.message).toContain("Missing model file");
|
|
36
|
+
});
|
|
37
|
+
// Test for Workflow Incompatibility - Missing Custom Node
|
|
38
|
+
it("should classify missing custom node errors as workflow_incompatibility", () => {
|
|
39
|
+
const missingNodeError = {
|
|
40
|
+
bodyJSON: {
|
|
41
|
+
error: {
|
|
42
|
+
type: "invalid_prompt",
|
|
43
|
+
message: "Node type not found: NonExistentNode",
|
|
44
|
+
},
|
|
45
|
+
node_errors: {},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
const classification = classifyFailure(missingNodeError);
|
|
49
|
+
expect(classification.type).toBe("workflow_incompatibility");
|
|
50
|
+
});
|
|
51
|
+
it('should classify python exception for missing nodes as workflow_incompatibility', () => {
|
|
52
|
+
const pythonError = {
|
|
53
|
+
bodyJSON: {
|
|
54
|
+
"exception_type": "Exception",
|
|
55
|
+
"exception_message": "Node type not found: ImpactWildcardEncode",
|
|
56
|
+
"traceback": "..."
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const classification = classifyFailure(pythonError);
|
|
60
|
+
expect(classification.type).toBe('workflow_incompatibility');
|
|
61
|
+
expect(classification.message).toBe('Node type not found: ImpactWildcardEncode');
|
|
62
|
+
});
|
|
63
|
+
// Test for Transient Failure - Out of Memory
|
|
64
|
+
it("should classify OOM errors as transient", () => {
|
|
65
|
+
const oomError = {
|
|
66
|
+
bodyJSON: {
|
|
67
|
+
exception_message: "CUDA out of memory. Tried to allocate...",
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
expect(classifyFailure(oomError)).toEqual({
|
|
71
|
+
type: "transient",
|
|
72
|
+
message: "CUDA out of memory",
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
// Test for Transient Failure - Other exceptions
|
|
76
|
+
it("should classify other exceptions as transient", () => {
|
|
77
|
+
const genericError = {
|
|
78
|
+
bodyJSON: {
|
|
79
|
+
exception_message: "Something else went wrong",
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
expect(classifyFailure(genericError)).toEqual({
|
|
83
|
+
type: "transient",
|
|
84
|
+
message: "Something else went wrong",
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
// Test for Default Case
|
|
88
|
+
it("should default to transient for unknown errors with a response body", () => {
|
|
89
|
+
const unknownError = {
|
|
90
|
+
bodyJSON: {
|
|
91
|
+
some_unusual_error: "details here",
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
expect(classifyFailure(unknownError)).toEqual({
|
|
95
|
+
type: "transient",
|
|
96
|
+
message: '{"some_unusual_error":"details here"}',
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
//# sourceMappingURL=helpers.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.spec.js","sourceRoot":"","sources":["../../../src/multipool/tests/helpers.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-queue-processor.spec.d.ts","sourceRoot":"","sources":["../../../src/multipool/tests/job-queue-processor.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, jest } from "bun:test";
|
|
2
|
+
import { JobQueueProcessor } from "../job-queue-processor.js";
|
|
3
|
+
import { Workflow } from "../workflow.js";
|
|
4
|
+
import { Logger } from "../logger.js";
|
|
5
|
+
// Mock dependencies
|
|
6
|
+
const createJobStateRegistryMock = () => ({
|
|
7
|
+
getJobStatus: jest.fn().mockReturnValue("pending"),
|
|
8
|
+
setJobStatus: jest.fn(),
|
|
9
|
+
setPromptId: jest.fn(),
|
|
10
|
+
updateJobAutoSeeds: jest.fn(),
|
|
11
|
+
setJobFailure: jest.fn(),
|
|
12
|
+
});
|
|
13
|
+
const createClientRegistryMock = () => ({
|
|
14
|
+
getOptimalClient: jest.fn(),
|
|
15
|
+
getOptimalIdleClient: jest.fn(),
|
|
16
|
+
clients: new Map(),
|
|
17
|
+
markClientIncompatibleWithWorkflow: jest.fn(),
|
|
18
|
+
getAllEligibleClientsForWorkflow: jest.fn().mockReturnValue([]),
|
|
19
|
+
});
|
|
20
|
+
const createLoggerMock = () => new Logger("test", "silent");
|
|
21
|
+
describe("JobQueueProcessor", () => {
|
|
22
|
+
let jobStateRegistryMock;
|
|
23
|
+
let clientRegistryMock;
|
|
24
|
+
let loggerMock;
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
jobStateRegistryMock = createJobStateRegistryMock();
|
|
27
|
+
clientRegistryMock = createClientRegistryMock();
|
|
28
|
+
loggerMock = createLoggerMock();
|
|
29
|
+
});
|
|
30
|
+
const createProcessor = (hash = "test-hash") => new JobQueueProcessor(jobStateRegistryMock, clientRegistryMock, hash, loggerMock);
|
|
31
|
+
it("should enqueue a job and trigger processing", async () => {
|
|
32
|
+
const processor = createProcessor();
|
|
33
|
+
const processQueueSpy = jest.spyOn(processor, "processQueue").mockImplementation(async () => { });
|
|
34
|
+
await processor.enqueueJob("job-1", new Workflow({}));
|
|
35
|
+
expect(processor.queue).toHaveLength(1);
|
|
36
|
+
expect(processor.queue[0].jobId).toBe("job-1");
|
|
37
|
+
expect(processQueueSpy).toHaveBeenCalled();
|
|
38
|
+
});
|
|
39
|
+
it("should not process queue if already processing", async () => {
|
|
40
|
+
const processor = createProcessor();
|
|
41
|
+
processor.isProcessing = true;
|
|
42
|
+
const loggerSpy = jest.spyOn(loggerMock, 'debug');
|
|
43
|
+
await processor.processQueue();
|
|
44
|
+
expect(loggerSpy).toHaveBeenCalledWith(`Job queue for workflow hash test-hash is already being processed, skipping.`);
|
|
45
|
+
});
|
|
46
|
+
it("should assign a job to an optimal client and run it successfully", async () => {
|
|
47
|
+
const processor = createProcessor();
|
|
48
|
+
const workflow = new Workflow({});
|
|
49
|
+
workflow.uploadAssets = jest.fn().mockResolvedValue(undefined);
|
|
50
|
+
const jobId = "job-1";
|
|
51
|
+
const clientMock = {
|
|
52
|
+
url: "http://localhost:8188",
|
|
53
|
+
nodeName: "test-client",
|
|
54
|
+
state: "idle",
|
|
55
|
+
api: {
|
|
56
|
+
getQueue: jest.fn().mockResolvedValue({ queue_running: [], queue_pending: [] }),
|
|
57
|
+
ext: { queue: { queuePrompt: jest.fn().mockResolvedValue({ prompt_id: "prompt-1" }) } },
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
clientRegistryMock.getOptimalClient.mockReturnValue(clientMock);
|
|
61
|
+
processor.queue.push({ jobId, workflow, attempts: 1 });
|
|
62
|
+
await processor.processQueue();
|
|
63
|
+
expect(clientRegistryMock.getOptimalClient).toHaveBeenCalledWith(workflow);
|
|
64
|
+
expect(jobStateRegistryMock.setJobStatus).toHaveBeenCalledWith(jobId, "assigned", clientMock.url);
|
|
65
|
+
expect(workflow.uploadAssets).toHaveBeenCalledWith(clientMock.api);
|
|
66
|
+
expect(clientMock.api.ext.queue.queuePrompt).toHaveBeenCalled();
|
|
67
|
+
expect(jobStateRegistryMock.setPromptId).toHaveBeenCalledWith(jobId, "prompt-1");
|
|
68
|
+
expect(jobStateRegistryMock.setJobStatus).toHaveBeenCalledWith(jobId, "running");
|
|
69
|
+
expect(clientMock.state).toBe("busy");
|
|
70
|
+
});
|
|
71
|
+
it("should re-queue a job if no idle clients are available", async () => {
|
|
72
|
+
const processor = createProcessor();
|
|
73
|
+
const workflow = new Workflow({});
|
|
74
|
+
const jobId = "job-1";
|
|
75
|
+
clientRegistryMock.getOptimalClient.mockReturnValue(null);
|
|
76
|
+
processor.queue.push({ jobId, workflow, attempts: 1 });
|
|
77
|
+
await processor.processQueue();
|
|
78
|
+
expect(jobStateRegistryMock.setJobStatus).toHaveBeenCalledWith(jobId, "pending");
|
|
79
|
+
expect(processor.queue).toHaveLength(1);
|
|
80
|
+
expect(processor.isProcessing).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
it("should dequeue a job", () => {
|
|
83
|
+
const processor = createProcessor();
|
|
84
|
+
processor.queue = [{ jobId: "job-1", workflow: new Workflow({}), attempts: 1 }];
|
|
85
|
+
processor.dequeueJob("job-1");
|
|
86
|
+
expect(processor.queue).toHaveLength(0);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=job-queue-processor.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-queue-processor.spec.js","sourceRoot":"","sources":["../../../src/multipool/tests/job-queue-processor.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { MultiWorkflowPool } from "src/multipool/multi-workflow-pool.js";
|
|
2
|
-
import { Workflow } from "src/multipool/workflow.js";
|
|
3
|
-
interface JobState {
|
|
4
|
-
jobId: string;
|
|
5
|
-
workflow: Workflow;
|
|
6
|
-
status: 'pending' | 'running' | 'completed' | 'failed' | 'canceled';
|
|
7
|
-
}
|
|
8
|
-
export declare class JobStateRegistry {
|
|
9
|
-
pool: MultiWorkflowPool;
|
|
10
|
-
jobs: Map<string, JobState>;
|
|
11
|
-
constructor(pool: MultiWorkflowPool);
|
|
12
|
-
addJob(workflow: Workflow): `${string}-${string}-${string}-${string}-${string}`;
|
|
13
|
-
getJobStatus(jobId: string): void;
|
|
14
|
-
cancelJob(jobId: string): void;
|
|
15
|
-
}
|
|
16
|
-
export {};
|
|
1
|
+
import { MultiWorkflowPool } from "src/multipool/multi-workflow-pool.js";
|
|
2
|
+
import { Workflow } from "src/multipool/workflow.js";
|
|
3
|
+
interface JobState {
|
|
4
|
+
jobId: string;
|
|
5
|
+
workflow: Workflow;
|
|
6
|
+
status: 'pending' | 'running' | 'completed' | 'failed' | 'canceled';
|
|
7
|
+
}
|
|
8
|
+
export declare class JobStateRegistry {
|
|
9
|
+
pool: MultiWorkflowPool;
|
|
10
|
+
jobs: Map<string, JobState>;
|
|
11
|
+
constructor(pool: MultiWorkflowPool);
|
|
12
|
+
addJob(workflow: Workflow): `${string}-${string}-${string}-${string}-${string}`;
|
|
13
|
+
getJobStatus(jobId: string): void;
|
|
14
|
+
cancelJob(jobId: string): void;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
17
17
|
//# sourceMappingURL=job-state-registry.d.ts.map
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
|
-
export class JobStateRegistry {
|
|
3
|
-
pool;
|
|
4
|
-
jobs = new Map();
|
|
5
|
-
constructor(pool) {
|
|
6
|
-
this.pool = pool;
|
|
7
|
-
}
|
|
8
|
-
addJob(workflow) {
|
|
9
|
-
// Create new job id
|
|
10
|
-
const jobId = randomUUID();
|
|
11
|
-
const jobState = {
|
|
12
|
-
jobId,
|
|
13
|
-
workflow,
|
|
14
|
-
status: 'pending',
|
|
15
|
-
};
|
|
16
|
-
this.jobs.set(jobId, jobState);
|
|
17
|
-
return jobId;
|
|
18
|
-
}
|
|
19
|
-
getJobStatus(jobId) {
|
|
20
|
-
}
|
|
21
|
-
cancelJob(jobId) {
|
|
22
|
-
}
|
|
23
|
-
}
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
export class JobStateRegistry {
|
|
3
|
+
pool;
|
|
4
|
+
jobs = new Map();
|
|
5
|
+
constructor(pool) {
|
|
6
|
+
this.pool = pool;
|
|
7
|
+
}
|
|
8
|
+
addJob(workflow) {
|
|
9
|
+
// Create new job id
|
|
10
|
+
const jobId = randomUUID();
|
|
11
|
+
const jobState = {
|
|
12
|
+
jobId,
|
|
13
|
+
workflow,
|
|
14
|
+
status: 'pending',
|
|
15
|
+
};
|
|
16
|
+
this.jobs.set(jobId, jobState);
|
|
17
|
+
return jobId;
|
|
18
|
+
}
|
|
19
|
+
getJobStatus(jobId) {
|
|
20
|
+
}
|
|
21
|
+
cancelJob(jobId) {
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
24
|
//# sourceMappingURL=job-state-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-state-registry.spec.d.ts","sourceRoot":"","sources":["../../../src/multipool/tests/job-state-registry.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, jest } from "bun:test";
|
|
2
|
+
import { JobStateRegistry } from "../job-state-registry.js";
|
|
3
|
+
import { ClientRegistry } from "../client-registry.js";
|
|
4
|
+
import { Workflow } from "../workflow.js";
|
|
5
|
+
import { Logger } from "../logger.js";
|
|
6
|
+
describe("JobStateRegistry", () => {
|
|
7
|
+
let jobRegistry;
|
|
8
|
+
let poolMock;
|
|
9
|
+
let clientRegistryMock;
|
|
10
|
+
let loggerMock;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
// Mock MultiWorkflowPool
|
|
13
|
+
poolMock = {
|
|
14
|
+
options: { enableProfiling: false },
|
|
15
|
+
queues: new Map(),
|
|
16
|
+
};
|
|
17
|
+
loggerMock = new Logger("test", "silent");
|
|
18
|
+
// Mock ClientRegistry
|
|
19
|
+
clientRegistryMock = new ClientRegistry(poolMock, loggerMock);
|
|
20
|
+
// Initialize JobStateRegistry
|
|
21
|
+
jobRegistry = new JobStateRegistry(poolMock, clientRegistryMock);
|
|
22
|
+
});
|
|
23
|
+
it("should add a new job with a pending status", () => {
|
|
24
|
+
const workflow = new Workflow({});
|
|
25
|
+
const jobId = jobRegistry.addJob(workflow);
|
|
26
|
+
expect(jobId).toBeString();
|
|
27
|
+
expect(jobRegistry.getJobStatus(jobId)).toBe("pending");
|
|
28
|
+
const jobState = jobRegistry.jobs.get(jobId);
|
|
29
|
+
expect(jobState).toBeDefined();
|
|
30
|
+
expect(jobState?.workflow).toBe(workflow);
|
|
31
|
+
expect(jobState?.resolver).toBeFunction();
|
|
32
|
+
expect(jobState?.resultsPromise).toBeInstanceOf(Promise);
|
|
33
|
+
});
|
|
34
|
+
it("should throw an error when getting the status of a non-existent job", () => {
|
|
35
|
+
expect(() => jobRegistry.getJobStatus("non-existent-job-id")).toThrow("Job with ID non-existent-job-id not found.");
|
|
36
|
+
});
|
|
37
|
+
it("should set job status", () => {
|
|
38
|
+
const workflow = new Workflow({});
|
|
39
|
+
const jobId = jobRegistry.addJob(workflow);
|
|
40
|
+
jobRegistry.setJobStatus(jobId, "assigned", "http://localhost:8188");
|
|
41
|
+
expect(jobRegistry.getJobStatus(jobId)).toBe("assigned");
|
|
42
|
+
const jobState = jobRegistry.jobs.get(jobId);
|
|
43
|
+
expect(jobState?.assignedClientUrl).toBe("http://localhost:8188");
|
|
44
|
+
});
|
|
45
|
+
it("should set prompt ID and map it to job ID", () => {
|
|
46
|
+
const workflow = new Workflow({});
|
|
47
|
+
const jobId = jobRegistry.addJob(workflow);
|
|
48
|
+
const promptId = "prompt-123";
|
|
49
|
+
jobRegistry.setPromptId(jobId, promptId);
|
|
50
|
+
const jobState = jobRegistry.jobs.get(jobId);
|
|
51
|
+
expect(jobState?.prompt_id).toBe(promptId);
|
|
52
|
+
expect(jobRegistry.promptIdToJobId.get(promptId)).toBe(jobId);
|
|
53
|
+
});
|
|
54
|
+
it("should complete a job and resolve the promise", async () => {
|
|
55
|
+
const workflow = new Workflow({});
|
|
56
|
+
const jobId = jobRegistry.addJob(workflow);
|
|
57
|
+
const promptId = "prompt-123";
|
|
58
|
+
jobRegistry.setPromptId(jobId, promptId);
|
|
59
|
+
jobRegistry.setJobStatus(jobId, "running", "http://localhost:8188");
|
|
60
|
+
const resultsPromise = jobRegistry.waitForResults(jobId);
|
|
61
|
+
// Simulate adding images
|
|
62
|
+
jobRegistry.addJobImages(promptId, [{ filename: "test.png", subfolder: "", type: "output" }]);
|
|
63
|
+
// Mock client for image URL generation
|
|
64
|
+
clientRegistryMock.clients.set("http://localhost:8188", {
|
|
65
|
+
api: { ext: { file: { getPathImage: (image) => `http://localhost:8188/view?filename=${image.filename}` } } }
|
|
66
|
+
});
|
|
67
|
+
jobRegistry.completeJob(promptId);
|
|
68
|
+
const results = await resultsPromise;
|
|
69
|
+
expect(jobRegistry.getJobStatus(jobId)).toBe("completed");
|
|
70
|
+
expect(results.status).toBe("completed");
|
|
71
|
+
expect(results.jobId).toBe(jobId);
|
|
72
|
+
expect(results.prompt_id).toBe(promptId);
|
|
73
|
+
expect(results.images).toEqual(["http://localhost:8188/view?filename=test.png"]);
|
|
74
|
+
});
|
|
75
|
+
it("should fail a job and resolve the promise with an error", async () => {
|
|
76
|
+
const workflow = new Workflow({});
|
|
77
|
+
const jobId = jobRegistry.addJob(workflow);
|
|
78
|
+
const promptId = "prompt-456";
|
|
79
|
+
jobRegistry.setPromptId(jobId, promptId);
|
|
80
|
+
jobRegistry.setJobStatus(jobId, "running");
|
|
81
|
+
const resultsPromise = jobRegistry.waitForResults(jobId);
|
|
82
|
+
const errorDetails = { error: "Test error" };
|
|
83
|
+
jobRegistry.setJobFailure(jobId, errorDetails);
|
|
84
|
+
const results = await resultsPromise;
|
|
85
|
+
expect(jobRegistry.getJobStatus(jobId)).toBe("failed");
|
|
86
|
+
expect(results.status).toBe("failed");
|
|
87
|
+
expect(results.jobId).toBe(jobId);
|
|
88
|
+
expect(results.prompt_id).toBe(promptId);
|
|
89
|
+
expect(results.error).toEqual(errorDetails);
|
|
90
|
+
});
|
|
91
|
+
it("should enable profiling when the pool option is set", () => {
|
|
92
|
+
poolMock.options.enableProfiling = true;
|
|
93
|
+
jobRegistry = new JobStateRegistry(poolMock, clientRegistryMock);
|
|
94
|
+
const workflow = new Workflow({});
|
|
95
|
+
const jobId = jobRegistry.addJob(workflow);
|
|
96
|
+
const jobState = jobRegistry.jobs.get(jobId);
|
|
97
|
+
expect(jobState?.profiler).toBeDefined();
|
|
98
|
+
});
|
|
99
|
+
describe("cancelJob", () => {
|
|
100
|
+
it("should cancel a pending job", async () => {
|
|
101
|
+
const workflow = new Workflow({});
|
|
102
|
+
const jobId = jobRegistry.addJob(workflow);
|
|
103
|
+
const resultsPromise = jobRegistry.waitForResults(jobId);
|
|
104
|
+
// Mock queue to check if dequeue is called
|
|
105
|
+
const queueMock = { dequeueJob: jest.fn() };
|
|
106
|
+
jobRegistry.pool.queues.set(workflow.structureHash || "general", queueMock);
|
|
107
|
+
await jobRegistry.cancelJob(jobId);
|
|
108
|
+
expect(jobRegistry.getJobStatus(jobId)).toBe("canceled");
|
|
109
|
+
expect(queueMock.dequeueJob).toHaveBeenCalledWith(jobId);
|
|
110
|
+
const result = await resultsPromise;
|
|
111
|
+
expect(result.status).toBe("canceled");
|
|
112
|
+
});
|
|
113
|
+
it("should cancel a running job", async () => {
|
|
114
|
+
const workflow = new Workflow({});
|
|
115
|
+
const jobId = jobRegistry.addJob(workflow);
|
|
116
|
+
const promptId = "prompt-789";
|
|
117
|
+
const clientUrl = "http://localhost:8188";
|
|
118
|
+
jobRegistry.setJobStatus(jobId, "running", clientUrl);
|
|
119
|
+
jobRegistry.setPromptId(jobId, promptId);
|
|
120
|
+
const resultsPromise = jobRegistry.waitForResults(jobId);
|
|
121
|
+
// Mock client and its API
|
|
122
|
+
const clientApiMock = { ext: { queue: { interrupt: jest.fn() } } };
|
|
123
|
+
clientRegistryMock.clients.set(clientUrl, { api: clientApiMock, state: "busy" });
|
|
124
|
+
// Mock queue processing
|
|
125
|
+
const queueMock = { processQueue: jest.fn().mockResolvedValue(undefined) };
|
|
126
|
+
jobRegistry.pool.queues.set(workflow.structureHash || "general", queueMock);
|
|
127
|
+
await jobRegistry.cancelJob(jobId);
|
|
128
|
+
expect(jobRegistry.getJobStatus(jobId)).toBe("canceled");
|
|
129
|
+
expect(clientApiMock.ext.queue.interrupt).toHaveBeenCalledWith(promptId);
|
|
130
|
+
expect(clientRegistryMock.clients.get(clientUrl)?.state).toBe("idle");
|
|
131
|
+
expect(queueMock.processQueue).toHaveBeenCalled();
|
|
132
|
+
const result = await resultsPromise;
|
|
133
|
+
expect(result.status).toBe("canceled");
|
|
134
|
+
});
|
|
135
|
+
it("should throw an error when trying to cancel a completed job", async () => {
|
|
136
|
+
const workflow = new Workflow({});
|
|
137
|
+
const jobId = jobRegistry.addJob(workflow);
|
|
138
|
+
jobRegistry.setJobStatus(jobId, "completed");
|
|
139
|
+
await expect(jobRegistry.cancelJob(jobId)).rejects.toThrow(`Cannot cancel job ${jobId} with status completed.`);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
//# sourceMappingURL=job-state-registry.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-state-registry.spec.js","sourceRoot":"","sources":["../../../src/multipool/tests/job-state-registry.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,12 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export declare class SimulatedUser {
|
|
2
|
+
promptGenerator: (() => string) | null;
|
|
3
|
+
modelFunction: (prompt: string) => Promise<string[]>;
|
|
4
|
+
shouldGenerate: boolean;
|
|
5
|
+
totalImages: number;
|
|
6
|
+
collectedImages: number;
|
|
7
|
+
constructor(generator?: (() => string) | null, modelFunction?: (prompt: string) => Promise<string[]>, totalImages?: number);
|
|
8
|
+
stop(): void;
|
|
9
|
+
start(): void;
|
|
10
|
+
generateImages(count: number): Promise<void>;
|
|
11
|
+
}
|
|
2
12
|
//# sourceMappingURL=multipool-basic.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multipool-basic.d.ts","sourceRoot":"","sources":["../../../src/multipool/tests/multipool-basic.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"multipool-basic.d.ts","sourceRoot":"","sources":["../../../src/multipool/tests/multipool-basic.ts"],"names":[],"mappings":"AA8GA,qBAAa,aAAa;IAExB,eAAe,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,IAAI,CAAC;IACvC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAkB;IACtE,cAAc,EAAE,OAAO,CAAQ;IAC/B,WAAW,EAAE,MAAM,CAAM;IACzB,eAAe,EAAE,MAAM,CAAK;gBAG1B,SAAS,GAAE,CAAC,MAAM,MAAM,CAAC,GAAG,IAAW,EACvC,aAAa,GAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAkB,EACrE,WAAW,GAAE,MAAW;IAO1B,IAAI;IAIJ,KAAK;IAOC,cAAc,CAAC,KAAK,EAAE,MAAM;CAkBnC"}
|