@livestore/webmesh 0.4.0-dev.9 → 0.5.0-dev.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/README.md +5 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/channel/direct-channel-internal.d.ts +2 -3
- package/dist/channel/direct-channel-internal.d.ts.map +1 -1
- package/dist/channel/direct-channel-internal.js +35 -38
- package/dist/channel/direct-channel-internal.js.map +1 -1
- package/dist/channel/direct-channel.d.ts.map +1 -1
- package/dist/channel/direct-channel.js +22 -23
- package/dist/channel/direct-channel.js.map +1 -1
- package/dist/channel/proxy-channel.d.ts +29 -5
- package/dist/channel/proxy-channel.d.ts.map +1 -1
- package/dist/channel/proxy-channel.js +87 -37
- package/dist/channel/proxy-channel.js.map +1 -1
- package/dist/common.d.ts +33 -35
- package/dist/common.d.ts.map +1 -1
- package/dist/common.js +7 -7
- package/dist/common.js.map +1 -1
- package/dist/mesh-schema.d.ts +262 -136
- package/dist/mesh-schema.d.ts.map +1 -1
- package/dist/mesh-schema.js +45 -44
- package/dist/mesh-schema.js.map +1 -1
- package/dist/node.d.ts +12 -6
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +47 -44
- package/dist/node.js.map +1 -1
- package/dist/node.test.js +253 -63
- package/dist/node.test.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js.map +1 -1
- package/dist/websocket-edge.d.ts +20 -18
- package/dist/websocket-edge.d.ts.map +1 -1
- package/dist/websocket-edge.js +33 -41
- package/dist/websocket-edge.js.map +1 -1
- package/dist/websocket-edge.test.d.ts +7 -0
- package/dist/websocket-edge.test.d.ts.map +1 -0
- package/dist/websocket-edge.test.js +74 -0
- package/dist/websocket-edge.test.js.map +1 -0
- package/dist/worker/mod.d.ts +24 -0
- package/dist/worker/mod.d.ts.map +1 -0
- package/dist/worker/mod.js +44 -0
- package/dist/worker/mod.js.map +1 -0
- package/dist/worker/schema.d.ts +10 -0
- package/dist/worker/schema.d.ts.map +1 -0
- package/dist/worker/schema.js +7 -0
- package/dist/worker/schema.js.map +1 -0
- package/package.json +48 -12
- package/src/channel/direct-channel-internal.ts +41 -47
- package/src/channel/direct-channel.ts +28 -25
- package/src/channel/proxy-channel.ts +120 -57
- package/src/common.ts +9 -7
- package/src/mesh-schema.ts +34 -33
- package/src/node.test.ts +356 -80
- package/src/node.ts +63 -55
- package/src/utils.ts +3 -3
- package/src/websocket-edge.test.ts +98 -0
- package/src/websocket-edge.ts +52 -48
- package/src/worker/mod.ts +89 -0
- package/src/worker/schema.ts +8 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { Effect, Queue, Scope, WebChannel } from '@livestore/utils/effect';
|
|
1
|
+
import { type PubSub, Effect, Queue, Scope, WebChannel } from '@livestore/utils/effect';
|
|
3
2
|
import { type ChannelName, type MeshNodeName, type MessageQueueItem } from '../common.ts';
|
|
4
3
|
import * as MeshSchema from '../mesh-schema.ts';
|
|
5
4
|
export interface MakeDirectChannelArgs {
|
|
@@ -20,7 +19,7 @@ export interface MakeDirectChannelArgs {
|
|
|
20
19
|
export declare const makeDirectChannelInternal: ({ nodeName, incomingPacketsQueue, target, checkTransferableEdges, channelName, schema: schema_, sendPacket, channelVersion, scope, sourceId, }: MakeDirectChannelArgs & {
|
|
21
20
|
channelVersion: number;
|
|
22
21
|
/** We're passing in the closeable scope from the wrapping direct channel */
|
|
23
|
-
scope: Scope.
|
|
22
|
+
scope: Scope.Closeable;
|
|
24
23
|
sourceId: string;
|
|
25
24
|
}) => Effect.Effect<WebChannel.WebChannel<any, any>, typeof MeshSchema.DirectChannelResponseNoTransferables.Type, Scope.Scope>;
|
|
26
25
|
//# sourceMappingURL=direct-channel-internal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"direct-channel-internal.d.ts","sourceRoot":"","sources":["../../src/channel/direct-channel-internal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"direct-channel-internal.d.ts","sourceRoot":"","sources":["../../src/channel/direct-channel-internal.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,MAAM,EAEX,MAAM,EAIN,KAAK,EAEL,KAAK,EAEL,UAAU,EACX,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAA0B,MAAM,cAAc,CAAA;AACjH,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAA;AAE/C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,YAAY,CAAA;IACtB,kDAAkD;IAClD,oBAAoB,EAAE,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAA;IACnD,sBAAsB,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IACnD,WAAW,EAAE,WAAW,CAAA;IACxB,MAAM,EAAE,YAAY,CAAA;IACpB,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,UAAU,CAAC,mBAAmB,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACvF,sBAAsB,EAAE,CACtB,MAAM,EAAE,OAAO,UAAU,CAAC,mBAAmB,CAAC,IAAI,KAC/C,OAAO,UAAU,CAAC,oCAAoC,CAAC,IAAI,GAAG,SAAS,CAAA;IAC5E,MAAM,EAAE,UAAU,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CACpD;AAOD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GAAI,gJAWvC,qBAAqB,GAAG;IACzB,cAAc,EAAE,MAAM,CAAA;IACtB,4EAA4E;IAC5E,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;CACjB,KAAG,MAAM,CAAC,MAAM,CACf,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAC/B,OAAO,UAAU,CAAC,oCAAoC,CAAC,IAAI,EAC3D,KAAK,CAAC,KAAK,CAiS0D,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { casesHandled, shouldNeverHappen } from '@livestore/utils';
|
|
2
|
-
import { Deferred, Effect, Exit,
|
|
2
|
+
import { Deferred, Effect, Exit, Fiber, Predicate, Queue, Schema, Scope, Stream, WebChannel, } from '@livestore/utils/effect';
|
|
3
3
|
import { packetAsOtelAttributes } from "../common.js";
|
|
4
4
|
import * as MeshSchema from "../mesh-schema.js";
|
|
5
5
|
const makeDeferredResult = (Deferred.make);
|
|
@@ -12,24 +12,22 @@ export const makeDirectChannelInternal = ({ nodeName, incomingPacketsQueue, targ
|
|
|
12
12
|
// Effect.spanEvent(`shutdown:${exit._tag === 'Success' ? 'Success' : Cause.pretty(exit.cause)}`),
|
|
13
13
|
// )
|
|
14
14
|
const deferred = yield* makeDeferredResult();
|
|
15
|
-
const span = yield* OtelTracer.currentOtelSpan.pipe(Effect.catchAll(() => Effect.succeed(undefined)));
|
|
16
|
-
// const span = {
|
|
17
|
-
// addEvent: (...msg: any[]) => console.log(`${nodeName}→${channelName}→${target}[${channelVersion}]`, ...msg),
|
|
18
|
-
// }
|
|
19
15
|
const schema = {
|
|
20
|
-
send: Schema.Union(schema_.send, MeshSchema.DirectChannelPing, MeshSchema.DirectChannelPong),
|
|
21
|
-
listen: Schema.Union(schema_.listen, MeshSchema.DirectChannelPing, MeshSchema.DirectChannelPong),
|
|
16
|
+
send: Schema.Union([schema_.send, MeshSchema.DirectChannelPing, MeshSchema.DirectChannelPong]),
|
|
17
|
+
listen: Schema.Union([schema_.listen, MeshSchema.DirectChannelPing, MeshSchema.DirectChannelPong]),
|
|
22
18
|
};
|
|
23
19
|
const channelStateRef = {
|
|
24
20
|
current: { _tag: 'Initial' },
|
|
25
21
|
};
|
|
26
22
|
const processMessagePacket = ({ packet, respondToSender }) => Effect.gen(function* () {
|
|
27
23
|
const channelState = channelStateRef.current;
|
|
28
|
-
|
|
24
|
+
yield* Effect.spanEvent(`process:${packet._tag}`, {
|
|
29
25
|
channelState: channelState._tag,
|
|
30
26
|
packetId: packet.id,
|
|
31
27
|
packetReqId: packet.reqId,
|
|
32
|
-
|
|
28
|
+
...(Predicate.hasProperty('channelVersion')(packet) === true
|
|
29
|
+
? { packetChannelVersion: packet.channelVersion }
|
|
30
|
+
: {}),
|
|
33
31
|
});
|
|
34
32
|
// const reqIdStr =
|
|
35
33
|
// Predicate.hasProperty('reqId')(packet) && packet.reqId !== undefined ? ` for ${packet.reqId}` : ''
|
|
@@ -45,7 +43,7 @@ export const makeDirectChannelInternal = ({ nodeName, incomingPacketsQueue, targ
|
|
|
45
43
|
// If the other side has a higher version, we need to close this channel and
|
|
46
44
|
// recreate it with the new version
|
|
47
45
|
if (packet.channelVersion > channelVersion) {
|
|
48
|
-
|
|
46
|
+
yield* Effect.spanEvent(`incoming packet has higher version (${packet.channelVersion}), closing channel`);
|
|
49
47
|
yield* Scope.close(scope, Exit.succeed('higher-version-expected'));
|
|
50
48
|
// TODO include expected version in the error so the channel gets recreated with the new version
|
|
51
49
|
return 'close';
|
|
@@ -63,7 +61,7 @@ export const makeDirectChannelInternal = ({ nodeName, incomingPacketsQueue, targ
|
|
|
63
61
|
remainingHops: packet.hops,
|
|
64
62
|
reqId: undefined,
|
|
65
63
|
});
|
|
66
|
-
|
|
64
|
+
yield* Effect.spanEvent(`incoming packet has lower version (${packet.channelVersion}), sending request to reconnect (${newPacket.id})`);
|
|
67
65
|
yield* sendPacket(newPacket);
|
|
68
66
|
return;
|
|
69
67
|
}
|
|
@@ -74,7 +72,7 @@ export const makeDirectChannelInternal = ({ nodeName, incomingPacketsQueue, targ
|
|
|
74
72
|
else {
|
|
75
73
|
// In case the instance of the source has changed, we need to close the channel
|
|
76
74
|
// and reconnect with a new channel
|
|
77
|
-
|
|
75
|
+
yield* Effect.spanEvent(`force-new-channel`);
|
|
78
76
|
yield* Scope.close(scope, Exit.succeed('force-new-channel'));
|
|
79
77
|
return 'close';
|
|
80
78
|
}
|
|
@@ -100,12 +98,12 @@ export const makeDirectChannelInternal = ({ nodeName, incomingPacketsQueue, targ
|
|
|
100
98
|
remainingHops: packet.hops,
|
|
101
99
|
reqId: packet.id,
|
|
102
100
|
});
|
|
103
|
-
|
|
101
|
+
yield* Effect.spanEvent(`Re-sending new request (${newRequestPacket.id}) for incoming request (${packet.id})`);
|
|
104
102
|
yield* sendPacket(newRequestPacket);
|
|
105
103
|
}
|
|
106
104
|
const isWinner = nodeName > target;
|
|
107
|
-
if (isWinner) {
|
|
108
|
-
|
|
105
|
+
if (isWinner === true) {
|
|
106
|
+
yield* Effect.spanEvent(`winner side: creating direct channel and sending response`);
|
|
109
107
|
const mc = new MessageChannel();
|
|
110
108
|
// We're using a direct channel with acks here to make sure messages are not lost
|
|
111
109
|
// which might happen during re-edge scenarios.
|
|
@@ -127,21 +125,19 @@ export const makeDirectChannelInternal = ({ nodeName, incomingPacketsQueue, targ
|
|
|
127
125
|
channelVersion,
|
|
128
126
|
}));
|
|
129
127
|
channelStateRef.current = { _tag: 'winner:ResponseSent', channel, otherSourceId: packet.sourceId };
|
|
130
|
-
// span?.addEvent(`winner side: waiting for ping`)
|
|
131
128
|
// Now we wait for the other side to respond via the channel
|
|
132
|
-
yield* channel.listen.pipe(Stream.
|
|
133
|
-
// span?.addEvent(`winner side: sending pong`)
|
|
129
|
+
yield* channel.listen.pipe(Stream.mapEffect(Effect.fromResult), Stream.filter(Schema.is(MeshSchema.DirectChannelPing)), Stream.take(1), Stream.runDrain);
|
|
134
130
|
yield* channel.send(MeshSchema.DirectChannelPong.make({}));
|
|
135
|
-
|
|
131
|
+
yield* Effect.spanEvent(`winner side: established`);
|
|
136
132
|
channelStateRef.current = { _tag: 'Established', otherSourceId: packet.sourceId };
|
|
137
133
|
yield* Deferred.succeed(deferred, channel);
|
|
138
134
|
}
|
|
139
135
|
else {
|
|
140
|
-
|
|
136
|
+
yield* Effect.spanEvent(`loser side: waiting for response`);
|
|
141
137
|
// Wait for `DirectChannelResponseSuccess` packet
|
|
142
138
|
channelStateRef.current = { _tag: 'loser:WaitingForResponse', otherSourceId: packet.sourceId };
|
|
143
139
|
}
|
|
144
|
-
|
|
140
|
+
return;
|
|
145
141
|
}
|
|
146
142
|
case 'DirectChannelResponseSuccess': {
|
|
147
143
|
if (channelState._tag !== 'loser:WaitingForResponse') {
|
|
@@ -153,8 +149,7 @@ export const makeDirectChannelInternal = ({ nodeName, incomingPacketsQueue, targ
|
|
|
153
149
|
schema,
|
|
154
150
|
debugId: channelVersion,
|
|
155
151
|
}).pipe(Effect.andThen(WebChannel.toOpenChannel));
|
|
156
|
-
const waitForPongFiber = yield* channel.listen.pipe(Stream.
|
|
157
|
-
// span?.addEvent(`loser side: sending ping`)
|
|
152
|
+
const waitForPongFiber = yield* channel.listen.pipe(Stream.mapEffect(Effect.fromResult), Stream.filter(Schema.is(MeshSchema.DirectChannelPong)), Stream.take(1), Stream.runDrain, Effect.forkChild);
|
|
158
153
|
// There seems to be some scenario where the initial ping message is lost.
|
|
159
154
|
// As a workaround until we find the root cause, we're retrying the ping a few times.
|
|
160
155
|
// TODO write a test that reproduces this issue and fix the root cause ()
|
|
@@ -162,9 +157,8 @@ export const makeDirectChannelInternal = ({ nodeName, incomingPacketsQueue, targ
|
|
|
162
157
|
yield* channel
|
|
163
158
|
.send(MeshSchema.DirectChannelPing.make({}))
|
|
164
159
|
.pipe(Effect.timeout(10), Effect.retry({ times: 2 }));
|
|
165
|
-
|
|
166
|
-
yield*
|
|
167
|
-
span?.addEvent(`loser side: established`);
|
|
160
|
+
yield* Fiber.join(waitForPongFiber);
|
|
161
|
+
yield* Effect.spanEvent(`loser side: established`);
|
|
168
162
|
channelStateRef.current = { _tag: 'Established', otherSourceId: channelState.otherSourceId };
|
|
169
163
|
yield* Deferred.succeed(deferred, channel);
|
|
170
164
|
return;
|
|
@@ -176,16 +170,6 @@ export const makeDirectChannelInternal = ({ nodeName, incomingPacketsQueue, targ
|
|
|
176
170
|
}).pipe(Effect.withSpan(`handleMessagePacket:${packet._tag}:${packet.source}→${packet.target}`, {
|
|
177
171
|
attributes: packetAsOtelAttributes(packet),
|
|
178
172
|
}));
|
|
179
|
-
yield* Effect.gen(function* () {
|
|
180
|
-
while (true) {
|
|
181
|
-
const packet = yield* Queue.take(incomingPacketsQueue);
|
|
182
|
-
const res = yield* processMessagePacket(packet);
|
|
183
|
-
// We want to give requests another chance to be processed
|
|
184
|
-
if (res === 'close') {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}).pipe(Effect.interruptible, Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
189
173
|
const channelState = channelStateRef.current;
|
|
190
174
|
if (channelState._tag !== 'Initial') {
|
|
191
175
|
return shouldNeverHappen(`Expected channel to be in Initial state, but was in ${channelState._tag} state`);
|
|
@@ -208,10 +192,23 @@ export const makeDirectChannelInternal = ({ nodeName, incomingPacketsQueue, targ
|
|
|
208
192
|
return yield* Effect.fail(noTransferableResponse);
|
|
209
193
|
}
|
|
210
194
|
yield* sendPacket(packet);
|
|
211
|
-
|
|
195
|
+
yield* Effect.spanEvent(`initial edge request sent (${packet.id})`);
|
|
212
196
|
});
|
|
213
197
|
yield* edgeRequest;
|
|
214
|
-
|
|
198
|
+
// Start draining only after `edgeRequest` moved the channel to `RequestSent`. Under Effect v4
|
|
199
|
+
// an eagerly forked processor can otherwise handle an already-buffered packet while still
|
|
200
|
+
// `Initial`.
|
|
201
|
+
yield* Effect.gen(function* () {
|
|
202
|
+
while (true) {
|
|
203
|
+
const packet = yield* Queue.take(incomingPacketsQueue);
|
|
204
|
+
const res = yield* processMessagePacket(packet);
|
|
205
|
+
// We want to give requests another chance to be processed
|
|
206
|
+
if (res === 'close') {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}).pipe(Effect.interruptible, Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
211
|
+
const channel = yield* Deferred.await(deferred);
|
|
215
212
|
return channel;
|
|
216
213
|
}).pipe(Effect.withSpanScoped(`makeDirectChannel:${channelVersion}`));
|
|
217
214
|
//# sourceMappingURL=direct-channel-internal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"direct-channel-internal.js","sourceRoot":"","sources":["../../src/channel/direct-channel-internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"direct-channel-internal.js","sourceRoot":"","sources":["../../src/channel/direct-channel-internal.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"direct-channel.d.ts","sourceRoot":"","sources":["../../src/channel/direct-channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EACR,MAAM,
|
|
1
|
+
{"version":3,"file":"direct-channel.d.ts","sourceRoot":"","sources":["../../src/channel/direct-channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EACR,MAAM,EAQN,KAAK,EAGL,UAAU,EACX,MAAM,yBAAyB,CAAA;AAIhC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAGzE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,GAAI,8HAS/B,qBAAqB;gBA0LU,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;;sBAI9D,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Cause, Deferred, Effect,
|
|
1
|
+
import { Cause, Deferred, Effect, Fiber, Result, Exit, Option, Queue, References, Schema, Scope, Stream, TxQueue, WebChannel, } from '@livestore/utils/effect';
|
|
2
2
|
import { nanoid } from '@livestore/utils/nanoid';
|
|
3
3
|
import * as WebmeshSchema from "../mesh-schema.js";
|
|
4
4
|
import { makeDirectChannelInternal } from "./direct-channel-internal.js";
|
|
@@ -21,7 +21,7 @@ export const makeDirectChannel = ({ schema, newEdgeAvailablePubSub, channelName,
|
|
|
21
21
|
/** Only used to identify whether a source is the same instance to know when to reconnect */
|
|
22
22
|
const sourceId = nanoid();
|
|
23
23
|
const listenQueue = yield* Queue.unbounded();
|
|
24
|
-
const sendQueue = yield*
|
|
24
|
+
const sendQueue = yield* TxQueue.unbounded();
|
|
25
25
|
const initialEdgeDeferred = yield* Deferred.make();
|
|
26
26
|
const debugInfo = {
|
|
27
27
|
pendingSends: 0,
|
|
@@ -30,7 +30,7 @@ export const makeDirectChannel = ({ schema, newEdgeAvailablePubSub, channelName,
|
|
|
30
30
|
isConnected: false,
|
|
31
31
|
innerChannelRef: { current: undefined },
|
|
32
32
|
};
|
|
33
|
-
|
|
33
|
+
//#region reconnect-loop
|
|
34
34
|
yield* Effect.gen(function* () {
|
|
35
35
|
const resultDeferred = yield* Deferred.make();
|
|
36
36
|
while (true) {
|
|
@@ -55,7 +55,7 @@ export const makeDirectChannel = ({ schema, newEdgeAvailablePubSub, channelName,
|
|
|
55
55
|
* - we'll use to fork the message channel in which allows us to interrupt it later
|
|
56
56
|
* - We need to make sure that "interruption" isn't "bubbling out"
|
|
57
57
|
*/
|
|
58
|
-
const waitForNewEdgeFiber = yield* Stream.fromPubSub(newEdgeAvailablePubSub).pipe(Stream.tap((edgeName) => Effect.spanEvent(`new-conn:${edgeName}`)), Stream.take(1), Stream.runDrain, Effect.as('new-edge'), Effect.
|
|
58
|
+
const waitForNewEdgeFiber = yield* Stream.fromPubSub(newEdgeAvailablePubSub).pipe(Stream.tap((edgeName) => Effect.spanEvent(`new-conn:${edgeName}`)), Stream.take(1), Stream.runDrain, Effect.as('new-edge'), Effect.forkChild);
|
|
59
59
|
const makeChannel = makeDirectChannelInternal({
|
|
60
60
|
nodeName,
|
|
61
61
|
sourceId,
|
|
@@ -68,23 +68,22 @@ export const makeDirectChannel = ({ schema, newEdgeAvailablePubSub, channelName,
|
|
|
68
68
|
newEdgeAvailablePubSub,
|
|
69
69
|
sendPacket,
|
|
70
70
|
scope: makeDirectChannelScope,
|
|
71
|
-
}).pipe(Scope.
|
|
72
|
-
// Given we only
|
|
71
|
+
}).pipe(Scope.provide(makeDirectChannelScope), Effect.forkIn(makeDirectChannelScope),
|
|
72
|
+
// Given we only await the exit later when observing the fiber,
|
|
73
73
|
// we don't want Effect to produce a "unhandled error" log message
|
|
74
|
-
Effect.
|
|
75
|
-
const raceResult = yield* Effect.raceFirst(makeChannel,
|
|
74
|
+
Effect.provideService(References.UnhandledLogLevel, undefined));
|
|
75
|
+
const raceResult = yield* Effect.raceFirst(makeChannel, Fiber.join(waitForNewEdgeFiber));
|
|
76
76
|
if (raceResult === 'new-edge') {
|
|
77
77
|
yield* Scope.close(makeDirectChannelScope, Exit.fail('new-edge'));
|
|
78
78
|
// We'll try again
|
|
79
79
|
}
|
|
80
80
|
else {
|
|
81
|
-
const channelExit = yield*
|
|
81
|
+
const channelExit = yield* Fiber.await(raceResult);
|
|
82
82
|
if (channelExit._tag === 'Failure') {
|
|
83
83
|
yield* Scope.close(makeDirectChannelScope, channelExit);
|
|
84
|
-
if (Cause.
|
|
85
|
-
Schema.is(WebmeshSchema.DirectChannelResponseNoTransferables)(channelExit.cause.error)) {
|
|
84
|
+
if (Option.exists(Cause.findErrorOption(channelExit.cause), (error) => Schema.is(WebmeshSchema.DirectChannelResponseNoTransferables)(error)) === true) {
|
|
86
85
|
// Only retry when there is a new edge available
|
|
87
|
-
yield*
|
|
86
|
+
yield* Effect.exit(Fiber.join(waitForNewEdgeFiber));
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
else {
|
|
@@ -95,46 +94,46 @@ export const makeDirectChannel = ({ schema, newEdgeAvailablePubSub, channelName,
|
|
|
95
94
|
}
|
|
96
95
|
}
|
|
97
96
|
// Now we wait until the first channel is established
|
|
98
|
-
const { channel, makeDirectChannelScope, channelVersion } = yield* resultDeferred;
|
|
97
|
+
const { channel, makeDirectChannelScope, channelVersion } = yield* Deferred.await(resultDeferred);
|
|
99
98
|
yield* Effect.spanEvent(`Connected#${channelVersion}`);
|
|
100
99
|
debugInfo.isConnected = true;
|
|
101
100
|
debugInfo.innerChannelRef.current = channel;
|
|
102
101
|
yield* Deferred.succeed(initialEdgeDeferred, void 0);
|
|
103
102
|
// We'll now forward all incoming messages to the listen queue
|
|
104
|
-
yield* channel.listen.pipe(Stream.
|
|
103
|
+
yield* channel.listen.pipe(Stream.mapEffect(Effect.fromResult),
|
|
105
104
|
// Stream.tap((msg) => Effect.log(`${target}→${channelName}→${nodeName}:message:${msg.message}`)),
|
|
106
|
-
Stream.
|
|
105
|
+
Stream.tapArray((array) => Queue.offerAll(listenQueue, array)), Stream.runDrain, Effect.tapCauseLogPretty, Effect.forkIn(makeDirectChannelScope));
|
|
107
106
|
yield* Effect.gen(function* () {
|
|
108
107
|
while (true) {
|
|
109
|
-
const [msg, deferred] = yield*
|
|
108
|
+
const [msg, deferred] = yield* TxQueue.peek(sendQueue);
|
|
110
109
|
// NOTE we don't need an explicit retry flow here since in case of the channel being closed,
|
|
111
110
|
// the send will never succeed. Meanwhile the send-loop fiber will be interrupted and
|
|
112
111
|
// given we only peeked at the queue, the message to send is still there.
|
|
113
112
|
yield* channel.send(msg);
|
|
114
113
|
yield* Deferred.succeed(deferred, void 0);
|
|
115
|
-
yield*
|
|
114
|
+
yield* TxQueue.take(sendQueue); // Remove the message from the queue
|
|
116
115
|
}
|
|
117
116
|
}).pipe(Effect.forkIn(makeDirectChannelScope));
|
|
118
117
|
// Wait until the channel is closed and then try to reconnect
|
|
119
|
-
yield* channel.closedDeferred;
|
|
118
|
+
yield* Deferred.await(channel.closedDeferred);
|
|
120
119
|
yield* Scope.close(makeDirectChannelScope, Exit.succeed('channel-closed'));
|
|
121
120
|
yield* Effect.spanEvent(`Disconnected#${channelVersion}`);
|
|
122
121
|
debugInfo.isConnected = false;
|
|
123
122
|
debugInfo.innerChannelRef.current = undefined;
|
|
124
123
|
}).pipe(Effect.scoped, // Additionally scoping here to clean up finalizers after each loop run
|
|
125
124
|
Effect.forever, Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
126
|
-
|
|
125
|
+
//#endregion reconnect-loop
|
|
127
126
|
const parentSpan = yield* Effect.currentSpan.pipe(Effect.orDie);
|
|
128
127
|
const send = (message) => Effect.gen(function* () {
|
|
129
128
|
const sentDeferred = yield* Deferred.make();
|
|
130
129
|
debugInfo.pendingSends++;
|
|
131
130
|
debugInfo.totalSends++;
|
|
132
|
-
yield*
|
|
133
|
-
yield* sentDeferred;
|
|
131
|
+
yield* TxQueue.offer(sendQueue, [message, sentDeferred]);
|
|
132
|
+
yield* Deferred.await(sentDeferred);
|
|
134
133
|
debugInfo.pendingSends--;
|
|
135
134
|
}).pipe(Effect.scoped, Effect.withParentSpan(parentSpan));
|
|
136
|
-
const listen = Stream.fromQueue(listenQueue
|
|
137
|
-
const closedDeferred = yield* Deferred.make()
|
|
135
|
+
const listen = Stream.fromQueue(listenQueue).pipe(Stream.rechunk(1), Stream.map(Result.succeed));
|
|
136
|
+
const closedDeferred = yield* Effect.acquireRelease(Deferred.make(), Deferred.done(Exit.void));
|
|
138
137
|
const webChannel = {
|
|
139
138
|
[WebChannel.WebChannelSymbol]: WebChannel.WebChannelSymbol,
|
|
140
139
|
send,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"direct-channel.js","sourceRoot":"","sources":["../../src/channel/direct-channel.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,QAAQ,EACR,MAAM,EACN,MAAM,EACN,IAAI,EACJ,MAAM,EACN,KAAK,EACL,MAAM,EACN,KAAK,EACL,MAAM,EACN,
|
|
1
|
+
{"version":3,"file":"direct-channel.js","sourceRoot":"","sources":["../../src/channel/direct-channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,29 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { Effect, Queue, Schema, Scope, WebChannel } from '@livestore/utils/effect';
|
|
1
|
+
import { type PubSub, Effect, Queue, Schema, Scope, WebChannel } from '@livestore/utils/effect';
|
|
3
2
|
import { type ChannelName, type MeshNodeName, type ProxyQueueItem } from '../common.ts';
|
|
4
3
|
import * as MeshSchema from '../mesh-schema.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Simulation parameters for proxy channel operations.
|
|
6
|
+
* Used for testing race conditions and timing-sensitive behavior.
|
|
7
|
+
*
|
|
8
|
+
* Each parameter represents a delay (in ms) injected at a specific point in the code.
|
|
9
|
+
* Values are bounded 0-500ms to prevent tests from running too long.
|
|
10
|
+
*/
|
|
11
|
+
export declare const ProxyChannelSimulationParams: Schema.Struct<{
|
|
12
|
+
/**
|
|
13
|
+
* Delays related to receiving and processing payload messages
|
|
14
|
+
*/
|
|
15
|
+
readonly onPayload: Schema.Struct<{
|
|
16
|
+
/** Delay before sending the ACK response (simulates slow ACK send) */
|
|
17
|
+
readonly beforeAckSend: Schema.Int;
|
|
18
|
+
/** Delay after forking the ACK send, before adding message to listen queue */
|
|
19
|
+
readonly afterAckFork: Schema.Int;
|
|
20
|
+
/** Delay after adding message to listen queue */
|
|
21
|
+
readonly afterListenQueueOffer: Schema.Int;
|
|
22
|
+
}>;
|
|
23
|
+
}>;
|
|
24
|
+
export type ProxyChannelSimulationParams = typeof ProxyChannelSimulationParams.Type;
|
|
25
|
+
/** Default simulation params with no delays */
|
|
26
|
+
export declare const defaultSimulationParams: ProxyChannelSimulationParams;
|
|
5
27
|
interface MakeProxyChannelArgs {
|
|
6
28
|
queue: Queue.Queue<ProxyQueueItem>;
|
|
7
29
|
nodeName: MeshNodeName;
|
|
@@ -10,10 +32,12 @@ interface MakeProxyChannelArgs {
|
|
|
10
32
|
channelName: ChannelName;
|
|
11
33
|
target: MeshNodeName;
|
|
12
34
|
schema: {
|
|
13
|
-
send: Schema.
|
|
14
|
-
listen: Schema.
|
|
35
|
+
send: Schema.Codec<any, any>;
|
|
36
|
+
listen: Schema.Codec<any, any>;
|
|
15
37
|
};
|
|
38
|
+
/** Optional simulation parameters for testing timing-sensitive behavior */
|
|
39
|
+
simulation?: ProxyChannelSimulationParams;
|
|
16
40
|
}
|
|
17
|
-
export declare const makeProxyChannel: ({ queue, nodeName, newEdgeAvailablePubSub, sendPacket, target, channelName, schema, }: MakeProxyChannelArgs) => Effect.Effect<WebChannel.WebChannel<any, any, never>, never, Scope.Scope>;
|
|
41
|
+
export declare const makeProxyChannel: ({ queue, nodeName, newEdgeAvailablePubSub, sendPacket, target, channelName, schema, simulation, }: MakeProxyChannelArgs) => Effect.Effect<WebChannel.WebChannel<any, any, never>, never, Scope.Scope>;
|
|
18
42
|
export {};
|
|
19
43
|
//# sourceMappingURL=proxy-channel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy-channel.d.ts","sourceRoot":"","sources":["../../src/channel/proxy-channel.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"proxy-channel.d.ts","sourceRoot":"","sources":["../../src/channel/proxy-channel.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,MAAM,EAEX,MAAM,EAKN,KAAK,EAEL,MAAM,EACN,KAAK,EAGL,UAAU,EACX,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,cAAc,EAEpB,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAA;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B;IACvC;;OAEG;;QAED,sEAAsE;;QAEtE,8EAA8E;;QAE9E,iDAAiD;;;EAGnD,CAAA;AAEF,MAAM,MAAM,4BAA4B,GAAG,OAAO,4BAA4B,CAAC,IAAI,CAAA;AAEnF,+CAA+C;AAC/C,eAAO,MAAM,uBAAuB,EAAE,4BAMrC,CAAA;AAED,UAAU,oBAAoB;IAC5B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;IAClC,QAAQ,EAAE,YAAY,CAAA;IACtB,sBAAsB,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IACnD,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,UAAU,CAAC,kBAAkB,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACtF,WAAW,EAAE,WAAW,CAAA;IACxB,MAAM,EAAE,YAAY,CAAA;IACpB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QAC5B,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;KAC/B,CAAA;IACD,2EAA2E;IAC3E,UAAU,CAAC,EAAE,4BAA4B,CAAA;CAC1C;AAED,eAAO,MAAM,gBAAgB,GAAI,mGAS9B,oBAAoB,8EAoapB,CAAA"}
|