@moltzap/client 2026.501.0 → 2026.501.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/channel-core.d.ts +9 -0
  2. package/dist/channel-core.d.ts.map +1 -1
  3. package/dist/channel-core.js +44 -0
  4. package/dist/channel-core.js.map +1 -1
  5. package/dist/channel-core.test.js +37 -0
  6. package/dist/channel-core.test.js.map +1 -1
  7. package/dist/cli/commands/apps.d.ts +1 -1
  8. package/dist/internal/__tests__/s2c-partition-key.test.d.ts +2 -0
  9. package/dist/internal/__tests__/s2c-partition-key.test.d.ts.map +1 -0
  10. package/dist/internal/__tests__/s2c-partition-key.test.js +230 -0
  11. package/dist/internal/__tests__/s2c-partition-key.test.js.map +1 -0
  12. package/dist/internal/__tests__/s2c-partition-worker.test.d.ts +2 -0
  13. package/dist/internal/__tests__/s2c-partition-worker.test.d.ts.map +1 -0
  14. package/dist/internal/__tests__/s2c-partition-worker.test.js +267 -0
  15. package/dist/internal/__tests__/s2c-partition-worker.test.js.map +1 -0
  16. package/dist/internal/__tests__/s2c-partitioned-dispatcher-real-ws.test.d.ts +2 -0
  17. package/dist/internal/__tests__/s2c-partitioned-dispatcher-real-ws.test.d.ts.map +1 -0
  18. package/dist/internal/__tests__/s2c-partitioned-dispatcher-real-ws.test.js +254 -0
  19. package/dist/internal/__tests__/s2c-partitioned-dispatcher-real-ws.test.js.map +1 -0
  20. package/dist/internal/__tests__/s2c-partitioned-dispatcher.test.d.ts +2 -0
  21. package/dist/internal/__tests__/s2c-partitioned-dispatcher.test.d.ts.map +1 -0
  22. package/dist/internal/__tests__/s2c-partitioned-dispatcher.test.js +571 -0
  23. package/dist/internal/__tests__/s2c-partitioned-dispatcher.test.js.map +1 -0
  24. package/dist/internal/s2c-dispatcher-errors.d.ts +66 -0
  25. package/dist/internal/s2c-dispatcher-errors.d.ts.map +1 -0
  26. package/dist/internal/s2c-dispatcher-errors.js +46 -0
  27. package/dist/internal/s2c-dispatcher-errors.js.map +1 -0
  28. package/dist/internal/s2c-partition-key.d.ts +70 -0
  29. package/dist/internal/s2c-partition-key.d.ts.map +1 -0
  30. package/dist/internal/s2c-partition-key.js +140 -0
  31. package/dist/internal/s2c-partition-key.js.map +1 -0
  32. package/dist/internal/s2c-partition-worker.d.ts +160 -0
  33. package/dist/internal/s2c-partition-worker.d.ts.map +1 -0
  34. package/dist/internal/s2c-partition-worker.js +141 -0
  35. package/dist/internal/s2c-partition-worker.js.map +1 -0
  36. package/dist/internal/s2c-partitioned-dispatcher.d.ts +181 -0
  37. package/dist/internal/s2c-partitioned-dispatcher.d.ts.map +1 -0
  38. package/dist/internal/s2c-partitioned-dispatcher.js +290 -0
  39. package/dist/internal/s2c-partitioned-dispatcher.js.map +1 -0
  40. package/dist/service.d.ts +8 -1
  41. package/dist/service.d.ts.map +1 -1
  42. package/dist/service.js +85 -12
  43. package/dist/service.js.map +1 -1
  44. package/dist/service.test.js +76 -4
  45. package/dist/service.test.js.map +1 -1
  46. package/dist/test-utils/channel-service-fixture.d.ts +6 -0
  47. package/dist/test-utils/channel-service-fixture.d.ts.map +1 -1
  48. package/dist/test-utils/channel-service-fixture.js +23 -0
  49. package/dist/test-utils/channel-service-fixture.js.map +1 -1
  50. package/dist/test-utils/fake-service.d.ts +3 -1
  51. package/dist/test-utils/fake-service.d.ts.map +1 -1
  52. package/dist/test-utils/fake-service.js +4 -0
  53. package/dist/test-utils/fake-service.js.map +1 -1
  54. package/dist/ws-client.d.ts +27 -0
  55. package/dist/ws-client.d.ts.map +1 -1
  56. package/dist/ws-client.js +107 -57
  57. package/dist/ws-client.js.map +1 -1
  58. package/dist/ws-client.test.js +7 -1
  59. package/dist/ws-client.test.js.map +1 -1
  60. package/package.json +3 -3
