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