@fluidframework/container-loader 2.0.0-internal.6.0.0 → 2.0.0-internal.6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/connectionManager.d.ts +3 -3
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +33 -24
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.d.ts +14 -14
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/connectionStateHandler.js +17 -12
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +26 -38
- package/dist/container.js.map +1 -1
- package/dist/contracts.d.ts +11 -7
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/deltaManager.d.ts +4 -4
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +5 -4
- package/dist/deltaManager.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/dist/protocol.d.ts +4 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +23 -1
- package/dist/protocol.js.map +1 -1
- package/lib/connectionManager.d.ts +3 -3
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +33 -24
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.d.ts +14 -14
- package/lib/connectionStateHandler.d.ts.map +1 -1
- package/lib/connectionStateHandler.js +17 -12
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +27 -39
- package/lib/container.js.map +1 -1
- package/lib/contracts.d.ts +11 -7
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/deltaManager.d.ts +4 -4
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +5 -4
- package/lib/deltaManager.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/protocol.d.ts +4 -2
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +23 -1
- package/lib/protocol.js.map +1 -1
- package/package.json +13 -17
- package/src/connectionManager.ts +46 -31
- package/src/connectionStateHandler.ts +28 -36
- package/src/container.ts +46 -51
- package/src/contracts.ts +12 -6
- package/src/deltaManager.ts +19 -13
- package/src/packageVersion.ts +1 -1
- package/src/protocol.ts +33 -1
package/lib/protocol.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAEvE,OAAO,EACN,gBAAgB,IAAI,oBAAoB,EACxC,eAAe,EACf,iBAAiB,EACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACN,mBAAmB,EACnB,qBAAqB,EAErB,yBAAyB,EAEzB,cAAc,EAEd,MAAM,sCAAsC,CAAC;AAG9C,eAAO,MAAM,kBAAkB,GAAa,CAAC;AAG7C,oBAAY,UAAU;IACrB,UAAU,SAAS;IACnB,WAAW,UAAU;IACrB,KAAK,UAAU;CACf;AAED;;GAEG;AACH,oBAAY,sBAAsB,GAAG,CACpC,UAAU,EAAE,mBAAmB,EAC/B,QAAQ,EAAE,eAAe,EACzB,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,KAC7C,gBAAgB,CAAC;AAEtB,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAC7D,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,aAAa,CAAC,OAAO,EAAE,cAAc,OAAE;CACvC;AAED,qBAAa,eAAgB,SAAQ,iBAAkB,YAAW,gBAAgB;aAKhE,QAAQ,EAAE,cAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,oBAAoB;gBAJrC,UAAU,EAAE,mBAAmB,EAC/B,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,MAAM,EACjC,QAAQ,EAAE,cAAc,EACvB,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO;IAqB9D,cAAc,CACpB,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,GACZ,qBAAqB;IAuBjB,aAAa,CAAC,OAAO,EAAE,cAAc;CAgC5C;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,cAAc,WAWzE"}
|
package/lib/protocol.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
+
import { canBeCoalescedByService } from "@fluidframework/driver-utils";
|
|
5
6
|
import { ProtocolOpHandler, } from "@fluidframework/protocol-base";
|
|
7
|
+
import { MessageType, } from "@fluidframework/protocol-definitions";
|
|
6
8
|
// "term" was an experimental feature that is being removed. The only safe value to use is 1.
|
|
7
9
|
export const OnlyValidTermValue = 1;
|
|
8
10
|
// ADO: #1986: Start using enum from protocol-base.
|
|
@@ -13,9 +15,10 @@ export var SignalType;
|
|
|
13
15
|
SignalType["Clear"] = "clear";
|
|
14
16
|
})(SignalType || (SignalType = {}));
|
|
15
17
|
export class ProtocolHandler extends ProtocolOpHandler {
|
|
16
|
-
constructor(attributes, quorumSnapshot, sendProposal, audience) {
|
|
18
|
+
constructor(attributes, quorumSnapshot, sendProposal, audience, shouldClientHaveLeft) {
|
|
17
19
|
super(attributes.minimumSequenceNumber, attributes.sequenceNumber, quorumSnapshot.members, quorumSnapshot.proposals, quorumSnapshot.values, sendProposal);
|
|
18
20
|
this.audience = audience;
|
|
21
|
+
this.shouldClientHaveLeft = shouldClientHaveLeft;
|
|
19
22
|
// Join / leave signals are ignored for "write" clients in favor of join / leave ops
|
|
20
23
|
this.quorum.on("addMember", (clientId, details) => audience.addMember(clientId, details.client));
|
|
21
24
|
this.quorum.on("removeMember", (clientId) => audience.removeMember(clientId));
|
|
@@ -23,6 +26,25 @@ export class ProtocolHandler extends ProtocolOpHandler {
|
|
|
23
26
|
this.audience.addMember(clientId, details.client);
|
|
24
27
|
}
|
|
25
28
|
}
|
|
29
|
+
processMessage(message, local) {
|
|
30
|
+
const client = this.quorum.getMember(message.clientId);
|
|
31
|
+
// Check and report if we're getting messages from a clientId that we previously
|
|
32
|
+
// flagged as shouldHaveLeft, or from a client that's not in the quorum but should be
|
|
33
|
+
if (message.clientId != null) {
|
|
34
|
+
if (client === undefined && message.type !== MessageType.ClientJoin) {
|
|
35
|
+
// pre-0.58 error message: messageClientIdMissingFromQuorum
|
|
36
|
+
throw new Error("Remote message's clientId is missing from the quorum");
|
|
37
|
+
}
|
|
38
|
+
// Here checking canBeCoalescedByService is used as an approximation of "is benign to process despite being unexpected".
|
|
39
|
+
// It's still not good to see these messages from unexpected clientIds, but since they don't harm the integrity of the
|
|
40
|
+
// document we don't need to blow up aggressively.
|
|
41
|
+
if (this.shouldClientHaveLeft(message.clientId) && !canBeCoalescedByService(message)) {
|
|
42
|
+
// pre-0.58 error message: messageClientIdShouldHaveLeft
|
|
43
|
+
throw new Error("Remote message's clientId already should have left");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return super.processMessage(message, local);
|
|
47
|
+
}
|
|
26
48
|
processSignal(message) {
|
|
27
49
|
const innerContent = message.content;
|
|
28
50
|
switch (innerContent.type) {
|
package/lib/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAGN,iBAAiB,GACjB,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IAudienceOwner } from \"@fluidframework/container-definitions\";\nimport { canBeCoalescedByService } from \"@fluidframework/driver-utils\";\nimport {\n\tIProtocolHandler as IBaseProtocolHandler,\n\tIQuorumSnapshot,\n\tProtocolOpHandler,\n} from \"@fluidframework/protocol-base\";\nimport {\n\tIDocumentAttributes,\n\tIProcessMessageResult,\n\tISequencedClient,\n\tISequencedDocumentMessage,\n\tISignalClient,\n\tISignalMessage,\n\tMessageType,\n} from \"@fluidframework/protocol-definitions\";\n\n// \"term\" was an experimental feature that is being removed. The only safe value to use is 1.\nexport const OnlyValidTermValue = 1 as const;\n\n// ADO: #1986: Start using enum from protocol-base.\nexport enum SignalType {\n\tClientJoin = \"join\", // same value as MessageType.ClientJoin,\n\tClientLeave = \"leave\", // same value as MessageType.ClientLeave,\n\tClear = \"clear\", // used only by client for synthetic signals\n}\n\n/**\n * Function to be used for creating a protocol handler.\n */\nexport type ProtocolHandlerBuilder = (\n\tattributes: IDocumentAttributes,\n\tsnapshot: IQuorumSnapshot,\n\tsendProposal: (key: string, value: any) => number,\n) => IProtocolHandler;\n\nexport interface IProtocolHandler extends IBaseProtocolHandler {\n\treadonly audience: IAudienceOwner;\n\tprocessSignal(message: ISignalMessage);\n}\n\nexport class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandler {\n\tconstructor(\n\t\tattributes: IDocumentAttributes,\n\t\tquorumSnapshot: IQuorumSnapshot,\n\t\tsendProposal: (key: string, value: any) => number,\n\t\tpublic readonly audience: IAudienceOwner,\n\t\tprivate readonly shouldClientHaveLeft: (clientId: string) => boolean,\n\t) {\n\t\tsuper(\n\t\t\tattributes.minimumSequenceNumber,\n\t\t\tattributes.sequenceNumber,\n\t\t\tquorumSnapshot.members,\n\t\t\tquorumSnapshot.proposals,\n\t\t\tquorumSnapshot.values,\n\t\t\tsendProposal,\n\t\t);\n\n\t\t// Join / leave signals are ignored for \"write\" clients in favor of join / leave ops\n\t\tthis.quorum.on(\"addMember\", (clientId, details) =>\n\t\t\taudience.addMember(clientId, details.client),\n\t\t);\n\t\tthis.quorum.on(\"removeMember\", (clientId) => audience.removeMember(clientId));\n\t\tfor (const [clientId, details] of this.quorum.getMembers()) {\n\t\t\tthis.audience.addMember(clientId, details.client);\n\t\t}\n\t}\n\n\tpublic processMessage(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t): IProcessMessageResult {\n\t\tconst client: ISequencedClient | undefined = this.quorum.getMember(message.clientId);\n\n\t\t// Check and report if we're getting messages from a clientId that we previously\n\t\t// flagged as shouldHaveLeft, or from a client that's not in the quorum but should be\n\t\tif (message.clientId != null) {\n\t\t\tif (client === undefined && message.type !== MessageType.ClientJoin) {\n\t\t\t\t// pre-0.58 error message: messageClientIdMissingFromQuorum\n\t\t\t\tthrow new Error(\"Remote message's clientId is missing from the quorum\");\n\t\t\t}\n\n\t\t\t// Here checking canBeCoalescedByService is used as an approximation of \"is benign to process despite being unexpected\".\n\t\t\t// It's still not good to see these messages from unexpected clientIds, but since they don't harm the integrity of the\n\t\t\t// document we don't need to blow up aggressively.\n\t\t\tif (this.shouldClientHaveLeft(message.clientId) && !canBeCoalescedByService(message)) {\n\t\t\t\t// pre-0.58 error message: messageClientIdShouldHaveLeft\n\t\t\t\tthrow new Error(\"Remote message's clientId already should have left\");\n\t\t\t}\n\t\t}\n\n\t\treturn super.processMessage(message, local);\n\t}\n\n\tpublic processSignal(message: ISignalMessage) {\n\t\tconst innerContent = message.content as { content: any; type: string };\n\t\tswitch (innerContent.type) {\n\t\t\tcase SignalType.Clear: {\n\t\t\t\tconst members = this.audience.getMembers();\n\t\t\t\tfor (const [clientId, client] of members) {\n\t\t\t\t\tif (client.mode === \"read\") {\n\t\t\t\t\t\tthis.audience.removeMember(clientId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientJoin: {\n\t\t\t\tconst newClient = innerContent.content as ISignalClient;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (newClient.client.mode === \"read\") {\n\t\t\t\t\tthis.audience.addMember(newClient.clientId, newClient.client);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientLeave: {\n\t\t\t\tconst leftClientId = innerContent.content as string;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (this.audience.getMember(leftClientId)?.mode === \"read\") {\n\t\t\t\t\tthis.audience.removeMember(leftClientId);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Function to check whether the protocol handler should process the Signal.\n * The protocol handler should strictly handle only ClientJoin, ClientLeave\n * and Clear signal types.\n */\nexport function protocolHandlerShouldProcessSignal(message: ISignalMessage) {\n\t// Signal originates from server\n\tif (message.clientId === null) {\n\t\tconst innerContent = message.content as { content: unknown; type: string };\n\t\treturn (\n\t\t\tinnerContent.type === SignalType.Clear ||\n\t\t\tinnerContent.type === SignalType.ClientJoin ||\n\t\t\tinnerContent.type === SignalType.ClientLeave\n\t\t);\n\t}\n\treturn false;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-loader",
|
|
3
|
-
"version": "2.0.0-internal.6.
|
|
3
|
+
"version": "2.0.0-internal.6.1.0",
|
|
4
4
|
"description": "Fluid container loader",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -37,14 +37,14 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
39
39
|
"@fluidframework/common-utils": "^1.1.1",
|
|
40
|
-
"@fluidframework/container-definitions": ">=2.0.0-internal.6.
|
|
41
|
-
"@fluidframework/container-utils": ">=2.0.0-internal.6.
|
|
42
|
-
"@fluidframework/core-interfaces": ">=2.0.0-internal.6.
|
|
43
|
-
"@fluidframework/driver-definitions": ">=2.0.0-internal.6.
|
|
44
|
-
"@fluidframework/driver-utils": ">=2.0.0-internal.6.
|
|
40
|
+
"@fluidframework/container-definitions": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
41
|
+
"@fluidframework/container-utils": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
42
|
+
"@fluidframework/core-interfaces": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
43
|
+
"@fluidframework/driver-definitions": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
44
|
+
"@fluidframework/driver-utils": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
45
45
|
"@fluidframework/protocol-base": "^1.0.0",
|
|
46
46
|
"@fluidframework/protocol-definitions": "^1.1.0",
|
|
47
|
-
"@fluidframework/telemetry-utils": ">=2.0.0-internal.6.
|
|
47
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
48
48
|
"debug": "^4.1.1",
|
|
49
49
|
"double-ended-queue": "^2.1.0-0",
|
|
50
50
|
"events": "^3.1.0",
|
|
@@ -53,13 +53,13 @@
|
|
|
53
53
|
"uuid": "^8.3.1"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@fluid-internal/test-loader-utils": ">=2.0.0-internal.6.
|
|
57
|
-
"@fluid-tools/build-cli": "^0.
|
|
56
|
+
"@fluid-internal/test-loader-utils": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
57
|
+
"@fluid-tools/build-cli": "^0.22.0",
|
|
58
58
|
"@fluidframework/build-common": "^2.0.0",
|
|
59
|
-
"@fluidframework/build-tools": "^0.
|
|
60
|
-
"@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-internal.
|
|
59
|
+
"@fluidframework/build-tools": "^0.22.0",
|
|
60
|
+
"@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-internal.6.0.0",
|
|
61
61
|
"@fluidframework/eslint-config-fluid": "^2.0.0",
|
|
62
|
-
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.6.
|
|
62
|
+
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.6.1.0 <2.0.0-internal.6.2.0",
|
|
63
63
|
"@microsoft/api-extractor": "^7.34.4",
|
|
64
64
|
"@types/double-ended-queue": "^2.1.0",
|
|
65
65
|
"@types/events": "^3.0.0",
|
|
@@ -82,11 +82,7 @@
|
|
|
82
82
|
"typescript": "~4.5.5"
|
|
83
83
|
},
|
|
84
84
|
"typeValidation": {
|
|
85
|
-
"broken": {
|
|
86
|
-
"InterfaceDeclaration_IContainerExperimental": {
|
|
87
|
-
"backCompat": false
|
|
88
|
-
}
|
|
89
|
-
}
|
|
85
|
+
"broken": {}
|
|
90
86
|
},
|
|
91
87
|
"scripts": {
|
|
92
88
|
"build": "fluid-build . --task build",
|
package/src/connectionManager.ts
CHANGED
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
IConnectionManager,
|
|
49
49
|
IConnectionManagerFactoryArgs,
|
|
50
50
|
IConnectionDetailsInternal,
|
|
51
|
+
IConnectionStateChangeReason,
|
|
51
52
|
} from "./contracts";
|
|
52
53
|
import { DeltaQueue } from "./deltaQueue";
|
|
53
54
|
import { SignalType } from "./protocol";
|
|
@@ -336,7 +337,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
336
337
|
|
|
337
338
|
private static detailsFromConnection(
|
|
338
339
|
connection: IDocumentDeltaConnection,
|
|
339
|
-
reason:
|
|
340
|
+
reason: IConnectionStateChangeReason,
|
|
340
341
|
): IConnectionDetailsInternal {
|
|
341
342
|
return {
|
|
342
343
|
claims: connection.claims,
|
|
@@ -389,7 +390,10 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
389
390
|
|
|
390
391
|
this._outbound.clear();
|
|
391
392
|
|
|
392
|
-
const disconnectReason =
|
|
393
|
+
const disconnectReason: IConnectionStateChangeReason = {
|
|
394
|
+
text: "Closing DeltaManager",
|
|
395
|
+
error,
|
|
396
|
+
};
|
|
393
397
|
|
|
394
398
|
// This raises "disconnect" event if we have active connection.
|
|
395
399
|
this.disconnectFromDeltaStream(disconnectReason);
|
|
@@ -406,7 +410,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
406
410
|
* Enables or disables automatic reconnecting.
|
|
407
411
|
* Will throw an error if reconnectMode set to Never.
|
|
408
412
|
*/
|
|
409
|
-
public setAutoReconnect(mode: ReconnectMode): void {
|
|
413
|
+
public setAutoReconnect(mode: ReconnectMode, reason: IConnectionStateChangeReason): void {
|
|
410
414
|
assert(
|
|
411
415
|
mode !== ReconnectMode.Never && this._reconnectMode !== ReconnectMode.Never,
|
|
412
416
|
0x278 /* "API is not supported for non-connecting or closed container" */,
|
|
@@ -416,7 +420,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
416
420
|
|
|
417
421
|
if (mode !== ReconnectMode.Enabled) {
|
|
418
422
|
// immediately disconnect - do not rely on service eventually dropping connection.
|
|
419
|
-
this.disconnectFromDeltaStream(
|
|
423
|
+
this.disconnectFromDeltaStream(reason);
|
|
420
424
|
}
|
|
421
425
|
}
|
|
422
426
|
|
|
@@ -463,12 +467,12 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
463
467
|
this.logger.sendErrorEvent({ eventName: "ForceReadonlyPendingChanged" });
|
|
464
468
|
}
|
|
465
469
|
|
|
466
|
-
reconnect = this.disconnectFromDeltaStream("Force readonly");
|
|
470
|
+
reconnect = this.disconnectFromDeltaStream({ text: "Force readonly" });
|
|
467
471
|
}
|
|
468
472
|
this.props.readonlyChangeHandler(this.readonly);
|
|
469
473
|
if (reconnect) {
|
|
470
474
|
// reconnect if we disconnected from before.
|
|
471
|
-
this.triggerConnect("Force Readonly", "read");
|
|
475
|
+
this.triggerConnect({ text: "Force Readonly" }, "read");
|
|
472
476
|
}
|
|
473
477
|
}
|
|
474
478
|
}
|
|
@@ -481,14 +485,17 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
481
485
|
}
|
|
482
486
|
}
|
|
483
487
|
|
|
484
|
-
public connect(reason:
|
|
485
|
-
this.connectCore(reason, connectionMode).catch((
|
|
486
|
-
const normalizedError = normalizeError(
|
|
488
|
+
public connect(reason: IConnectionStateChangeReason, connectionMode?: ConnectionMode) {
|
|
489
|
+
this.connectCore(reason, connectionMode).catch((e) => {
|
|
490
|
+
const normalizedError = normalizeError(e, { props: fatalConnectErrorProp });
|
|
487
491
|
this.props.closeHandler(normalizedError);
|
|
488
492
|
});
|
|
489
493
|
}
|
|
490
494
|
|
|
491
|
-
private async connectCore(
|
|
495
|
+
private async connectCore(
|
|
496
|
+
reason: IConnectionStateChangeReason,
|
|
497
|
+
connectionMode?: ConnectionMode,
|
|
498
|
+
): Promise<void> {
|
|
492
499
|
assert(!this._disposed, 0x26a /* "not closed" */);
|
|
493
500
|
|
|
494
501
|
if (this.connection !== undefined) {
|
|
@@ -664,7 +671,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
664
671
|
* And report the error if it escapes for any reason.
|
|
665
672
|
* @param args - The connection arguments
|
|
666
673
|
*/
|
|
667
|
-
private triggerConnect(reason:
|
|
674
|
+
private triggerConnect(reason: IConnectionStateChangeReason, connectionMode: ConnectionMode) {
|
|
668
675
|
// reconnect() includes async awaits, and that causes potential race conditions
|
|
669
676
|
// where we might already have a connection. If it were to happen, it's possible that we will connect
|
|
670
677
|
// with different mode to `connectionMode`. Glancing through the caller chains, it looks like code should be
|
|
@@ -684,7 +691,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
684
691
|
* @param error - Error causing the disconnect if any.
|
|
685
692
|
* @returns A boolean that indicates if there was an existing connection (or pending connection) to disconnect
|
|
686
693
|
*/
|
|
687
|
-
private disconnectFromDeltaStream(reason:
|
|
694
|
+
private disconnectFromDeltaStream(reason: IConnectionStateChangeReason): boolean {
|
|
688
695
|
this.pendingReconnect = false;
|
|
689
696
|
|
|
690
697
|
if (this.connection === undefined) {
|
|
@@ -717,7 +724,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
717
724
|
this._outbound.clear();
|
|
718
725
|
connection.dispose();
|
|
719
726
|
|
|
720
|
-
this.props.disconnectHandler(reason
|
|
727
|
+
this.props.disconnectHandler(reason);
|
|
721
728
|
|
|
722
729
|
this._connectionVerboseProps = {};
|
|
723
730
|
|
|
@@ -727,7 +734,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
727
734
|
/**
|
|
728
735
|
* Cancel in-progress connection attempt.
|
|
729
736
|
*/
|
|
730
|
-
private cancelConnection(reason:
|
|
737
|
+
private cancelConnection(reason: IConnectionStateChangeReason) {
|
|
731
738
|
assert(
|
|
732
739
|
this.pendingConnection !== undefined,
|
|
733
740
|
0x345 /* this.pendingConnection is undefined when trying to cancel */,
|
|
@@ -735,7 +742,10 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
735
742
|
this.pendingConnection.abort();
|
|
736
743
|
this.pendingConnection = undefined;
|
|
737
744
|
this.logger.sendTelemetryEvent({ eventName: "ConnectionCancelReceived" });
|
|
738
|
-
this.props.cancelConnectionHandler(
|
|
745
|
+
this.props.cancelConnectionHandler({
|
|
746
|
+
text: `Cancel Pending Connection due to ${reason.text}`,
|
|
747
|
+
error: reason.error,
|
|
748
|
+
});
|
|
739
749
|
}
|
|
740
750
|
|
|
741
751
|
/**
|
|
@@ -746,7 +756,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
746
756
|
private setupNewSuccessfulConnection(
|
|
747
757
|
connection: IDocumentDeltaConnection,
|
|
748
758
|
requestedMode: ConnectionMode,
|
|
749
|
-
reason:
|
|
759
|
+
reason: IConnectionStateChangeReason,
|
|
750
760
|
) {
|
|
751
761
|
// Old connection should have been cleaned up before establishing a new one
|
|
752
762
|
assert(
|
|
@@ -789,7 +799,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
789
799
|
|
|
790
800
|
if (this._disposed) {
|
|
791
801
|
// Raise proper events, Log telemetry event and close connection.
|
|
792
|
-
this.disconnectFromDeltaStream("ConnectionManager already closed");
|
|
802
|
+
this.disconnectFromDeltaStream({ text: "ConnectionManager already closed" });
|
|
793
803
|
return;
|
|
794
804
|
}
|
|
795
805
|
|
|
@@ -894,7 +904,9 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
894
904
|
* @returns A promise that resolves when the connection is reestablished or we stop trying
|
|
895
905
|
*/
|
|
896
906
|
private reconnectOnError(requestedMode: ConnectionMode, error: IAnyDriverError) {
|
|
897
|
-
this.reconnect(requestedMode, error.message, error).catch(
|
|
907
|
+
this.reconnect(requestedMode, { text: error.message, error }).catch(
|
|
908
|
+
this.props.closeHandler,
|
|
909
|
+
);
|
|
898
910
|
}
|
|
899
911
|
|
|
900
912
|
/**
|
|
@@ -906,26 +918,25 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
906
918
|
*/
|
|
907
919
|
private async reconnect(
|
|
908
920
|
requestedMode: ConnectionMode,
|
|
909
|
-
|
|
910
|
-
error?: IAnyDriverError,
|
|
921
|
+
reason: IConnectionStateChangeReason<IAnyDriverError>,
|
|
911
922
|
) {
|
|
912
923
|
// We quite often get protocol errors before / after observing nack/disconnect
|
|
913
924
|
// we do not want to run through same sequence twice.
|
|
914
925
|
// If we're already disconnected/disconnecting it's not appropriate to call this again.
|
|
915
926
|
assert(this.connection !== undefined, 0x0eb /* "Missing connection for reconnect" */);
|
|
916
927
|
|
|
917
|
-
this.disconnectFromDeltaStream(
|
|
928
|
+
this.disconnectFromDeltaStream(reason);
|
|
918
929
|
|
|
919
930
|
// We will always trigger reconnect, even if canRetry is false.
|
|
920
931
|
// Any truly fatal error state will result in container close upon attempted reconnect,
|
|
921
932
|
// which is a preferable to closing abruptly when a live connection fails.
|
|
922
|
-
if (error
|
|
933
|
+
if (reason.error?.canRetry === false) {
|
|
923
934
|
this.logger.sendTelemetryEvent(
|
|
924
935
|
{
|
|
925
936
|
eventName: "reconnectingDespiteFatalError",
|
|
926
937
|
reconnectMode: this.reconnectMode,
|
|
927
938
|
},
|
|
928
|
-
error,
|
|
939
|
+
reason.error,
|
|
929
940
|
);
|
|
930
941
|
}
|
|
931
942
|
|
|
@@ -942,9 +953,9 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
942
953
|
}
|
|
943
954
|
|
|
944
955
|
// If the error tells us to wait before retrying, then do so.
|
|
945
|
-
const delayMs = getRetryDelayFromError(error);
|
|
946
|
-
if (error !== undefined && delayMs !== undefined) {
|
|
947
|
-
this.props.reconnectionDelayHandler(delayMs, error);
|
|
956
|
+
const delayMs = getRetryDelayFromError(reason.error);
|
|
957
|
+
if (reason.error !== undefined && delayMs !== undefined) {
|
|
958
|
+
this.props.reconnectionDelayHandler(delayMs, reason.error);
|
|
948
959
|
await new Promise<void>((resolve) => {
|
|
949
960
|
setTimeout(resolve, delayMs);
|
|
950
961
|
});
|
|
@@ -956,9 +967,13 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
956
967
|
await waitForOnline();
|
|
957
968
|
|
|
958
969
|
this.triggerConnect(
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
970
|
+
{
|
|
971
|
+
text:
|
|
972
|
+
reason.error !== undefined
|
|
973
|
+
? "Reconnecting due to Error"
|
|
974
|
+
: `Reconnecting due to: ${reason.text}`,
|
|
975
|
+
error: reason.error,
|
|
976
|
+
},
|
|
962
977
|
requestedMode,
|
|
963
978
|
);
|
|
964
979
|
}
|
|
@@ -1029,7 +1044,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
1029
1044
|
// still valid?
|
|
1030
1045
|
await this.reconnect(
|
|
1031
1046
|
"write", // connectionMode
|
|
1032
|
-
"Switch to write", // message
|
|
1047
|
+
{ text: "Switch to write" }, // message
|
|
1033
1048
|
);
|
|
1034
1049
|
}
|
|
1035
1050
|
})
|
|
@@ -1083,7 +1098,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
1083
1098
|
// Note - this may close container!
|
|
1084
1099
|
this.reconnect(
|
|
1085
1100
|
"read", // connectionMode
|
|
1086
|
-
"Switch to read", // message
|
|
1101
|
+
{ text: "Switch to read" }, // message
|
|
1087
1102
|
).catch((error) => {
|
|
1088
1103
|
this.logger.sendErrorEvent({ eventName: "SwitchToReadConnection" }, error);
|
|
1089
1104
|
});
|
|
@@ -6,16 +6,16 @@
|
|
|
6
6
|
import { ITelemetryProperties, TelemetryEventCategory } from "@fluidframework/core-interfaces";
|
|
7
7
|
import { assert, Timer } from "@fluidframework/common-utils";
|
|
8
8
|
import { IDeltaManager } from "@fluidframework/container-definitions";
|
|
9
|
-
import { IAnyDriverError } from "@fluidframework/driver-definitions";
|
|
10
9
|
import { ISequencedClient, IClient } from "@fluidframework/protocol-definitions";
|
|
11
10
|
import {
|
|
12
11
|
ITelemetryLoggerExt,
|
|
13
12
|
PerformanceEvent,
|
|
14
13
|
loggerToMonitoringContext,
|
|
15
14
|
} from "@fluidframework/telemetry-utils";
|
|
15
|
+
import { IAnyDriverError } from "@fluidframework/driver-definitions";
|
|
16
16
|
import { CatchUpMonitor, ICatchUpMonitor } from "./catchUpMonitor";
|
|
17
17
|
import { ConnectionState } from "./connectionState";
|
|
18
|
-
import { IConnectionDetailsInternal } from "./contracts";
|
|
18
|
+
import { IConnectionDetailsInternal, IConnectionStateChangeReason } from "./contracts";
|
|
19
19
|
import { IProtocolHandler } from "./protocol";
|
|
20
20
|
|
|
21
21
|
// Based on recent data, it looks like majority of cases where we get stuck are due to really slow or
|
|
@@ -33,8 +33,7 @@ export interface IConnectionStateHandlerInputs {
|
|
|
33
33
|
connectionStateChanged: (
|
|
34
34
|
value: ConnectionState,
|
|
35
35
|
oldState: ConnectionState,
|
|
36
|
-
reason?:
|
|
37
|
-
error?: IAnyDriverError,
|
|
36
|
+
reason?: IConnectionStateChangeReason,
|
|
38
37
|
) => void;
|
|
39
38
|
/** Whether to expect the client to join in write mode on next connection */
|
|
40
39
|
shouldClientJoinWrite: () => boolean;
|
|
@@ -61,14 +60,14 @@ export interface IConnectionStateHandler {
|
|
|
61
60
|
dispose(): void;
|
|
62
61
|
initProtocol(protocol: IProtocolHandler): void;
|
|
63
62
|
receivedConnectEvent(details: IConnectionDetailsInternal): void;
|
|
64
|
-
receivedDisconnectEvent(reason:
|
|
65
|
-
establishingConnection(reason:
|
|
63
|
+
receivedDisconnectEvent(reason: IConnectionStateChangeReason): void;
|
|
64
|
+
establishingConnection(reason: IConnectionStateChangeReason): void;
|
|
66
65
|
/**
|
|
67
66
|
* Switches state to disconnected when we are still establishing connection during container.load(),
|
|
68
67
|
* container connect() or reconnect and the container gets closed or disposed or disconnect happens.
|
|
69
68
|
* @param reason - reason for cancelling the connection.
|
|
70
69
|
*/
|
|
71
|
-
cancelEstablishingConnection(reason:
|
|
70
|
+
cancelEstablishingConnection(reason: IConnectionStateChangeReason): void;
|
|
72
71
|
}
|
|
73
72
|
|
|
74
73
|
export function createConnectionStateHandler(
|
|
@@ -150,15 +149,15 @@ class ConnectionStateHandlerPassThrough
|
|
|
150
149
|
public initProtocol(protocol: IProtocolHandler) {
|
|
151
150
|
return this.pimpl.initProtocol(protocol);
|
|
152
151
|
}
|
|
153
|
-
public receivedDisconnectEvent(reason:
|
|
154
|
-
return this.pimpl.receivedDisconnectEvent(reason
|
|
152
|
+
public receivedDisconnectEvent(reason: IConnectionStateChangeReason<IAnyDriverError>) {
|
|
153
|
+
return this.pimpl.receivedDisconnectEvent(reason);
|
|
155
154
|
}
|
|
156
155
|
|
|
157
|
-
public establishingConnection(reason:
|
|
156
|
+
public establishingConnection(reason: IConnectionStateChangeReason) {
|
|
158
157
|
return this.pimpl.establishingConnection(reason);
|
|
159
158
|
}
|
|
160
159
|
|
|
161
|
-
public cancelEstablishingConnection(reason:
|
|
160
|
+
public cancelEstablishingConnection(reason: IConnectionStateChangeReason) {
|
|
162
161
|
return this.pimpl.cancelEstablishingConnection(reason);
|
|
163
162
|
}
|
|
164
163
|
|
|
@@ -176,10 +175,9 @@ class ConnectionStateHandlerPassThrough
|
|
|
176
175
|
public connectionStateChanged(
|
|
177
176
|
value: ConnectionState,
|
|
178
177
|
oldState: ConnectionState,
|
|
179
|
-
reason?:
|
|
180
|
-
error?: IAnyDriverError,
|
|
178
|
+
reason?: IConnectionStateChangeReason,
|
|
181
179
|
) {
|
|
182
|
-
return this.inputs.connectionStateChanged(value, oldState, reason
|
|
180
|
+
return this.inputs.connectionStateChanged(value, oldState, reason);
|
|
183
181
|
}
|
|
184
182
|
public shouldClientJoinWrite() {
|
|
185
183
|
return this.inputs.shouldClientJoinWrite();
|
|
@@ -223,8 +221,7 @@ class ConnectionStateCatchup extends ConnectionStateHandlerPassThrough {
|
|
|
223
221
|
public connectionStateChanged(
|
|
224
222
|
value: ConnectionState,
|
|
225
223
|
oldState: ConnectionState,
|
|
226
|
-
reason?:
|
|
227
|
-
error?: IAnyDriverError,
|
|
224
|
+
reason?: IConnectionStateChangeReason<IAnyDriverError>,
|
|
228
225
|
) {
|
|
229
226
|
switch (value) {
|
|
230
227
|
case ConnectionState.Connected:
|
|
@@ -268,7 +265,7 @@ class ConnectionStateCatchup extends ConnectionStateHandlerPassThrough {
|
|
|
268
265
|
default:
|
|
269
266
|
}
|
|
270
267
|
this._connectionState = value;
|
|
271
|
-
this.inputs.connectionStateChanged(value, oldState, reason
|
|
268
|
+
this.inputs.connectionStateChanged(value, oldState, reason);
|
|
272
269
|
}
|
|
273
270
|
|
|
274
271
|
private readonly transitionToConnectedState = () => {
|
|
@@ -277,11 +274,9 @@ class ConnectionStateCatchup extends ConnectionStateHandlerPassThrough {
|
|
|
277
274
|
assert(state === ConnectionState.Connected, 0x3e5 /* invariant broken */);
|
|
278
275
|
assert(this._connectionState === ConnectionState.CatchingUp, 0x3e6 /* invariant broken */);
|
|
279
276
|
this._connectionState = ConnectionState.Connected;
|
|
280
|
-
this.inputs.connectionStateChanged(
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
"caught up",
|
|
284
|
-
);
|
|
277
|
+
this.inputs.connectionStateChanged(ConnectionState.Connected, ConnectionState.CatchingUp, {
|
|
278
|
+
text: "caught up",
|
|
279
|
+
});
|
|
285
280
|
};
|
|
286
281
|
}
|
|
287
282
|
|
|
@@ -495,12 +490,12 @@ class ConnectionStateHandler implements IConnectionStateHandler {
|
|
|
495
490
|
}
|
|
496
491
|
}
|
|
497
492
|
|
|
498
|
-
public receivedDisconnectEvent(reason:
|
|
493
|
+
public receivedDisconnectEvent(reason: IConnectionStateChangeReason<IAnyDriverError>) {
|
|
499
494
|
this.connection = undefined;
|
|
500
|
-
this.setConnectionState(ConnectionState.Disconnected, reason
|
|
495
|
+
this.setConnectionState(ConnectionState.Disconnected, reason);
|
|
501
496
|
}
|
|
502
497
|
|
|
503
|
-
public cancelEstablishingConnection(reason:
|
|
498
|
+
public cancelEstablishingConnection(reason: IConnectionStateChangeReason) {
|
|
504
499
|
assert(
|
|
505
500
|
this._connectionState === ConnectionState.EstablishingConnection,
|
|
506
501
|
0x6d3 /* Connection state should be EstablishingConnection */,
|
|
@@ -511,14 +506,13 @@ class ConnectionStateHandler implements IConnectionStateHandler {
|
|
|
511
506
|
this.handler.connectionStateChanged(ConnectionState.Disconnected, oldState, reason);
|
|
512
507
|
}
|
|
513
508
|
|
|
514
|
-
public establishingConnection(reason:
|
|
509
|
+
public establishingConnection(reason: IConnectionStateChangeReason) {
|
|
515
510
|
const oldState = this._connectionState;
|
|
516
511
|
this._connectionState = ConnectionState.EstablishingConnection;
|
|
517
|
-
this.handler.connectionStateChanged(
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
);
|
|
512
|
+
this.handler.connectionStateChanged(ConnectionState.EstablishingConnection, oldState, {
|
|
513
|
+
text: `Establishing Connection due to ${reason.text}`,
|
|
514
|
+
error: reason.error,
|
|
515
|
+
});
|
|
522
516
|
}
|
|
523
517
|
|
|
524
518
|
private shouldWaitForJoinSignal() {
|
|
@@ -583,14 +577,12 @@ class ConnectionStateHandler implements IConnectionStateHandler {
|
|
|
583
577
|
|
|
584
578
|
private setConnectionState(
|
|
585
579
|
value: ConnectionState.Disconnected,
|
|
586
|
-
reason:
|
|
587
|
-
error?: IAnyDriverError,
|
|
580
|
+
reason: IConnectionStateChangeReason,
|
|
588
581
|
): void;
|
|
589
582
|
private setConnectionState(value: ConnectionState.Connected): void;
|
|
590
583
|
private setConnectionState(
|
|
591
584
|
value: ConnectionState.Disconnected | ConnectionState.Connected,
|
|
592
|
-
reason?:
|
|
593
|
-
error?: IAnyDriverError,
|
|
585
|
+
reason?: IConnectionStateChangeReason,
|
|
594
586
|
): void {
|
|
595
587
|
if (this.connectionState === value) {
|
|
596
588
|
// Already in the desired state - exit early
|
|
@@ -651,7 +643,7 @@ class ConnectionStateHandler implements IConnectionStateHandler {
|
|
|
651
643
|
}
|
|
652
644
|
|
|
653
645
|
// Report transition before we propagate event across layers
|
|
654
|
-
this.handler.connectionStateChanged(this._connectionState, oldState, reason
|
|
646
|
+
this.handler.connectionStateChanged(this._connectionState, oldState, reason);
|
|
655
647
|
}
|
|
656
648
|
|
|
657
649
|
// Helper method to switch between quorum and audience.
|