@dxos/messaging 0.5.9-main.07b4bad → 0.5.9-main.1c1903d
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/lib/browser/index.mjs +812 -559
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +778 -545
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/messenger-monitor.d.ts +8 -0
- package/dist/types/src/messenger-monitor.d.ts.map +1 -0
- package/dist/types/src/messenger.d.ts +1 -0
- package/dist/types/src/messenger.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-client-monitor.d.ts +30 -0
- package/dist/types/src/signal-client/signal-client-monitor.d.ts.map +1 -0
- package/dist/types/src/signal-client/signal-client.d.ts +25 -50
- package/dist/types/src/signal-client/signal-client.d.ts.map +1 -1
- package/dist/types/src/signal-client/signal-local-state.d.ts +46 -0
- package/dist/types/src/signal-client/signal-local-state.d.ts.map +1 -0
- package/dist/types/src/signal-client/signal-rpc-client-monitor.d.ts +6 -0
- package/dist/types/src/signal-client/signal-rpc-client-monitor.d.ts.map +1 -0
- package/dist/types/src/signal-client/signal-rpc-client.d.ts +4 -2
- package/dist/types/src/signal-client/signal-rpc-client.d.ts.map +1 -1
- package/dist/types/src/signal-manager/memory-signal-manager.d.ts +0 -2
- package/dist/types/src/signal-manager/memory-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-manager/signal-manager.d.ts +0 -2
- package/dist/types/src/signal-manager/signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-manager/websocket-signal-manager-monitor.d.ts +8 -0
- package/dist/types/src/signal-manager/websocket-signal-manager-monitor.d.ts.map +1 -0
- package/dist/types/src/signal-manager/websocket-signal-manager.d.ts +7 -3
- package/dist/types/src/signal-manager/websocket-signal-manager.d.ts.map +1 -1
- package/dist/types/src/signal-methods.d.ts +6 -4
- package/dist/types/src/signal-methods.d.ts.map +1 -1
- package/package.json +13 -12
- package/src/messenger-monitor.ts +20 -0
- package/src/messenger.ts +16 -5
- package/src/signal-client/signal-client-monitor.ts +111 -0
- package/src/signal-client/signal-client.test.ts +111 -259
- package/src/signal-client/signal-client.ts +141 -252
- package/src/signal-client/signal-local-state.ts +156 -0
- package/src/signal-client/signal-rpc-client-monitor.ts +15 -0
- package/src/signal-client/signal-rpc-client.ts +38 -21
- package/src/signal-manager/memory-signal-manager.ts +0 -2
- package/src/signal-manager/signal-manager.ts +0 -2
- package/src/signal-manager/websocket-signal-manager-monitor.ts +20 -0
- package/src/signal-manager/websocket-signal-manager.ts +48 -26
- package/src/signal-methods.ts +6 -4
|
@@ -13,9 +13,25 @@ import { Context } from "@dxos/context";
|
|
|
13
13
|
import { invariant } from "@dxos/invariant";
|
|
14
14
|
import { PublicKey } from "@dxos/keys";
|
|
15
15
|
import { log } from "@dxos/log";
|
|
16
|
-
import { TimeoutError as ProtocolTimeoutError, schema, trace } from "@dxos/protocols";
|
|
16
|
+
import { TimeoutError as ProtocolTimeoutError, schema, trace as trace2 } from "@dxos/protocols";
|
|
17
17
|
import { ComplexMap, ComplexSet } from "@dxos/util";
|
|
18
18
|
|
|
19
|
+
// packages/core/mesh/messaging/src/messenger-monitor.ts
|
|
20
|
+
import { trace } from "@dxos/tracing";
|
|
21
|
+
var MessengerMonitor = class {
|
|
22
|
+
recordMessageAckFailed() {
|
|
23
|
+
trace.metrics.increment("mesh.signal.messenger.failed-ack", 1);
|
|
24
|
+
}
|
|
25
|
+
recordReliableMessage(params) {
|
|
26
|
+
trace.metrics.increment("mesh.signal.messenger.reliable-send", 1, {
|
|
27
|
+
tags: {
|
|
28
|
+
success: params.sent,
|
|
29
|
+
attempts: params.sendAttempts
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
19
35
|
// packages/core/mesh/messaging/src/timeouts.ts
|
|
20
36
|
var MESSAGE_TIMEOUT = 1e4;
|
|
21
37
|
|
|
@@ -26,6 +42,7 @@ var Acknowledgement = schema.getCodecForType("dxos.mesh.messaging.Acknowledgemen
|
|
|
26
42
|
var RECEIVED_MESSAGES_GC_INTERVAL = 12e4;
|
|
27
43
|
var Messenger = class {
|
|
28
44
|
constructor({ signalManager, retryDelay = 300 }) {
|
|
45
|
+
this._monitor = new MessengerMonitor();
|
|
29
46
|
// { peerId, payloadType } => listeners set
|
|
30
47
|
this._listeners = new ComplexMap(({ peerId, payloadType }) => peerId.toHex() + payloadType);
|
|
31
48
|
// peerId => listeners set
|
|
@@ -46,18 +63,18 @@ var Messenger = class {
|
|
|
46
63
|
return;
|
|
47
64
|
}
|
|
48
65
|
const traceId = PublicKey.random().toHex();
|
|
49
|
-
log.trace("dxos.mesh.messenger.open",
|
|
66
|
+
log.trace("dxos.mesh.messenger.open", trace2.begin({
|
|
50
67
|
id: traceId
|
|
51
68
|
}), {
|
|
52
69
|
F: __dxlog_file,
|
|
53
|
-
L:
|
|
70
|
+
L: 71,
|
|
54
71
|
S: this,
|
|
55
72
|
C: (f, a) => f(...a)
|
|
56
73
|
});
|
|
57
74
|
this._ctx = new Context({
|
|
58
75
|
onError: (err) => log.catch(err, void 0, {
|
|
59
76
|
F: __dxlog_file,
|
|
60
|
-
L:
|
|
77
|
+
L: 73,
|
|
61
78
|
S: this,
|
|
62
79
|
C: (f, a) => f(...a)
|
|
63
80
|
})
|
|
@@ -67,7 +84,7 @@ var Messenger = class {
|
|
|
67
84
|
from: message.author
|
|
68
85
|
}, {
|
|
69
86
|
F: __dxlog_file,
|
|
70
|
-
L:
|
|
87
|
+
L: 77,
|
|
71
88
|
S: this,
|
|
72
89
|
C: (f, a) => f(...a)
|
|
73
90
|
});
|
|
@@ -77,11 +94,11 @@ var Messenger = class {
|
|
|
77
94
|
this._performGc();
|
|
78
95
|
}, RECEIVED_MESSAGES_GC_INTERVAL);
|
|
79
96
|
this._closed = false;
|
|
80
|
-
log.trace("dxos.mesh.messenger.open",
|
|
97
|
+
log.trace("dxos.mesh.messenger.open", trace2.end({
|
|
81
98
|
id: traceId
|
|
82
99
|
}), {
|
|
83
100
|
F: __dxlog_file,
|
|
84
|
-
L:
|
|
101
|
+
L: 92,
|
|
85
102
|
S: this,
|
|
86
103
|
C: (f, a) => f(...a)
|
|
87
104
|
});
|
|
@@ -96,7 +113,7 @@ var Messenger = class {
|
|
|
96
113
|
async sendMessage({ author, recipient, payload }) {
|
|
97
114
|
invariant(!this._closed, "Closed", {
|
|
98
115
|
F: __dxlog_file,
|
|
99
|
-
L:
|
|
116
|
+
L: 104,
|
|
100
117
|
S: this,
|
|
101
118
|
A: [
|
|
102
119
|
"!this._closed",
|
|
@@ -110,7 +127,7 @@ var Messenger = class {
|
|
|
110
127
|
};
|
|
111
128
|
invariant(!this._onAckCallbacks.has(reliablePayload.messageId), void 0, {
|
|
112
129
|
F: __dxlog_file,
|
|
113
|
-
L:
|
|
130
|
+
L: 111,
|
|
114
131
|
S: this,
|
|
115
132
|
A: [
|
|
116
133
|
"!this._onAckCallbacks.has(reliablePayload.messageId!)",
|
|
@@ -123,12 +140,13 @@ var Messenger = class {
|
|
|
123
140
|
recipient
|
|
124
141
|
}, {
|
|
125
142
|
F: __dxlog_file,
|
|
126
|
-
L:
|
|
143
|
+
L: 112,
|
|
127
144
|
S: this,
|
|
128
145
|
C: (f, a) => f(...a)
|
|
129
146
|
});
|
|
130
147
|
let messageReceived;
|
|
131
148
|
let timeoutHit;
|
|
149
|
+
let sendAttempts = 0;
|
|
132
150
|
const promise = new Promise((resolve, reject) => {
|
|
133
151
|
messageReceived = resolve;
|
|
134
152
|
timeoutHit = reject;
|
|
@@ -138,10 +156,11 @@ var Messenger = class {
|
|
|
138
156
|
messageId: reliablePayload.messageId
|
|
139
157
|
}, {
|
|
140
158
|
F: __dxlog_file,
|
|
141
|
-
L:
|
|
159
|
+
L: 127,
|
|
142
160
|
S: this,
|
|
143
161
|
C: (f, a) => f(...a)
|
|
144
162
|
});
|
|
163
|
+
sendAttempts++;
|
|
145
164
|
await this._encodeAndSend({
|
|
146
165
|
author,
|
|
147
166
|
recipient,
|
|
@@ -150,7 +169,7 @@ var Messenger = class {
|
|
|
150
169
|
err
|
|
151
170
|
}, {
|
|
152
171
|
F: __dxlog_file,
|
|
153
|
-
L:
|
|
172
|
+
L: 130,
|
|
154
173
|
S: this,
|
|
155
174
|
C: (f, a) => f(...a)
|
|
156
175
|
}));
|
|
@@ -160,18 +179,26 @@ var Messenger = class {
|
|
|
160
179
|
messageId: reliablePayload.messageId
|
|
161
180
|
}, {
|
|
162
181
|
F: __dxlog_file,
|
|
163
|
-
L:
|
|
182
|
+
L: 139,
|
|
164
183
|
S: this,
|
|
165
184
|
C: (f, a) => f(...a)
|
|
166
185
|
});
|
|
167
186
|
this._onAckCallbacks.delete(reliablePayload.messageId);
|
|
168
187
|
timeoutHit(new ProtocolTimeoutError("signaling message not delivered", new TimeoutError(MESSAGE_TIMEOUT, "Message not delivered")));
|
|
169
188
|
void messageContext.dispose();
|
|
189
|
+
this._monitor.recordReliableMessage({
|
|
190
|
+
sendAttempts,
|
|
191
|
+
sent: false
|
|
192
|
+
});
|
|
170
193
|
}, MESSAGE_TIMEOUT);
|
|
171
194
|
this._onAckCallbacks.set(reliablePayload.messageId, () => {
|
|
172
195
|
messageReceived();
|
|
173
196
|
this._onAckCallbacks.delete(reliablePayload.messageId);
|
|
174
197
|
void messageContext.dispose();
|
|
198
|
+
this._monitor.recordReliableMessage({
|
|
199
|
+
sendAttempts,
|
|
200
|
+
sent: true
|
|
201
|
+
});
|
|
175
202
|
});
|
|
176
203
|
await this._encodeAndSend({
|
|
177
204
|
author,
|
|
@@ -187,7 +214,7 @@ var Messenger = class {
|
|
|
187
214
|
async listen({ peerId, payloadType, onMessage }) {
|
|
188
215
|
invariant(!this._closed, "Closed", {
|
|
189
216
|
F: __dxlog_file,
|
|
190
|
-
L:
|
|
217
|
+
L: 177,
|
|
191
218
|
S: this,
|
|
192
219
|
A: [
|
|
193
220
|
"!this._closed",
|
|
@@ -251,7 +278,7 @@ var Messenger = class {
|
|
|
251
278
|
async _handleReliablePayload({ author, recipient, payload }) {
|
|
252
279
|
invariant(payload.type_url === "dxos.mesh.messaging.ReliablePayload", void 0, {
|
|
253
280
|
F: __dxlog_file,
|
|
254
|
-
L:
|
|
281
|
+
L: 238,
|
|
255
282
|
S: this,
|
|
256
283
|
A: [
|
|
257
284
|
"payload.type_url === 'dxos.mesh.messaging.ReliablePayload'",
|
|
@@ -265,15 +292,20 @@ var Messenger = class {
|
|
|
265
292
|
messageId: reliablePayload.messageId
|
|
266
293
|
}, {
|
|
267
294
|
F: __dxlog_file,
|
|
268
|
-
L:
|
|
295
|
+
L: 241,
|
|
269
296
|
S: this,
|
|
270
297
|
C: (f, a) => f(...a)
|
|
271
298
|
});
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
299
|
+
try {
|
|
300
|
+
await this._sendAcknowledgement({
|
|
301
|
+
author,
|
|
302
|
+
recipient,
|
|
303
|
+
messageId: reliablePayload.messageId
|
|
304
|
+
});
|
|
305
|
+
} catch (err) {
|
|
306
|
+
this._monitor.recordMessageAckFailed();
|
|
307
|
+
throw err;
|
|
308
|
+
}
|
|
277
309
|
if (this._receivedMessages.has(reliablePayload.messageId)) {
|
|
278
310
|
return;
|
|
279
311
|
}
|
|
@@ -287,7 +319,7 @@ var Messenger = class {
|
|
|
287
319
|
async _handleAcknowledgement({ payload }) {
|
|
288
320
|
invariant(payload.type_url === "dxos.mesh.messaging.Acknowledgement", void 0, {
|
|
289
321
|
F: __dxlog_file,
|
|
290
|
-
L:
|
|
322
|
+
L: 269,
|
|
291
323
|
S: this,
|
|
292
324
|
A: [
|
|
293
325
|
"payload.type_url === 'dxos.mesh.messaging.Acknowledgement'",
|
|
@@ -303,7 +335,7 @@ var Messenger = class {
|
|
|
303
335
|
to: author
|
|
304
336
|
}, {
|
|
305
337
|
F: __dxlog_file,
|
|
306
|
-
L:
|
|
338
|
+
L: 282,
|
|
307
339
|
S: this,
|
|
308
340
|
C: (f, a) => f(...a)
|
|
309
341
|
});
|
|
@@ -354,7 +386,7 @@ var Messenger = class {
|
|
|
354
386
|
elapsed
|
|
355
387
|
}, {
|
|
356
388
|
F: __dxlog_file,
|
|
357
|
-
L:
|
|
389
|
+
L: 330,
|
|
358
390
|
S: this,
|
|
359
391
|
C: (f, a) => f(...a)
|
|
360
392
|
});
|
|
@@ -363,37 +395,310 @@ var Messenger = class {
|
|
|
363
395
|
};
|
|
364
396
|
|
|
365
397
|
// packages/core/mesh/messaging/src/signal-client/signal-client.ts
|
|
366
|
-
import { DeferredTask, Event, Trigger as Trigger2,
|
|
367
|
-
import {
|
|
398
|
+
import { DeferredTask, Event as Event2, Trigger as Trigger2, scheduleTask as scheduleTask2, scheduleTaskInterval as scheduleTaskInterval3, sleep } from "@dxos/async";
|
|
399
|
+
import { cancelWithContext as cancelWithContext2, Resource } from "@dxos/context";
|
|
368
400
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
369
|
-
import { PublicKey as
|
|
370
|
-
import { log as
|
|
371
|
-
import { trace as
|
|
401
|
+
import { PublicKey as PublicKey4 } from "@dxos/keys";
|
|
402
|
+
import { log as log4 } from "@dxos/log";
|
|
403
|
+
import { trace as trace6 } from "@dxos/protocols";
|
|
372
404
|
import { SignalState } from "@dxos/protocols/proto/dxos/mesh/signal";
|
|
373
|
-
|
|
405
|
+
|
|
406
|
+
// packages/core/mesh/messaging/src/signal-client/signal-client-monitor.ts
|
|
407
|
+
import { trace as trace3 } from "@dxos/tracing";
|
|
408
|
+
var SignalClientMonitor = class {
|
|
409
|
+
constructor() {
|
|
410
|
+
this._performance = {
|
|
411
|
+
sentMessages: 0,
|
|
412
|
+
receivedMessages: 0,
|
|
413
|
+
reconnectCounter: 0,
|
|
414
|
+
joinCounter: 0,
|
|
415
|
+
leaveCounter: 0
|
|
416
|
+
};
|
|
417
|
+
/**
|
|
418
|
+
* Timestamp of when the connection attempt was began.
|
|
419
|
+
*/
|
|
420
|
+
this._connectionStarted = /* @__PURE__ */ new Date();
|
|
421
|
+
/**
|
|
422
|
+
* Timestamp of last state change.
|
|
423
|
+
*/
|
|
424
|
+
this._lastStateChange = /* @__PURE__ */ new Date();
|
|
425
|
+
}
|
|
426
|
+
getRecordedTimestamps() {
|
|
427
|
+
return {
|
|
428
|
+
connectionStarted: this._connectionStarted,
|
|
429
|
+
lastStateChange: this._lastStateChange
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
recordStateChangeTime() {
|
|
433
|
+
this._lastStateChange = /* @__PURE__ */ new Date();
|
|
434
|
+
}
|
|
435
|
+
recordConnectionStartTime() {
|
|
436
|
+
this._connectionStarted = /* @__PURE__ */ new Date();
|
|
437
|
+
}
|
|
438
|
+
recordReconnect(params) {
|
|
439
|
+
this._performance.reconnectCounter++;
|
|
440
|
+
trace3.metrics.increment("mesh.signal.signal-client.reconnect", 1, {
|
|
441
|
+
tags: {
|
|
442
|
+
success: params.success
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
recordJoin() {
|
|
447
|
+
this._performance.joinCounter++;
|
|
448
|
+
}
|
|
449
|
+
recordLeave() {
|
|
450
|
+
this._performance.leaveCounter++;
|
|
451
|
+
}
|
|
452
|
+
recordMessageReceived(message) {
|
|
453
|
+
this._performance.receivedMessages++;
|
|
454
|
+
trace3.metrics.increment("mesh.signal.signal-client.received-total", 1, {
|
|
455
|
+
tags: createIdentityTags(message)
|
|
456
|
+
});
|
|
457
|
+
trace3.metrics.distribution("mesh.signal.signal-client.bytes-in", getByteCount(message), {
|
|
458
|
+
tags: createIdentityTags(message)
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
async recordMessageSending(message, sendMessage) {
|
|
462
|
+
this._performance.sentMessages++;
|
|
463
|
+
const tags = createIdentityTags(message);
|
|
464
|
+
let success = true;
|
|
465
|
+
try {
|
|
466
|
+
const reqStart = Date.now();
|
|
467
|
+
await sendMessage();
|
|
468
|
+
const reqDuration = Date.now() - reqStart;
|
|
469
|
+
trace3.metrics.distribution("mesh.signal.signal-client.send-duration", reqDuration, {
|
|
470
|
+
tags
|
|
471
|
+
});
|
|
472
|
+
trace3.metrics.distribution("mesh.signal.signal-client.bytes-out", getByteCount(message), {
|
|
473
|
+
tags
|
|
474
|
+
});
|
|
475
|
+
} catch (err) {
|
|
476
|
+
success = false;
|
|
477
|
+
}
|
|
478
|
+
trace3.metrics.increment("mesh.signal.signal-client.sent-total", 1, {
|
|
479
|
+
tags: {
|
|
480
|
+
...tags,
|
|
481
|
+
success
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
recordStreamCloseErrors(count) {
|
|
486
|
+
trace3.metrics.increment("mesh.signal.signal-client.stream-close-errors", count);
|
|
487
|
+
}
|
|
488
|
+
recordReconciliation(params) {
|
|
489
|
+
trace3.metrics.increment("mesh.signal.signal-client.reconciliation", 1, {
|
|
490
|
+
tags: {
|
|
491
|
+
success: params.success
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
var getByteCount = (message) => {
|
|
497
|
+
return message.author.asUint8Array().length + message.recipient.asUint8Array().length + message.payload.type_url.length + message.payload.value.length;
|
|
498
|
+
};
|
|
499
|
+
var createIdentityTags = (message) => {
|
|
500
|
+
return {
|
|
501
|
+
peer: message.author.toHex()
|
|
502
|
+
};
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
// packages/core/mesh/messaging/src/signal-client/signal-local-state.ts
|
|
506
|
+
import { asyncTimeout, Event } from "@dxos/async";
|
|
507
|
+
import { cancelWithContext } from "@dxos/context";
|
|
508
|
+
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
509
|
+
import { log as log2 } from "@dxos/log";
|
|
510
|
+
import { ComplexMap as ComplexMap2, ComplexSet as ComplexSet2, safeAwaitAll } from "@dxos/util";
|
|
511
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/messaging/src/signal-client/signal-local-state.ts";
|
|
512
|
+
var SignalLocalState = class {
|
|
513
|
+
constructor(_onMessage, _onSwarmEvent) {
|
|
514
|
+
this._onMessage = _onMessage;
|
|
515
|
+
this._onSwarmEvent = _onSwarmEvent;
|
|
516
|
+
this._swarmStreams = new ComplexMap2(({ topic, peerId }) => topic.toHex() + peerId.toHex());
|
|
517
|
+
this._joinedTopics = new ComplexSet2(({ topic, peerId }) => topic.toHex() + peerId.toHex());
|
|
518
|
+
this._subscribedMessages = new ComplexSet2(({ peerId }) => peerId.toHex());
|
|
519
|
+
this.messageStreams = new ComplexMap2((key) => key.toHex());
|
|
520
|
+
this.reconciled = new Event();
|
|
521
|
+
}
|
|
522
|
+
async safeCloseStreams() {
|
|
523
|
+
const streams = [
|
|
524
|
+
...this._swarmStreams.values()
|
|
525
|
+
].concat([
|
|
526
|
+
...this.messageStreams.values()
|
|
527
|
+
]);
|
|
528
|
+
this._swarmStreams.clear();
|
|
529
|
+
this.messageStreams.clear();
|
|
530
|
+
const failureCount = (await safeAwaitAll(streams, (s) => s.close())).length;
|
|
531
|
+
return {
|
|
532
|
+
failureCount
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
join({ topic, peerId }) {
|
|
536
|
+
this._joinedTopics.add({
|
|
537
|
+
topic,
|
|
538
|
+
peerId
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
leave({ topic, peerId }) {
|
|
542
|
+
void this._swarmStreams.get({
|
|
543
|
+
topic,
|
|
544
|
+
peerId
|
|
545
|
+
})?.close();
|
|
546
|
+
this._swarmStreams.delete({
|
|
547
|
+
topic,
|
|
548
|
+
peerId
|
|
549
|
+
});
|
|
550
|
+
this._joinedTopics.delete({
|
|
551
|
+
topic,
|
|
552
|
+
peerId
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
subscribeMessages(peerId) {
|
|
556
|
+
this._subscribedMessages.add({
|
|
557
|
+
peerId
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
unsubscribeMessages(peerId) {
|
|
561
|
+
log2("unsubscribing from messages", {
|
|
562
|
+
peerId
|
|
563
|
+
}, {
|
|
564
|
+
F: __dxlog_file2,
|
|
565
|
+
L: 76,
|
|
566
|
+
S: this,
|
|
567
|
+
C: (f, a) => f(...a)
|
|
568
|
+
});
|
|
569
|
+
this._subscribedMessages.delete({
|
|
570
|
+
peerId
|
|
571
|
+
});
|
|
572
|
+
void this.messageStreams.get(peerId)?.close();
|
|
573
|
+
this.messageStreams.delete(peerId);
|
|
574
|
+
}
|
|
575
|
+
async reconcile(ctx, client) {
|
|
576
|
+
await this._reconcileSwarmSubscriptions(ctx, client);
|
|
577
|
+
await this._reconcileMessageSubscriptions(ctx, client);
|
|
578
|
+
this.reconciled.emit();
|
|
579
|
+
}
|
|
580
|
+
async _reconcileSwarmSubscriptions(ctx, client) {
|
|
581
|
+
for (const { topic, peerId } of this._swarmStreams.keys()) {
|
|
582
|
+
if (this._joinedTopics.has({
|
|
583
|
+
topic,
|
|
584
|
+
peerId
|
|
585
|
+
})) {
|
|
586
|
+
continue;
|
|
587
|
+
}
|
|
588
|
+
void this._swarmStreams.get({
|
|
589
|
+
topic,
|
|
590
|
+
peerId
|
|
591
|
+
})?.close();
|
|
592
|
+
this._swarmStreams.delete({
|
|
593
|
+
topic,
|
|
594
|
+
peerId
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
for (const { topic, peerId } of this._joinedTopics.values()) {
|
|
598
|
+
if (this._swarmStreams.has({
|
|
599
|
+
topic,
|
|
600
|
+
peerId
|
|
601
|
+
})) {
|
|
602
|
+
continue;
|
|
603
|
+
}
|
|
604
|
+
const swarmStream = await asyncTimeout(cancelWithContext(ctx, client.join({
|
|
605
|
+
topic,
|
|
606
|
+
peerId
|
|
607
|
+
})), 5e3);
|
|
608
|
+
swarmStream.subscribe(async (swarmEvent) => {
|
|
609
|
+
if (this._joinedTopics.has({
|
|
610
|
+
topic,
|
|
611
|
+
peerId
|
|
612
|
+
})) {
|
|
613
|
+
log2("swarm event", {
|
|
614
|
+
swarmEvent
|
|
615
|
+
}, {
|
|
616
|
+
F: __dxlog_file2,
|
|
617
|
+
L: 112,
|
|
618
|
+
S: this,
|
|
619
|
+
C: (f, a) => f(...a)
|
|
620
|
+
});
|
|
621
|
+
await this._onSwarmEvent({
|
|
622
|
+
topic,
|
|
623
|
+
swarmEvent
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
this._swarmStreams.set({
|
|
628
|
+
topic,
|
|
629
|
+
peerId
|
|
630
|
+
}, swarmStream);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
async _reconcileMessageSubscriptions(ctx, client) {
|
|
634
|
+
for (const peerId of this.messageStreams.keys()) {
|
|
635
|
+
if (this._subscribedMessages.has({
|
|
636
|
+
peerId
|
|
637
|
+
})) {
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
640
|
+
void this.messageStreams.get(peerId)?.close();
|
|
641
|
+
this.messageStreams.delete(peerId);
|
|
642
|
+
}
|
|
643
|
+
for (const { peerId } of this._subscribedMessages.values()) {
|
|
644
|
+
if (this.messageStreams.has(peerId)) {
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
const messageStream = await asyncTimeout(cancelWithContext(ctx, client.receiveMessages(peerId)), 5e3);
|
|
648
|
+
messageStream.subscribe(async (signalMessage) => {
|
|
649
|
+
if (this._subscribedMessages.has({
|
|
650
|
+
peerId
|
|
651
|
+
})) {
|
|
652
|
+
const message = {
|
|
653
|
+
author: PublicKey2.from(signalMessage.author),
|
|
654
|
+
recipient: PublicKey2.from(signalMessage.recipient),
|
|
655
|
+
payload: signalMessage.payload
|
|
656
|
+
};
|
|
657
|
+
await this._onMessage(message);
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
this.messageStreams.set(peerId, messageStream);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
};
|
|
374
664
|
|
|
375
665
|
// packages/core/mesh/messaging/src/signal-client/signal-rpc-client.ts
|
|
376
666
|
import WebSocket from "isomorphic-ws";
|
|
377
|
-
import { scheduleTaskInterval as scheduleTaskInterval2, Trigger } from "@dxos/async";
|
|
667
|
+
import { scheduleTaskInterval as scheduleTaskInterval2, TimeoutError as TimeoutError2, Trigger } from "@dxos/async";
|
|
378
668
|
import { Context as Context2 } from "@dxos/context";
|
|
379
669
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
380
|
-
import { PublicKey as
|
|
381
|
-
import { log as
|
|
382
|
-
import { schema as schema2, trace as
|
|
670
|
+
import { PublicKey as PublicKey3 } from "@dxos/keys";
|
|
671
|
+
import { log as log3 } from "@dxos/log";
|
|
672
|
+
import { schema as schema2, trace as trace5 } from "@dxos/protocols";
|
|
383
673
|
import { createProtoRpcPeer } from "@dxos/rpc";
|
|
384
|
-
|
|
674
|
+
|
|
675
|
+
// packages/core/mesh/messaging/src/signal-client/signal-rpc-client-monitor.ts
|
|
676
|
+
import { trace as trace4 } from "@dxos/tracing";
|
|
677
|
+
var SignalRpcClientMonitor = class {
|
|
678
|
+
recordClientCloseFailure(params) {
|
|
679
|
+
trace4.metrics.increment("mesh.signal.signal-rpc-client.close-failure", 1, {
|
|
680
|
+
tags: {
|
|
681
|
+
reason: params.failureReason
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
// packages/core/mesh/messaging/src/signal-client/signal-rpc-client.ts
|
|
688
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/mesh/messaging/src/signal-client/signal-rpc-client.ts";
|
|
385
689
|
var SIGNAL_KEEPALIVE_INTERVAL = 1e4;
|
|
386
690
|
var SignalRPCClient = class {
|
|
387
691
|
constructor({ url, callbacks = {} }) {
|
|
388
692
|
this._connectTrigger = new Trigger();
|
|
389
693
|
this._closed = false;
|
|
390
694
|
this._closeComplete = new Trigger();
|
|
391
|
-
|
|
392
|
-
|
|
695
|
+
this._monitor = new SignalRpcClientMonitor();
|
|
696
|
+
const traceId = PublicKey3.random().toHex();
|
|
697
|
+
log3.trace("dxos.mesh.signal-rpc-client.constructor", trace5.begin({
|
|
393
698
|
id: traceId
|
|
394
699
|
}), {
|
|
395
|
-
F:
|
|
396
|
-
L:
|
|
700
|
+
F: __dxlog_file3,
|
|
701
|
+
L: 60,
|
|
397
702
|
S: this,
|
|
398
703
|
C: (f, a) => f(...a)
|
|
399
704
|
});
|
|
@@ -413,9 +718,9 @@ var SignalRPCClient = class {
|
|
|
413
718
|
try {
|
|
414
719
|
this._socket.send(msg);
|
|
415
720
|
} catch (err) {
|
|
416
|
-
|
|
417
|
-
F:
|
|
418
|
-
L:
|
|
721
|
+
log3.warn("send error", err, {
|
|
722
|
+
F: __dxlog_file3,
|
|
723
|
+
L: 79,
|
|
419
724
|
S: this,
|
|
420
725
|
C: (f, a) => f(...a)
|
|
421
726
|
});
|
|
@@ -438,9 +743,13 @@ var SignalRPCClient = class {
|
|
|
438
743
|
this._socket.onopen = async () => {
|
|
439
744
|
try {
|
|
440
745
|
await this._rpc.open();
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
746
|
+
if (this._closed) {
|
|
747
|
+
await this._safeCloseRpc();
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
log3(`RPC open ${this._url}`, void 0, {
|
|
751
|
+
F: __dxlog_file3,
|
|
752
|
+
L: 104,
|
|
444
753
|
S: this,
|
|
445
754
|
C: (f, a) => f(...a)
|
|
446
755
|
});
|
|
@@ -452,12 +761,14 @@ var SignalRPCClient = class {
|
|
|
452
761
|
}, SIGNAL_KEEPALIVE_INTERVAL);
|
|
453
762
|
} catch (err) {
|
|
454
763
|
this._callbacks.onError?.(err);
|
|
764
|
+
this._socket.close();
|
|
765
|
+
this._closed = true;
|
|
455
766
|
}
|
|
456
767
|
};
|
|
457
768
|
this._socket.onclose = async () => {
|
|
458
|
-
|
|
459
|
-
F:
|
|
460
|
-
L:
|
|
769
|
+
log3(`Disconnected ${this._url}`, void 0, {
|
|
770
|
+
F: __dxlog_file3,
|
|
771
|
+
L: 127,
|
|
461
772
|
S: this,
|
|
462
773
|
C: (f, a) => f(...a)
|
|
463
774
|
});
|
|
@@ -467,89 +778,73 @@ var SignalRPCClient = class {
|
|
|
467
778
|
};
|
|
468
779
|
this._socket.onerror = async (event) => {
|
|
469
780
|
if (this._closed) {
|
|
781
|
+
this._socket.close();
|
|
470
782
|
return;
|
|
471
783
|
}
|
|
472
|
-
this._callbacks.onError?.(event.error ?? new Error(event.message));
|
|
473
|
-
this._connectTrigger.reset();
|
|
474
|
-
try {
|
|
475
|
-
await this._rpc?.close();
|
|
476
|
-
} catch (err) {
|
|
477
|
-
log2.catch(err, void 0, {
|
|
478
|
-
F: __dxlog_file2,
|
|
479
|
-
L: 134,
|
|
480
|
-
S: this,
|
|
481
|
-
C: (f, a) => f(...a)
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
784
|
this._closed = true;
|
|
485
|
-
|
|
785
|
+
this._callbacks.onError?.(event.error ?? new Error(event.message));
|
|
786
|
+
await this._safeCloseRpc();
|
|
787
|
+
log3.warn(`Socket ${event.type ?? "unknown"} error`, {
|
|
788
|
+
message: event.message,
|
|
486
789
|
url: this._url
|
|
487
790
|
}, {
|
|
488
|
-
F:
|
|
489
|
-
L:
|
|
791
|
+
F: __dxlog_file3,
|
|
792
|
+
L: 143,
|
|
490
793
|
S: this,
|
|
491
794
|
C: (f, a) => f(...a)
|
|
492
795
|
});
|
|
493
796
|
};
|
|
494
|
-
|
|
797
|
+
log3.trace("dxos.mesh.signal-rpc-client.constructor", trace5.end({
|
|
495
798
|
id: traceId
|
|
496
799
|
}), {
|
|
497
|
-
F:
|
|
498
|
-
L:
|
|
800
|
+
F: __dxlog_file3,
|
|
801
|
+
L: 146,
|
|
499
802
|
S: this,
|
|
500
803
|
C: (f, a) => f(...a)
|
|
501
804
|
});
|
|
502
805
|
}
|
|
503
806
|
async close() {
|
|
504
|
-
|
|
807
|
+
if (this._closed) {
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
505
810
|
this._closed = true;
|
|
811
|
+
await this._keepaliveCtx?.dispose();
|
|
506
812
|
try {
|
|
507
|
-
await this.
|
|
508
|
-
if (this._socket
|
|
813
|
+
await this._safeCloseRpc();
|
|
814
|
+
if (this._socket.readyState === WebSocket.OPEN || this._socket.readyState === WebSocket.CONNECTING) {
|
|
509
815
|
this._socket.close();
|
|
510
816
|
}
|
|
511
817
|
await this._closeComplete.wait({
|
|
512
818
|
timeout: 1e3
|
|
513
819
|
});
|
|
514
820
|
} catch (err) {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
S: this,
|
|
519
|
-
C: (f, a) => f(...a)
|
|
821
|
+
const failureReason = err instanceof TimeoutError2 ? "timeout" : err?.constructor?.name ?? "unknown";
|
|
822
|
+
this._monitor.recordClientCloseFailure({
|
|
823
|
+
failureReason
|
|
520
824
|
});
|
|
521
825
|
}
|
|
522
826
|
}
|
|
523
827
|
async join({ topic, peerId }) {
|
|
524
|
-
|
|
828
|
+
log3("join", {
|
|
525
829
|
topic,
|
|
526
830
|
peerId,
|
|
527
831
|
metadata: this._callbacks?.getMetadata?.()
|
|
528
832
|
}, {
|
|
529
|
-
F:
|
|
530
|
-
L:
|
|
833
|
+
F: __dxlog_file3,
|
|
834
|
+
L: 172,
|
|
531
835
|
S: this,
|
|
532
836
|
C: (f, a) => f(...a)
|
|
533
837
|
});
|
|
534
|
-
await this._connectTrigger.wait();
|
|
535
838
|
invariant2(!this._closed, "SignalRPCClient is closed", {
|
|
536
|
-
F:
|
|
537
|
-
L:
|
|
839
|
+
F: __dxlog_file3,
|
|
840
|
+
L: 173,
|
|
538
841
|
S: this,
|
|
539
842
|
A: [
|
|
540
843
|
"!this._closed",
|
|
541
844
|
"'SignalRPCClient is closed'"
|
|
542
845
|
]
|
|
543
846
|
});
|
|
544
|
-
|
|
545
|
-
F: __dxlog_file2,
|
|
546
|
-
L: 164,
|
|
547
|
-
S: this,
|
|
548
|
-
A: [
|
|
549
|
-
"this._rpc",
|
|
550
|
-
"'Rpc is not initialized'"
|
|
551
|
-
]
|
|
552
|
-
});
|
|
847
|
+
await this._connectTrigger.wait();
|
|
553
848
|
const swarmStream = this._rpc.rpc.Signal.join({
|
|
554
849
|
swarm: topic.asUint8Array(),
|
|
555
850
|
peer: peerId.asUint8Array(),
|
|
@@ -559,17 +854,17 @@ var SignalRPCClient = class {
|
|
|
559
854
|
return swarmStream;
|
|
560
855
|
}
|
|
561
856
|
async receiveMessages(peerId) {
|
|
562
|
-
|
|
857
|
+
log3("receiveMessages", {
|
|
563
858
|
peerId
|
|
564
859
|
}, {
|
|
565
|
-
F:
|
|
566
|
-
L:
|
|
860
|
+
F: __dxlog_file3,
|
|
861
|
+
L: 185,
|
|
567
862
|
S: this,
|
|
568
863
|
C: (f, a) => f(...a)
|
|
569
864
|
});
|
|
570
865
|
invariant2(!this._closed, "SignalRPCClient is closed", {
|
|
571
|
-
F:
|
|
572
|
-
L:
|
|
866
|
+
F: __dxlog_file3,
|
|
867
|
+
L: 186,
|
|
573
868
|
S: this,
|
|
574
869
|
A: [
|
|
575
870
|
"!this._closed",
|
|
@@ -577,15 +872,6 @@ var SignalRPCClient = class {
|
|
|
577
872
|
]
|
|
578
873
|
});
|
|
579
874
|
await this._connectTrigger.wait();
|
|
580
|
-
invariant2(this._rpc, "Rpc is not initialized", {
|
|
581
|
-
F: __dxlog_file2,
|
|
582
|
-
L: 178,
|
|
583
|
-
S: this,
|
|
584
|
-
A: [
|
|
585
|
-
"this._rpc",
|
|
586
|
-
"'Rpc is not initialized'"
|
|
587
|
-
]
|
|
588
|
-
});
|
|
589
875
|
const messageStream = this._rpc.rpc.Signal.receiveMessages({
|
|
590
876
|
peer: peerId.asUint8Array()
|
|
591
877
|
});
|
|
@@ -593,20 +879,20 @@ var SignalRPCClient = class {
|
|
|
593
879
|
return messageStream;
|
|
594
880
|
}
|
|
595
881
|
async sendMessage({ author, recipient, payload }) {
|
|
596
|
-
|
|
882
|
+
log3("sendMessage", {
|
|
597
883
|
author,
|
|
598
884
|
recipient,
|
|
599
885
|
payload,
|
|
600
886
|
metadata: this._callbacks?.getMetadata?.()
|
|
601
887
|
}, {
|
|
602
|
-
F:
|
|
603
|
-
L:
|
|
888
|
+
F: __dxlog_file3,
|
|
889
|
+
L: 196,
|
|
604
890
|
S: this,
|
|
605
891
|
C: (f, a) => f(...a)
|
|
606
892
|
});
|
|
607
893
|
invariant2(!this._closed, "SignalRPCClient is closed", {
|
|
608
|
-
F:
|
|
609
|
-
L:
|
|
894
|
+
F: __dxlog_file3,
|
|
895
|
+
L: 197,
|
|
610
896
|
S: this,
|
|
611
897
|
A: [
|
|
612
898
|
"!this._closed",
|
|
@@ -614,15 +900,6 @@ var SignalRPCClient = class {
|
|
|
614
900
|
]
|
|
615
901
|
});
|
|
616
902
|
await this._connectTrigger.wait();
|
|
617
|
-
invariant2(this._rpc, "Rpc is not initialized", {
|
|
618
|
-
F: __dxlog_file2,
|
|
619
|
-
L: 190,
|
|
620
|
-
S: this,
|
|
621
|
-
A: [
|
|
622
|
-
"this._rpc",
|
|
623
|
-
"'Rpc is not initialized'"
|
|
624
|
-
]
|
|
625
|
-
});
|
|
626
903
|
await this._rpc.rpc.Signal.sendMessage({
|
|
627
904
|
author: author.asUint8Array(),
|
|
628
905
|
recipient: recipient.asUint8Array(),
|
|
@@ -630,53 +907,59 @@ var SignalRPCClient = class {
|
|
|
630
907
|
metadata: this._callbacks?.getMetadata?.()
|
|
631
908
|
});
|
|
632
909
|
}
|
|
910
|
+
async _safeCloseRpc() {
|
|
911
|
+
try {
|
|
912
|
+
this._connectTrigger.reset();
|
|
913
|
+
await this._rpc.close();
|
|
914
|
+
} catch (err) {
|
|
915
|
+
log3.catch(err, void 0, {
|
|
916
|
+
F: __dxlog_file3,
|
|
917
|
+
L: 212,
|
|
918
|
+
S: this,
|
|
919
|
+
C: (f, a) => f(...a)
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
}
|
|
633
923
|
};
|
|
634
924
|
|
|
635
925
|
// packages/core/mesh/messaging/src/signal-client/signal-client.ts
|
|
636
|
-
var
|
|
926
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/mesh/messaging/src/signal-client/signal-client.ts";
|
|
637
927
|
var DEFAULT_RECONNECT_TIMEOUT = 100;
|
|
638
928
|
var MAX_RECONNECT_TIMEOUT = 5e3;
|
|
639
929
|
var ERROR_RECONCILE_DELAY = 1e3;
|
|
640
930
|
var RECONCILE_INTERVAL = 5e3;
|
|
641
|
-
var SignalClient = class {
|
|
931
|
+
var SignalClient = class extends Resource {
|
|
642
932
|
/**
|
|
643
933
|
* @param _host Signal server websocket URL.
|
|
934
|
+
* @param onMessage called when a new message is received.
|
|
935
|
+
* @param onSwarmEvent called when a new swarm event is received.
|
|
936
|
+
* @param _getMetadata signal-message metadata provider, called for every message.
|
|
644
937
|
*/
|
|
645
|
-
constructor(_host,
|
|
938
|
+
constructor(_host, onMessage, onSwarmEvent, _getMetadata) {
|
|
939
|
+
super();
|
|
646
940
|
this._host = _host;
|
|
647
|
-
this._onMessage = _onMessage;
|
|
648
|
-
this._onSwarmEvent = _onSwarmEvent;
|
|
649
941
|
this._getMetadata = _getMetadata;
|
|
942
|
+
this._monitor = new SignalClientMonitor();
|
|
650
943
|
this._state = SignalState.CLOSED;
|
|
651
|
-
this.
|
|
652
|
-
this._connectionStarted = /* @__PURE__ */ new Date();
|
|
653
|
-
this._lastStateChange = /* @__PURE__ */ new Date();
|
|
944
|
+
this._lastReconciliationFailed = false;
|
|
654
945
|
this._clientReady = new Trigger2();
|
|
655
|
-
this.
|
|
656
|
-
this.
|
|
657
|
-
this.
|
|
658
|
-
this._joinedTopics = new ComplexSet2(({ topic, peerId }) => topic.toHex() + peerId.toHex());
|
|
659
|
-
this._messageStreams = new ComplexMap2((key) => key.toHex());
|
|
660
|
-
this._subscribedMessages = new ComplexSet2(({ peerId }) => peerId.toHex());
|
|
661
|
-
this._reconciled = new Event();
|
|
662
|
-
this._instanceId = PublicKey3.random().toHex();
|
|
663
|
-
this._performance = {
|
|
664
|
-
sentMessages: 0,
|
|
665
|
-
receivedMessages: 0,
|
|
666
|
-
reconnectCounter: 0,
|
|
667
|
-
joinCounter: 0,
|
|
668
|
-
leaveCounter: 0
|
|
669
|
-
};
|
|
946
|
+
this._reconnectAfter = DEFAULT_RECONNECT_TIMEOUT;
|
|
947
|
+
this._instanceId = PublicKey4.random().toHex();
|
|
948
|
+
this.statusChanged = new Event2();
|
|
670
949
|
if (!this._host.startsWith("wss://") && !this._host.startsWith("ws://")) {
|
|
671
950
|
throw new Error(`Signal server requires a websocket URL. Provided: ${this._host}`);
|
|
672
951
|
}
|
|
952
|
+
this.localState = new SignalLocalState((message) => {
|
|
953
|
+
this._monitor.recordMessageReceived(message);
|
|
954
|
+
return onMessage(message);
|
|
955
|
+
}, onSwarmEvent);
|
|
673
956
|
}
|
|
674
|
-
async
|
|
675
|
-
|
|
957
|
+
async _open() {
|
|
958
|
+
log4.trace("dxos.mesh.signal-client.open", trace6.begin({
|
|
676
959
|
id: this._instanceId
|
|
677
960
|
}), {
|
|
678
|
-
F:
|
|
679
|
-
L:
|
|
961
|
+
F: __dxlog_file4,
|
|
962
|
+
L: 83,
|
|
680
963
|
S: this,
|
|
681
964
|
C: (f, a) => f(...a)
|
|
682
965
|
});
|
|
@@ -686,26 +969,33 @@ var SignalClient = class {
|
|
|
686
969
|
].includes(this._state)) {
|
|
687
970
|
return;
|
|
688
971
|
}
|
|
689
|
-
this.
|
|
690
|
-
onError: (err) => {
|
|
691
|
-
if (this._state === SignalState.CLOSED || this._ctx?.disposed) {
|
|
692
|
-
return;
|
|
693
|
-
}
|
|
694
|
-
if (this._state === SignalState.CONNECTED) {
|
|
695
|
-
log3.warn("SignalClient error:", err, {
|
|
696
|
-
F: __dxlog_file3,
|
|
697
|
-
L: 140,
|
|
698
|
-
S: this,
|
|
699
|
-
C: (f, a) => f(...a)
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
this._scheduleReconcileAfterError();
|
|
703
|
-
}
|
|
704
|
-
});
|
|
972
|
+
this._setState(SignalState.CONNECTING);
|
|
705
973
|
this._reconcileTask = new DeferredTask(this._ctx, async () => {
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
974
|
+
try {
|
|
975
|
+
await cancelWithContext2(this._connectionCtx, this._clientReady.wait({
|
|
976
|
+
timeout: 5e3
|
|
977
|
+
}));
|
|
978
|
+
invariant3(this._state === SignalState.CONNECTED, "Not connected to Signal Server", {
|
|
979
|
+
F: __dxlog_file4,
|
|
980
|
+
L: 93,
|
|
981
|
+
S: this,
|
|
982
|
+
A: [
|
|
983
|
+
"this._state === SignalState.CONNECTED",
|
|
984
|
+
"'Not connected to Signal Server'"
|
|
985
|
+
]
|
|
986
|
+
});
|
|
987
|
+
await this.localState.reconcile(this._connectionCtx, this._client);
|
|
988
|
+
this._monitor.recordReconciliation({
|
|
989
|
+
success: true
|
|
990
|
+
});
|
|
991
|
+
this._lastReconciliationFailed = false;
|
|
992
|
+
} catch (err) {
|
|
993
|
+
this._lastReconciliationFailed = true;
|
|
994
|
+
this._monitor.recordReconciliation({
|
|
995
|
+
success: false
|
|
996
|
+
});
|
|
997
|
+
throw err;
|
|
998
|
+
}
|
|
709
999
|
});
|
|
710
1000
|
scheduleTaskInterval3(this._ctx, async () => {
|
|
711
1001
|
if (this._state === SignalState.CONNECTED) {
|
|
@@ -713,23 +1003,46 @@ var SignalClient = class {
|
|
|
713
1003
|
}
|
|
714
1004
|
}, RECONCILE_INTERVAL);
|
|
715
1005
|
this._reconnectTask = new DeferredTask(this._ctx, async () => {
|
|
716
|
-
|
|
1006
|
+
try {
|
|
1007
|
+
await this._reconnect();
|
|
1008
|
+
this._monitor.recordReconnect({
|
|
1009
|
+
success: true
|
|
1010
|
+
});
|
|
1011
|
+
} catch (err) {
|
|
1012
|
+
this._monitor.recordReconnect({
|
|
1013
|
+
success: false
|
|
1014
|
+
});
|
|
1015
|
+
throw err;
|
|
1016
|
+
}
|
|
717
1017
|
});
|
|
718
|
-
this._setState(SignalState.CONNECTING);
|
|
719
1018
|
this._createClient();
|
|
720
|
-
|
|
1019
|
+
log4.trace("dxos.mesh.signal-client.open", trace6.end({
|
|
721
1020
|
id: this._instanceId
|
|
722
1021
|
}), {
|
|
723
|
-
F:
|
|
724
|
-
L:
|
|
1022
|
+
F: __dxlog_file4,
|
|
1023
|
+
L: 126,
|
|
725
1024
|
S: this,
|
|
726
1025
|
C: (f, a) => f(...a)
|
|
727
1026
|
});
|
|
728
1027
|
}
|
|
729
|
-
async
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
1028
|
+
async _catch(err) {
|
|
1029
|
+
if (this._state === SignalState.CLOSED || this._ctx.disposed) {
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
if (this._state === SignalState.CONNECTED && !this._lastReconciliationFailed) {
|
|
1033
|
+
log4.warn("SignalClient error:", err, {
|
|
1034
|
+
F: __dxlog_file4,
|
|
1035
|
+
L: 135,
|
|
1036
|
+
S: this,
|
|
1037
|
+
C: (f, a) => f(...a)
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
this._scheduleReconcileAfterError();
|
|
1041
|
+
}
|
|
1042
|
+
async _close() {
|
|
1043
|
+
log4("closing...", void 0, {
|
|
1044
|
+
F: __dxlog_file4,
|
|
1045
|
+
L: 141,
|
|
733
1046
|
S: this,
|
|
734
1047
|
C: (f, a) => f(...a)
|
|
735
1048
|
});
|
|
@@ -738,14 +1051,11 @@ var SignalClient = class {
|
|
|
738
1051
|
].includes(this._state)) {
|
|
739
1052
|
return;
|
|
740
1053
|
}
|
|
741
|
-
await this._ctx?.dispose();
|
|
742
|
-
this._clientReady.reset();
|
|
743
|
-
await this._client?.close();
|
|
744
|
-
this._client = void 0;
|
|
745
1054
|
this._setState(SignalState.CLOSED);
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
1055
|
+
await this._safeResetClient();
|
|
1056
|
+
log4("closed", void 0, {
|
|
1057
|
+
F: __dxlog_file4,
|
|
1058
|
+
L: 149,
|
|
749
1059
|
S: this,
|
|
750
1060
|
C: (f, a) => f(...a)
|
|
751
1061
|
});
|
|
@@ -756,228 +1066,181 @@ var SignalClient = class {
|
|
|
756
1066
|
state: this._state,
|
|
757
1067
|
error: this._lastError?.message,
|
|
758
1068
|
reconnectIn: this._reconnectAfter,
|
|
759
|
-
|
|
760
|
-
lastStateChange: this._lastStateChange
|
|
1069
|
+
...this._monitor.getRecordedTimestamps()
|
|
761
1070
|
};
|
|
762
1071
|
}
|
|
763
|
-
async join(
|
|
764
|
-
|
|
765
|
-
topic,
|
|
766
|
-
peerId
|
|
1072
|
+
async join(args) {
|
|
1073
|
+
log4("joining", {
|
|
1074
|
+
topic: args.topic,
|
|
1075
|
+
peerId: args.peerId
|
|
767
1076
|
}, {
|
|
768
|
-
F:
|
|
769
|
-
L:
|
|
1077
|
+
F: __dxlog_file4,
|
|
1078
|
+
L: 163,
|
|
770
1079
|
S: this,
|
|
771
1080
|
C: (f, a) => f(...a)
|
|
772
1081
|
});
|
|
773
|
-
this.
|
|
774
|
-
this.
|
|
775
|
-
|
|
776
|
-
peerId
|
|
777
|
-
});
|
|
778
|
-
this._reconcileTask.schedule();
|
|
1082
|
+
this._monitor.recordJoin();
|
|
1083
|
+
this.localState.join(args);
|
|
1084
|
+
this._reconcileTask?.schedule();
|
|
779
1085
|
}
|
|
780
|
-
async leave(
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
peerId
|
|
1086
|
+
async leave(args) {
|
|
1087
|
+
log4("leaving", {
|
|
1088
|
+
topic: args.topic,
|
|
1089
|
+
peerId: args.peerId
|
|
785
1090
|
}, {
|
|
786
|
-
F:
|
|
787
|
-
L:
|
|
1091
|
+
F: __dxlog_file4,
|
|
1092
|
+
L: 170,
|
|
788
1093
|
S: this,
|
|
789
1094
|
C: (f, a) => f(...a)
|
|
790
1095
|
});
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
peerId
|
|
794
|
-
})?.close();
|
|
795
|
-
this._swarmStreams.delete({
|
|
796
|
-
topic,
|
|
797
|
-
peerId
|
|
798
|
-
});
|
|
799
|
-
this._joinedTopics.delete({
|
|
800
|
-
topic,
|
|
801
|
-
peerId
|
|
802
|
-
});
|
|
1096
|
+
this._monitor.recordLeave();
|
|
1097
|
+
this.localState.leave(args);
|
|
803
1098
|
}
|
|
804
1099
|
async sendMessage(msg) {
|
|
805
|
-
this.
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
1100
|
+
return this._monitor.recordMessageSending(msg, async () => {
|
|
1101
|
+
await this._clientReady.wait();
|
|
1102
|
+
invariant3(this._state === SignalState.CONNECTED, "Not connected to Signal Server", {
|
|
1103
|
+
F: __dxlog_file4,
|
|
1104
|
+
L: 178,
|
|
1105
|
+
S: this,
|
|
1106
|
+
A: [
|
|
1107
|
+
"this._state === SignalState.CONNECTED",
|
|
1108
|
+
"'Not connected to Signal Server'"
|
|
1109
|
+
]
|
|
1110
|
+
});
|
|
1111
|
+
await this._client.sendMessage(msg);
|
|
815
1112
|
});
|
|
816
|
-
await this._client.sendMessage(msg);
|
|
817
1113
|
}
|
|
818
1114
|
async subscribeMessages(peerId) {
|
|
819
|
-
|
|
1115
|
+
log4("subscribing to messages", {
|
|
820
1116
|
peerId
|
|
821
1117
|
}, {
|
|
822
|
-
F:
|
|
823
|
-
L:
|
|
1118
|
+
F: __dxlog_file4,
|
|
1119
|
+
L: 184,
|
|
824
1120
|
S: this,
|
|
825
1121
|
C: (f, a) => f(...a)
|
|
826
1122
|
});
|
|
827
|
-
this.
|
|
828
|
-
|
|
829
|
-
});
|
|
830
|
-
this._reconcileTask.schedule();
|
|
1123
|
+
this.localState.subscribeMessages(peerId);
|
|
1124
|
+
this._reconcileTask?.schedule();
|
|
831
1125
|
}
|
|
832
1126
|
async unsubscribeMessages(peerId) {
|
|
833
|
-
|
|
1127
|
+
log4("unsubscribing from messages", {
|
|
834
1128
|
peerId
|
|
835
1129
|
}, {
|
|
836
|
-
F:
|
|
837
|
-
L:
|
|
1130
|
+
F: __dxlog_file4,
|
|
1131
|
+
L: 190,
|
|
838
1132
|
S: this,
|
|
839
1133
|
C: (f, a) => f(...a)
|
|
840
1134
|
});
|
|
841
|
-
this.
|
|
842
|
-
peerId
|
|
843
|
-
});
|
|
844
|
-
void this._messageStreams.get(peerId)?.close();
|
|
845
|
-
this._messageStreams.delete(peerId);
|
|
1135
|
+
this.localState.unsubscribeMessages(peerId);
|
|
846
1136
|
}
|
|
847
1137
|
_scheduleReconcileAfterError() {
|
|
848
|
-
scheduleTask2(this._ctx, () =>
|
|
849
|
-
this._reconcileTask.schedule();
|
|
850
|
-
}, ERROR_RECONCILE_DELAY);
|
|
851
|
-
}
|
|
852
|
-
_setState(newState) {
|
|
853
|
-
this._state = newState;
|
|
854
|
-
this._lastStateChange = /* @__PURE__ */ new Date();
|
|
855
|
-
log3("signal state changed", {
|
|
856
|
-
status: this.getStatus()
|
|
857
|
-
}, {
|
|
858
|
-
F: __dxlog_file3,
|
|
859
|
-
L: 246,
|
|
860
|
-
S: this,
|
|
861
|
-
C: (f, a) => f(...a)
|
|
862
|
-
});
|
|
863
|
-
this.statusChanged.emit(this.getStatus());
|
|
1138
|
+
scheduleTask2(this._ctx, () => this._reconcileTask.schedule(), ERROR_RECONCILE_DELAY);
|
|
864
1139
|
}
|
|
865
1140
|
_createClient() {
|
|
866
|
-
|
|
1141
|
+
log4("creating client", {
|
|
867
1142
|
host: this._host,
|
|
868
1143
|
state: this._state
|
|
869
1144
|
}, {
|
|
870
|
-
F:
|
|
871
|
-
L:
|
|
1145
|
+
F: __dxlog_file4,
|
|
1146
|
+
L: 199,
|
|
872
1147
|
S: this,
|
|
873
1148
|
C: (f, a) => f(...a)
|
|
874
1149
|
});
|
|
875
1150
|
invariant3(!this._client, "Client already created", {
|
|
876
|
-
F:
|
|
877
|
-
L:
|
|
1151
|
+
F: __dxlog_file4,
|
|
1152
|
+
L: 200,
|
|
878
1153
|
S: this,
|
|
879
1154
|
A: [
|
|
880
1155
|
"!this._client",
|
|
881
1156
|
"'Client already created'"
|
|
882
1157
|
]
|
|
883
1158
|
});
|
|
884
|
-
this.
|
|
1159
|
+
this._monitor.recordConnectionStartTime();
|
|
885
1160
|
this._connectionCtx = this._ctx.derive();
|
|
886
1161
|
this._connectionCtx.onDispose(async () => {
|
|
887
|
-
|
|
888
|
-
F:
|
|
889
|
-
L:
|
|
1162
|
+
log4("connection context disposed", void 0, {
|
|
1163
|
+
F: __dxlog_file4,
|
|
1164
|
+
L: 207,
|
|
890
1165
|
S: this,
|
|
891
1166
|
C: (f, a) => f(...a)
|
|
892
1167
|
});
|
|
893
|
-
await
|
|
894
|
-
|
|
895
|
-
this._swarmStreams.clear();
|
|
896
|
-
this._messageStreams.clear();
|
|
1168
|
+
const { failureCount } = await this.localState.safeCloseStreams();
|
|
1169
|
+
this._monitor.recordStreamCloseErrors(failureCount);
|
|
897
1170
|
});
|
|
898
1171
|
try {
|
|
899
|
-
|
|
1172
|
+
const client = new SignalRPCClient({
|
|
900
1173
|
url: this._host,
|
|
901
1174
|
callbacks: {
|
|
902
1175
|
onConnected: () => {
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
this._clientReady.wake();
|
|
913
|
-
this._reconcileTask.schedule();
|
|
1176
|
+
if (client === this._client) {
|
|
1177
|
+
log4("socket connected", void 0, {
|
|
1178
|
+
F: __dxlog_file4,
|
|
1179
|
+
L: 218,
|
|
1180
|
+
S: this,
|
|
1181
|
+
C: (f, a) => f(...a)
|
|
1182
|
+
});
|
|
1183
|
+
this._onConnected();
|
|
1184
|
+
}
|
|
914
1185
|
},
|
|
915
1186
|
onDisconnected: () => {
|
|
916
|
-
|
|
1187
|
+
if (client !== this._client) {
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1190
|
+
log4("socket disconnected", {
|
|
917
1191
|
state: this._state
|
|
918
1192
|
}, {
|
|
919
|
-
F:
|
|
920
|
-
L:
|
|
1193
|
+
F: __dxlog_file4,
|
|
1194
|
+
L: 227,
|
|
921
1195
|
S: this,
|
|
922
1196
|
C: (f, a) => f(...a)
|
|
923
1197
|
});
|
|
924
1198
|
if (this._state === SignalState.ERROR) {
|
|
925
1199
|
this._setState(SignalState.DISCONNECTED);
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
if (this._state !== SignalState.CONNECTED && this._state !== SignalState.CONNECTING) {
|
|
929
|
-
this._incrementReconnectTimeout();
|
|
1200
|
+
} else {
|
|
1201
|
+
this._onDisconnected();
|
|
930
1202
|
}
|
|
931
|
-
this._setState(SignalState.DISCONNECTED);
|
|
932
|
-
this._reconnectTask.schedule();
|
|
933
1203
|
},
|
|
934
1204
|
onError: (error) => {
|
|
935
|
-
|
|
936
|
-
error,
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
1205
|
+
if (client === this._client) {
|
|
1206
|
+
log4("socket error", {
|
|
1207
|
+
error,
|
|
1208
|
+
state: this._state
|
|
1209
|
+
}, {
|
|
1210
|
+
F: __dxlog_file4,
|
|
1211
|
+
L: 239,
|
|
1212
|
+
S: this,
|
|
1213
|
+
C: (f, a) => f(...a)
|
|
1214
|
+
});
|
|
1215
|
+
this._onDisconnected({
|
|
1216
|
+
error
|
|
1217
|
+
});
|
|
947
1218
|
}
|
|
948
|
-
this._setState(SignalState.ERROR);
|
|
949
|
-
this._reconnectTask.schedule();
|
|
950
1219
|
},
|
|
951
1220
|
getMetadata: this._getMetadata
|
|
952
1221
|
}
|
|
953
1222
|
});
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
this._reconnectTask.schedule();
|
|
1223
|
+
this._client = client;
|
|
1224
|
+
} catch (error) {
|
|
1225
|
+
this._client = void 0;
|
|
1226
|
+
this._onDisconnected({
|
|
1227
|
+
error
|
|
1228
|
+
});
|
|
961
1229
|
}
|
|
962
1230
|
}
|
|
963
|
-
_incrementReconnectTimeout() {
|
|
964
|
-
this._reconnectAfter *= 2;
|
|
965
|
-
this._reconnectAfter = Math.min(this._reconnectAfter, MAX_RECONNECT_TIMEOUT);
|
|
966
|
-
}
|
|
967
1231
|
async _reconnect() {
|
|
968
|
-
|
|
1232
|
+
log4(`reconnecting in ${this._reconnectAfter}ms`, {
|
|
969
1233
|
state: this._state
|
|
970
1234
|
}, {
|
|
971
|
-
F:
|
|
972
|
-
L:
|
|
1235
|
+
F: __dxlog_file4,
|
|
1236
|
+
L: 254,
|
|
973
1237
|
S: this,
|
|
974
1238
|
C: (f, a) => f(...a)
|
|
975
1239
|
});
|
|
976
|
-
this._performance.reconnectCounter++;
|
|
977
1240
|
if (this._state === SignalState.RECONNECTING) {
|
|
978
|
-
|
|
979
|
-
F:
|
|
980
|
-
L:
|
|
1241
|
+
log4.info("Signal api already reconnecting.", void 0, {
|
|
1242
|
+
F: __dxlog_file4,
|
|
1243
|
+
L: 257,
|
|
981
1244
|
S: this,
|
|
982
1245
|
C: (f, a) => f(...a)
|
|
983
1246
|
});
|
|
@@ -986,149 +1249,96 @@ var SignalClient = class {
|
|
|
986
1249
|
if (this._state === SignalState.CLOSED) {
|
|
987
1250
|
return;
|
|
988
1251
|
}
|
|
989
|
-
this._clientReady.reset();
|
|
990
|
-
await this._connectionCtx?.dispose();
|
|
991
|
-
this._client?.close().catch(() => {
|
|
992
|
-
});
|
|
993
|
-
this._client = void 0;
|
|
994
|
-
await cancelWithContext(this._ctx, sleep(this._reconnectAfter));
|
|
995
1252
|
this._setState(SignalState.RECONNECTING);
|
|
1253
|
+
await this._safeResetClient();
|
|
1254
|
+
await cancelWithContext2(this._ctx, sleep(this._reconnectAfter));
|
|
996
1255
|
this._createClient();
|
|
997
1256
|
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
for (const { topic, peerId } of this._swarmStreams.keys()) {
|
|
1011
|
-
if (this._joinedTopics.has({
|
|
1012
|
-
topic,
|
|
1013
|
-
peerId
|
|
1014
|
-
})) {
|
|
1015
|
-
continue;
|
|
1016
|
-
}
|
|
1017
|
-
void this._swarmStreams.get({
|
|
1018
|
-
topic,
|
|
1019
|
-
peerId
|
|
1020
|
-
})?.close();
|
|
1021
|
-
this._swarmStreams.delete({
|
|
1022
|
-
topic,
|
|
1023
|
-
peerId
|
|
1024
|
-
});
|
|
1257
|
+
_onConnected() {
|
|
1258
|
+
this._lastError = void 0;
|
|
1259
|
+
this._lastReconciliationFailed = false;
|
|
1260
|
+
this._reconnectAfter = DEFAULT_RECONNECT_TIMEOUT;
|
|
1261
|
+
this._setState(SignalState.CONNECTED);
|
|
1262
|
+
this._clientReady.wake();
|
|
1263
|
+
this._reconcileTask.schedule();
|
|
1264
|
+
}
|
|
1265
|
+
_onDisconnected(options) {
|
|
1266
|
+
this._updateReconnectTimeout();
|
|
1267
|
+
if (this._state === SignalState.CLOSED) {
|
|
1268
|
+
return;
|
|
1025
1269
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
continue;
|
|
1032
|
-
}
|
|
1033
|
-
const swarmStream = await asyncTimeout(cancelWithContext(this._connectionCtx, client.join({
|
|
1034
|
-
topic,
|
|
1035
|
-
peerId
|
|
1036
|
-
})), 5e3);
|
|
1037
|
-
swarmStream.subscribe(async (swarmEvent) => {
|
|
1038
|
-
log3("swarm event", {
|
|
1039
|
-
swarmEvent
|
|
1040
|
-
}, {
|
|
1041
|
-
F: __dxlog_file3,
|
|
1042
|
-
L: 379,
|
|
1043
|
-
S: this,
|
|
1044
|
-
C: (f, a) => f(...a)
|
|
1045
|
-
});
|
|
1046
|
-
await this._onSwarmEvent({
|
|
1047
|
-
topic,
|
|
1048
|
-
swarmEvent
|
|
1049
|
-
});
|
|
1050
|
-
});
|
|
1051
|
-
this._swarmStreams.set({
|
|
1052
|
-
topic,
|
|
1053
|
-
peerId
|
|
1054
|
-
}, swarmStream);
|
|
1270
|
+
if (options?.error) {
|
|
1271
|
+
this._lastError = options.error;
|
|
1272
|
+
this._setState(SignalState.ERROR);
|
|
1273
|
+
} else {
|
|
1274
|
+
this._setState(SignalState.DISCONNECTED);
|
|
1055
1275
|
}
|
|
1276
|
+
this._reconnectTask.schedule();
|
|
1056
1277
|
}
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1278
|
+
_setState(newState) {
|
|
1279
|
+
this._state = newState;
|
|
1280
|
+
this._monitor.recordStateChangeTime();
|
|
1281
|
+
log4("signal state changed", {
|
|
1282
|
+
status: this.getStatus()
|
|
1283
|
+
}, {
|
|
1284
|
+
F: __dxlog_file4,
|
|
1285
|
+
L: 298,
|
|
1063
1286
|
S: this,
|
|
1064
|
-
|
|
1065
|
-
"this._state === SignalState.CONNECTED",
|
|
1066
|
-
"'Not connected to Signal Server'"
|
|
1067
|
-
]
|
|
1287
|
+
C: (f, a) => f(...a)
|
|
1068
1288
|
});
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
void this._messageStreams.get(peerId)?.close();
|
|
1076
|
-
this._messageStreams.delete(peerId);
|
|
1077
|
-
}
|
|
1078
|
-
for (const { peerId } of this._subscribedMessages.values()) {
|
|
1079
|
-
if (this._messageStreams.has(peerId)) {
|
|
1080
|
-
continue;
|
|
1081
|
-
}
|
|
1082
|
-
const messageStream = await asyncTimeout(cancelWithContext(this._connectionCtx, client.receiveMessages(peerId)), 5e3);
|
|
1083
|
-
messageStream.subscribe(async (message) => {
|
|
1084
|
-
this._performance.receivedMessages++;
|
|
1085
|
-
await this._onMessage({
|
|
1086
|
-
author: PublicKey3.from(message.author),
|
|
1087
|
-
recipient: PublicKey3.from(message.recipient),
|
|
1088
|
-
payload: message.payload
|
|
1089
|
-
});
|
|
1090
|
-
});
|
|
1091
|
-
this._messageStreams.set(peerId, messageStream);
|
|
1289
|
+
this.statusChanged.emit(this.getStatus());
|
|
1290
|
+
}
|
|
1291
|
+
_updateReconnectTimeout() {
|
|
1292
|
+
if (this._state !== SignalState.CONNECTED && this._state !== SignalState.CONNECTING) {
|
|
1293
|
+
this._reconnectAfter *= 2;
|
|
1294
|
+
this._reconnectAfter = Math.min(this._reconnectAfter, MAX_RECONNECT_TIMEOUT);
|
|
1092
1295
|
}
|
|
1093
1296
|
}
|
|
1297
|
+
async _safeResetClient() {
|
|
1298
|
+
await this._connectionCtx?.dispose();
|
|
1299
|
+
this._connectionCtx = void 0;
|
|
1300
|
+
this._clientReady.reset();
|
|
1301
|
+
await this._client?.close().catch(() => {
|
|
1302
|
+
});
|
|
1303
|
+
this._client = void 0;
|
|
1304
|
+
}
|
|
1094
1305
|
};
|
|
1095
1306
|
|
|
1096
1307
|
// packages/core/mesh/messaging/src/signal-manager/memory-signal-manager.ts
|
|
1097
|
-
import { Event as
|
|
1098
|
-
import { Context as
|
|
1308
|
+
import { Event as Event3, Trigger as Trigger3 } from "@dxos/async";
|
|
1309
|
+
import { Context as Context3 } from "@dxos/context";
|
|
1099
1310
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
1100
|
-
import { PublicKey as
|
|
1101
|
-
import { log as
|
|
1311
|
+
import { PublicKey as PublicKey5 } from "@dxos/keys";
|
|
1312
|
+
import { log as log5 } from "@dxos/log";
|
|
1102
1313
|
import { schema as schema3 } from "@dxos/protocols";
|
|
1103
1314
|
import { ComplexMap as ComplexMap3, ComplexSet as ComplexSet3 } from "@dxos/util";
|
|
1104
|
-
var
|
|
1315
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/mesh/messaging/src/signal-manager/memory-signal-manager.ts";
|
|
1105
1316
|
var MemorySignalManagerContext = class {
|
|
1106
1317
|
constructor() {
|
|
1107
1318
|
// Swarm messages.
|
|
1108
|
-
this.swarmEvent = new
|
|
1319
|
+
this.swarmEvent = new Event3();
|
|
1109
1320
|
// Mapping from topic to set of peers.
|
|
1110
|
-
this.swarms = new ComplexMap3(
|
|
1321
|
+
this.swarms = new ComplexMap3(PublicKey5.hash);
|
|
1111
1322
|
// Map of connections for each peer for signaling.
|
|
1112
|
-
this.connections = new ComplexMap3(
|
|
1323
|
+
this.connections = new ComplexMap3(PublicKey5.hash);
|
|
1113
1324
|
}
|
|
1114
1325
|
};
|
|
1115
1326
|
var MemorySignalManager = class {
|
|
1116
1327
|
constructor(_context) {
|
|
1117
1328
|
this._context = _context;
|
|
1118
|
-
this.statusChanged = new
|
|
1119
|
-
this.
|
|
1120
|
-
this.
|
|
1121
|
-
this.onMessage = new Event2();
|
|
1329
|
+
this.statusChanged = new Event3();
|
|
1330
|
+
this.swarmEvent = new Event3();
|
|
1331
|
+
this.onMessage = new Event3();
|
|
1122
1332
|
this._joinedSwarms = new ComplexSet3(({ topic, peerId }) => topic.toHex() + peerId.toHex());
|
|
1123
1333
|
this._freezeTrigger = new Trigger3().wake();
|
|
1124
|
-
this._ctx = new
|
|
1334
|
+
this._ctx = new Context3();
|
|
1125
1335
|
this._ctx.onDispose(this._context.swarmEvent.on((data) => this.swarmEvent.emit(data)));
|
|
1126
1336
|
}
|
|
1127
1337
|
async open() {
|
|
1128
1338
|
if (!this._ctx.disposed) {
|
|
1129
1339
|
return;
|
|
1130
1340
|
}
|
|
1131
|
-
this._ctx = new
|
|
1341
|
+
this._ctx = new Context3();
|
|
1132
1342
|
this._ctx.onDispose(this._context.swarmEvent.on((data) => this.swarmEvent.emit(data)));
|
|
1133
1343
|
await Promise.all([
|
|
1134
1344
|
...this._joinedSwarms.values()
|
|
@@ -1152,8 +1362,8 @@ var MemorySignalManager = class {
|
|
|
1152
1362
|
}
|
|
1153
1363
|
async join({ topic, peerId }) {
|
|
1154
1364
|
invariant4(!this._ctx.disposed, "Closed", {
|
|
1155
|
-
F:
|
|
1156
|
-
L:
|
|
1365
|
+
F: __dxlog_file5,
|
|
1366
|
+
L: 100,
|
|
1157
1367
|
S: this,
|
|
1158
1368
|
A: [
|
|
1159
1369
|
"!this._ctx.disposed",
|
|
@@ -1165,7 +1375,7 @@ var MemorySignalManager = class {
|
|
|
1165
1375
|
peerId
|
|
1166
1376
|
});
|
|
1167
1377
|
if (!this._context.swarms.has(topic)) {
|
|
1168
|
-
this._context.swarms.set(topic, new ComplexSet3(
|
|
1378
|
+
this._context.swarms.set(topic, new ComplexSet3(PublicKey5.hash));
|
|
1169
1379
|
}
|
|
1170
1380
|
this._context.swarms.get(topic).add(peerId);
|
|
1171
1381
|
this._context.swarmEvent.emit({
|
|
@@ -1193,8 +1403,8 @@ var MemorySignalManager = class {
|
|
|
1193
1403
|
}
|
|
1194
1404
|
async leave({ topic, peerId }) {
|
|
1195
1405
|
invariant4(!this._ctx.disposed, "Closed", {
|
|
1196
|
-
F:
|
|
1197
|
-
L:
|
|
1406
|
+
F: __dxlog_file5,
|
|
1407
|
+
L: 136,
|
|
1198
1408
|
S: this,
|
|
1199
1409
|
A: [
|
|
1200
1410
|
"!this._ctx.disposed",
|
|
@@ -1206,7 +1416,7 @@ var MemorySignalManager = class {
|
|
|
1206
1416
|
peerId
|
|
1207
1417
|
});
|
|
1208
1418
|
if (!this._context.swarms.has(topic)) {
|
|
1209
|
-
this._context.swarms.set(topic, new ComplexSet3(
|
|
1419
|
+
this._context.swarms.set(topic, new ComplexSet3(PublicKey5.hash));
|
|
1210
1420
|
}
|
|
1211
1421
|
this._context.swarms.get(topic).delete(peerId);
|
|
1212
1422
|
const swarmEvent = {
|
|
@@ -1220,19 +1430,19 @@ var MemorySignalManager = class {
|
|
|
1220
1430
|
});
|
|
1221
1431
|
}
|
|
1222
1432
|
async sendMessage({ author, recipient, payload }) {
|
|
1223
|
-
|
|
1433
|
+
log5("send message", {
|
|
1224
1434
|
author,
|
|
1225
1435
|
recipient,
|
|
1226
1436
|
...dec(payload)
|
|
1227
1437
|
}, {
|
|
1228
|
-
F:
|
|
1229
|
-
L:
|
|
1438
|
+
F: __dxlog_file5,
|
|
1439
|
+
L: 156,
|
|
1230
1440
|
S: this,
|
|
1231
1441
|
C: (f, a) => f(...a)
|
|
1232
1442
|
});
|
|
1233
1443
|
invariant4(recipient, void 0, {
|
|
1234
|
-
F:
|
|
1235
|
-
L:
|
|
1444
|
+
F: __dxlog_file5,
|
|
1445
|
+
L: 158,
|
|
1236
1446
|
S: this,
|
|
1237
1447
|
A: [
|
|
1238
1448
|
"recipient",
|
|
@@ -1240,8 +1450,8 @@ var MemorySignalManager = class {
|
|
|
1240
1450
|
]
|
|
1241
1451
|
});
|
|
1242
1452
|
invariant4(!this._ctx.disposed, "Closed", {
|
|
1243
|
-
F:
|
|
1244
|
-
L:
|
|
1453
|
+
F: __dxlog_file5,
|
|
1454
|
+
L: 159,
|
|
1245
1455
|
S: this,
|
|
1246
1456
|
A: [
|
|
1247
1457
|
"!this._ctx.disposed",
|
|
@@ -1251,24 +1461,24 @@ var MemorySignalManager = class {
|
|
|
1251
1461
|
await this._freezeTrigger.wait();
|
|
1252
1462
|
const remote = this._context.connections.get(recipient);
|
|
1253
1463
|
if (!remote) {
|
|
1254
|
-
|
|
1464
|
+
log5.warn("recipient is not subscribed for messages", {
|
|
1255
1465
|
author,
|
|
1256
1466
|
recipient
|
|
1257
1467
|
}, {
|
|
1258
|
-
F:
|
|
1259
|
-
L:
|
|
1468
|
+
F: __dxlog_file5,
|
|
1469
|
+
L: 165,
|
|
1260
1470
|
S: this,
|
|
1261
1471
|
C: (f, a) => f(...a)
|
|
1262
1472
|
});
|
|
1263
1473
|
return;
|
|
1264
1474
|
}
|
|
1265
1475
|
if (remote._ctx.disposed) {
|
|
1266
|
-
|
|
1476
|
+
log5.warn("recipient is disposed", {
|
|
1267
1477
|
author,
|
|
1268
1478
|
recipient
|
|
1269
1479
|
}, {
|
|
1270
|
-
F:
|
|
1271
|
-
L:
|
|
1480
|
+
F: __dxlog_file5,
|
|
1481
|
+
L: 170,
|
|
1272
1482
|
S: this,
|
|
1273
1483
|
C: (f, a) => f(...a)
|
|
1274
1484
|
});
|
|
@@ -1276,24 +1486,24 @@ var MemorySignalManager = class {
|
|
|
1276
1486
|
}
|
|
1277
1487
|
remote._freezeTrigger.wait().then(() => {
|
|
1278
1488
|
if (remote._ctx.disposed) {
|
|
1279
|
-
|
|
1489
|
+
log5.warn("recipient is disposed", {
|
|
1280
1490
|
author,
|
|
1281
1491
|
recipient
|
|
1282
1492
|
}, {
|
|
1283
|
-
F:
|
|
1284
|
-
L:
|
|
1493
|
+
F: __dxlog_file5,
|
|
1494
|
+
L: 178,
|
|
1285
1495
|
S: this,
|
|
1286
1496
|
C: (f, a) => f(...a)
|
|
1287
1497
|
});
|
|
1288
1498
|
return;
|
|
1289
1499
|
}
|
|
1290
|
-
|
|
1500
|
+
log5("receive message", {
|
|
1291
1501
|
author,
|
|
1292
1502
|
recipient,
|
|
1293
1503
|
...dec(payload)
|
|
1294
1504
|
}, {
|
|
1295
|
-
F:
|
|
1296
|
-
L:
|
|
1505
|
+
F: __dxlog_file5,
|
|
1506
|
+
L: 182,
|
|
1297
1507
|
S: this,
|
|
1298
1508
|
C: (f, a) => f(...a)
|
|
1299
1509
|
});
|
|
@@ -1303,33 +1513,33 @@ var MemorySignalManager = class {
|
|
|
1303
1513
|
payload
|
|
1304
1514
|
});
|
|
1305
1515
|
}).catch((err) => {
|
|
1306
|
-
|
|
1516
|
+
log5.error("error while waiting for freeze", {
|
|
1307
1517
|
err
|
|
1308
1518
|
}, {
|
|
1309
|
-
F:
|
|
1310
|
-
L:
|
|
1519
|
+
F: __dxlog_file5,
|
|
1520
|
+
L: 187,
|
|
1311
1521
|
S: this,
|
|
1312
1522
|
C: (f, a) => f(...a)
|
|
1313
1523
|
});
|
|
1314
1524
|
});
|
|
1315
1525
|
}
|
|
1316
1526
|
async subscribeMessages(peerId) {
|
|
1317
|
-
|
|
1527
|
+
log5("subscribing", {
|
|
1318
1528
|
peerId
|
|
1319
1529
|
}, {
|
|
1320
|
-
F:
|
|
1321
|
-
L:
|
|
1530
|
+
F: __dxlog_file5,
|
|
1531
|
+
L: 192,
|
|
1322
1532
|
S: this,
|
|
1323
1533
|
C: (f, a) => f(...a)
|
|
1324
1534
|
});
|
|
1325
1535
|
this._context.connections.set(peerId, this);
|
|
1326
1536
|
}
|
|
1327
1537
|
async unsubscribeMessages(peerId) {
|
|
1328
|
-
|
|
1538
|
+
log5("unsubscribing", {
|
|
1329
1539
|
peerId
|
|
1330
1540
|
}, {
|
|
1331
|
-
F:
|
|
1332
|
-
L:
|
|
1541
|
+
F: __dxlog_file5,
|
|
1542
|
+
L: 197,
|
|
1333
1543
|
S: this,
|
|
1334
1544
|
C: (f, a) => f(...a)
|
|
1335
1545
|
});
|
|
@@ -1357,12 +1567,31 @@ var dec = (payload) => {
|
|
|
1357
1567
|
};
|
|
1358
1568
|
|
|
1359
1569
|
// packages/core/mesh/messaging/src/signal-manager/websocket-signal-manager.ts
|
|
1360
|
-
import { Event as
|
|
1361
|
-
import { Context as
|
|
1570
|
+
import { Event as Event4, sleep as sleep2, synchronized } from "@dxos/async";
|
|
1571
|
+
import { Context as Context4 } from "@dxos/context";
|
|
1362
1572
|
import { invariant as invariant5 } from "@dxos/invariant";
|
|
1363
|
-
import { PublicKey as
|
|
1364
|
-
import { log as
|
|
1365
|
-
import { RateLimitExceededError, TimeoutError as
|
|
1573
|
+
import { PublicKey as PublicKey6 } from "@dxos/keys";
|
|
1574
|
+
import { log as log6 } from "@dxos/log";
|
|
1575
|
+
import { RateLimitExceededError, TimeoutError as TimeoutError3, trace as trace8 } from "@dxos/protocols";
|
|
1576
|
+
import { BitField, safeAwaitAll as safeAwaitAll2 } from "@dxos/util";
|
|
1577
|
+
|
|
1578
|
+
// packages/core/mesh/messaging/src/signal-manager/websocket-signal-manager-monitor.ts
|
|
1579
|
+
import { trace as trace7 } from "@dxos/tracing";
|
|
1580
|
+
var WebsocketSignalManagerMonitor = class {
|
|
1581
|
+
recordRateLimitExceeded() {
|
|
1582
|
+
trace7.metrics.increment("mesh.signal.signal-manager.rate-limit-hit", 1);
|
|
1583
|
+
}
|
|
1584
|
+
recordServerFailure(params) {
|
|
1585
|
+
trace7.metrics.increment("mesh.signal.signal-manager.server-failure", 1, {
|
|
1586
|
+
tags: {
|
|
1587
|
+
server: params.serverName,
|
|
1588
|
+
restarted: params.willRestart
|
|
1589
|
+
}
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
};
|
|
1593
|
+
|
|
1594
|
+
// packages/core/mesh/messaging/src/signal-manager/websocket-signal-manager.ts
|
|
1366
1595
|
function _ts_decorate(decorators, target, key, desc) {
|
|
1367
1596
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1368
1597
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
@@ -1373,7 +1602,7 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
1373
1602
|
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1374
1603
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1375
1604
|
}
|
|
1376
|
-
var
|
|
1605
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/mesh/messaging/src/signal-manager/websocket-signal-manager.ts";
|
|
1377
1606
|
var MAX_SERVER_FAILURES = 5;
|
|
1378
1607
|
var WSS_SIGNAL_SERVER_REBOOT_DELAY = 3e3;
|
|
1379
1608
|
var WebsocketSignalManager = class {
|
|
@@ -1381,18 +1610,18 @@ var WebsocketSignalManager = class {
|
|
|
1381
1610
|
this._hosts = _hosts;
|
|
1382
1611
|
this._getMetadata = _getMetadata;
|
|
1383
1612
|
this._servers = /* @__PURE__ */ new Map();
|
|
1613
|
+
this._monitor = new WebsocketSignalManagerMonitor();
|
|
1384
1614
|
this._opened = false;
|
|
1385
1615
|
this.failureCount = /* @__PURE__ */ new Map();
|
|
1386
|
-
this.statusChanged = new
|
|
1387
|
-
this.
|
|
1388
|
-
this.
|
|
1389
|
-
this.
|
|
1390
|
-
|
|
1391
|
-
log5("Created WebsocketSignalManager", {
|
|
1616
|
+
this.statusChanged = new Event4();
|
|
1617
|
+
this.swarmEvent = new Event4();
|
|
1618
|
+
this.onMessage = new Event4();
|
|
1619
|
+
this._instanceId = PublicKey6.random().toHex();
|
|
1620
|
+
log6("Created WebsocketSignalManager", {
|
|
1392
1621
|
hosts: this._hosts
|
|
1393
1622
|
}, {
|
|
1394
|
-
F:
|
|
1395
|
-
L:
|
|
1623
|
+
F: __dxlog_file6,
|
|
1624
|
+
L: 58,
|
|
1396
1625
|
S: this,
|
|
1397
1626
|
C: (f, a) => f(...a)
|
|
1398
1627
|
});
|
|
@@ -1404,39 +1633,37 @@ var WebsocketSignalManager = class {
|
|
|
1404
1633
|
server.statusChanged.on(() => this.statusChanged.emit(this.getStatus()));
|
|
1405
1634
|
this._servers.set(host.server, server);
|
|
1406
1635
|
this.failureCount.set(host.server, 0);
|
|
1407
|
-
server.commandTrace.on((trace5) => this.commandTrace.emit(trace5));
|
|
1408
1636
|
}
|
|
1637
|
+
this._failedServersBitfield = BitField.zeros(this._hosts.length);
|
|
1409
1638
|
}
|
|
1410
1639
|
async open() {
|
|
1411
1640
|
if (this._opened) {
|
|
1412
1641
|
return;
|
|
1413
1642
|
}
|
|
1414
|
-
|
|
1643
|
+
log6("open signal manager", {
|
|
1415
1644
|
hosts: this._hosts
|
|
1416
1645
|
}, {
|
|
1417
|
-
F:
|
|
1418
|
-
L:
|
|
1646
|
+
F: __dxlog_file6,
|
|
1647
|
+
L: 85,
|
|
1419
1648
|
S: this,
|
|
1420
1649
|
C: (f, a) => f(...a)
|
|
1421
1650
|
});
|
|
1422
|
-
|
|
1651
|
+
log6.trace("dxos.mesh.websocket-signal-manager.open", trace8.begin({
|
|
1423
1652
|
id: this._instanceId
|
|
1424
1653
|
}), {
|
|
1425
|
-
F:
|
|
1426
|
-
L:
|
|
1654
|
+
F: __dxlog_file6,
|
|
1655
|
+
L: 86,
|
|
1427
1656
|
S: this,
|
|
1428
1657
|
C: (f, a) => f(...a)
|
|
1429
1658
|
});
|
|
1430
1659
|
this._initContext();
|
|
1431
|
-
|
|
1432
|
-
...this._servers.values()
|
|
1433
|
-
].forEach((server) => server.open());
|
|
1660
|
+
await safeAwaitAll2(this._servers.values(), (server) => server.open());
|
|
1434
1661
|
this._opened = true;
|
|
1435
|
-
|
|
1662
|
+
log6.trace("dxos.mesh.websocket-signal-manager.open", trace8.end({
|
|
1436
1663
|
id: this._instanceId
|
|
1437
1664
|
}), {
|
|
1438
|
-
F:
|
|
1439
|
-
L:
|
|
1665
|
+
F: __dxlog_file6,
|
|
1666
|
+
L: 93,
|
|
1440
1667
|
S: this,
|
|
1441
1668
|
C: (f, a) => f(...a)
|
|
1442
1669
|
});
|
|
@@ -1447,20 +1674,20 @@ var WebsocketSignalManager = class {
|
|
|
1447
1674
|
}
|
|
1448
1675
|
this._opened = false;
|
|
1449
1676
|
await this._ctx.dispose();
|
|
1450
|
-
await
|
|
1677
|
+
await safeAwaitAll2(this._servers.values(), (server) => server.close());
|
|
1451
1678
|
}
|
|
1452
1679
|
async restartServer(serverName) {
|
|
1453
|
-
|
|
1680
|
+
log6("restarting server", {
|
|
1454
1681
|
serverName
|
|
1455
1682
|
}, {
|
|
1456
|
-
F:
|
|
1457
|
-
L:
|
|
1683
|
+
F: __dxlog_file6,
|
|
1684
|
+
L: 107,
|
|
1458
1685
|
S: this,
|
|
1459
1686
|
C: (f, a) => f(...a)
|
|
1460
1687
|
});
|
|
1461
1688
|
invariant5(this._opened, "server already closed", {
|
|
1462
|
-
F:
|
|
1463
|
-
L:
|
|
1689
|
+
F: __dxlog_file6,
|
|
1690
|
+
L: 108,
|
|
1464
1691
|
S: this,
|
|
1465
1692
|
A: [
|
|
1466
1693
|
"this._opened",
|
|
@@ -1469,8 +1696,8 @@ var WebsocketSignalManager = class {
|
|
|
1469
1696
|
});
|
|
1470
1697
|
const server = this._servers.get(serverName);
|
|
1471
1698
|
invariant5(server, "server not found", {
|
|
1472
|
-
F:
|
|
1473
|
-
L:
|
|
1699
|
+
F: __dxlog_file6,
|
|
1700
|
+
L: 111,
|
|
1474
1701
|
S: this,
|
|
1475
1702
|
A: [
|
|
1476
1703
|
"server",
|
|
@@ -1485,18 +1712,18 @@ var WebsocketSignalManager = class {
|
|
|
1485
1712
|
return Array.from(this._servers.values()).map((server) => server.getStatus());
|
|
1486
1713
|
}
|
|
1487
1714
|
async join({ topic, peerId }) {
|
|
1488
|
-
|
|
1715
|
+
log6("join", {
|
|
1489
1716
|
topic,
|
|
1490
1717
|
peerId
|
|
1491
1718
|
}, {
|
|
1492
|
-
F:
|
|
1493
|
-
L:
|
|
1719
|
+
F: __dxlog_file6,
|
|
1720
|
+
L: 124,
|
|
1494
1721
|
S: this,
|
|
1495
1722
|
C: (f, a) => f(...a)
|
|
1496
1723
|
});
|
|
1497
1724
|
invariant5(this._opened, "Closed", {
|
|
1498
|
-
F:
|
|
1499
|
-
L:
|
|
1725
|
+
F: __dxlog_file6,
|
|
1726
|
+
L: 125,
|
|
1500
1727
|
S: this,
|
|
1501
1728
|
A: [
|
|
1502
1729
|
"this._opened",
|
|
@@ -1509,18 +1736,18 @@ var WebsocketSignalManager = class {
|
|
|
1509
1736
|
}));
|
|
1510
1737
|
}
|
|
1511
1738
|
async leave({ topic, peerId }) {
|
|
1512
|
-
|
|
1739
|
+
log6("leaving", {
|
|
1513
1740
|
topic,
|
|
1514
1741
|
peerId
|
|
1515
1742
|
}, {
|
|
1516
|
-
F:
|
|
1517
|
-
L:
|
|
1743
|
+
F: __dxlog_file6,
|
|
1744
|
+
L: 131,
|
|
1518
1745
|
S: this,
|
|
1519
1746
|
C: (f, a) => f(...a)
|
|
1520
1747
|
});
|
|
1521
1748
|
invariant5(this._opened, "Closed", {
|
|
1522
|
-
F:
|
|
1523
|
-
L:
|
|
1749
|
+
F: __dxlog_file6,
|
|
1750
|
+
L: 132,
|
|
1524
1751
|
S: this,
|
|
1525
1752
|
A: [
|
|
1526
1753
|
"this._opened",
|
|
@@ -1533,89 +1760,115 @@ var WebsocketSignalManager = class {
|
|
|
1533
1760
|
}));
|
|
1534
1761
|
}
|
|
1535
1762
|
async sendMessage({ author, recipient, payload }) {
|
|
1536
|
-
|
|
1763
|
+
log6("signal", {
|
|
1537
1764
|
recipient
|
|
1538
1765
|
}, {
|
|
1539
|
-
F:
|
|
1540
|
-
L:
|
|
1766
|
+
F: __dxlog_file6,
|
|
1767
|
+
L: 145,
|
|
1541
1768
|
S: this,
|
|
1542
1769
|
C: (f, a) => f(...a)
|
|
1543
1770
|
});
|
|
1544
1771
|
invariant5(this._opened, "Closed", {
|
|
1545
|
-
F:
|
|
1546
|
-
L:
|
|
1772
|
+
F: __dxlog_file6,
|
|
1773
|
+
L: 146,
|
|
1547
1774
|
S: this,
|
|
1548
1775
|
A: [
|
|
1549
1776
|
"this._opened",
|
|
1550
1777
|
"'Closed'"
|
|
1551
1778
|
]
|
|
1552
1779
|
});
|
|
1553
|
-
void this._forEachServer(async (server, serverName) => {
|
|
1780
|
+
void this._forEachServer(async (server, serverName, index) => {
|
|
1554
1781
|
void server.sendMessage({
|
|
1555
1782
|
author,
|
|
1556
1783
|
recipient,
|
|
1557
1784
|
payload
|
|
1558
|
-
}).catch((err) => {
|
|
1785
|
+
}).then(() => this._clearServerFailedFlag(serverName, index)).catch((err) => {
|
|
1559
1786
|
if (err instanceof RateLimitExceededError) {
|
|
1560
|
-
|
|
1787
|
+
log6.info("WSS rate limit exceeded", {
|
|
1561
1788
|
err
|
|
1562
1789
|
}, {
|
|
1563
|
-
F:
|
|
1564
|
-
L:
|
|
1790
|
+
F: __dxlog_file6,
|
|
1791
|
+
L: 154,
|
|
1565
1792
|
S: this,
|
|
1566
1793
|
C: (f, a) => f(...a)
|
|
1567
1794
|
});
|
|
1568
|
-
|
|
1569
|
-
|
|
1795
|
+
this._monitor.recordRateLimitExceeded();
|
|
1796
|
+
} else if (err instanceof TimeoutError3 || err.constructor.name === "TimeoutError") {
|
|
1797
|
+
log6.info("WSS sendMessage timeout", {
|
|
1570
1798
|
err
|
|
1571
1799
|
}, {
|
|
1572
|
-
F:
|
|
1573
|
-
L:
|
|
1800
|
+
F: __dxlog_file6,
|
|
1801
|
+
L: 157,
|
|
1574
1802
|
S: this,
|
|
1575
1803
|
C: (f, a) => f(...a)
|
|
1576
1804
|
});
|
|
1577
|
-
void this.checkServerFailure(serverName);
|
|
1805
|
+
void this.checkServerFailure(serverName, index);
|
|
1578
1806
|
} else {
|
|
1579
|
-
|
|
1807
|
+
log6.warn(`error sending to ${serverName}`, {
|
|
1580
1808
|
err
|
|
1581
1809
|
}, {
|
|
1582
|
-
F:
|
|
1583
|
-
L:
|
|
1810
|
+
F: __dxlog_file6,
|
|
1811
|
+
L: 160,
|
|
1584
1812
|
S: this,
|
|
1585
1813
|
C: (f, a) => f(...a)
|
|
1586
1814
|
});
|
|
1587
|
-
void this.checkServerFailure(serverName);
|
|
1815
|
+
void this.checkServerFailure(serverName, index);
|
|
1588
1816
|
}
|
|
1589
1817
|
});
|
|
1590
1818
|
});
|
|
1591
1819
|
}
|
|
1592
|
-
async checkServerFailure(serverName) {
|
|
1820
|
+
async checkServerFailure(serverName, index) {
|
|
1593
1821
|
const failureCount = this.failureCount.get(serverName) ?? 0;
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1822
|
+
const isRestartRequired = failureCount > MAX_SERVER_FAILURES;
|
|
1823
|
+
this._monitor.recordServerFailure({
|
|
1824
|
+
serverName,
|
|
1825
|
+
willRestart: isRestartRequired
|
|
1826
|
+
});
|
|
1827
|
+
if (isRestartRequired) {
|
|
1828
|
+
if (!BitField.get(this._failedServersBitfield, index)) {
|
|
1829
|
+
log6.warn("too many failures for ws-server, restarting", {
|
|
1830
|
+
serverName,
|
|
1831
|
+
failureCount
|
|
1832
|
+
}, {
|
|
1833
|
+
F: __dxlog_file6,
|
|
1834
|
+
L: 174,
|
|
1835
|
+
S: this,
|
|
1836
|
+
C: (f, a) => f(...a)
|
|
1837
|
+
});
|
|
1838
|
+
BitField.set(this._failedServersBitfield, index, true);
|
|
1839
|
+
}
|
|
1601
1840
|
await this.restartServer(serverName);
|
|
1602
1841
|
this.failureCount.set(serverName, 0);
|
|
1603
1842
|
return;
|
|
1604
1843
|
}
|
|
1605
1844
|
this.failureCount.set(serverName, (this.failureCount.get(serverName) ?? 0) + 1);
|
|
1606
1845
|
}
|
|
1846
|
+
_clearServerFailedFlag(serverName, index) {
|
|
1847
|
+
if (BitField.get(this._failedServersBitfield, index)) {
|
|
1848
|
+
log6.info("server connection restored", {
|
|
1849
|
+
serverName
|
|
1850
|
+
}, {
|
|
1851
|
+
F: __dxlog_file6,
|
|
1852
|
+
L: 187,
|
|
1853
|
+
S: this,
|
|
1854
|
+
C: (f, a) => f(...a)
|
|
1855
|
+
});
|
|
1856
|
+
BitField.set(this._failedServersBitfield, index, false);
|
|
1857
|
+
this.failureCount.set(serverName, 0);
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1607
1860
|
async subscribeMessages(peerId) {
|
|
1608
|
-
|
|
1861
|
+
log6("subscribed for message stream", {
|
|
1609
1862
|
peerId
|
|
1610
1863
|
}, {
|
|
1611
|
-
F:
|
|
1612
|
-
L:
|
|
1864
|
+
F: __dxlog_file6,
|
|
1865
|
+
L: 194,
|
|
1613
1866
|
S: this,
|
|
1614
1867
|
C: (f, a) => f(...a)
|
|
1615
1868
|
});
|
|
1616
1869
|
invariant5(this._opened, "Closed", {
|
|
1617
|
-
F:
|
|
1618
|
-
L:
|
|
1870
|
+
F: __dxlog_file6,
|
|
1871
|
+
L: 195,
|
|
1619
1872
|
S: this,
|
|
1620
1873
|
A: [
|
|
1621
1874
|
"this._opened",
|
|
@@ -1625,17 +1878,17 @@ var WebsocketSignalManager = class {
|
|
|
1625
1878
|
await this._forEachServer(async (server) => server.subscribeMessages(peerId));
|
|
1626
1879
|
}
|
|
1627
1880
|
async unsubscribeMessages(peerId) {
|
|
1628
|
-
|
|
1881
|
+
log6("subscribed for message stream", {
|
|
1629
1882
|
peerId
|
|
1630
1883
|
}, {
|
|
1631
|
-
F:
|
|
1632
|
-
L:
|
|
1884
|
+
F: __dxlog_file6,
|
|
1885
|
+
L: 201,
|
|
1633
1886
|
S: this,
|
|
1634
1887
|
C: (f, a) => f(...a)
|
|
1635
1888
|
});
|
|
1636
1889
|
invariant5(this._opened, "Closed", {
|
|
1637
|
-
F:
|
|
1638
|
-
L:
|
|
1890
|
+
F: __dxlog_file6,
|
|
1891
|
+
L: 202,
|
|
1639
1892
|
S: this,
|
|
1640
1893
|
A: [
|
|
1641
1894
|
"this._opened",
|
|
@@ -1645,17 +1898,17 @@ var WebsocketSignalManager = class {
|
|
|
1645
1898
|
await this._forEachServer(async (server) => server.unsubscribeMessages(peerId));
|
|
1646
1899
|
}
|
|
1647
1900
|
_initContext() {
|
|
1648
|
-
this._ctx = new
|
|
1649
|
-
onError: (err) =>
|
|
1650
|
-
F:
|
|
1651
|
-
L:
|
|
1901
|
+
this._ctx = new Context4({
|
|
1902
|
+
onError: (err) => log6.catch(err, void 0, {
|
|
1903
|
+
F: __dxlog_file6,
|
|
1904
|
+
L: 209,
|
|
1652
1905
|
S: this,
|
|
1653
1906
|
C: (f, a) => f(...a)
|
|
1654
1907
|
})
|
|
1655
1908
|
});
|
|
1656
1909
|
}
|
|
1657
1910
|
async _forEachServer(fn) {
|
|
1658
|
-
return Promise.all(Array.from(this._servers.entries()).map(([serverName, server]) => fn(server, serverName)));
|
|
1911
|
+
return Promise.all(Array.from(this._servers.entries()).map(([serverName, server], idx) => fn(server, serverName, idx)));
|
|
1659
1912
|
}
|
|
1660
1913
|
};
|
|
1661
1914
|
_ts_decorate([
|
|
@@ -1676,16 +1929,16 @@ _ts_decorate([
|
|
|
1676
1929
|
|
|
1677
1930
|
// packages/core/mesh/messaging/src/signal-manager/utils.ts
|
|
1678
1931
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
1679
|
-
import { log as
|
|
1932
|
+
import { log as log7 } from "@dxos/log";
|
|
1680
1933
|
import { DeviceKind } from "@dxos/protocols/proto/dxos/client/services";
|
|
1681
|
-
var
|
|
1934
|
+
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/core/mesh/messaging/src/signal-manager/utils.ts";
|
|
1682
1935
|
var setIdentityTags = ({ identityService, devicesService, setTag }) => {
|
|
1683
1936
|
identityService.queryIdentity().subscribe((idqr) => {
|
|
1684
1937
|
if (!idqr?.identity?.identityKey) {
|
|
1685
|
-
|
|
1938
|
+
log7("empty response from identity service", {
|
|
1686
1939
|
idqr
|
|
1687
1940
|
}, {
|
|
1688
|
-
F:
|
|
1941
|
+
F: __dxlog_file7,
|
|
1689
1942
|
L: 21,
|
|
1690
1943
|
S: void 0,
|
|
1691
1944
|
C: (f, a) => f(...a)
|
|
@@ -1696,10 +1949,10 @@ var setIdentityTags = ({ identityService, devicesService, setTag }) => {
|
|
|
1696
1949
|
});
|
|
1697
1950
|
devicesService.queryDevices().subscribe((dqr) => {
|
|
1698
1951
|
if (!dqr || !dqr.devices || dqr.devices.length === 0) {
|
|
1699
|
-
|
|
1952
|
+
log7("empty response from device service", {
|
|
1700
1953
|
device: dqr
|
|
1701
1954
|
}, {
|
|
1702
|
-
F:
|
|
1955
|
+
F: __dxlog_file7,
|
|
1703
1956
|
L: 30,
|
|
1704
1957
|
S: void 0,
|
|
1705
1958
|
C: (f, a) => f(...a)
|
|
@@ -1707,7 +1960,7 @@ var setIdentityTags = ({ identityService, devicesService, setTag }) => {
|
|
|
1707
1960
|
return;
|
|
1708
1961
|
}
|
|
1709
1962
|
invariant6(dqr, "empty response from device service", {
|
|
1710
|
-
F:
|
|
1963
|
+
F: __dxlog_file7,
|
|
1711
1964
|
L: 33,
|
|
1712
1965
|
S: void 0,
|
|
1713
1966
|
A: [
|
|
@@ -1717,10 +1970,10 @@ var setIdentityTags = ({ identityService, devicesService, setTag }) => {
|
|
|
1717
1970
|
});
|
|
1718
1971
|
const thisDevice = dqr.devices.find((device) => device.kind === DeviceKind.CURRENT);
|
|
1719
1972
|
if (!thisDevice) {
|
|
1720
|
-
|
|
1973
|
+
log7("no current device", {
|
|
1721
1974
|
device: dqr
|
|
1722
1975
|
}, {
|
|
1723
|
-
F:
|
|
1976
|
+
F: __dxlog_file7,
|
|
1724
1977
|
L: 37,
|
|
1725
1978
|
S: void 0,
|
|
1726
1979
|
C: (f, a) => f(...a)
|