@adonis-agora/durable 0.51.1 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/src/bounded-runner.d.ts +29 -0
- package/dist/src/bounded-runner.d.ts.map +1 -0
- package/dist/src/bounded-runner.js +79 -0
- package/dist/src/bounded-runner.js.map +1 -0
- package/dist/src/child-delivery.d.ts +14 -0
- package/dist/src/child-delivery.d.ts.map +1 -0
- package/dist/src/child-delivery.js +17 -0
- package/dist/src/child-delivery.js.map +1 -0
- package/dist/src/codec-state-store.d.ts +2 -0
- package/dist/src/codec-state-store.d.ts.map +1 -1
- package/dist/src/codec-state-store.js +5 -0
- package/dist/src/codec-state-store.js.map +1 -1
- package/dist/src/dashboard/index.d.ts +1 -1
- package/dist/src/dashboard/index.js +1 -1
- package/dist/src/engine.d.ts +95 -1
- package/dist/src/engine.d.ts.map +1 -1
- package/dist/src/engine.js +464 -39
- package/dist/src/engine.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/interfaces.d.ts +55 -0
- package/dist/src/interfaces.d.ts.map +1 -1
- package/dist/src/interfaces.js.map +1 -1
- package/dist/src/run-waiting.d.ts +5 -0
- package/dist/src/run-waiting.d.ts.map +1 -1
- package/dist/src/run-waiting.js +20 -0
- package/dist/src/run-waiting.js.map +1 -1
- package/dist/src/stores/lucid.d.ts +1 -0
- package/dist/src/stores/lucid.d.ts.map +1 -1
- package/dist/src/stores/lucid.js +7 -0
- package/dist/src/stores/lucid.js.map +1 -1
- package/dist/src/testing/in-memory-state-store.d.ts +1 -0
- package/dist/src/testing/in-memory-state-store.d.ts.map +1 -1
- package/dist/src/testing/in-memory-state-store.js +9 -0
- package/dist/src/testing/in-memory-state-store.js.map +1 -1
- package/dist/src/testing-kit/conformance.d.ts +1 -0
- package/dist/src/testing-kit/conformance.d.ts.map +1 -1
- package/dist/src/testing-kit/conformance.js +1 -0
- package/dist/src/testing-kit/conformance.js.map +1 -1
- package/dist/src/testing-kit/run-dispatch-contract.d.ts +29 -0
- package/dist/src/testing-kit/run-dispatch-contract.d.ts.map +1 -0
- package/dist/src/testing-kit/run-dispatch-contract.js +472 -0
- package/dist/src/testing-kit/run-dispatch-contract.js.map +1 -0
- package/dist/src/testing-kit/state-store-conformance.d.ts.map +1 -1
- package/dist/src/testing-kit/state-store-conformance.js +14 -0
- package/dist/src/testing-kit/state-store-conformance.js.map +1 -1
- package/dist/src/transports/bullmq/bullmq-transport.d.ts +20 -1
- package/dist/src/transports/bullmq/bullmq-transport.d.ts.map +1 -1
- package/dist/src/transports/bullmq/bullmq-transport.js +57 -1
- package/dist/src/transports/bullmq/bullmq-transport.js.map +1 -1
- package/dist/src/transports/bullmq/deps.d.ts +6 -0
- package/dist/src/transports/bullmq/deps.d.ts.map +1 -1
- package/dist/src/transports/bullmq/deps.js.map +1 -1
- package/dist/src/transports/bullmq/naming.d.ts +10 -0
- package/dist/src/transports/bullmq/naming.d.ts.map +1 -1
- package/dist/src/transports/bullmq/naming.js +15 -0
- package/dist/src/transports/bullmq/naming.js.map +1 -1
- package/dist/src/transports/db-schema.d.ts +2 -0
- package/dist/src/transports/db-schema.d.ts.map +1 -1
- package/dist/src/transports/db-schema.js +2 -0
- package/dist/src/transports/db-schema.js.map +1 -1
- package/dist/src/transports/db.d.ts +22 -1
- package/dist/src/transports/db.d.ts.map +1 -1
- package/dist/src/transports/db.js +104 -5
- package/dist/src/transports/db.js.map +1 -1
- package/dist/src/transports/queue-mock-adapter.d.ts +6 -1
- package/dist/src/transports/queue-mock-adapter.d.ts.map +1 -1
- package/dist/src/transports/queue-mock-adapter.js +7 -1
- package/dist/src/transports/queue-mock-adapter.js.map +1 -1
- package/dist/src/transports/queue.d.ts +18 -1
- package/dist/src/transports/queue.d.ts.map +1 -1
- package/dist/src/transports/queue.js +59 -0
- package/dist/src/transports/queue.js.map +1 -1
- package/dist/src/workflow-ctx.d.ts +1 -1
- package/dist/src/workflow-ctx.d.ts.map +1 -1
- package/dist/src/workflow-ctx.js +35 -12
- package/dist/src/workflow-ctx.js.map +1 -1
- package/package.json +2 -1
- package/skills/durable-reliability/SKILL.md +3 -2
- package/skills/durable-setup/SKILL.md +11 -7
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
+
import { InMemoryStateStore, WorkflowEngine, } from '../index.js';
|
|
3
|
+
import { DURABLE_STEP_NAME } from '../step-name-symbol.js';
|
|
4
|
+
function record(transport) {
|
|
5
|
+
const original = transport.dispatchRuns.bind(transport);
|
|
6
|
+
const out = {
|
|
7
|
+
transport,
|
|
8
|
+
dispatched: [],
|
|
9
|
+
calls: [],
|
|
10
|
+
namespaces: [],
|
|
11
|
+
failNext: (n) => {
|
|
12
|
+
failures = n;
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
let failures = 0;
|
|
16
|
+
transport.dispatchRuns = async (runs, opts) => {
|
|
17
|
+
if (failures > 0) {
|
|
18
|
+
failures -= 1;
|
|
19
|
+
throw new Error('run queue unavailable');
|
|
20
|
+
}
|
|
21
|
+
out.calls.push([...runs]);
|
|
22
|
+
out.namespaces.push(opts?.namespace);
|
|
23
|
+
out.dispatched.push(...runs);
|
|
24
|
+
await original(runs, opts);
|
|
25
|
+
};
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
async function until(cond, timeoutMs, what = 'condition') {
|
|
29
|
+
const deadline = Date.now() + timeoutMs;
|
|
30
|
+
while (!(await cond())) {
|
|
31
|
+
if (Date.now() > deadline)
|
|
32
|
+
throw new Error(`timed out waiting for ${what}`);
|
|
33
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
37
|
+
/**
|
|
38
|
+
* The contract of the run queue a transport offers the engine ({@link Transport.dispatchRuns} /
|
|
39
|
+
* {@link Transport.onDispatchedRun}), run end to end through real engines sharing one in-memory store: every
|
|
40
|
+
* run the engine would execute on itself goes through the queue, the instances consuming it split
|
|
41
|
+
* the work without running anything twice, and nothing is lost when the queue fails or an instance
|
|
42
|
+
* shuts down. Call it from a spec file with a factory for the transport under test.
|
|
43
|
+
*/
|
|
44
|
+
export function runRunDispatchContract(name, factory) {
|
|
45
|
+
describe(`run dispatch contract: ${name}`, () => {
|
|
46
|
+
const timeout = factory.settleTimeoutMs ?? 20_000;
|
|
47
|
+
let store;
|
|
48
|
+
let engines = [];
|
|
49
|
+
let transports = [];
|
|
50
|
+
beforeEach(async () => {
|
|
51
|
+
await factory.setup?.();
|
|
52
|
+
store = new InMemoryStateStore();
|
|
53
|
+
engines = [];
|
|
54
|
+
transports = [];
|
|
55
|
+
});
|
|
56
|
+
afterEach(async () => {
|
|
57
|
+
await Promise.all(engines.map((e) => e.drain(5_000).catch(() => undefined)));
|
|
58
|
+
await Promise.all(transports.map((t) => t.close?.().catch(() => undefined)));
|
|
59
|
+
await factory.teardown?.();
|
|
60
|
+
});
|
|
61
|
+
/** An engine on a fresh transport of this test, with its transport's dispatches recorded. */
|
|
62
|
+
const instance = async (opts = {}) => {
|
|
63
|
+
const transport = await factory.make();
|
|
64
|
+
transports.push(transport);
|
|
65
|
+
const recorded = record(transport);
|
|
66
|
+
const engine = new WorkflowEngine({
|
|
67
|
+
store,
|
|
68
|
+
transport,
|
|
69
|
+
reconcileMs: opts.reconcileMs ?? 0,
|
|
70
|
+
...(opts.namespace !== undefined ? { namespace: opts.namespace } : {}),
|
|
71
|
+
});
|
|
72
|
+
engines.push(engine);
|
|
73
|
+
return { engine, recorded };
|
|
74
|
+
};
|
|
75
|
+
const settled = async (runId) => {
|
|
76
|
+
await until(async () => {
|
|
77
|
+
const run = await store.getRun(runId);
|
|
78
|
+
return (run !== null &&
|
|
79
|
+
(run.status === 'completed' || run.status === 'failed' || run.status === 'dead'));
|
|
80
|
+
}, timeout, `run ${runId} to finish`);
|
|
81
|
+
return store.getRun(runId);
|
|
82
|
+
};
|
|
83
|
+
const startsOf = (r) => r.dispatched.filter((d) => d.reason === 'start').map((d) => d.runId);
|
|
84
|
+
const wakesOf = (r) => r.dispatched.filter((d) => d.reason === 'wake').map((d) => d.runId);
|
|
85
|
+
it('delivers a start for a new pending state while the previous one is being handled', async () => {
|
|
86
|
+
const transport = await factory.make();
|
|
87
|
+
transports.push(transport);
|
|
88
|
+
const seen = [];
|
|
89
|
+
let release;
|
|
90
|
+
const gate = new Promise((r) => {
|
|
91
|
+
release = r;
|
|
92
|
+
});
|
|
93
|
+
transport.onDispatchedRun(async (run) => {
|
|
94
|
+
seen.push(run);
|
|
95
|
+
if (seen.length === 1)
|
|
96
|
+
await gate;
|
|
97
|
+
}, { concurrency: 2 });
|
|
98
|
+
await transport.dispatchRuns([{ runId: 'again', reason: 'start', key: '1' }]);
|
|
99
|
+
await until(() => seen.length === 1, timeout, 'the first delivery');
|
|
100
|
+
// The run went `pending` again (a retry) while the first delivery is still being handled.
|
|
101
|
+
await transport.dispatchRuns([{ runId: 'again', reason: 'start', key: '2' }]);
|
|
102
|
+
await until(() => seen.length === 2, timeout, 'the start of the new pending state');
|
|
103
|
+
release();
|
|
104
|
+
// A marker dispatched last: once it is handled, nothing else is coming.
|
|
105
|
+
await transport.dispatchRuns([{ runId: 'marker', reason: 'wake' }]);
|
|
106
|
+
await until(() => seen.some((r) => r.runId === 'marker'), timeout, 'the marker');
|
|
107
|
+
expect(seen.filter((r) => r.runId === 'again').map((r) => [r.reason, r.key])).toEqual([
|
|
108
|
+
['start', '1'],
|
|
109
|
+
['start', '2'],
|
|
110
|
+
]);
|
|
111
|
+
}, timeout * 2);
|
|
112
|
+
it('keeps the run queues of different namespaces apart', async () => {
|
|
113
|
+
const transport = await factory.make();
|
|
114
|
+
transports.push(transport);
|
|
115
|
+
const byNamespace = { blue: [], green: [] };
|
|
116
|
+
for (const ns of ['blue', 'green']) {
|
|
117
|
+
transport.onDispatchedRun(async (run) => {
|
|
118
|
+
byNamespace[ns]?.push(run.runId);
|
|
119
|
+
}, { concurrency: 4, namespace: ns });
|
|
120
|
+
}
|
|
121
|
+
await transport.dispatchRuns([{ runId: 'b1' }, { runId: 'b2' }], { namespace: 'blue' });
|
|
122
|
+
await transport.dispatchRuns([{ runId: 'g1' }], { namespace: 'green' });
|
|
123
|
+
await until(() => (byNamespace.blue?.length ?? 0) + (byNamespace.green?.length ?? 0) === 3, timeout, 'every run');
|
|
124
|
+
expect(byNamespace.blue?.sort()).toEqual(['b1', 'b2']);
|
|
125
|
+
expect(byNamespace.green).toEqual(['g1']);
|
|
126
|
+
}, timeout * 2);
|
|
127
|
+
it("keeps a pool's runs on the instances of its namespace", async () => {
|
|
128
|
+
const blue1 = await instance({ namespace: 'blue' });
|
|
129
|
+
const blue2 = await instance({ namespace: 'blue' });
|
|
130
|
+
const green = await instance({ namespace: 'green' });
|
|
131
|
+
const by = {};
|
|
132
|
+
for (const [label, { engine }] of [
|
|
133
|
+
['blue1', blue1],
|
|
134
|
+
['blue2', blue2],
|
|
135
|
+
['green', green],
|
|
136
|
+
]) {
|
|
137
|
+
engine.register('w', '1', async (ctx) => {
|
|
138
|
+
by[ctx.runId] = label;
|
|
139
|
+
return label;
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
await blue1.engine.start('w', {}, 'b');
|
|
143
|
+
await green.engine.start('w', {}, 'g');
|
|
144
|
+
expect(['blue1', 'blue2']).toContain((await settled('b'))?.output);
|
|
145
|
+
expect((await settled('g'))?.output).toBe('green');
|
|
146
|
+
expect(blue1.recorded.namespaces).toEqual(['blue']);
|
|
147
|
+
expect(green.recorded.namespaces).toEqual(['green']);
|
|
148
|
+
}, timeout * 2);
|
|
149
|
+
it("carries the run's priority", async () => {
|
|
150
|
+
const { engine, recorded } = await instance();
|
|
151
|
+
engine.register('w', '1', async () => 'ok');
|
|
152
|
+
await engine.start('w', {}, 'urgent', { priority: 7 });
|
|
153
|
+
await settled('urgent');
|
|
154
|
+
expect(recorded.dispatched.find((d) => d.runId === 'urgent')?.priority).toBe(7);
|
|
155
|
+
}, timeout * 2);
|
|
156
|
+
/** The fan forms every child-fan case runs: both combinators, with and without waves. */
|
|
157
|
+
const FANS = [
|
|
158
|
+
{ mode: 'all', concurrency: undefined },
|
|
159
|
+
{ mode: 'allSettled', concurrency: undefined },
|
|
160
|
+
{ mode: 'all', concurrency: 40 },
|
|
161
|
+
{ mode: 'allSettled', concurrency: 40 },
|
|
162
|
+
];
|
|
163
|
+
const fanOf = (ctx, mode, inputs, concurrency) => {
|
|
164
|
+
const opts = concurrency === undefined ? undefined : { concurrency };
|
|
165
|
+
return mode === 'all'
|
|
166
|
+
? ctx.all('child', inputs, opts)
|
|
167
|
+
: ctx.allSettled('child', inputs, opts);
|
|
168
|
+
};
|
|
169
|
+
/** What child `i` returns, and whether it fails (an allSettled fan has failures to report). */
|
|
170
|
+
const childResult = (mode, i) => {
|
|
171
|
+
if (mode === 'allSettled' && i % 5 === 2)
|
|
172
|
+
throw new Error(`boom-${i}`);
|
|
173
|
+
return i * 2;
|
|
174
|
+
};
|
|
175
|
+
const expectedFan = (mode, n) => Array.from({ length: n }, (_, i) => {
|
|
176
|
+
if (mode === 'all')
|
|
177
|
+
return i * 2;
|
|
178
|
+
return i % 5 === 2
|
|
179
|
+
? expect.objectContaining({ status: 'rejected', error: `boom-${i}` })
|
|
180
|
+
: { status: 'fulfilled', value: i * 2 };
|
|
181
|
+
});
|
|
182
|
+
for (const { mode, concurrency } of FANS) {
|
|
183
|
+
it(`sends the start and every child start of a ctx.${mode} fan (concurrency ${concurrency}) through the run queue, in batches`, async () => {
|
|
184
|
+
const { engine, recorded } = await instance();
|
|
185
|
+
const n = 120;
|
|
186
|
+
engine.register('child', '1', async (_ctx, input) => childResult(mode, input));
|
|
187
|
+
engine.register('parent', '1', async (ctx) => fanOf(ctx, mode, Array.from({ length: n }, (_, i) => i), concurrency));
|
|
188
|
+
await engine.start('parent', {}, 'fan');
|
|
189
|
+
const run = await settled('fan');
|
|
190
|
+
expect(run?.status).toBe('completed');
|
|
191
|
+
expect(run?.output).toEqual(expectedFan(mode, n));
|
|
192
|
+
const starts = startsOf(recorded);
|
|
193
|
+
expect(starts).toContain('fan');
|
|
194
|
+
const childStarts = starts.filter((id) => id !== 'fan');
|
|
195
|
+
expect(new Set(childStarts).size).toBe(n);
|
|
196
|
+
// Batched: the children's starts went out in a handful of calls, not one per child.
|
|
197
|
+
const callsWithChildren = recorded.calls.filter((c) => c.some((d) => d.reason === 'start' && d.runId !== 'fan'));
|
|
198
|
+
expect(callsWithChildren.length).toBeLessThanOrEqual(n / 10);
|
|
199
|
+
}, timeout * 2);
|
|
200
|
+
it(`two instances split a ctx.${mode} fan (concurrency ${concurrency}) and run each child once`, async () => {
|
|
201
|
+
const a = await instance();
|
|
202
|
+
const b = await instance();
|
|
203
|
+
const runs = new Map();
|
|
204
|
+
// Every child holds its slot until both instances have run one: an instance takes at most
|
|
205
|
+
// 64 runs from the queue at once, so with more children sent than that the other instance
|
|
206
|
+
// must take some, whatever the timing.
|
|
207
|
+
let release;
|
|
208
|
+
const bothRan = new Promise((r) => {
|
|
209
|
+
release = r;
|
|
210
|
+
});
|
|
211
|
+
const n = 160;
|
|
212
|
+
for (const [label, { engine }] of [
|
|
213
|
+
['a', a],
|
|
214
|
+
['b', b],
|
|
215
|
+
]) {
|
|
216
|
+
engine.register('child', '1', async (ctx, input) => {
|
|
217
|
+
runs.set(ctx.runId, [...(runs.get(ctx.runId) ?? []), label]);
|
|
218
|
+
const by = new Set([...runs.values()].map((r) => r[0]));
|
|
219
|
+
if (by.has('a') && by.has('b'))
|
|
220
|
+
release();
|
|
221
|
+
await bothRan;
|
|
222
|
+
return childResult(mode, input);
|
|
223
|
+
});
|
|
224
|
+
engine.register('parent', '1', async (ctx) => fanOf(ctx, mode, Array.from({ length: n }, (_, i) => i), concurrency === undefined ? undefined : 140));
|
|
225
|
+
}
|
|
226
|
+
await a.engine.start('parent', {}, 'split');
|
|
227
|
+
const run = await settled('split');
|
|
228
|
+
expect(run?.status).toBe('completed');
|
|
229
|
+
expect(run?.output).toEqual(expectedFan(mode, n));
|
|
230
|
+
expect(runs.size).toBe(n);
|
|
231
|
+
for (const [, by] of runs)
|
|
232
|
+
expect(by).toHaveLength(1);
|
|
233
|
+
const byA = [...runs.values()].filter((by) => by[0] === 'a').length;
|
|
234
|
+
expect(byA).toBeGreaterThan(0);
|
|
235
|
+
expect(byA).toBeLessThan(n);
|
|
236
|
+
}, timeout * 3);
|
|
237
|
+
}
|
|
238
|
+
for (const { mode, concurrency } of FANS) {
|
|
239
|
+
it(`two instances run a ctx.${mode} step fan (concurrency ${concurrency}) with each step once`, async () => {
|
|
240
|
+
const a = await instance();
|
|
241
|
+
const b = await instance();
|
|
242
|
+
const name = `contract.line.${mode}.${concurrency ?? 'all'}`;
|
|
243
|
+
const step = Object.assign(() => undefined, { [DURABLE_STEP_NAME]: name });
|
|
244
|
+
const ran = new Map();
|
|
245
|
+
for (const t of transports) {
|
|
246
|
+
const serve = t.handle;
|
|
247
|
+
if (typeof serve !== 'function')
|
|
248
|
+
return;
|
|
249
|
+
serve.call(t, name, async (input) => {
|
|
250
|
+
const i = input;
|
|
251
|
+
ran.set(i, (ran.get(i) ?? 0) + 1);
|
|
252
|
+
return childResult(mode, i);
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
const n = 80;
|
|
256
|
+
const inputs = Array.from({ length: n }, (_, i) => i);
|
|
257
|
+
for (const { engine } of [a, b]) {
|
|
258
|
+
engine.register('stepfan', '1', async (ctx) => {
|
|
259
|
+
const opts = concurrency === undefined ? undefined : { concurrency };
|
|
260
|
+
const ref = step;
|
|
261
|
+
return mode === 'all'
|
|
262
|
+
? ctx.all(ref, inputs, opts)
|
|
263
|
+
: ctx.allSettled(ref, inputs, opts);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
await a.engine.start('stepfan', {}, 'stepfan');
|
|
267
|
+
const run = await settled('stepfan');
|
|
268
|
+
expect(run?.status).toBe('completed');
|
|
269
|
+
expect(run?.output).toEqual(expectedFan(mode, n));
|
|
270
|
+
expect(ran.size).toBe(n);
|
|
271
|
+
for (const [, times] of ran)
|
|
272
|
+
expect(times).toBe(1);
|
|
273
|
+
}, timeout * 3);
|
|
274
|
+
}
|
|
275
|
+
it('a failed enqueue leaves the run pending, and the pending-run poll runs it', async () => {
|
|
276
|
+
const { engine, recorded } = await instance();
|
|
277
|
+
let executions = 0;
|
|
278
|
+
engine.register('w', '1', async () => {
|
|
279
|
+
executions += 1;
|
|
280
|
+
return 'ok';
|
|
281
|
+
});
|
|
282
|
+
recorded.failNext(1);
|
|
283
|
+
await engine.start('w', {}, 'unsent');
|
|
284
|
+
await sleep(100);
|
|
285
|
+
expect((await store.getRun('unsent'))?.status).toBe('pending');
|
|
286
|
+
expect(executions).toBe(0);
|
|
287
|
+
await engine.runPending();
|
|
288
|
+
const run = await settled('unsent');
|
|
289
|
+
expect(run?.output).toBe('ok');
|
|
290
|
+
expect(executions).toBe(1);
|
|
291
|
+
}, timeout * 2);
|
|
292
|
+
it('a wake that cannot be enqueued resumes the run on this instance instead', async () => {
|
|
293
|
+
const { engine, recorded } = await instance();
|
|
294
|
+
engine.register('waiter', '1', async (ctx) => ctx.waitForSignal('go:unsent-wake'));
|
|
295
|
+
await engine.start('waiter', {}, 'unsent-wake');
|
|
296
|
+
await until(async () => (await store.getRun('unsent-wake'))?.status === 'suspended', timeout, 'the run to suspend');
|
|
297
|
+
recorded.failNext(1);
|
|
298
|
+
await engine.signal('go:unsent-wake', 'here');
|
|
299
|
+
expect((await settled('unsent-wake'))?.output).toBe('here');
|
|
300
|
+
expect(wakesOf(recorded)).not.toContain('unsent-wake');
|
|
301
|
+
}, timeout * 2);
|
|
302
|
+
it('the consumer skips a dispatched run that is no longer pending or already finished', async () => {
|
|
303
|
+
const { engine, recorded } = await instance();
|
|
304
|
+
let executions = 0;
|
|
305
|
+
engine.register('w', '1', async () => {
|
|
306
|
+
executions += 1;
|
|
307
|
+
return 'ok';
|
|
308
|
+
});
|
|
309
|
+
await engine.start('w', {}, 'done');
|
|
310
|
+
await settled('done');
|
|
311
|
+
expect(executions).toBe(1);
|
|
312
|
+
await recorded.transport.dispatchRuns([
|
|
313
|
+
{ runId: 'done', reason: 'start' },
|
|
314
|
+
{ runId: 'done', reason: 'wake' },
|
|
315
|
+
{ runId: 'never-created', reason: 'start' },
|
|
316
|
+
]);
|
|
317
|
+
// A pending run dispatched the same way is taken: the consumer is alive.
|
|
318
|
+
const now = new Date();
|
|
319
|
+
await store.createRun({
|
|
320
|
+
id: 'after',
|
|
321
|
+
workflow: 'w',
|
|
322
|
+
workflowVersion: '1',
|
|
323
|
+
status: 'pending',
|
|
324
|
+
input: {},
|
|
325
|
+
namespace: 'default',
|
|
326
|
+
createdAt: now,
|
|
327
|
+
updatedAt: now,
|
|
328
|
+
});
|
|
329
|
+
await recorded.transport.dispatchRuns([{ runId: 'after', reason: 'start' }]);
|
|
330
|
+
await settled('after');
|
|
331
|
+
await sleep(200);
|
|
332
|
+
expect(executions).toBe(2);
|
|
333
|
+
expect((await store.getRun('done'))?.status).toBe('completed');
|
|
334
|
+
}, timeout * 2);
|
|
335
|
+
it('an instance that drains takes no more runs; another instance runs them', async () => {
|
|
336
|
+
const a = await instance();
|
|
337
|
+
const b = await instance();
|
|
338
|
+
const by = [];
|
|
339
|
+
a.engine.register('w', '1', async () => {
|
|
340
|
+
by.push('a');
|
|
341
|
+
return 'a';
|
|
342
|
+
});
|
|
343
|
+
b.engine.register('w', '1', async () => {
|
|
344
|
+
by.push('b');
|
|
345
|
+
return 'b';
|
|
346
|
+
});
|
|
347
|
+
await a.engine.drain(5_000);
|
|
348
|
+
// A draining instance still dispatches: the run is enqueued, not dropped.
|
|
349
|
+
await a.engine.start('w', {}, 'handed-over');
|
|
350
|
+
const run = await settled('handed-over');
|
|
351
|
+
expect(run?.output).toBe('b');
|
|
352
|
+
expect(by).toEqual(['b']);
|
|
353
|
+
expect(startsOf(a.recorded)).toContain('handed-over');
|
|
354
|
+
}, timeout * 2);
|
|
355
|
+
it('drain waits for a run the consumer is executing', async () => {
|
|
356
|
+
const { engine } = await instance();
|
|
357
|
+
let entered = false;
|
|
358
|
+
engine.register('slow', '1', async () => {
|
|
359
|
+
entered = true;
|
|
360
|
+
await sleep(300);
|
|
361
|
+
return 'done';
|
|
362
|
+
});
|
|
363
|
+
await engine.start('slow', {}, 'slow');
|
|
364
|
+
await until(() => entered, timeout, 'the run to start');
|
|
365
|
+
await engine.drain(5_000);
|
|
366
|
+
expect((await store.getRun('slow'))?.status).toBe('completed');
|
|
367
|
+
}, timeout * 2);
|
|
368
|
+
it('a signal wakes its run through the run queue', async () => {
|
|
369
|
+
const a = await instance();
|
|
370
|
+
const b = await instance();
|
|
371
|
+
for (const { engine } of [a, b]) {
|
|
372
|
+
engine.register('waiter', '1', async (ctx) => ctx.waitForSignal('go:sig'));
|
|
373
|
+
}
|
|
374
|
+
await a.engine.start('waiter', {}, 'sig');
|
|
375
|
+
await until(async () => (await store.getRun('sig'))?.status === 'suspended', timeout, 'the run to suspend');
|
|
376
|
+
await a.engine.signal('go:sig', 'hello');
|
|
377
|
+
const run = await settled('sig');
|
|
378
|
+
expect(run?.output).toBe('hello');
|
|
379
|
+
expect(wakesOf(a.recorded)).toContain('sig');
|
|
380
|
+
}, timeout * 2);
|
|
381
|
+
it('a finished child wakes its parent through the run queue', async () => {
|
|
382
|
+
const { engine, recorded } = await instance();
|
|
383
|
+
engine.register('child', '1', async () => 7);
|
|
384
|
+
engine.register('parent', '1', async (ctx) => (await ctx.child('child', {})) + 1);
|
|
385
|
+
await engine.start('parent', {}, 'parent-of-one');
|
|
386
|
+
const run = await settled('parent-of-one');
|
|
387
|
+
expect(run?.output).toBe(8);
|
|
388
|
+
expect(wakesOf(recorded)).toContain('parent-of-one');
|
|
389
|
+
}, timeout * 2);
|
|
390
|
+
it('a due timer is handed off through the run queue', async () => {
|
|
391
|
+
const { engine, recorded } = await instance();
|
|
392
|
+
engine.register('napper', '1', async (ctx) => {
|
|
393
|
+
await ctx.sleep(50);
|
|
394
|
+
return 'rested';
|
|
395
|
+
});
|
|
396
|
+
await engine.start('napper', {}, 'nap');
|
|
397
|
+
await until(async () => (await store.getRun('nap'))?.status === 'suspended', timeout, 'the run to sleep');
|
|
398
|
+
await sleep(80);
|
|
399
|
+
await engine.resumeDueTimers();
|
|
400
|
+
const run = await settled('nap');
|
|
401
|
+
expect(run?.output).toBe('rested');
|
|
402
|
+
expect(wakesOf(recorded)).toContain('nap');
|
|
403
|
+
}, timeout * 2);
|
|
404
|
+
it('continue-as-new hands the next run to the run queue', async () => {
|
|
405
|
+
const { engine, recorded } = await instance();
|
|
406
|
+
engine.register('looper', '1', async (ctx, input) => {
|
|
407
|
+
const n = input.n;
|
|
408
|
+
if (n < 2)
|
|
409
|
+
return ctx.continueAsNew({ n: n + 1 });
|
|
410
|
+
return n;
|
|
411
|
+
});
|
|
412
|
+
await engine.start('looper', { n: 0 }, 'loop');
|
|
413
|
+
await until(() => startsOf(recorded).filter((id) => id !== 'loop').length >= 2, timeout, 'the continuations to be enqueued');
|
|
414
|
+
const last = startsOf(recorded).at(-1);
|
|
415
|
+
expect((await settled(last))?.output).toBe(2);
|
|
416
|
+
}, timeout * 2);
|
|
417
|
+
it('a retried run goes back through the run queue', async () => {
|
|
418
|
+
const { engine, recorded } = await instance();
|
|
419
|
+
let attempts = 0;
|
|
420
|
+
engine.register('flaky', '1', async () => {
|
|
421
|
+
attempts += 1;
|
|
422
|
+
if (attempts === 1)
|
|
423
|
+
throw new Error('first attempt fails');
|
|
424
|
+
return 'second';
|
|
425
|
+
});
|
|
426
|
+
await engine.start('flaky', {}, 'flaky');
|
|
427
|
+
expect((await settled('flaky'))?.status).toBe('failed');
|
|
428
|
+
const before = startsOf(recorded).filter((id) => id === 'flaky').length;
|
|
429
|
+
await engine.requeue('flaky');
|
|
430
|
+
expect((await settled('flaky'))?.output).toBe('second');
|
|
431
|
+
expect(startsOf(recorded).filter((id) => id === 'flaky').length).toBe(before + 1);
|
|
432
|
+
}, timeout * 2);
|
|
433
|
+
it('a run orphaned by a dead instance is recovered through the run queue', async () => {
|
|
434
|
+
const { engine, recorded } = await instance();
|
|
435
|
+
engine.register('orphan', '1', async () => 'recovered');
|
|
436
|
+
const now = new Date();
|
|
437
|
+
await store.createRun({
|
|
438
|
+
id: 'orphan',
|
|
439
|
+
workflow: 'orphan',
|
|
440
|
+
workflowVersion: '1',
|
|
441
|
+
status: 'running',
|
|
442
|
+
input: {},
|
|
443
|
+
namespace: 'default',
|
|
444
|
+
lockedBy: 'a-dead-instance',
|
|
445
|
+
lockedUntil: 1,
|
|
446
|
+
createdAt: now,
|
|
447
|
+
updatedAt: now,
|
|
448
|
+
});
|
|
449
|
+
await engine.recoverIncomplete();
|
|
450
|
+
expect((await settled('orphan'))?.output).toBe('recovered');
|
|
451
|
+
expect(startsOf(recorded)).toContain('orphan');
|
|
452
|
+
}, timeout * 2);
|
|
453
|
+
it('a freed singleton slot wakes the next run through the run queue', async () => {
|
|
454
|
+
const { engine, recorded } = await instance();
|
|
455
|
+
engine.register('single', '1', async (ctx, input) => {
|
|
456
|
+
const { id } = input;
|
|
457
|
+
if (id === 'first')
|
|
458
|
+
await ctx.waitForSignal('release');
|
|
459
|
+
return id;
|
|
460
|
+
}, { singleton: { key: () => 'k' } });
|
|
461
|
+
await engine.start('single', { id: 'first' }, 'first');
|
|
462
|
+
await until(async () => (await store.getRun('first'))?.status === 'suspended', timeout, 'the first run to hold the slot');
|
|
463
|
+
await engine.start('single', { id: 'second' }, 'second');
|
|
464
|
+
await until(async () => (await store.getRun('second'))?.status === 'suspended', timeout, 'the second run to queue behind the slot');
|
|
465
|
+
await engine.signal('release', undefined);
|
|
466
|
+
expect((await settled('first'))?.output).toBe('first');
|
|
467
|
+
expect((await settled('second'))?.output).toBe('second');
|
|
468
|
+
expect(wakesOf(recorded)).toContain('second');
|
|
469
|
+
}, timeout * 2);
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
//# sourceMappingURL=run-dispatch-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-dispatch-contract.js","sourceRoot":"","sources":["../../../src/testing-kit/run-dispatch-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-store-conformance.d.ts","sourceRoot":"","sources":["../../../src/testing-kit/state-store-conformance.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,UAAU,EAIhB,MAAM,aAAa,CAAC;AAGrB;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B;;;;;;OAMG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wFAAwF;AACxF,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEjE;;;;;GAKG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,QAAQ,CAAC,uBAAuB,QAAQ;IACxC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAkCD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"state-store-conformance.d.ts","sourceRoot":"","sources":["../../../src/testing-kit/state-store-conformance.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,UAAU,EAIhB,MAAM,aAAa,CAAC;AAGrB;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B;;;;;;OAMG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wFAAwF;AACxF,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEjE;;;;;GAKG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,QAAQ,CAAC,uBAAuB,QAAQ;IACxC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAkCD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAyoDtF"}
|
|
@@ -105,6 +105,20 @@ export function runStateStoreContract(name, makeStore) {
|
|
|
105
105
|
t('returns null for a missing run', async () => {
|
|
106
106
|
expect(await store.getRun('nope')).toBeNull();
|
|
107
107
|
});
|
|
108
|
+
t('getRuns (when implemented) reads several runs at once, leaving out unknown ids', async () => {
|
|
109
|
+
if (!store.getRuns)
|
|
110
|
+
return;
|
|
111
|
+
await store.createRun(run());
|
|
112
|
+
await store.createRun(run({ id: 'r2', status: 'completed', input: { orderId: 'o2' }, output: { total: 2 } }));
|
|
113
|
+
expect(await store.getRuns([])).toEqual([]);
|
|
114
|
+
const got = (await store.getRuns(['r2', 'nope', 'r1', 'r2'])).sort((a, b) => a.id.localeCompare(b.id));
|
|
115
|
+
expect(got.map((r) => r.id)).toEqual(['r1', 'r2']);
|
|
116
|
+
expect(got[0]?.input).toEqual({ orderId: 'o1' });
|
|
117
|
+
expect(got[1]?.status).toBe('completed');
|
|
118
|
+
expect(got[1]?.output).toEqual({ total: 2 });
|
|
119
|
+
// The same run as getRun reads it.
|
|
120
|
+
expect(got[1]).toEqual(await store.getRun('r2'));
|
|
121
|
+
});
|
|
108
122
|
t('createRun rejects a duplicate id (the engine converges racing starts on the winner)', async () => {
|
|
109
123
|
await store.createRun(run({ status: 'completed', output: { total: 1 } }));
|
|
110
124
|
await expect(store.createRun(run())).rejects.toThrow();
|