@fluidframework/driver-base 2.0.0-dev.3.1.0.125672 → 2.0.0-dev.4.1.0.148229
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/documentDeltaConnection.d.ts +6 -2
- package/dist/documentDeltaConnection.d.ts.map +1 -1
- package/dist/documentDeltaConnection.js +91 -25
- package/dist/documentDeltaConnection.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/lib/documentDeltaConnection.d.ts +6 -2
- package/lib/documentDeltaConnection.d.ts.map +1 -1
- package/lib/documentDeltaConnection.js +92 -26
- package/lib/documentDeltaConnection.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/test/types/validateDriverBasePrevious.generated.js.map +1 -1
- package/package.json +33 -35
- package/src/documentDeltaConnection.ts +108 -25
- package/src/packageVersion.ts +1 -1
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
loggerToMonitoringContext,
|
|
31
31
|
MonitoringContext,
|
|
32
32
|
EventEmitterWithErrorHandling,
|
|
33
|
+
normalizeError,
|
|
33
34
|
} from "@fluidframework/telemetry-utils";
|
|
34
35
|
import type { Socket } from "socket.io-client";
|
|
35
36
|
// For now, this package is versioned and released in unison with the specific drivers
|
|
@@ -81,10 +82,21 @@ export class DocumentDeltaConnection
|
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
public get disposed() {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
// Increase the stack trace limit temporarily, so as to debug better in case it occurs.
|
|
86
|
+
// We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.
|
|
87
|
+
const originalStackTraceLimit = (Error as any).stackTraceLimit;
|
|
88
|
+
try {
|
|
89
|
+
(Error as any).stackTraceLimit = 50;
|
|
90
|
+
assert(
|
|
91
|
+
this._disposed || this.socket.connected,
|
|
92
|
+
0x244 /* "Socket is closed, but connection is not!" */,
|
|
93
|
+
);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
const normalizedError = this.addPropsToError(error);
|
|
96
|
+
throw normalizedError;
|
|
97
|
+
} finally {
|
|
98
|
+
(Error as any).stackTraceLimit = originalStackTraceLimit;
|
|
99
|
+
}
|
|
88
100
|
return this._disposed;
|
|
89
101
|
}
|
|
90
102
|
|
|
@@ -120,6 +132,7 @@ export class DocumentDeltaConnection
|
|
|
120
132
|
public documentId: string,
|
|
121
133
|
logger: ITelemetryLogger,
|
|
122
134
|
private readonly enableLongPollingDowngrades: boolean = false,
|
|
135
|
+
protected readonly connectionId?: string,
|
|
123
136
|
) {
|
|
124
137
|
super((name, error) => {
|
|
125
138
|
logger.sendErrorEvent(
|
|
@@ -223,7 +236,18 @@ export class DocumentDeltaConnection
|
|
|
223
236
|
}
|
|
224
237
|
|
|
225
238
|
private checkNotClosed() {
|
|
226
|
-
|
|
239
|
+
// Increase the stack trace limit temporarily, so as to debug better in case it occurs.
|
|
240
|
+
// We are seeing this in telemetry and we are unable to figure out why it is happening, so this should help.
|
|
241
|
+
const originalStackTraceLimit = (Error as any).stackTraceLimit;
|
|
242
|
+
try {
|
|
243
|
+
(Error as any).stackTraceLimit = 50;
|
|
244
|
+
assert(!this.disposed, 0x20c /* "connection disposed" */);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
const normalizedError = this.addPropsToError(error);
|
|
247
|
+
throw normalizedError;
|
|
248
|
+
} finally {
|
|
249
|
+
(Error as any).stackTraceLimit = originalStackTraceLimit;
|
|
250
|
+
}
|
|
227
251
|
}
|
|
228
252
|
|
|
229
253
|
/**
|
|
@@ -318,7 +342,26 @@ export class DocumentDeltaConnection
|
|
|
318
342
|
/**
|
|
319
343
|
* Disconnect from the websocket and close the websocket too.
|
|
320
344
|
*/
|
|
321
|
-
|
|
345
|
+
private closeSocket(error: IAnyDriverError) {
|
|
346
|
+
if (this._disposed) {
|
|
347
|
+
// This would be rare situation due to complexity around socket emitting events.
|
|
348
|
+
this.logger.sendTelemetryEvent(
|
|
349
|
+
{
|
|
350
|
+
eventName: "SocketCloseOnDisposedConnection",
|
|
351
|
+
driverVersion,
|
|
352
|
+
details: JSON.stringify({
|
|
353
|
+
...this.getConnectionDetailsProps(),
|
|
354
|
+
trackedListenerCount: this.trackedListeners.size,
|
|
355
|
+
}),
|
|
356
|
+
},
|
|
357
|
+
error,
|
|
358
|
+
);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
this.closeSocketCore(error);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
protected closeSocketCore(error: IAnyDriverError) {
|
|
322
365
|
this.disconnect(error);
|
|
323
366
|
}
|
|
324
367
|
|
|
@@ -332,8 +375,7 @@ export class DocumentDeltaConnection
|
|
|
332
375
|
eventName: "ClientClosingDeltaConnection",
|
|
333
376
|
driverVersion,
|
|
334
377
|
details: JSON.stringify({
|
|
335
|
-
|
|
336
|
-
socketConnected: this.socket.connected,
|
|
378
|
+
...this.getConnectionDetailsProps(),
|
|
337
379
|
}),
|
|
338
380
|
});
|
|
339
381
|
this.disconnect(
|
|
@@ -361,23 +403,24 @@ export class DocumentDeltaConnection
|
|
|
361
403
|
// to prevent normal messages from being emitted.
|
|
362
404
|
this._disposed = true;
|
|
363
405
|
|
|
364
|
-
//
|
|
365
|
-
//
|
|
406
|
+
// Remove all listeners listening on the socket. These are listeners on socket and not on this connection
|
|
407
|
+
// object. Anyway since we have disposed this connection object, nobody should listen to event on socket
|
|
408
|
+
// anymore.
|
|
409
|
+
this.removeTrackedListeners();
|
|
410
|
+
|
|
411
|
+
// Clear the connection/socket before letting the deltaManager/connection manager know about the disconnect.
|
|
412
|
+
this.disconnectCore();
|
|
413
|
+
|
|
414
|
+
// Let user of connection object know about disconnect.
|
|
366
415
|
this.emit("disconnect", err);
|
|
367
416
|
this.logger.sendTelemetryEvent({
|
|
368
417
|
eventName: "AfterDisconnectEvent",
|
|
369
418
|
driverVersion,
|
|
370
419
|
details: JSON.stringify({
|
|
371
|
-
|
|
420
|
+
...this.getConnectionDetailsProps(),
|
|
372
421
|
disconnectListenerCount: this.listenerCount("disconnect"),
|
|
373
422
|
}),
|
|
374
423
|
});
|
|
375
|
-
// user of DeltaConnection should have processed "disconnect" event and removed all listeners. Not clear
|
|
376
|
-
// if we want to enforce that, as some users (like LocalDocumentService) do not unregister any handlers
|
|
377
|
-
// assert(this.listenerCount("disconnect") === 0, "'disconnect` events should be processed synchronously");
|
|
378
|
-
|
|
379
|
-
this.removeTrackedListeners();
|
|
380
|
-
this.disconnectCore();
|
|
381
424
|
}
|
|
382
425
|
|
|
383
426
|
/**
|
|
@@ -403,14 +446,34 @@ export class DocumentDeltaConnection
|
|
|
403
446
|
|
|
404
447
|
this._details = await new Promise<IConnected>((resolve, reject) => {
|
|
405
448
|
const failAndCloseSocket = (err: IAnyDriverError) => {
|
|
406
|
-
|
|
449
|
+
try {
|
|
450
|
+
this.closeSocket(err);
|
|
451
|
+
} catch (failError) {
|
|
452
|
+
const normalizedError = this.addPropsToError(failError);
|
|
453
|
+
this.logger.sendErrorEvent({ eventName: "CloseSocketError" }, normalizedError);
|
|
454
|
+
}
|
|
407
455
|
reject(err);
|
|
408
456
|
};
|
|
409
457
|
|
|
410
458
|
const failConnection = (err: IAnyDriverError) => {
|
|
411
|
-
|
|
459
|
+
try {
|
|
460
|
+
this.disconnect(err);
|
|
461
|
+
} catch (failError) {
|
|
462
|
+
const normalizedError = this.addPropsToError(failError);
|
|
463
|
+
this.logger.sendErrorEvent(
|
|
464
|
+
{ eventName: "FailConnectionError" },
|
|
465
|
+
normalizedError,
|
|
466
|
+
);
|
|
467
|
+
}
|
|
412
468
|
reject(err);
|
|
413
469
|
};
|
|
470
|
+
|
|
471
|
+
// Immediately set the connection timeout.
|
|
472
|
+
// Give extra 2 seconds for handshake on top of socket connection timeout.
|
|
473
|
+
this.socketConnectionTimeout = setTimeout(() => {
|
|
474
|
+
failConnection(this.createErrorObject("orderingServiceHandshakeTimeout"));
|
|
475
|
+
}, timeout + 2000);
|
|
476
|
+
|
|
414
477
|
// Listen for connection issues
|
|
415
478
|
this.addConnectionListener("connect_error", (error) => {
|
|
416
479
|
internalSocketConnectionFailureCount++;
|
|
@@ -560,16 +623,31 @@ export class DocumentDeltaConnection
|
|
|
560
623
|
});
|
|
561
624
|
|
|
562
625
|
this.socket.emit("connect_document", connectMessage);
|
|
563
|
-
|
|
564
|
-
// Give extra 2 seconds for handshake on top of socket connection timeout
|
|
565
|
-
this.socketConnectionTimeout = setTimeout(() => {
|
|
566
|
-
failConnection(this.createErrorObject("orderingServiceHandshakeTimeout"));
|
|
567
|
-
}, timeout + 2000);
|
|
568
626
|
});
|
|
569
627
|
|
|
570
628
|
assert(!this.disposed, 0x246 /* "checking consistency of socket & _disposed flags" */);
|
|
571
629
|
}
|
|
572
630
|
|
|
631
|
+
private addPropsToError(errorToBeNormalized: unknown) {
|
|
632
|
+
const normalizedError = normalizeError(errorToBeNormalized, {
|
|
633
|
+
props: {
|
|
634
|
+
details: JSON.stringify({
|
|
635
|
+
...this.getConnectionDetailsProps(),
|
|
636
|
+
}),
|
|
637
|
+
},
|
|
638
|
+
});
|
|
639
|
+
return normalizedError;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
private getConnectionDetailsProps() {
|
|
643
|
+
return {
|
|
644
|
+
disposed: this._disposed,
|
|
645
|
+
socketConnected: this.socket?.connected,
|
|
646
|
+
clientId: this._details?.clientId,
|
|
647
|
+
connectionId: this.connectionId,
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
|
|
573
651
|
protected earlyOpHandler = (documentId: string, msgs: ISequencedDocumentMessage[]) => {
|
|
574
652
|
this.queuedMessages.push(...msgs);
|
|
575
653
|
};
|
|
@@ -654,7 +732,12 @@ export class DocumentDeltaConnection
|
|
|
654
732
|
const errorObj = createGenericNetworkError(
|
|
655
733
|
`socket.io (${handler}): ${message}`,
|
|
656
734
|
{ canRetry },
|
|
657
|
-
{
|
|
735
|
+
{
|
|
736
|
+
driverVersion,
|
|
737
|
+
details: JSON.stringify({
|
|
738
|
+
...this.getConnectionDetailsProps(),
|
|
739
|
+
}),
|
|
740
|
+
},
|
|
658
741
|
);
|
|
659
742
|
|
|
660
743
|
return errorObj;
|
package/src/packageVersion.ts
CHANGED