@moltzap/client 2026.501.1 → 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.
- package/dist/internal/__tests__/s2c-partition-key.test.d.ts +2 -0
- package/dist/internal/__tests__/s2c-partition-key.test.d.ts.map +1 -0
- package/dist/internal/__tests__/s2c-partition-key.test.js +230 -0
- package/dist/internal/__tests__/s2c-partition-key.test.js.map +1 -0
- package/dist/internal/__tests__/s2c-partition-worker.test.d.ts +2 -0
- package/dist/internal/__tests__/s2c-partition-worker.test.d.ts.map +1 -0
- package/dist/internal/__tests__/s2c-partition-worker.test.js +267 -0
- package/dist/internal/__tests__/s2c-partition-worker.test.js.map +1 -0
- package/dist/internal/__tests__/s2c-partitioned-dispatcher-real-ws.test.d.ts +2 -0
- package/dist/internal/__tests__/s2c-partitioned-dispatcher-real-ws.test.d.ts.map +1 -0
- package/dist/internal/__tests__/s2c-partitioned-dispatcher-real-ws.test.js +254 -0
- package/dist/internal/__tests__/s2c-partitioned-dispatcher-real-ws.test.js.map +1 -0
- package/dist/internal/__tests__/s2c-partitioned-dispatcher.test.d.ts +2 -0
- package/dist/internal/__tests__/s2c-partitioned-dispatcher.test.d.ts.map +1 -0
- package/dist/internal/__tests__/s2c-partitioned-dispatcher.test.js +571 -0
- package/dist/internal/__tests__/s2c-partitioned-dispatcher.test.js.map +1 -0
- package/dist/internal/s2c-dispatcher-errors.d.ts +66 -0
- package/dist/internal/s2c-dispatcher-errors.d.ts.map +1 -0
- package/dist/internal/s2c-dispatcher-errors.js +46 -0
- package/dist/internal/s2c-dispatcher-errors.js.map +1 -0
- package/dist/internal/s2c-partition-key.d.ts +70 -0
- package/dist/internal/s2c-partition-key.d.ts.map +1 -0
- package/dist/internal/s2c-partition-key.js +140 -0
- package/dist/internal/s2c-partition-key.js.map +1 -0
- package/dist/internal/s2c-partition-worker.d.ts +160 -0
- package/dist/internal/s2c-partition-worker.d.ts.map +1 -0
- package/dist/internal/s2c-partition-worker.js +141 -0
- package/dist/internal/s2c-partition-worker.js.map +1 -0
- package/dist/internal/s2c-partitioned-dispatcher.d.ts +181 -0
- package/dist/internal/s2c-partitioned-dispatcher.d.ts.map +1 -0
- package/dist/internal/s2c-partitioned-dispatcher.js +290 -0
- package/dist/internal/s2c-partitioned-dispatcher.js.map +1 -0
- package/dist/ws-client.d.ts +27 -0
- package/dist/ws-client.d.ts.map +1 -1
- package/dist/ws-client.js +107 -57
- package/dist/ws-client.js.map +1 -1
- package/dist/ws-client.test.js +7 -1
- package/dist/ws-client.test.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s2c-partition-key.test.d.ts","sourceRoot":"","sources":["../../../src/internal/__tests__/s2c-partition-key.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for the partition-key extractor.
|
|
3
|
+
*
|
|
4
|
+
* Spec: moltzap#356 §8 (test plan, file 1).
|
|
5
|
+
*
|
|
6
|
+
* The extractor is pure (`Either`-returning, no Effect). Tests pass
|
|
7
|
+
* synthetic `PartitionableRequest` records and assert the branded key
|
|
8
|
+
* value or the typed `MalformedPartitionKeyError._tag`.
|
|
9
|
+
*
|
|
10
|
+
* Mutation surface: every `_tag` branch + the lifecycle sentinel +
|
|
11
|
+
* cross-conversation key disjointness are independently asserted so a
|
|
12
|
+
* collapsing mutation flips at least one test.
|
|
13
|
+
*/
|
|
14
|
+
import { describe, it, expect } from "vitest";
|
|
15
|
+
import { Either } from "effect";
|
|
16
|
+
import { s2cRpcMethods } from "@moltzap/protocol";
|
|
17
|
+
import { describePartitionKey, extractPartitionKey, LIFECYCLE_CONVERSATION_SENTINEL, } from "../s2c-partition-key.js";
|
|
18
|
+
const SESSION_A = "11111111-1111-4111-8111-111111111111";
|
|
19
|
+
const SESSION_B = "22222222-2222-4222-8222-222222222222";
|
|
20
|
+
const CONV_X = "conv-X";
|
|
21
|
+
const CONV_Y = "conv-Y";
|
|
22
|
+
function reqOnBeforeDispatch(overrides = {}) {
|
|
23
|
+
return {
|
|
24
|
+
id: "rpc-1",
|
|
25
|
+
method: "apps/onBeforeDispatch",
|
|
26
|
+
params: {
|
|
27
|
+
sessionId: SESSION_A,
|
|
28
|
+
conversationId: CONV_X,
|
|
29
|
+
...overrides,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function reqOnBeforeMessageDelivery() {
|
|
34
|
+
return {
|
|
35
|
+
id: "rpc-2",
|
|
36
|
+
method: "apps/onBeforeMessageDelivery",
|
|
37
|
+
params: { sessionId: SESSION_A, conversationId: CONV_X },
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function reqLifecycle(method) {
|
|
41
|
+
return {
|
|
42
|
+
id: "rpc-3",
|
|
43
|
+
method,
|
|
44
|
+
params: { sessionId: SESSION_A },
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
describe("extractPartitionKey — happy paths", () => {
|
|
48
|
+
it("apps/onBeforeDispatch with sessionId+conversationId yields a key", () => {
|
|
49
|
+
const result = extractPartitionKey(reqOnBeforeDispatch());
|
|
50
|
+
expect(Either.isRight(result)).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
it("apps/onBeforeMessageDelivery yields a key disjoint from before_dispatch for same (session, conv)", () => {
|
|
53
|
+
const a = extractPartitionKey(reqOnBeforeDispatch());
|
|
54
|
+
const b = extractPartitionKey(reqOnBeforeMessageDelivery());
|
|
55
|
+
expect(Either.isRight(a) && Either.isRight(b)).toBe(true);
|
|
56
|
+
if (Either.isRight(a) && Either.isRight(b)) {
|
|
57
|
+
// Different keys is the load-bearing invariant — same (S, C) but
|
|
58
|
+
// different hookKind partitions onto independent fibers.
|
|
59
|
+
expect(a.right).not.toBe(b.right);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
it("apps/onJoin yields key with LIFECYCLE_CONVERSATION_SENTINEL", () => {
|
|
63
|
+
const result = extractPartitionKey(reqLifecycle("apps/onJoin"));
|
|
64
|
+
expect(Either.isRight(result)).toBe(true);
|
|
65
|
+
if (Either.isRight(result)) {
|
|
66
|
+
const parts = describePartitionKey(result.right);
|
|
67
|
+
expect(parts.conversationId).toBe(LIFECYCLE_CONVERSATION_SENTINEL);
|
|
68
|
+
expect(parts.method).toBe("apps/onJoin");
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
it("apps/onClose yields key with LIFECYCLE_CONVERSATION_SENTINEL", () => {
|
|
72
|
+
const result = extractPartitionKey(reqLifecycle("apps/onClose"));
|
|
73
|
+
expect(Either.isRight(result)).toBe(true);
|
|
74
|
+
if (Either.isRight(result)) {
|
|
75
|
+
const parts = describePartitionKey(result.right);
|
|
76
|
+
expect(parts.conversationId).toBe(LIFECYCLE_CONVERSATION_SENTINEL);
|
|
77
|
+
expect(parts.method).toBe("apps/onClose");
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
it("apps/onSessionActive yields key with LIFECYCLE_CONVERSATION_SENTINEL", () => {
|
|
81
|
+
const result = extractPartitionKey(reqLifecycle("apps/onSessionActive"));
|
|
82
|
+
expect(Either.isRight(result)).toBe(true);
|
|
83
|
+
if (Either.isRight(result)) {
|
|
84
|
+
const parts = describePartitionKey(result.right);
|
|
85
|
+
expect(parts.conversationId).toBe(LIFECYCLE_CONVERSATION_SENTINEL);
|
|
86
|
+
expect(parts.method).toBe("apps/onSessionActive");
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
it("distinct sessions yield distinct keys for the same method+conv", () => {
|
|
90
|
+
const a = extractPartitionKey(reqOnBeforeDispatch());
|
|
91
|
+
const b = extractPartitionKey({
|
|
92
|
+
id: "rpc-99",
|
|
93
|
+
method: "apps/onBeforeDispatch",
|
|
94
|
+
params: { sessionId: SESSION_B, conversationId: CONV_X },
|
|
95
|
+
});
|
|
96
|
+
expect(Either.isRight(a) && Either.isRight(b)).toBe(true);
|
|
97
|
+
if (Either.isRight(a) && Either.isRight(b)) {
|
|
98
|
+
expect(a.right).not.toBe(b.right);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
it("distinct conversations yield distinct keys for the same method+session", () => {
|
|
102
|
+
const a = extractPartitionKey(reqOnBeforeDispatch());
|
|
103
|
+
const b = extractPartitionKey({
|
|
104
|
+
id: "rpc-99",
|
|
105
|
+
method: "apps/onBeforeDispatch",
|
|
106
|
+
params: { sessionId: SESSION_A, conversationId: CONV_Y },
|
|
107
|
+
});
|
|
108
|
+
expect(Either.isRight(a) && Either.isRight(b)).toBe(true);
|
|
109
|
+
if (Either.isRight(a) && Either.isRight(b)) {
|
|
110
|
+
expect(a.right).not.toBe(b.right);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
describe("extractPartitionKey — failure modes (each `_tag`)", () => {
|
|
115
|
+
it("missing params.sessionId → MalformedPartitionKeyError reason=missing-session-id", () => {
|
|
116
|
+
const result = extractPartitionKey(reqOnBeforeDispatch({ sessionId: undefined }));
|
|
117
|
+
expect(Either.isLeft(result)).toBe(true);
|
|
118
|
+
if (Either.isLeft(result)) {
|
|
119
|
+
expect(result.left._tag).toBe("MalformedPartitionKeyError");
|
|
120
|
+
expect(result.left.reason).toBe("missing-session-id");
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
it("missing params.conversationId on hook method → reason=missing-conversation-id", () => {
|
|
124
|
+
const result = extractPartitionKey(reqOnBeforeDispatch({ conversationId: undefined }));
|
|
125
|
+
expect(Either.isLeft(result)).toBe(true);
|
|
126
|
+
if (Either.isLeft(result)) {
|
|
127
|
+
expect(result.left.reason).toBe("missing-conversation-id");
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
it("unknown method name → reason=unknown-method", () => {
|
|
131
|
+
const result = extractPartitionKey({
|
|
132
|
+
id: "rpc-x",
|
|
133
|
+
method: "apps/notARealMethod",
|
|
134
|
+
params: { sessionId: SESSION_A },
|
|
135
|
+
});
|
|
136
|
+
expect(Either.isLeft(result)).toBe(true);
|
|
137
|
+
if (Either.isLeft(result)) {
|
|
138
|
+
expect(result.left.reason).toBe("unknown-method");
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
it("non-object params → reason=params-shape", () => {
|
|
142
|
+
const result = extractPartitionKey({
|
|
143
|
+
id: "rpc-y",
|
|
144
|
+
method: "apps/onBeforeDispatch",
|
|
145
|
+
params: "not-an-object",
|
|
146
|
+
});
|
|
147
|
+
expect(Either.isLeft(result)).toBe(true);
|
|
148
|
+
if (Either.isLeft(result)) {
|
|
149
|
+
expect(result.left.reason).toBe("params-shape");
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
it("array params → reason=params-shape", () => {
|
|
153
|
+
const result = extractPartitionKey({
|
|
154
|
+
id: "rpc-z",
|
|
155
|
+
method: "apps/onBeforeDispatch",
|
|
156
|
+
params: [SESSION_A, CONV_X],
|
|
157
|
+
});
|
|
158
|
+
expect(Either.isLeft(result)).toBe(true);
|
|
159
|
+
if (Either.isLeft(result)) {
|
|
160
|
+
expect(result.left.reason).toBe("params-shape");
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
it("empty-string sessionId → reason=missing-session-id", () => {
|
|
164
|
+
const result = extractPartitionKey(reqOnBeforeDispatch({ sessionId: "" }));
|
|
165
|
+
expect(Either.isLeft(result)).toBe(true);
|
|
166
|
+
if (Either.isLeft(result)) {
|
|
167
|
+
expect(result.left.reason).toBe("missing-session-id");
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
describe("extractPartitionKey — schema drift guard against `@moltzap/protocol`", () => {
|
|
172
|
+
// Architect plan §3.2 documented the "literal Set, not derived from
|
|
173
|
+
// s2cRpcMethods" choice as a deliberate cycle-avoidance trade. This
|
|
174
|
+
// test is the counter-measure: every wire method the protocol
|
|
175
|
+
// declares must be partitionable. Adding a new entry to
|
|
176
|
+
// `s2cRpcMethods` without updating `LIFECYCLE_METHODS` or
|
|
177
|
+
// `CONVERSATION_BEARING_METHODS` in `s2c-partition-key.ts` compiles
|
|
178
|
+
// cleanly today; this test fails until the routing layer catches up.
|
|
179
|
+
it("every method in s2cRpcMethods is recognised by extractPartitionKey", () => {
|
|
180
|
+
const synthesise = (method) => ({
|
|
181
|
+
id: "rpc-drift",
|
|
182
|
+
method,
|
|
183
|
+
// Provide both routing fields so the only failure mode under
|
|
184
|
+
// test is `unknown-method`, not missing-session-id /
|
|
185
|
+
// missing-conversation-id / params-shape.
|
|
186
|
+
params: { sessionId: SESSION_A, conversationId: CONV_X },
|
|
187
|
+
});
|
|
188
|
+
const offenders = [];
|
|
189
|
+
for (const def of s2cRpcMethods) {
|
|
190
|
+
const result = extractPartitionKey(synthesise(def.name));
|
|
191
|
+
if (Either.isLeft(result)) {
|
|
192
|
+
offenders.push({ method: def.name, reason: result.left.reason });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (offenders.length > 0) {
|
|
196
|
+
expect.fail(`s2c partition extractor rejects ${offenders.length} method(s) declared in @moltzap/protocol's s2cRpcMethods:\n` +
|
|
197
|
+
offenders
|
|
198
|
+
.map((o) => ` - ${o.method} (reason=${o.reason})`)
|
|
199
|
+
.join("\n") +
|
|
200
|
+
`\nUpdate LIFECYCLE_METHODS or CONVERSATION_BEARING_METHODS in ` +
|
|
201
|
+
`packages/client/src/internal/s2c-partition-key.ts so the ` +
|
|
202
|
+
`union covers every entry of s2cRpcMethods.`);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
describe("describePartitionKey — round-trip", () => {
|
|
207
|
+
it("describePartitionKey(extractPartitionKey(req)) preserves sessionId+conversationId+method", () => {
|
|
208
|
+
const req = reqOnBeforeDispatch();
|
|
209
|
+
const key = extractPartitionKey(req);
|
|
210
|
+
expect(Either.isRight(key)).toBe(true);
|
|
211
|
+
if (Either.isRight(key)) {
|
|
212
|
+
const parts = describePartitionKey(key.right);
|
|
213
|
+
expect(parts.sessionId).toBe(SESSION_A);
|
|
214
|
+
expect(parts.conversationId).toBe(CONV_X);
|
|
215
|
+
expect(parts.method).toBe("apps/onBeforeDispatch");
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
it("preserves the lifecycle sentinel for lifecycle methods", () => {
|
|
219
|
+
const req = reqLifecycle("apps/onSessionActive");
|
|
220
|
+
const key = extractPartitionKey(req);
|
|
221
|
+
expect(Either.isRight(key)).toBe(true);
|
|
222
|
+
if (Either.isRight(key)) {
|
|
223
|
+
const parts = describePartitionKey(key.right);
|
|
224
|
+
expect(parts.sessionId).toBe(SESSION_A);
|
|
225
|
+
expect(parts.conversationId).toBe(LIFECYCLE_CONVERSATION_SENTINEL);
|
|
226
|
+
expect(parts.method).toBe("apps/onSessionActive");
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
//# sourceMappingURL=s2c-partition-key.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s2c-partition-key.test.js","sourceRoot":"","sources":["../../../src/internal/__tests__/s2c-partition-key.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s2c-partition-worker.test.d.ts","sourceRoot":"","sources":["../../../src/internal/__tests__/s2c-partition-worker.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for the per-partition worker.
|
|
3
|
+
*
|
|
4
|
+
* Spec: moltzap#356 §8 (test plan, file 2).
|
|
5
|
+
*
|
|
6
|
+
* Tests run the worker in isolation against a synthetic handler. Drive
|
|
7
|
+
* via `Effect.runPromise` with a dedicated `Scope`; assert ordering,
|
|
8
|
+
* non-blocking offer, idle-since transitions, and scope-anchored
|
|
9
|
+
* teardown.
|
|
10
|
+
*/
|
|
11
|
+
import { describe, it, expect } from "vitest";
|
|
12
|
+
import { Deferred, Effect, Exit, Fiber, MutableRef, Ref, Scope } from "effect";
|
|
13
|
+
import { makePartitionWorker } from "../s2c-partition-worker.js";
|
|
14
|
+
const KEY = "test-key";
|
|
15
|
+
const REQ = (id) => ({
|
|
16
|
+
id,
|
|
17
|
+
method: "apps/onBeforeDispatch",
|
|
18
|
+
params: {},
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* Drive a scoped Effect under a fresh Scope. Returns the Effect's
|
|
22
|
+
* value plus the Scope so the caller can close it explicitly to
|
|
23
|
+
* exercise scope-anchored teardown.
|
|
24
|
+
*/
|
|
25
|
+
function withScope(body) {
|
|
26
|
+
return Effect.gen(function* () {
|
|
27
|
+
const scope = yield* Scope.make();
|
|
28
|
+
const result = yield* body(scope);
|
|
29
|
+
yield* Scope.close(scope, Exit.void);
|
|
30
|
+
return result;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Spin until the worker's queue is drained (size === 0). Used to
|
|
35
|
+
* synchronize with the worker fiber having actually taken an item
|
|
36
|
+
* off the queue and started running its handler.
|
|
37
|
+
*/
|
|
38
|
+
function waitUntilQueueDrained(worker) {
|
|
39
|
+
return Effect.gen(function* () {
|
|
40
|
+
for (let i = 0; i < 1000; i++) {
|
|
41
|
+
const size = yield* worker.queueSize;
|
|
42
|
+
if (size === 0)
|
|
43
|
+
return;
|
|
44
|
+
yield* Effect.yieldNow();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
describe("makePartitionWorker — ordering", () => {
|
|
49
|
+
it("preserves FIFO order across N offers to the same worker", async () => {
|
|
50
|
+
const result = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
|
|
51
|
+
const seen = yield* Ref.make([]);
|
|
52
|
+
const allDone = yield* Deferred.make();
|
|
53
|
+
const handle = (req) => Effect.gen(function* () {
|
|
54
|
+
yield* Ref.update(seen, (xs) => [...xs, req.id]);
|
|
55
|
+
const xs = yield* Ref.get(seen);
|
|
56
|
+
if (xs.length === 5) {
|
|
57
|
+
yield* Deferred.succeed(allDone, undefined);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
const worker = yield* makePartitionWorker({
|
|
61
|
+
key: KEY,
|
|
62
|
+
capacity: 16,
|
|
63
|
+
handle,
|
|
64
|
+
scope,
|
|
65
|
+
});
|
|
66
|
+
for (let i = 0; i < 5; i++) {
|
|
67
|
+
yield* worker.offer(REQ(`rpc-${i}`));
|
|
68
|
+
}
|
|
69
|
+
yield* Deferred.await(allDone);
|
|
70
|
+
return yield* Ref.get(seen);
|
|
71
|
+
})));
|
|
72
|
+
expect(result).toEqual(["rpc-0", "rpc-1", "rpc-2", "rpc-3", "rpc-4"]);
|
|
73
|
+
});
|
|
74
|
+
it("handler defects are caught and logged; subsequent offers still run", async () => {
|
|
75
|
+
const result = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
|
|
76
|
+
const seen = yield* Ref.make([]);
|
|
77
|
+
const second = yield* Deferred.make();
|
|
78
|
+
const handle = (req) => Effect.gen(function* () {
|
|
79
|
+
yield* Ref.update(seen, (xs) => [...xs, req.id]);
|
|
80
|
+
if (req.id === "rpc-bad") {
|
|
81
|
+
return yield* Effect.die("synthetic defect");
|
|
82
|
+
}
|
|
83
|
+
if (req.id === "rpc-good") {
|
|
84
|
+
yield* Deferred.succeed(second, undefined);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
const worker = yield* makePartitionWorker({
|
|
88
|
+
key: KEY,
|
|
89
|
+
capacity: 16,
|
|
90
|
+
handle,
|
|
91
|
+
logger: { info: () => { }, warn: () => { }, error: () => { } },
|
|
92
|
+
scope,
|
|
93
|
+
});
|
|
94
|
+
yield* worker.offer(REQ("rpc-bad"));
|
|
95
|
+
yield* worker.offer(REQ("rpc-good"));
|
|
96
|
+
yield* Deferred.await(second);
|
|
97
|
+
return yield* Ref.get(seen);
|
|
98
|
+
})));
|
|
99
|
+
expect(result).toEqual(["rpc-bad", "rpc-good"]);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
describe("makePartitionWorker — backpressure", () => {
|
|
103
|
+
it("offer to full bounded queue fails-fast with PartitionQueueFullError (does NOT suspend)", async () => {
|
|
104
|
+
const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
|
|
105
|
+
// Park every handler on a Deferred so the queue fills.
|
|
106
|
+
const release = yield* Deferred.make();
|
|
107
|
+
const handle = () => Deferred.await(release);
|
|
108
|
+
const capacity = 2;
|
|
109
|
+
const worker = yield* makePartitionWorker({
|
|
110
|
+
key: KEY,
|
|
111
|
+
capacity,
|
|
112
|
+
handle,
|
|
113
|
+
scope,
|
|
114
|
+
});
|
|
115
|
+
// First offer goes to the handler; yield so the worker
|
|
116
|
+
// fiber consumes it and parks on `release`. Then the queue
|
|
117
|
+
// is empty. Fill it: capacity offers land, the (capacity+1)th
|
|
118
|
+
// must fail fast.
|
|
119
|
+
yield* worker.offer(REQ("rpc-1"));
|
|
120
|
+
// Spin until the worker fiber has drained rpc-1 off the
|
|
121
|
+
// queue and parked the handler on `release`. We assert on
|
|
122
|
+
// queueSize === 0 (not idleSince) because `worker.offer`
|
|
123
|
+
// flips idleSince to Busy synchronously, before the worker
|
|
124
|
+
// fiber takes the item.
|
|
125
|
+
yield* waitUntilQueueDrained(worker);
|
|
126
|
+
yield* worker.offer(REQ("rpc-2"));
|
|
127
|
+
yield* worker.offer(REQ("rpc-3"));
|
|
128
|
+
const overflow = yield* Effect.either(worker.offer(REQ("rpc-4")));
|
|
129
|
+
yield* Deferred.succeed(release, undefined);
|
|
130
|
+
return overflow;
|
|
131
|
+
})));
|
|
132
|
+
expect(verdict._tag).toBe("Left");
|
|
133
|
+
if (verdict._tag === "Left") {
|
|
134
|
+
expect(verdict.left._tag).toBe("PartitionQueueFullError");
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
it("offer after Scope close fails with PartitionQueueFullError (queue shut down)", async () => {
|
|
138
|
+
const verdict = await Effect.runPromise(Effect.gen(function* () {
|
|
139
|
+
const scope = yield* Scope.make();
|
|
140
|
+
const handle = () => Effect.void;
|
|
141
|
+
const worker = yield* makePartitionWorker({
|
|
142
|
+
key: KEY,
|
|
143
|
+
capacity: 4,
|
|
144
|
+
handle,
|
|
145
|
+
scope,
|
|
146
|
+
});
|
|
147
|
+
yield* Scope.close(scope, Exit.void);
|
|
148
|
+
// Give the finalizer a chance to run.
|
|
149
|
+
yield* Effect.yieldNow();
|
|
150
|
+
return yield* Effect.either(worker.offer(REQ("rpc-late")));
|
|
151
|
+
}));
|
|
152
|
+
expect(verdict._tag).toBe("Left");
|
|
153
|
+
if (verdict._tag === "Left") {
|
|
154
|
+
expect(verdict.left._tag).toBe("PartitionQueueFullError");
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
describe("makePartitionWorker — idle-since clock", () => {
|
|
159
|
+
it("idleSince is Busy while a request is queued or in-flight", async () => {
|
|
160
|
+
const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
|
|
161
|
+
const release = yield* Deferred.make();
|
|
162
|
+
const handle = () => Deferred.await(release);
|
|
163
|
+
const worker = yield* makePartitionWorker({
|
|
164
|
+
key: KEY,
|
|
165
|
+
capacity: 4,
|
|
166
|
+
handle,
|
|
167
|
+
scope,
|
|
168
|
+
});
|
|
169
|
+
yield* worker.offer(REQ("rpc-1"));
|
|
170
|
+
// Yield so the worker fiber transitions to Busy.
|
|
171
|
+
yield* Effect.yieldNow();
|
|
172
|
+
yield* Effect.yieldNow();
|
|
173
|
+
const state = MutableRef.get(worker.idleSince);
|
|
174
|
+
yield* Deferred.succeed(release, undefined);
|
|
175
|
+
return state._tag;
|
|
176
|
+
})));
|
|
177
|
+
expect(verdict).toBe("Busy");
|
|
178
|
+
});
|
|
179
|
+
it("idleSince transitions to Idle{sinceMs} after the queue drains and the handler returns", async () => {
|
|
180
|
+
const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
|
|
181
|
+
const done = yield* Deferred.make();
|
|
182
|
+
const handle = (_req) => Deferred.succeed(done, undefined).pipe(Effect.asVoid);
|
|
183
|
+
const fakeNow = yield* Ref.make(1000);
|
|
184
|
+
const clock = () => Effect.runSync(Ref.get(fakeNow));
|
|
185
|
+
const worker = yield* makePartitionWorker({
|
|
186
|
+
key: KEY,
|
|
187
|
+
capacity: 4,
|
|
188
|
+
handle,
|
|
189
|
+
clock,
|
|
190
|
+
scope,
|
|
191
|
+
});
|
|
192
|
+
// Bump clock so the post-drain Idle.sinceMs is observably new.
|
|
193
|
+
yield* Ref.set(fakeNow, 5000);
|
|
194
|
+
yield* worker.offer(REQ("rpc-1"));
|
|
195
|
+
yield* Deferred.await(done);
|
|
196
|
+
// Yield so the worker's post-handler `MutableRef.set(Idle, …)`
|
|
197
|
+
// commits before we observe.
|
|
198
|
+
yield* Effect.yieldNow();
|
|
199
|
+
yield* Effect.yieldNow();
|
|
200
|
+
return MutableRef.get(worker.idleSince);
|
|
201
|
+
})));
|
|
202
|
+
expect(verdict._tag).toBe("Idle");
|
|
203
|
+
if (verdict._tag === "Idle") {
|
|
204
|
+
expect(verdict.sinceMs).toBe(5000);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
it("idleSince resets to Busy when a new request is offered", async () => {
|
|
208
|
+
const verdict = await Effect.runPromise(withScope((scope) => Effect.gen(function* () {
|
|
209
|
+
const release = yield* Deferred.make();
|
|
210
|
+
const handle = () => Deferred.await(release);
|
|
211
|
+
const worker = yield* makePartitionWorker({
|
|
212
|
+
key: KEY,
|
|
213
|
+
capacity: 4,
|
|
214
|
+
handle,
|
|
215
|
+
scope,
|
|
216
|
+
});
|
|
217
|
+
yield* worker.offer(REQ("rpc-1"));
|
|
218
|
+
yield* Effect.yieldNow();
|
|
219
|
+
const busyState = MutableRef.get(worker.idleSince);
|
|
220
|
+
yield* Deferred.succeed(release, undefined);
|
|
221
|
+
return busyState._tag;
|
|
222
|
+
})));
|
|
223
|
+
expect(verdict).toBe("Busy");
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
describe("makePartitionWorker — scope teardown", () => {
|
|
227
|
+
it("Scope.close interrupts the worker fiber and shuts the queue (no hang)", async () => {
|
|
228
|
+
const fiberDone = await Effect.runPromise(Effect.gen(function* () {
|
|
229
|
+
const scope = yield* Scope.make();
|
|
230
|
+
const handle = () => Effect.void;
|
|
231
|
+
const worker = yield* makePartitionWorker({
|
|
232
|
+
key: KEY,
|
|
233
|
+
capacity: 4,
|
|
234
|
+
handle,
|
|
235
|
+
scope,
|
|
236
|
+
});
|
|
237
|
+
yield* Scope.close(scope, Exit.void);
|
|
238
|
+
// Wait for the fiber to settle. `Fiber.await` returns when the
|
|
239
|
+
// fiber exits — for a healthy teardown this is immediate.
|
|
240
|
+
const exit = yield* Fiber.await(worker.fiber);
|
|
241
|
+
return Exit.isInterrupted(exit) || Exit.isSuccess(exit);
|
|
242
|
+
}));
|
|
243
|
+
expect(fiberDone).toBe(true);
|
|
244
|
+
});
|
|
245
|
+
it("Scope.close while handler is suspended on Deferred.await interrupts cleanly", async () => {
|
|
246
|
+
const fiberDone = await Effect.runPromise(Effect.gen(function* () {
|
|
247
|
+
const scope = yield* Scope.make();
|
|
248
|
+
const release = yield* Deferred.make();
|
|
249
|
+
const handle = () => Deferred.await(release);
|
|
250
|
+
const worker = yield* makePartitionWorker({
|
|
251
|
+
key: KEY,
|
|
252
|
+
capacity: 4,
|
|
253
|
+
handle,
|
|
254
|
+
scope,
|
|
255
|
+
});
|
|
256
|
+
yield* worker.offer(REQ("rpc-suspended"));
|
|
257
|
+
yield* Effect.yieldNow();
|
|
258
|
+
// Close while the handler is parked on Deferred.await. The
|
|
259
|
+
// worker fiber must interrupt cleanly without hanging.
|
|
260
|
+
yield* Scope.close(scope, Exit.void);
|
|
261
|
+
const exit = yield* Fiber.await(worker.fiber);
|
|
262
|
+
return Exit.isInterrupted(exit) || Exit.isSuccess(exit);
|
|
263
|
+
}));
|
|
264
|
+
expect(fiberDone).toBe(true);
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
//# sourceMappingURL=s2c-partition-worker.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s2c-partition-worker.test.js","sourceRoot":"","sources":["../../../src/internal/__tests__/s2c-partition-worker.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s2c-partitioned-dispatcher-real-ws.test.d.ts","sourceRoot":"","sources":["../../../src/internal/__tests__/s2c-partitioned-dispatcher-real-ws.test.ts"],"names":[],"mappings":""}
|