@@ -0,0 +1,571 @@
1
+ /**
2
+ * Unit tests for the partitioned s2c dispatcher.
3
+ *
4
+ * Spec: moltzap#356 §8 (test plan, file 3).
5
+ *
6
+ * Covers routing, partition allocation, the soft cap, the idle reaper,
7
+ * and the deadlock scenario at the dispatcher boundary (without the
8
+ * full AppHost stack — that's the conformance + integration tests).
9
+ */
10
+ import { describe, it, expect } from "vitest";
11
+ import { Deferred, Effect, Exit, Ref, Scope } from "effect";
12
+ import { DEFAULT_PARTITIONED_DISPATCHER_CONFIG, makePartitionedDispatcher, } from "../s2c-partitioned-dispatcher.js";
13
+ const SESSION_A = "11111111-1111-4111-8111-111111111111";
14
+ const CONV_X = "conv-X";
15
+ const CONV_Y = "conv-Y";
16
+ const reqBeforeDispatch = (id, sessionId = SESSION_A, conv = CONV_X) => ({
17
+ id,
18
+ method: "apps/onBeforeDispatch",
19
+ params: { sessionId, conversationId: conv },
20
+ });
21
+ const reqBeforeMessageDelivery = (id, sessionId = SESSION_A, conv = CONV_X) => ({
22
+ id,
23
+ method: "apps/onBeforeMessageDelivery",
24
+ params: { sessionId, conversationId: conv },
25
+ });
26
+ const reqLifecycle = (id, method = "apps/onJoin", sessionId = SESSION_A) => ({
27
+ id,
28
+ method,
29
+ params: { sessionId },
30
+ });
31
+ /** Drive a body under a fresh CloseableScope; close on exit. */
32
+ function withScope(body) {
33
+ return Effect.gen(function* () {
34
+ const scope = yield* Scope.make();
35
+ const result = yield* body(scope);
36
+ yield* Scope.close(scope, Exit.void);
37
+ return result;
38
+ });
39
+ }
40
+ describe("makePartitionedDispatcher — routing", () => {
41
+ it("two offers with the same key land on the same worker (FIFO preserved)", async () => {
42
+ const seen = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
43
+ const order = yield* Ref.make([]);
44
+ const allDone = yield* Deferred.make();
45
+ const dispatcher = yield* makePartitionedDispatcher({
46
+ handle: (req) => Effect.gen(function* () {
47
+ yield* Ref.update(order, (xs) => [...xs, req.id]);
48
+ const xs = yield* Ref.get(order);
49
+ if (xs.length === 3) {
50
+ yield* Deferred.succeed(allDone, undefined);
51
+ }
52
+ }),
53
+ scope,
54
+ });
55
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-1"));
56
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-2"));
57
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-3"));
58
+ yield* Deferred.await(allDone);
59
+ return yield* Ref.get(order);
60
+ })));
61
+ expect(seen).toEqual(["rpc-1", "rpc-2", "rpc-3"]);
62
+ });
63
+ it("two offers with different keys execute concurrently (no FIFO between them)", async () => {
64
+ // Different keys (A=session A, conv X; B=session A, conv Y) on
65
+ // independent fibers. Park request-A on a Deferred; request-B
66
+ // must complete BEFORE we release request-A. If routing
67
+ // collapsed onto one fiber, request-B would never run.
68
+ const result = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
69
+ const releaseA = yield* Deferred.make();
70
+ const bDone = yield* Deferred.make();
71
+ const handle = (req) => Effect.gen(function* () {
72
+ if (req.id === "rpc-A-park") {
73
+ yield* Deferred.await(releaseA);
74
+ }
75
+ else if (req.id === "rpc-B-go") {
76
+ yield* Deferred.succeed(bDone, undefined);
77
+ }
78
+ });
79
+ const dispatcher = yield* makePartitionedDispatcher({
80
+ handle,
81
+ scope,
82
+ });
83
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-A-park", SESSION_A, CONV_X));
84
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-B-go", SESSION_A, CONV_Y));
85
+ // bDone fires only if rpc-B ran without being blocked by
86
+ // rpc-A's parked Deferred.
87
+ yield* Deferred.await(bDone);
88
+ // Release rpc-A so the test's Scope.close doesn't have to
89
+ // interrupt a parked fiber.
90
+ yield* Deferred.succeed(releaseA, undefined);
91
+ return "concurrent";
92
+ })));
93
+ expect(result).toBe("concurrent");
94
+ });
95
+ it("offer with malformed params returns MalformedPartitionKeyError", async () => {
96
+ const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
97
+ const dispatcher = yield* makePartitionedDispatcher({
98
+ handle: () => Effect.void,
99
+ scope,
100
+ });
101
+ return yield* Effect.either(dispatcher.offer({
102
+ id: "rpc-x",
103
+ method: "apps/onBeforeDispatch",
104
+ params: { /* sessionId missing */ conversationId: CONV_X },
105
+ }));
106
+ })));
107
+ expect(verdict._tag).toBe("Left");
108
+ if (verdict._tag === "Left") {
109
+ expect(verdict.left._tag).toBe("MalformedPartitionKeyError");
110
+ }
111
+ });
112
+ });
113
+ describe("makePartitionedDispatcher — soft cap", () => {
114
+ it("allocates up to maxPartitions partitions", async () => {
115
+ const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
116
+ const release = yield* Deferred.make();
117
+ const dispatcher = yield* makePartitionedDispatcher({
118
+ handle: () => Deferred.await(release),
119
+ scope,
120
+ config: { maxPartitions: 4 },
121
+ });
122
+ // Distinct conversationIds → distinct keys → distinct
123
+ // partitions, all parked on `release`.
124
+ for (let i = 0; i < 4; i++) {
125
+ yield* dispatcher.offer(reqBeforeDispatch(`rpc-${i}`, SESSION_A, `conv-${i}`));
126
+ }
127
+ const stats = yield* dispatcher.stats;
128
+ yield* Deferred.succeed(release, undefined);
129
+ return stats.activePartitions;
130
+ })));
131
+ expect(verdict).toBe(4);
132
+ });
133
+ it("(N+1)th distinct key returns PartitionLimitError when no idle partition is reclaimable", async () => {
134
+ const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
135
+ const release = yield* Deferred.make();
136
+ const dispatcher = yield* makePartitionedDispatcher({
137
+ handle: () => Deferred.await(release),
138
+ scope,
139
+ config: { maxPartitions: 2 },
140
+ });
141
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-1", SESSION_A, "conv-A"));
142
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-2", SESSION_A, "conv-B"));
143
+ // Third distinct key → should fail with PartitionLimitError.
144
+ const overflow = yield* Effect.either(dispatcher.offer(reqBeforeDispatch("rpc-3", SESSION_A, "conv-C")));
145
+ yield* Deferred.succeed(release, undefined);
146
+ return overflow;
147
+ })));
148
+ expect(verdict._tag).toBe("Left");
149
+ if (verdict._tag === "Left") {
150
+ expect(verdict.left._tag).toBe("PartitionLimitError");
151
+ }
152
+ });
153
+ });
154
+ describe("makePartitionedDispatcher — backpressure", () => {
155
+ it("partitionQueueFull on partition A does not block partition B (independent fibers)", async () => {
156
+ // Park partition A's handler so its queue fills; offer to
157
+ // partition B must still succeed and run.
158
+ const result = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
159
+ const releaseA = yield* Deferred.make();
160
+ const bDone = yield* Deferred.make();
161
+ const dispatcher = yield* makePartitionedDispatcher({
162
+ handle: (req) => Effect.gen(function* () {
163
+ if (req.method === "apps/onBeforeDispatch") {
164
+ yield* Deferred.await(releaseA);
165
+ }
166
+ else if (req.id === "rpc-B-go") {
167
+ yield* Deferred.succeed(bDone, undefined);
168
+ }
169
+ }),
170
+ scope,
171
+ config: { partitionQueueCapacity: 1 },
172
+ });
173
+ // Start partition A; first offer goes into the handler.
174
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-A-1", SESSION_A, CONV_X));
175
+ // Wait until the handler has actually taken rpc-A-1 off the
176
+ // queue (queue size 0). Then fill the queue with rpc-A-2 so
177
+ // a third offer to A would fail.
178
+ for (let i = 0; i < 200; i++) {
179
+ const stats = yield* dispatcher.stats;
180
+ const partA = stats.partitions.find((p) => p.key.includes("apps/onBeforeDispatch"));
181
+ if (partA && partA.queueSize === 0)
182
+ break;
183
+ yield* Effect.yieldNow();
184
+ }
185
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-A-2", SESSION_A, CONV_X));
186
+ // Partition A is now at capacity. A third offer to A would
187
+ // fail. Meanwhile a different-key offer (partition B) must
188
+ // still run.
189
+ yield* dispatcher.offer(reqBeforeMessageDelivery("rpc-B-go", SESSION_A, CONV_X));
190
+ yield* Deferred.await(bDone);
191
+ yield* Deferred.succeed(releaseA, undefined);
192
+ return "B-ran";
193
+ })));
194
+ expect(result).toBe("B-ran");
195
+ });
196
+ it("PartitionQueueFullError is returned when one partition fills, leaving sibling partitions unaffected", async () => {
197
+ // Verify the exact failure tag. Park A's handler, fill the queue,
198
+ // then push one more — it should fail with PartitionQueueFullError.
199
+ const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
200
+ const release = yield* Deferred.make();
201
+ const dispatcher = yield* makePartitionedDispatcher({
202
+ handle: () => Deferred.await(release),
203
+ scope,
204
+ config: { partitionQueueCapacity: 1 },
205
+ });
206
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-1", SESSION_A, CONV_X));
207
+ // Wait for the handler to take rpc-1 off the queue.
208
+ for (let i = 0; i < 200; i++) {
209
+ const stats = yield* dispatcher.stats;
210
+ const part = stats.partitions[0];
211
+ if (part && part.queueSize === 0)
212
+ break;
213
+ yield* Effect.yieldNow();
214
+ }
215
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-2", SESSION_A, CONV_X));
216
+ const overflow = yield* Effect.either(dispatcher.offer(reqBeforeDispatch("rpc-3", SESSION_A, CONV_X)));
217
+ yield* Deferred.succeed(release, undefined);
218
+ return overflow;
219
+ })));
220
+ expect(verdict._tag).toBe("Left");
221
+ if (verdict._tag === "Left") {
222
+ expect(verdict.left._tag).toBe("PartitionQueueFullError");
223
+ }
224
+ });
225
+ });
226
+ describe("makePartitionedDispatcher — deadlock fix (D10 reproducer at dispatcher level)", () => {
227
+ it("before_dispatch suspended on Deferred.await does NOT block before_message_delivery " +
228
+ "for the same (sessionId, conversationId) — release path completes; suspended fiber resumes", async () => {
229
+ // Direct reproducer of arena#248. Dispatcher boundary version of
230
+ // the conformance + integration tests.
231
+ //
232
+ // 1. Server sends `apps/onBeforeDispatch` for (S, C). Handler
233
+ // parks on `releaseDispatch`.
234
+ // 2. Server sends `apps/onBeforeMessageDelivery` for the SAME
235
+ // (S, C) — handler runs, succeeds `releaseDispatch`.
236
+ // 3. The parked dispatch handler resumes and completes.
237
+ //
238
+ // Pre-#356 (single-fiber dispatcher): step 2 queues behind
239
+ // step 1; release never fires; parked Deferred sleeps forever.
240
+ // Post-#356 (partitioned): different `hookKind` → different
241
+ // key → different fiber → step 2 runs concurrently.
242
+ const result = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
243
+ const releaseDispatch = yield* Deferred.make();
244
+ const dispatchDone = yield* Deferred.make();
245
+ const deliveryDone = yield* Deferred.make();
246
+ const dispatcher = yield* makePartitionedDispatcher({
247
+ handle: (req) => Effect.gen(function* () {
248
+ if (req.method === "apps/onBeforeDispatch") {
249
+ // Park.
250
+ yield* Deferred.await(releaseDispatch);
251
+ yield* Deferred.succeed(dispatchDone, undefined);
252
+ }
253
+ else if (req.method === "apps/onBeforeMessageDelivery") {
254
+ // The lease-release hook in arena's pattern. Run
255
+ // to completion and signal the dispatch path to
256
+ // resume.
257
+ yield* Deferred.succeed(releaseDispatch, undefined);
258
+ yield* Deferred.succeed(deliveryDone, undefined);
259
+ }
260
+ }),
261
+ scope,
262
+ });
263
+ // Step 1: park dispatch handler.
264
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-dispatch-1", SESSION_A, CONV_X));
265
+ // Step 2: send delivery handler for the SAME conversation.
266
+ yield* dispatcher.offer(reqBeforeMessageDelivery("rpc-delivery-1", SESSION_A, CONV_X));
267
+ // Both must complete. With pre-#356 single-fiber
268
+ // dispatch, this hangs forever (the test's `runPromise`
269
+ // would never resolve — vitest's `testTimeout` would
270
+ // catch it).
271
+ yield* Deferred.await(deliveryDone);
272
+ yield* Deferred.await(dispatchDone);
273
+ return "no-deadlock";
274
+ })));
275
+ expect(result).toBe("no-deadlock");
276
+ }, /* per-test timeout = */ 5000);
277
+ });
278
+ describe("makePartitionedDispatcher — idle reaper", () => {
279
+ it("worker idle past idlePartitionTtlMs is finalized on next reaper tick", async () => {
280
+ const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
281
+ // Inject a virtual clock so the test doesn't sleep.
282
+ const fakeNow = yield* Ref.make(0);
283
+ const clock = () => Effect.runSync(Ref.get(fakeNow));
284
+ const dispatcher = yield* makePartitionedDispatcher({
285
+ handle: () => Effect.void,
286
+ scope,
287
+ clock,
288
+ config: {
289
+ idlePartitionTtlMs: 100,
290
+ idleReaperIntervalMs: 10,
291
+ },
292
+ });
293
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-1", SESSION_A, CONV_X));
294
+ // Wait for the handler to finish so the partition becomes
295
+ // Idle.
296
+ for (let i = 0; i < 200; i++) {
297
+ const stats = yield* dispatcher.stats;
298
+ const part = stats.partitions[0];
299
+ if (part && part.idle)
300
+ break;
301
+ yield* Effect.yieldNow();
302
+ }
303
+ // Bump the virtual clock past the TTL.
304
+ yield* Ref.set(fakeNow, 10_000);
305
+ // Reaper ticks every idleReaperIntervalMs. Wait up to
306
+ // ~500ms wall-clock for the reaper to observe the bump and
307
+ // finalize the partition.
308
+ let finalized = false;
309
+ for (let i = 0; i < 50; i++) {
310
+ const stats = yield* dispatcher.stats;
311
+ if (stats.activePartitions === 0) {
312
+ finalized = true;
313
+ break;
314
+ }
315
+ yield* Effect.sleep("20 millis");
316
+ }
317
+ return finalized;
318
+ })));
319
+ expect(verdict).toBe(true);
320
+ });
321
+ it("worker that becomes Busy before TTL is NOT reaped", async () => {
322
+ const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
323
+ const release = yield* Deferred.make();
324
+ const fakeNow = yield* Ref.make(0);
325
+ const clock = () => Effect.runSync(Ref.get(fakeNow));
326
+ const dispatcher = yield* makePartitionedDispatcher({
327
+ handle: () => Deferred.await(release),
328
+ scope,
329
+ clock,
330
+ config: {
331
+ idlePartitionTtlMs: 100,
332
+ idleReaperIntervalMs: 10,
333
+ },
334
+ });
335
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-busy", SESSION_A, CONV_X));
336
+ // Bump clock past TTL while handler is still parked. Reaper
337
+ // sees `idleSince._tag === "Busy"` and skips reclamation.
338
+ yield* Ref.set(fakeNow, 10_000);
339
+ // Give reaper several ticks.
340
+ yield* Effect.sleep("100 millis");
341
+ const stats = yield* dispatcher.stats;
342
+ yield* Deferred.succeed(release, undefined);
343
+ return stats.activePartitions;
344
+ })));
345
+ expect(verdict).toBe(1);
346
+ });
347
+ });
348
+ describe("makePartitionedDispatcher — scope teardown", () => {
349
+ it("Scope.close finalizes every partition worker (no leak)", async () => {
350
+ const result = await Effect.runPromise(Effect.gen(function* () {
351
+ const scope = yield* Scope.make();
352
+ const release = yield* Deferred.make();
353
+ const dispatcher = yield* makePartitionedDispatcher({
354
+ handle: () => Deferred.await(release),
355
+ scope,
356
+ });
357
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-1"));
358
+ yield* dispatcher.offer(reqBeforeMessageDelivery("rpc-2"));
359
+ yield* dispatcher.offer(reqLifecycle("rpc-3", "apps/onJoin"));
360
+ // Close while every handler is parked. Must not hang.
361
+ yield* Scope.close(scope, Exit.void);
362
+ // Release any awaiters (no-op if scope close already
363
+ // interrupted the worker fibers).
364
+ yield* Deferred.succeed(release, undefined).pipe(Effect.ignore);
365
+ return "torn-down";
366
+ }));
367
+ expect(result).toBe("torn-down");
368
+ });
369
+ });
370
+ describe("makePartitionedDispatcher — reaper releases per-worker scopes", () => {
371
+ it("reaped workers release queue finalizers from dispatcher scope", async () => {
372
+ // Architect plan §4.2 + §10 leak-pinning: with per-worker child
373
+ // scopes, reaping a worker MUST close its queue.shutdown finalizer
374
+ // synchronously inside the reaper tick, not pin it on the
375
+ // dispatcher scope until the connection closes.
376
+ //
377
+ // What this test asserts (observable behaviour):
378
+ // 1. After TTL expiry, `dispatcher.stats.activePartitions` drops
379
+ // to 0. The map is cleared.
380
+ // 2. The cap (set to N) rebudgets — N FRESH conv keys allocate
381
+ // successfully without `PartitionLimitError`. If map removal
382
+ // were the only fix, this would still pass.
383
+ // 3. A handler invocation count separates "fresh worker
384
+ // allocated" from "old worker still alive in a different
385
+ // map slot": the test counts how many handler invocations
386
+ // fire across the whole run. With per-worker-scope close,
387
+ // each post-reap offer goes to a brand-new worker, so the
388
+ // handler fires once per pre-reap offer + once per
389
+ // post-reap offer = 2N. With the broken behaviour where the
390
+ // old worker's drain fiber lingers on the dispatcher scope,
391
+ // the count would still be 2N (the lingering fiber never
392
+ // gets new items because the map points to a fresh worker)
393
+ // — so this is not a perfect distinguisher of leaked-vs-not,
394
+ // but combined with `s2c-partition-worker.test.ts > "offer
395
+ // after Scope close fails with PartitionQueueFullError"`,
396
+ // we cover both the per-worker-scope contract and the
397
+ // reaper's use of it.
398
+ // 4. The Retiring-tag race fix is exercised end-to-end by
399
+ // issuing offers concurrently with reap (race window is
400
+ // microseconds; we run several reap+offer cycles to stress
401
+ // it). Every offer either succeeds (new worker post-reap)
402
+ // or fails with a typed `OfferRejected` — never silently
403
+ // drops the request, never hangs.
404
+ const N = 128;
405
+ const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
406
+ const fakeNow = yield* Ref.make(0);
407
+ const clock = () => Effect.runSync(Ref.get(fakeNow));
408
+ const handlerCount = yield* Ref.make(0);
409
+ const dispatcher = yield* makePartitionedDispatcher({
410
+ handle: () => Ref.update(handlerCount, (n) => n + 1),
411
+ scope,
412
+ clock,
413
+ config: {
414
+ maxPartitions: N,
415
+ idlePartitionTtlMs: 100,
416
+ idleReaperIntervalMs: 10,
417
+ },
418
+ });
419
+ // Spawn N partitions across N distinct conv keys.
420
+ for (let i = 0; i < N; i++) {
421
+ yield* dispatcher.offer(reqBeforeDispatch(`rpc-${i}`, SESSION_A, `conv-${i}`));
422
+ }
423
+ // Wait until every worker is Idle (handler returned).
424
+ for (let attempt = 0; attempt < 200; attempt++) {
425
+ const stats = yield* dispatcher.stats;
426
+ const allIdle = stats.activePartitions === N &&
427
+ stats.partitions.every((p) => p.idle);
428
+ if (allIdle)
429
+ break;
430
+ yield* Effect.yieldNow();
431
+ }
432
+ const preStats = yield* dispatcher.stats;
433
+ const handlerCountPreReap = yield* Ref.get(handlerCount);
434
+ // Trip the TTL.
435
+ yield* Ref.set(fakeNow, 10_000);
436
+ // Wait for the reaper to drain the map.
437
+ let reaped = false;
438
+ for (let attempt = 0; attempt < 100; attempt++) {
439
+ const stats = yield* dispatcher.stats;
440
+ if (stats.activePartitions === 0) {
441
+ reaped = true;
442
+ break;
443
+ }
444
+ yield* Effect.sleep("20 millis");
445
+ }
446
+ // Cap rebudget proof + fresh-worker proof: spawn N fresh
447
+ // partitions. Each must succeed (not hit PartitionLimitError),
448
+ // each must fire the handler (proving a real, alive worker
449
+ // is processing — not a stale reference returning an
450
+ // already-shutdown queue).
451
+ for (let i = 0; i < N; i++) {
452
+ yield* dispatcher.offer(reqBeforeDispatch(`rpc-fresh-${i}`, SESSION_A, `conv-fresh-${i}`));
453
+ }
454
+ // Wait for the fresh handlers to all run.
455
+ for (let attempt = 0; attempt < 200; attempt++) {
456
+ const c = yield* Ref.get(handlerCount);
457
+ if (c === 2 * N)
458
+ break;
459
+ yield* Effect.yieldNow();
460
+ }
461
+ const postStats = yield* dispatcher.stats;
462
+ const handlerCountPostRefill = yield* Ref.get(handlerCount);
463
+ return {
464
+ beforeCount: preStats.activePartitions,
465
+ reaped,
466
+ afterRefillCount: postStats.activePartitions,
467
+ handlerCountPreReap,
468
+ handlerCountPostRefill,
469
+ };
470
+ })));
471
+ expect(verdict.beforeCount).toBe(N);
472
+ expect(verdict.reaped).toBe(true);
473
+ expect(verdict.afterRefillCount).toBe(N);
474
+ // 2N handler invocations: N pre-reap + N post-refill. If reap had
475
+ // not actually retired the workers (e.g. fresh allocations had
476
+ // failed), the post-refill handlers would not have run.
477
+ expect(verdict.handlerCountPreReap).toBe(N);
478
+ expect(verdict.handlerCountPostRefill).toBe(2 * N);
479
+ });
480
+ it("offer racing the reaper either succeeds against a fresh worker or fails with a typed OfferRejected — never silently drops", async () => {
481
+ // P1 race fix: an offer that observes a still-mapped worker just
482
+ // as the reaper claims it must NOT silently drop the request. The
483
+ // dispatcher's `Retiring` reservation makes `worker.offer` refuse
484
+ // to enqueue once the reaper has set the tag. The reader fiber
485
+ // gets `OfferRejected` (specifically `PartitionQueueFullError`)
486
+ // and writes a wire error response.
487
+ //
488
+ // Test shape: drive many cycles of (offer → reap → offer-same-key)
489
+ // with very short TTLs so the producer races the reaper. Every
490
+ // offer outcome is captured; none may be `null` / no result.
491
+ const cycles = 50;
492
+ const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
493
+ const fakeNow = yield* Ref.make(0);
494
+ const clock = () => Effect.runSync(Ref.get(fakeNow));
495
+ const handlerCount = yield* Ref.make(0);
496
+ const dispatcher = yield* makePartitionedDispatcher({
497
+ handle: () => Ref.update(handlerCount, (n) => n + 1),
498
+ scope,
499
+ clock,
500
+ config: {
501
+ maxPartitions: 8,
502
+ idlePartitionTtlMs: 1,
503
+ idleReaperIntervalMs: 1,
504
+ },
505
+ });
506
+ const outcomes = [];
507
+ for (let i = 0; i < cycles; i++) {
508
+ yield* Ref.set(fakeNow, 1000 * i);
509
+ const result = yield* Effect.either(dispatcher.offer(reqBeforeDispatch(`rpc-cycle-${i}`, SESSION_A, "conv-race")));
510
+ outcomes.push(result._tag === "Right" ? "ok" : "rejected");
511
+ // Yield so the reaper has a chance to run between cycles.
512
+ yield* Effect.yieldNow();
513
+ }
514
+ // Wait for any in-flight handlers to finish so the count
515
+ // settles before we read it.
516
+ for (let attempt = 0; attempt < 200; attempt++) {
517
+ const c = yield* Ref.get(handlerCount);
518
+ const ok = outcomes.filter((o) => o === "ok").length;
519
+ if (c === ok)
520
+ break;
521
+ yield* Effect.sleep("5 millis");
522
+ }
523
+ const handlerCalls = yield* Ref.get(handlerCount);
524
+ return { outcomes, handlerCalls };
525
+ })));
526
+ // Every cycle produced a typed outcome (ok or rejected). No
527
+ // exception, no hang, no missing entry.
528
+ expect(verdict.outcomes.length).toBe(cycles);
529
+ for (const outcome of verdict.outcomes) {
530
+ expect(["ok", "rejected"]).toContain(outcome);
531
+ }
532
+ // Load-bearing: every "ok" outcome corresponds to a handler
533
+ // invocation. Pre-fix, an offer could race the reaper, return
534
+ // `Right` from `dispatcher.offer`, then have its queued request
535
+ // silently dropped by `Scope.close` firing `Queue.shutdown` —
536
+ // `handlerCalls` would be strictly less than `okCount`.
537
+ const okCount = verdict.outcomes.filter((o) => o === "ok").length;
538
+ expect(verdict.handlerCalls).toBe(okCount);
539
+ });
540
+ });
541
+ describe("makePartitionedDispatcher — runSync(close()) contract (regression of ws-client.test.ts:1248)", () => {
542
+ it("dispatcher.shutdown is safe to runFork from a runSync context", async () => {
543
+ // dispatcher.shutdown closes the dispatcher's Scope. The Scope
544
+ // close yields through the runtime (queue.shutdown +
545
+ // fiber.interrupt are async), so it must NOT be runSync-able by
546
+ // the caller — but `runFork` must succeed without throwing.
547
+ // This mirrors the ws-client.ts invocation pattern.
548
+ await Effect.runPromise(Effect.gen(function* () {
549
+ const scope = yield* Scope.make();
550
+ const dispatcher = yield* makePartitionedDispatcher({
551
+ handle: () => Effect.void,
552
+ scope,
553
+ });
554
+ yield* dispatcher.offer(reqBeforeDispatch("rpc-1"));
555
+ // Use Effect.runFork-equivalent via Effect.forkDaemon — a
556
+ // runSync caller wraps `Scope.close(...)` similarly.
557
+ const fiber = yield* Effect.forkDaemon(Scope.close(scope, Exit.void));
558
+ yield* fiber.await;
559
+ }));
560
+ expect(true).toBe(true);
561
+ });
562
+ });
563
+ describe("makePartitionedDispatcher — defaults", () => {
564
+ it("DEFAULT_PARTITIONED_DISPATCHER_CONFIG carries the architect's documented values", () => {
565
+ expect(DEFAULT_PARTITIONED_DISPATCHER_CONFIG.maxPartitions).toBe(256);
566
+ expect(DEFAULT_PARTITIONED_DISPATCHER_CONFIG.partitionQueueCapacity).toBe(32);
567
+ expect(DEFAULT_PARTITIONED_DISPATCHER_CONFIG.idlePartitionTtlMs).toBe(60_000);
568
+ expect(DEFAULT_PARTITIONED_DISPATCHER_CONFIG.idleReaperIntervalMs).toBe(5_000);
569
+ });
570
+ });
571
+ //# sourceMappingURL=s2c-partitioned-dispatcher.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s2c-partitioned-dispatcher.test.js","sourceRoot":"","sources":["../../../src/internal/__tests__/s2c-partitioned-dispatcher.test.ts"],"names":[],"mappings":"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"}