@powerhousedao/reactor 5.0.0-staging.1 → 5.0.0-staging.11
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/bench/event-bus.bench.js +17 -27
- package/dist/bench/event-bus.bench.js.map +1 -1
- package/dist/bench/queue-only.bench.js +1 -0
- package/dist/bench/queue-only.bench.js.map +1 -1
- package/dist/bench/reactor-throughput.bench.js +42 -45
- package/dist/bench/reactor-throughput.bench.js.map +1 -1
- package/dist/src/events/event-bus.d.ts +3 -3
- package/dist/src/events/event-bus.d.ts.map +1 -1
- package/dist/src/events/event-bus.js +1 -1
- package/dist/src/events/event-bus.js.map +1 -1
- package/dist/src/events/interfaces.d.ts +1 -1
- package/dist/src/events/interfaces.d.ts.map +1 -1
- package/dist/src/executor/interfaces.d.ts +31 -54
- package/dist/src/executor/interfaces.d.ts.map +1 -1
- package/dist/src/executor/simple-job-executor-manager.d.ts +27 -0
- package/dist/src/executor/simple-job-executor-manager.d.ts.map +1 -0
- package/dist/src/executor/simple-job-executor-manager.js +128 -0
- package/dist/src/executor/simple-job-executor-manager.js.map +1 -0
- package/dist/src/executor/simple-job-executor.d.ts +19 -0
- package/dist/src/executor/simple-job-executor.d.ts.map +1 -0
- package/dist/src/executor/simple-job-executor.js +69 -0
- package/dist/src/executor/simple-job-executor.js.map +1 -0
- package/dist/src/executor/types.d.ts +23 -8
- package/dist/src/executor/types.d.ts.map +1 -1
- package/dist/src/executor/types.js.map +1 -1
- package/dist/src/index.d.ts +5 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/queue/interfaces.d.ts +45 -5
- package/dist/src/queue/interfaces.d.ts.map +1 -1
- package/dist/src/queue/job-execution-handle.d.ts +24 -0
- package/dist/src/queue/job-execution-handle.d.ts.map +1 -0
- package/dist/src/queue/job-execution-handle.js +62 -0
- package/dist/src/queue/job-execution-handle.js.map +1 -0
- package/dist/src/queue/queue.d.ts +54 -5
- package/dist/src/queue/queue.d.ts.map +1 -1
- package/dist/src/queue/queue.js +237 -23
- package/dist/src/queue/queue.js.map +1 -1
- package/dist/src/queue/types.d.ts +25 -0
- package/dist/src/queue/types.d.ts.map +1 -1
- package/dist/src/queue/types.js +12 -0
- package/dist/src/queue/types.js.map +1 -1
- package/dist/src/reactor.d.ts +3 -12
- package/dist/src/reactor.d.ts.map +1 -1
- package/dist/src/reactor.js +14 -25
- package/dist/src/reactor.js.map +1 -1
- package/dist/src/registry/implementation.d.ts +62 -0
- package/dist/src/registry/implementation.d.ts.map +1 -0
- package/dist/src/registry/implementation.js +96 -0
- package/dist/src/registry/implementation.js.map +1 -0
- package/dist/src/registry/index.d.ts +3 -0
- package/dist/src/registry/index.d.ts.map +1 -0
- package/dist/src/registry/index.js +2 -0
- package/dist/src/registry/index.js.map +1 -0
- package/dist/src/registry/interfaces.d.ts +39 -0
- package/dist/src/registry/interfaces.d.ts.map +1 -0
- package/dist/src/registry/interfaces.js +2 -0
- package/dist/src/registry/interfaces.js.map +1 -0
- package/dist/src/shared/factories.d.ts +1 -1
- package/dist/src/shared/factories.d.ts.map +1 -1
- package/dist/src/utils.d.ts +2 -2
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +3 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/test/event-bus.test.js +19 -10
- package/dist/test/event-bus.test.js.map +1 -1
- package/dist/test/executor/executor-integration.test.d.ts +2 -0
- package/dist/test/executor/executor-integration.test.d.ts.map +1 -0
- package/dist/test/executor/executor-integration.test.js +287 -0
- package/dist/test/executor/executor-integration.test.js.map +1 -0
- package/dist/test/executor/job-execution-handle.test.d.ts +2 -0
- package/dist/test/executor/job-execution-handle.test.d.ts.map +1 -0
- package/dist/test/executor/job-execution-handle.test.js +272 -0
- package/dist/test/executor/job-execution-handle.test.js.map +1 -0
- package/dist/test/executor/simple-job-executor-manager.test.d.ts +2 -0
- package/dist/test/executor/simple-job-executor-manager.test.d.ts.map +1 -0
- package/dist/test/executor/simple-job-executor-manager.test.js +132 -0
- package/dist/test/executor/simple-job-executor-manager.test.js.map +1 -0
- package/dist/test/executor/simple-job-executor.test.d.ts +2 -0
- package/dist/test/executor/simple-job-executor.test.d.ts.map +1 -0
- package/dist/test/executor/simple-job-executor.test.js +139 -0
- package/dist/test/executor/simple-job-executor.test.js.map +1 -0
- package/dist/test/factories.d.ts +123 -0
- package/dist/test/factories.d.ts.map +1 -0
- package/dist/test/factories.js +319 -0
- package/dist/test/factories.js.map +1 -0
- package/dist/test/integration/document-drive-integration.test.d.ts +2 -0
- package/dist/test/integration/document-drive-integration.test.d.ts.map +1 -0
- package/dist/test/integration/document-drive-integration.test.js +1102 -0
- package/dist/test/integration/document-drive-integration.test.js.map +1 -0
- package/dist/test/integration/reactor-read.test.d.ts.map +1 -0
- package/dist/test/{reactor-read.test.js → integration/reactor-read.test.js} +28 -67
- package/dist/test/integration/reactor-read.test.js.map +1 -0
- package/dist/test/queue/queue-integration.test.d.ts +2 -0
- package/dist/test/queue/queue-integration.test.d.ts.map +1 -0
- package/dist/test/queue/queue-integration.test.js +322 -0
- package/dist/test/queue/queue-integration.test.js.map +1 -0
- package/dist/test/{queue.test.d.ts.map → queue/queue.test.d.ts.map} +1 -1
- package/dist/test/queue/queue.test.js +770 -0
- package/dist/test/queue/queue.test.js.map +1 -0
- package/dist/test/registry/registry.test.d.ts +2 -0
- package/dist/test/registry/registry.test.d.ts.map +1 -0
- package/dist/test/registry/registry.test.js +182 -0
- package/dist/test/registry/registry.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +11 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +3 -3
- package/dist/bench/end-to-end-flow.bench.d.ts +0 -2
- package/dist/bench/end-to-end-flow.bench.d.ts.map +0 -1
- package/dist/bench/end-to-end-flow.bench.js +0 -266
- package/dist/bench/end-to-end-flow.bench.js.map +0 -1
- package/dist/src/executor/job-executor.d.ts +0 -62
- package/dist/src/executor/job-executor.d.ts.map +0 -1
- package/dist/src/executor/job-executor.js +0 -325
- package/dist/src/executor/job-executor.js.map +0 -1
- package/dist/test/job-executor.test.d.ts +0 -2
- package/dist/test/job-executor.test.d.ts.map +0 -1
- package/dist/test/job-executor.test.js +0 -587
- package/dist/test/job-executor.test.js.map +0 -1
- package/dist/test/queue.test.js +0 -407
- package/dist/test/queue.test.js.map +0 -1
- package/dist/test/reactor-read.test.d.ts.map +0 -1
- package/dist/test/reactor-read.test.js.map +0 -1
- package/dist/test/reactor-write.test.d.ts +0 -2
- package/dist/test/reactor-write.test.d.ts.map +0 -1
- package/dist/test/reactor-write.test.js +0 -232
- package/dist/test/reactor-write.test.js.map +0 -1
- /package/dist/test/{reactor-read.test.d.ts → integration/reactor-read.test.d.ts} +0 -0
- /package/dist/test/{queue.test.d.ts → queue/queue.test.d.ts} +0 -0
|
@@ -1,587 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { EventBus } from "../src/events/event-bus.js";
|
|
3
|
-
import { InMemoryJobExecutor, JobExecutorEventTypes, } from "../src/executor/job-executor.js";
|
|
4
|
-
import { InMemoryQueue } from "../src/queue/queue.js";
|
|
5
|
-
describe("InMemoryJobExecutor", () => {
|
|
6
|
-
let executor;
|
|
7
|
-
let eventBus;
|
|
8
|
-
let queue;
|
|
9
|
-
let mockEventBusEmit;
|
|
10
|
-
const createTestOperation = (overrides = {}) => ({
|
|
11
|
-
index: 1,
|
|
12
|
-
timestampUtcMs: new Date().toISOString(),
|
|
13
|
-
hash: "test-hash",
|
|
14
|
-
skip: 0,
|
|
15
|
-
action: {
|
|
16
|
-
id: "action-1",
|
|
17
|
-
type: "test-operation",
|
|
18
|
-
timestampUtcMs: new Date().toISOString(),
|
|
19
|
-
input: { test: "data" },
|
|
20
|
-
scope: "global",
|
|
21
|
-
...overrides.action,
|
|
22
|
-
},
|
|
23
|
-
id: "op-1",
|
|
24
|
-
...overrides,
|
|
25
|
-
});
|
|
26
|
-
const createTestJob = (overrides = {}) => ({
|
|
27
|
-
id: "job-1",
|
|
28
|
-
documentId: "doc-1",
|
|
29
|
-
scope: "global",
|
|
30
|
-
branch: "main",
|
|
31
|
-
operation: createTestOperation(),
|
|
32
|
-
createdAt: new Date().toISOString(),
|
|
33
|
-
retryCount: 0,
|
|
34
|
-
maxRetries: 3,
|
|
35
|
-
...overrides,
|
|
36
|
-
});
|
|
37
|
-
beforeEach(() => {
|
|
38
|
-
eventBus = new EventBus();
|
|
39
|
-
mockEventBusEmit = vi.fn().mockResolvedValue(undefined);
|
|
40
|
-
eventBus.emit = mockEventBusEmit;
|
|
41
|
-
queue = new InMemoryQueue(eventBus);
|
|
42
|
-
executor = new InMemoryJobExecutor(eventBus, queue);
|
|
43
|
-
});
|
|
44
|
-
describe("start", () => {
|
|
45
|
-
it("should start the executor with default config", async () => {
|
|
46
|
-
await executor.start();
|
|
47
|
-
const status = await executor.getStatus();
|
|
48
|
-
expect(status.isRunning).toBe(true);
|
|
49
|
-
expect(status.activeJobs).toBe(0);
|
|
50
|
-
expect(status.totalJobsProcessed).toBe(0);
|
|
51
|
-
});
|
|
52
|
-
it("should start the executor with custom config", async () => {
|
|
53
|
-
const config = {
|
|
54
|
-
maxConcurrency: 10,
|
|
55
|
-
jobTimeout: 60000,
|
|
56
|
-
retryBaseDelay: 2000,
|
|
57
|
-
retryMaxDelay: 60000,
|
|
58
|
-
};
|
|
59
|
-
await executor.start(config);
|
|
60
|
-
const status = await executor.getStatus();
|
|
61
|
-
expect(status.isRunning).toBe(true);
|
|
62
|
-
});
|
|
63
|
-
it("should emit executor started event", async () => {
|
|
64
|
-
await executor.start();
|
|
65
|
-
expect(mockEventBusEmit).toHaveBeenCalledWith(JobExecutorEventTypes.EXECUTOR_STARTED, expect.objectContaining({
|
|
66
|
-
config: expect.any(Object),
|
|
67
|
-
startedAt: expect.any(String),
|
|
68
|
-
}));
|
|
69
|
-
});
|
|
70
|
-
it("should throw error if already running", async () => {
|
|
71
|
-
await executor.start();
|
|
72
|
-
await expect(executor.start()).rejects.toThrow("Job executor is already running");
|
|
73
|
-
});
|
|
74
|
-
it("should process existing jobs in queue on start", async () => {
|
|
75
|
-
const realEventBus = new EventBus();
|
|
76
|
-
const realQueue = new InMemoryQueue(realEventBus);
|
|
77
|
-
const realExecutor = new InMemoryJobExecutor(realEventBus, realQueue);
|
|
78
|
-
const job = createTestJob();
|
|
79
|
-
await realQueue.enqueue(job);
|
|
80
|
-
await realExecutor.start({ maxConcurrency: 1 });
|
|
81
|
-
// Give time for job processing
|
|
82
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
83
|
-
const status = await realExecutor.getStatus();
|
|
84
|
-
expect(status.totalJobsProcessed).toBeGreaterThan(0);
|
|
85
|
-
await realExecutor.stop();
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
describe("stop", () => {
|
|
89
|
-
beforeEach(async () => {
|
|
90
|
-
await executor.start();
|
|
91
|
-
});
|
|
92
|
-
it("should stop the executor gracefully", async () => {
|
|
93
|
-
await executor.stop(true);
|
|
94
|
-
const status = await executor.getStatus();
|
|
95
|
-
expect(status.isRunning).toBe(false);
|
|
96
|
-
});
|
|
97
|
-
it("should stop the executor non-gracefully", async () => {
|
|
98
|
-
await executor.stop(false);
|
|
99
|
-
const status = await executor.getStatus();
|
|
100
|
-
expect(status.isRunning).toBe(false);
|
|
101
|
-
});
|
|
102
|
-
it("should emit executor stopped event", async () => {
|
|
103
|
-
await executor.stop();
|
|
104
|
-
expect(mockEventBusEmit).toHaveBeenCalledWith(JobExecutorEventTypes.EXECUTOR_STOPPED, expect.objectContaining({
|
|
105
|
-
stoppedAt: expect.any(String),
|
|
106
|
-
graceful: true,
|
|
107
|
-
}));
|
|
108
|
-
});
|
|
109
|
-
it("should handle stop when not running", async () => {
|
|
110
|
-
await executor.stop();
|
|
111
|
-
await expect(executor.stop()).resolves.not.toThrow();
|
|
112
|
-
});
|
|
113
|
-
it("should wait for active jobs when stopping gracefully", async () => {
|
|
114
|
-
const job = createTestJob();
|
|
115
|
-
await queue.enqueue(job);
|
|
116
|
-
// Give some time for job to start
|
|
117
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
118
|
-
const stopPromise = executor.stop(true);
|
|
119
|
-
// Should eventually complete
|
|
120
|
-
await expect(stopPromise).resolves.not.toThrow();
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
describe("executeJob", () => {
|
|
124
|
-
beforeEach(async () => {
|
|
125
|
-
await executor.start();
|
|
126
|
-
});
|
|
127
|
-
afterEach(async () => {
|
|
128
|
-
await executor.stop();
|
|
129
|
-
});
|
|
130
|
-
it("should execute a job successfully", async () => {
|
|
131
|
-
const job = createTestJob();
|
|
132
|
-
const result = await executor.executeJob(job);
|
|
133
|
-
expect(result.success).toBe(true);
|
|
134
|
-
expect(result.job).toEqual(job);
|
|
135
|
-
expect(result.duration).toBeGreaterThan(0);
|
|
136
|
-
expect(result.completedAt).toBeDefined();
|
|
137
|
-
expect(result.metadata).toBeDefined();
|
|
138
|
-
});
|
|
139
|
-
it("should emit job started and completed events", async () => {
|
|
140
|
-
const job = createTestJob();
|
|
141
|
-
await executor.executeJob(job);
|
|
142
|
-
expect(mockEventBusEmit).toHaveBeenCalledWith(JobExecutorEventTypes.JOB_STARTED, expect.objectContaining({
|
|
143
|
-
job,
|
|
144
|
-
startedAt: expect.any(String),
|
|
145
|
-
}));
|
|
146
|
-
expect(mockEventBusEmit).toHaveBeenCalledWith(JobExecutorEventTypes.JOB_COMPLETED, expect.objectContaining({
|
|
147
|
-
job,
|
|
148
|
-
result: expect.any(Object),
|
|
149
|
-
}));
|
|
150
|
-
});
|
|
151
|
-
it("should handle job execution failure", async () => {
|
|
152
|
-
const job = createTestJob();
|
|
153
|
-
// Mock the performJobExecution to always fail
|
|
154
|
-
const executorInstance = executor;
|
|
155
|
-
const originalPerformJobExecution = executorInstance
|
|
156
|
-
.performJobExecution;
|
|
157
|
-
executorInstance.performJobExecution = vi
|
|
158
|
-
.fn()
|
|
159
|
-
.mockRejectedValue(new Error("Test failure"));
|
|
160
|
-
const result = await executor.executeJob(job);
|
|
161
|
-
expect(result.success).toBe(false);
|
|
162
|
-
expect(result.error).toBe("Test failure");
|
|
163
|
-
// Restore original method
|
|
164
|
-
executorInstance.performJobExecution =
|
|
165
|
-
originalPerformJobExecution;
|
|
166
|
-
});
|
|
167
|
-
it("should emit job failed event on failure", async () => {
|
|
168
|
-
const job = createTestJob();
|
|
169
|
-
// Mock the performJobExecution to always fail
|
|
170
|
-
const executorInstance = executor;
|
|
171
|
-
executorInstance.performJobExecution = vi
|
|
172
|
-
.fn()
|
|
173
|
-
.mockRejectedValue(new Error("Test failure"));
|
|
174
|
-
await executor.executeJob(job);
|
|
175
|
-
expect(mockEventBusEmit).toHaveBeenCalledWith(JobExecutorEventTypes.JOB_FAILED, expect.objectContaining({
|
|
176
|
-
job,
|
|
177
|
-
error: "Test failure",
|
|
178
|
-
willRetry: true,
|
|
179
|
-
retryCount: 0,
|
|
180
|
-
}));
|
|
181
|
-
});
|
|
182
|
-
it("should update statistics on job completion", async () => {
|
|
183
|
-
const job = createTestJob();
|
|
184
|
-
await executor.executeJob(job);
|
|
185
|
-
const status = await executor.getStatus();
|
|
186
|
-
expect(status.totalJobsProcessed).toBe(1);
|
|
187
|
-
expect(status.totalJobsSucceeded).toBe(1);
|
|
188
|
-
expect(status.totalJobsFailed).toBe(0);
|
|
189
|
-
expect(status.lastJobCompletedAt).toBeDefined();
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
describe("getStatus", () => {
|
|
193
|
-
it("should return correct status when not running", async () => {
|
|
194
|
-
const status = await executor.getStatus();
|
|
195
|
-
expect(status.isRunning).toBe(false);
|
|
196
|
-
expect(status.activeJobs).toBe(0);
|
|
197
|
-
expect(status.totalJobsProcessed).toBe(0);
|
|
198
|
-
expect(status.totalJobsSucceeded).toBe(0);
|
|
199
|
-
expect(status.totalJobsFailed).toBe(0);
|
|
200
|
-
expect(status.uptime).toBeUndefined();
|
|
201
|
-
});
|
|
202
|
-
it("should return correct status when running", async () => {
|
|
203
|
-
await executor.start();
|
|
204
|
-
const status = await executor.getStatus();
|
|
205
|
-
expect(status.isRunning).toBe(true);
|
|
206
|
-
expect(status.uptime).toBeGreaterThanOrEqual(0);
|
|
207
|
-
await executor.stop();
|
|
208
|
-
});
|
|
209
|
-
it("should track active jobs correctly", async () => {
|
|
210
|
-
await executor.start();
|
|
211
|
-
const job1 = createTestJob({ id: "job-1" });
|
|
212
|
-
const job2 = createTestJob({ id: "job-2" });
|
|
213
|
-
// Start jobs concurrently
|
|
214
|
-
const promise1 = executor.executeJob(job1);
|
|
215
|
-
const promise2 = executor.executeJob(job2);
|
|
216
|
-
// Check status while jobs are running
|
|
217
|
-
const statusDuringExecution = await executor.getStatus();
|
|
218
|
-
expect(statusDuringExecution.activeJobs).toBeGreaterThan(0);
|
|
219
|
-
// Wait for jobs to complete
|
|
220
|
-
await Promise.all([promise1, promise2]);
|
|
221
|
-
// Check status after completion
|
|
222
|
-
const statusAfterCompletion = await executor.getStatus();
|
|
223
|
-
expect(statusAfterCompletion.activeJobs).toBe(0);
|
|
224
|
-
await executor.stop();
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
describe("getStats", () => {
|
|
228
|
-
beforeEach(async () => {
|
|
229
|
-
await executor.start();
|
|
230
|
-
});
|
|
231
|
-
afterEach(async () => {
|
|
232
|
-
await executor.stop();
|
|
233
|
-
});
|
|
234
|
-
it("should return correct initial stats", async () => {
|
|
235
|
-
const stats = await executor.getStats();
|
|
236
|
-
expect(stats.averageExecutionTime).toBe(0);
|
|
237
|
-
expect(stats.successRate).toBe(0);
|
|
238
|
-
expect(stats.jobsPerSecond).toBe(0);
|
|
239
|
-
expect(stats.queueBacklog).toBe(0);
|
|
240
|
-
});
|
|
241
|
-
it("should calculate stats correctly after job execution", async () => {
|
|
242
|
-
const job = createTestJob();
|
|
243
|
-
await executor.executeJob(job);
|
|
244
|
-
const stats = await executor.getStats();
|
|
245
|
-
expect(stats.averageExecutionTime).toBeGreaterThan(0);
|
|
246
|
-
expect(stats.successRate).toBe(1);
|
|
247
|
-
expect(stats.jobsPerSecond).toBeGreaterThan(0);
|
|
248
|
-
});
|
|
249
|
-
it("should include queue backlog in stats", async () => {
|
|
250
|
-
const job1 = createTestJob({ id: "job-1" });
|
|
251
|
-
const job2 = createTestJob({ id: "job-2" });
|
|
252
|
-
await queue.enqueue(job1);
|
|
253
|
-
await queue.enqueue(job2);
|
|
254
|
-
const stats = await executor.getStats();
|
|
255
|
-
expect(stats.queueBacklog).toBe(2);
|
|
256
|
-
});
|
|
257
|
-
});
|
|
258
|
-
describe("pause and resume", () => {
|
|
259
|
-
beforeEach(async () => {
|
|
260
|
-
await executor.start();
|
|
261
|
-
});
|
|
262
|
-
afterEach(async () => {
|
|
263
|
-
await executor.stop();
|
|
264
|
-
});
|
|
265
|
-
it("should pause job execution", async () => {
|
|
266
|
-
await executor.pause();
|
|
267
|
-
const job = createTestJob();
|
|
268
|
-
await queue.enqueue(job);
|
|
269
|
-
// Give some time to see if job gets processed
|
|
270
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
271
|
-
const queueSize = await queue.totalSize();
|
|
272
|
-
expect(queueSize).toBe(1); // Job should still be in queue
|
|
273
|
-
});
|
|
274
|
-
it("should resume job execution", async () => {
|
|
275
|
-
await executor.pause();
|
|
276
|
-
const job = createTestJob();
|
|
277
|
-
await queue.enqueue(job);
|
|
278
|
-
await executor.resume();
|
|
279
|
-
// Give some time for job processing
|
|
280
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
281
|
-
const queueSize = await queue.totalSize();
|
|
282
|
-
expect(queueSize).toBe(0); // Job should be processed
|
|
283
|
-
});
|
|
284
|
-
});
|
|
285
|
-
describe("event subscription", () => {
|
|
286
|
-
let realEventBus;
|
|
287
|
-
let realExecutor;
|
|
288
|
-
beforeEach(async () => {
|
|
289
|
-
// Use real event bus for event subscription tests
|
|
290
|
-
realEventBus = new EventBus();
|
|
291
|
-
const realQueue = new InMemoryQueue(realEventBus);
|
|
292
|
-
realExecutor = new InMemoryJobExecutor(realEventBus, realQueue);
|
|
293
|
-
await realExecutor.start();
|
|
294
|
-
});
|
|
295
|
-
afterEach(async () => {
|
|
296
|
-
await realExecutor.stop();
|
|
297
|
-
});
|
|
298
|
-
it("should allow subscribing to job started events", async () => {
|
|
299
|
-
const events = [];
|
|
300
|
-
const unsubscribe = realExecutor.on("jobStarted", (data) => {
|
|
301
|
-
events.push(data);
|
|
302
|
-
});
|
|
303
|
-
const job = createTestJob();
|
|
304
|
-
await realExecutor.executeJob(job);
|
|
305
|
-
expect(events).toHaveLength(1);
|
|
306
|
-
expect(events[0].job).toEqual(job);
|
|
307
|
-
unsubscribe();
|
|
308
|
-
});
|
|
309
|
-
it("should allow subscribing to job completed events", async () => {
|
|
310
|
-
const events = [];
|
|
311
|
-
const unsubscribe = realExecutor.on("jobCompleted", (data) => {
|
|
312
|
-
events.push(data);
|
|
313
|
-
});
|
|
314
|
-
const job = createTestJob();
|
|
315
|
-
await realExecutor.executeJob(job);
|
|
316
|
-
expect(events).toHaveLength(1);
|
|
317
|
-
expect(events[0].job).toEqual(job);
|
|
318
|
-
expect(events[0].result.success).toBe(true);
|
|
319
|
-
unsubscribe();
|
|
320
|
-
});
|
|
321
|
-
it("should allow subscribing to job failed events", async () => {
|
|
322
|
-
const events = [];
|
|
323
|
-
const unsubscribe = realExecutor.on("jobFailed", (data) => {
|
|
324
|
-
events.push(data);
|
|
325
|
-
});
|
|
326
|
-
const job = createTestJob();
|
|
327
|
-
// Mock the performJobExecution to always fail
|
|
328
|
-
const executorInstance = realExecutor;
|
|
329
|
-
executorInstance.performJobExecution = vi
|
|
330
|
-
.fn()
|
|
331
|
-
.mockRejectedValue(new Error("Test failure"));
|
|
332
|
-
await realExecutor.executeJob(job);
|
|
333
|
-
expect(events).toHaveLength(1);
|
|
334
|
-
expect(events[0].job).toEqual(job);
|
|
335
|
-
expect(events[0].error).toBe("Test failure");
|
|
336
|
-
unsubscribe();
|
|
337
|
-
});
|
|
338
|
-
it("should allow subscribing to executor started events", async () => {
|
|
339
|
-
await realExecutor.stop();
|
|
340
|
-
const events = [];
|
|
341
|
-
const unsubscribe = realExecutor.on("executorStarted", (data) => {
|
|
342
|
-
events.push(data);
|
|
343
|
-
});
|
|
344
|
-
await realExecutor.start();
|
|
345
|
-
expect(events).toHaveLength(1);
|
|
346
|
-
expect(events[0].config).toBeDefined();
|
|
347
|
-
expect(events[0].startedAt).toBeDefined();
|
|
348
|
-
unsubscribe();
|
|
349
|
-
});
|
|
350
|
-
it("should allow subscribing to executor stopped events", async () => {
|
|
351
|
-
const events = [];
|
|
352
|
-
const unsubscribe = realExecutor.on("executorStopped", (data) => {
|
|
353
|
-
events.push(data);
|
|
354
|
-
});
|
|
355
|
-
await realExecutor.stop();
|
|
356
|
-
expect(events).toHaveLength(1);
|
|
357
|
-
expect(events[0].stoppedAt).toBeDefined();
|
|
358
|
-
expect(events[0].graceful).toBe(true);
|
|
359
|
-
unsubscribe();
|
|
360
|
-
});
|
|
361
|
-
it("should throw error for unknown event type", () => {
|
|
362
|
-
expect(() => {
|
|
363
|
-
realExecutor.on("unknownEvent", () => { });
|
|
364
|
-
}).toThrow("Unknown event type: unknownEvent");
|
|
365
|
-
});
|
|
366
|
-
});
|
|
367
|
-
describe("concurrency control", () => {
|
|
368
|
-
it("should respect maxConcurrency setting", async () => {
|
|
369
|
-
const realEventBus = new EventBus();
|
|
370
|
-
const realQueue = new InMemoryQueue(realEventBus);
|
|
371
|
-
const realExecutor = new InMemoryJobExecutor(realEventBus, realQueue);
|
|
372
|
-
await realExecutor.start({ maxConcurrency: 2 });
|
|
373
|
-
const jobs = [
|
|
374
|
-
createTestJob({ id: "job-1" }),
|
|
375
|
-
createTestJob({ id: "job-2" }),
|
|
376
|
-
createTestJob({ id: "job-3" }),
|
|
377
|
-
createTestJob({ id: "job-4" }),
|
|
378
|
-
];
|
|
379
|
-
// Enqueue all jobs
|
|
380
|
-
for (const job of jobs) {
|
|
381
|
-
await realQueue.enqueue(job);
|
|
382
|
-
}
|
|
383
|
-
// Give some time for processing to start
|
|
384
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
385
|
-
const status = await realExecutor.getStatus();
|
|
386
|
-
expect(status.activeJobs).toBeLessThanOrEqual(2);
|
|
387
|
-
await realExecutor.stop();
|
|
388
|
-
});
|
|
389
|
-
it("should process jobs concurrently up to the limit", async () => {
|
|
390
|
-
const realEventBus = new EventBus();
|
|
391
|
-
const realQueue = new InMemoryQueue(realEventBus);
|
|
392
|
-
const realExecutor = new InMemoryJobExecutor(realEventBus, realQueue);
|
|
393
|
-
await realExecutor.start({ maxConcurrency: 3 });
|
|
394
|
-
// Mock performJobExecution to take longer so we can observe concurrency
|
|
395
|
-
const executorInstance = realExecutor;
|
|
396
|
-
executorInstance.performJobExecution = vi
|
|
397
|
-
.fn()
|
|
398
|
-
.mockImplementation(() => {
|
|
399
|
-
return new Promise((resolve) => setTimeout(() => resolve({ metadata: {} }), 200));
|
|
400
|
-
});
|
|
401
|
-
const jobs = [
|
|
402
|
-
createTestJob({ id: "job-1" }),
|
|
403
|
-
createTestJob({ id: "job-2" }),
|
|
404
|
-
createTestJob({ id: "job-3" }),
|
|
405
|
-
];
|
|
406
|
-
// Enqueue all jobs
|
|
407
|
-
for (const job of jobs) {
|
|
408
|
-
await realQueue.enqueue(job);
|
|
409
|
-
}
|
|
410
|
-
// Give some time for processing to start
|
|
411
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
412
|
-
const status = await realExecutor.getStatus();
|
|
413
|
-
expect(status.activeJobs).toBe(3);
|
|
414
|
-
await realExecutor.stop();
|
|
415
|
-
});
|
|
416
|
-
});
|
|
417
|
-
describe("retry logic", () => {
|
|
418
|
-
let realEventBus;
|
|
419
|
-
let realQueue;
|
|
420
|
-
let realExecutor;
|
|
421
|
-
beforeEach(async () => {
|
|
422
|
-
// Use real event bus and queue for retry logic tests
|
|
423
|
-
realEventBus = new EventBus();
|
|
424
|
-
realQueue = new InMemoryQueue(realEventBus);
|
|
425
|
-
realExecutor = new InMemoryJobExecutor(realEventBus, realQueue);
|
|
426
|
-
await realExecutor.start({ retryBaseDelay: 10, retryMaxDelay: 100 });
|
|
427
|
-
});
|
|
428
|
-
afterEach(async () => {
|
|
429
|
-
await realExecutor.stop();
|
|
430
|
-
});
|
|
431
|
-
it("should retry failed jobs", async () => {
|
|
432
|
-
const job = createTestJob({ maxRetries: 2 });
|
|
433
|
-
let callCount = 0;
|
|
434
|
-
const executorInstance = realExecutor;
|
|
435
|
-
executorInstance.performJobExecution = vi
|
|
436
|
-
.fn()
|
|
437
|
-
.mockImplementation(() => {
|
|
438
|
-
callCount++;
|
|
439
|
-
if (callCount <= 2) {
|
|
440
|
-
throw new Error("Simulated failure");
|
|
441
|
-
}
|
|
442
|
-
return Promise.resolve({ metadata: {} });
|
|
443
|
-
});
|
|
444
|
-
await realQueue.enqueue(job);
|
|
445
|
-
// Give time for retries
|
|
446
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
447
|
-
expect(callCount).toBe(3); // Initial attempt + 2 retries
|
|
448
|
-
});
|
|
449
|
-
it("should respect maxRetries limit", async () => {
|
|
450
|
-
const job = createTestJob({ maxRetries: 1 });
|
|
451
|
-
let callCount = 0;
|
|
452
|
-
const executorInstance = realExecutor;
|
|
453
|
-
executorInstance.performJobExecution = vi
|
|
454
|
-
.fn()
|
|
455
|
-
.mockImplementation(() => {
|
|
456
|
-
callCount++;
|
|
457
|
-
throw new Error("Always fails");
|
|
458
|
-
});
|
|
459
|
-
await realQueue.enqueue(job);
|
|
460
|
-
// Give time for retries
|
|
461
|
-
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
462
|
-
expect(callCount).toBe(2); // Initial attempt + 1 retry
|
|
463
|
-
});
|
|
464
|
-
it("should use exponential backoff for retries", async () => {
|
|
465
|
-
const job = createTestJob({ maxRetries: 3 });
|
|
466
|
-
const retryTimes = [];
|
|
467
|
-
let callCount = 0;
|
|
468
|
-
const executorInstance = realExecutor;
|
|
469
|
-
executorInstance.performJobExecution = vi
|
|
470
|
-
.fn()
|
|
471
|
-
.mockImplementation(() => {
|
|
472
|
-
callCount++;
|
|
473
|
-
retryTimes.push(Date.now());
|
|
474
|
-
throw new Error("Always fails");
|
|
475
|
-
});
|
|
476
|
-
await realQueue.enqueue(job);
|
|
477
|
-
// Give time for retries
|
|
478
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
479
|
-
expect(retryTimes.length).toBeGreaterThan(1);
|
|
480
|
-
// Check that delays are increasing (exponential backoff)
|
|
481
|
-
for (let i = 1; i < retryTimes.length - 1; i++) {
|
|
482
|
-
const delay1 = retryTimes[i] - retryTimes[i - 1];
|
|
483
|
-
const delay2 = retryTimes[i + 1] - retryTimes[i];
|
|
484
|
-
expect(delay2).toBeGreaterThanOrEqual(delay1 * 0.9); // Allow for some jitter
|
|
485
|
-
}
|
|
486
|
-
});
|
|
487
|
-
});
|
|
488
|
-
describe("job timeout", () => {
|
|
489
|
-
beforeEach(async () => {
|
|
490
|
-
await executor.start({ jobTimeout: 100 });
|
|
491
|
-
});
|
|
492
|
-
afterEach(async () => {
|
|
493
|
-
await executor.stop();
|
|
494
|
-
});
|
|
495
|
-
it("should timeout long-running jobs", async () => {
|
|
496
|
-
const job = createTestJob();
|
|
497
|
-
const executorInstance = executor;
|
|
498
|
-
executorInstance.performJobExecution = vi
|
|
499
|
-
.fn()
|
|
500
|
-
.mockImplementation(() => {
|
|
501
|
-
return new Promise((resolve) => setTimeout(resolve, 200)); // Longer than timeout
|
|
502
|
-
});
|
|
503
|
-
const result = await executor.executeJob(job);
|
|
504
|
-
expect(result.success).toBe(false);
|
|
505
|
-
expect(result.error).toContain("timed out");
|
|
506
|
-
});
|
|
507
|
-
it("should complete jobs within timeout", async () => {
|
|
508
|
-
const job = createTestJob();
|
|
509
|
-
const executorInstance = executor;
|
|
510
|
-
executorInstance.performJobExecution = vi
|
|
511
|
-
.fn()
|
|
512
|
-
.mockImplementation(() => {
|
|
513
|
-
return new Promise((resolve) => setTimeout(() => resolve({ metadata: {} }), 50)); // Within timeout
|
|
514
|
-
});
|
|
515
|
-
const result = await executor.executeJob(job);
|
|
516
|
-
expect(result.success).toBe(true);
|
|
517
|
-
});
|
|
518
|
-
});
|
|
519
|
-
describe("job abortion", () => {
|
|
520
|
-
beforeEach(async () => {
|
|
521
|
-
await executor.start();
|
|
522
|
-
});
|
|
523
|
-
afterEach(async () => {
|
|
524
|
-
await executor.stop();
|
|
525
|
-
});
|
|
526
|
-
it("should abort jobs when stopping non-gracefully", async () => {
|
|
527
|
-
const job = createTestJob();
|
|
528
|
-
const executorInstance = executor;
|
|
529
|
-
executorInstance.performJobExecution = vi
|
|
530
|
-
.fn()
|
|
531
|
-
.mockImplementation((job, signal) => {
|
|
532
|
-
return new Promise((resolve, reject) => {
|
|
533
|
-
const timeout = setTimeout(() => resolve({ metadata: {} }), 1000);
|
|
534
|
-
signal.addEventListener("abort", () => {
|
|
535
|
-
clearTimeout(timeout);
|
|
536
|
-
reject(new Error("Job was aborted"));
|
|
537
|
-
});
|
|
538
|
-
});
|
|
539
|
-
});
|
|
540
|
-
// Start job execution
|
|
541
|
-
const jobPromise = executor.executeJob(job);
|
|
542
|
-
// Stop executor non-gracefully after a short delay
|
|
543
|
-
setTimeout(() => executor.stop(false), 50);
|
|
544
|
-
const result = await jobPromise;
|
|
545
|
-
expect(result.success).toBe(false);
|
|
546
|
-
expect(result.error).toContain("aborted");
|
|
547
|
-
});
|
|
548
|
-
});
|
|
549
|
-
describe("edge cases", () => {
|
|
550
|
-
it("should handle empty queue gracefully", async () => {
|
|
551
|
-
await executor.start();
|
|
552
|
-
// Give some time for processing
|
|
553
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
554
|
-
const status = await executor.getStatus();
|
|
555
|
-
expect(status.activeJobs).toBe(0);
|
|
556
|
-
await executor.stop();
|
|
557
|
-
});
|
|
558
|
-
it("should handle rapid start/stop cycles", async () => {
|
|
559
|
-
for (let i = 0; i < 5; i++) {
|
|
560
|
-
await executor.start();
|
|
561
|
-
await executor.stop();
|
|
562
|
-
}
|
|
563
|
-
const status = await executor.getStatus();
|
|
564
|
-
expect(status.isRunning).toBe(false);
|
|
565
|
-
});
|
|
566
|
-
it("should handle jobs with missing optional properties", async () => {
|
|
567
|
-
await executor.start();
|
|
568
|
-
const job = {
|
|
569
|
-
id: "minimal-job",
|
|
570
|
-
documentId: "doc-1",
|
|
571
|
-
scope: "global",
|
|
572
|
-
branch: "main",
|
|
573
|
-
operation: createTestOperation(),
|
|
574
|
-
createdAt: new Date().toISOString(),
|
|
575
|
-
// retryCount and maxRetries are optional
|
|
576
|
-
};
|
|
577
|
-
const result = await executor.executeJob(job);
|
|
578
|
-
expect(result).toBeDefined();
|
|
579
|
-
await executor.stop();
|
|
580
|
-
});
|
|
581
|
-
it("should handle event bus errors gracefully", async () => {
|
|
582
|
-
mockEventBusEmit.mockRejectedValueOnce(new Error("Event bus error"));
|
|
583
|
-
await expect(executor.start()).rejects.toThrow("Event bus error");
|
|
584
|
-
});
|
|
585
|
-
});
|
|
586
|
-
});
|
|
587
|
-
//# sourceMappingURL=job-executor.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"job-executor.test.js","sourceRoot":"","sources":["../../test/job-executor.test.ts"],"names":[],"mappings":"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"}
|