@fluidframework/container-loader 1.2.2 → 2.0.0-internal.1.0.0.82159
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/audience.d.ts +2 -2
- package/dist/audience.d.ts.map +1 -1
- package/dist/audience.js.map +1 -1
- package/dist/catchUpMonitor.d.ts +40 -0
- package/dist/catchUpMonitor.d.ts.map +1 -0
- package/dist/catchUpMonitor.js +74 -0
- package/dist/catchUpMonitor.js.map +1 -0
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +0 -1
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionState.d.ts +0 -5
- package/dist/connectionState.d.ts.map +1 -1
- package/dist/connectionState.js +0 -5
- package/dist/connectionState.js.map +1 -1
- package/dist/connectionStateHandler.d.ts +12 -4
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/connectionStateHandler.js +47 -15
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +8 -6
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +82 -46
- package/dist/container.js.map +1 -1
- package/dist/containerStorageAdapter.d.ts +2 -2
- package/dist/containerStorageAdapter.d.ts.map +1 -1
- package/dist/containerStorageAdapter.js +2 -2
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +6 -6
- package/dist/deltaManager.js.map +1 -1
- package/dist/deltaManagerProxy.d.ts +4 -1
- package/dist/deltaManagerProxy.d.ts.map +1 -1
- package/dist/deltaQueue.d.ts +9 -2
- package/dist/deltaQueue.d.ts.map +1 -1
- package/dist/deltaQueue.js +31 -26
- package/dist/deltaQueue.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +7 -0
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +4 -3
- package/dist/loader.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/protocol.d.ts +22 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +52 -0
- package/dist/protocol.js.map +1 -0
- package/dist/protocolTreeDocumentStorageService.d.ts +1 -1
- package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/dist/retriableDocumentStorageService.d.ts +2 -2
- package/dist/retriableDocumentStorageService.d.ts.map +1 -1
- package/dist/retriableDocumentStorageService.js +2 -2
- package/dist/retriableDocumentStorageService.js.map +1 -1
- package/lib/audience.d.ts +2 -2
- package/lib/audience.d.ts.map +1 -1
- package/lib/audience.js.map +1 -1
- package/lib/catchUpMonitor.d.ts +40 -0
- package/lib/catchUpMonitor.d.ts.map +1 -0
- package/lib/catchUpMonitor.js +69 -0
- package/lib/catchUpMonitor.js.map +1 -0
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +0 -1
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionState.d.ts +0 -5
- package/lib/connectionState.d.ts.map +1 -1
- package/lib/connectionState.js +0 -5
- package/lib/connectionState.js.map +1 -1
- package/lib/connectionStateHandler.d.ts +12 -4
- package/lib/connectionStateHandler.d.ts.map +1 -1
- package/lib/connectionStateHandler.js +47 -15
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +8 -6
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +82 -46
- package/lib/container.js.map +1 -1
- package/lib/containerStorageAdapter.d.ts +2 -2
- package/lib/containerStorageAdapter.d.ts.map +1 -1
- package/lib/containerStorageAdapter.js +2 -2
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +6 -6
- package/lib/deltaManager.js.map +1 -1
- package/lib/deltaManagerProxy.d.ts +4 -1
- package/lib/deltaManagerProxy.d.ts.map +1 -1
- package/lib/deltaQueue.d.ts +9 -2
- package/lib/deltaQueue.d.ts.map +1 -1
- package/lib/deltaQueue.js +32 -27
- package/lib/deltaQueue.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/loader.d.ts +7 -0
- package/lib/loader.d.ts.map +1 -1
- package/lib/loader.js +4 -3
- package/lib/loader.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/protocol.d.ts +22 -0
- package/lib/protocol.d.ts.map +1 -0
- package/lib/protocol.js +48 -0
- package/lib/protocol.js.map +1 -0
- package/lib/protocolTreeDocumentStorageService.d.ts +1 -1
- package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/lib/retriableDocumentStorageService.d.ts +2 -2
- package/lib/retriableDocumentStorageService.d.ts.map +1 -1
- package/lib/retriableDocumentStorageService.js +2 -2
- package/lib/retriableDocumentStorageService.js.map +1 -1
- package/package.json +23 -15
- package/src/audience.ts +2 -2
- package/src/catchUpMonitor.ts +99 -0
- package/src/connectionManager.ts +0 -1
- package/src/connectionState.ts +0 -6
- package/src/connectionStateHandler.ts +55 -15
- package/src/container.ts +115 -63
- package/src/containerStorageAdapter.ts +8 -2
- package/src/deltaManager.ts +6 -4
- package/src/deltaQueue.ts +34 -28
- package/src/index.ts +4 -0
- package/src/loader.ts +13 -2
- package/src/packageVersion.ts +1 -1
- package/src/protocol.ts +96 -0
- package/src/retriableDocumentStorageService.ts +8 -2
package/lib/container.js
CHANGED
|
@@ -9,7 +9,6 @@ import { assert, performance, unreachableCase } from "@fluidframework/common-uti
|
|
|
9
9
|
import { AttachState, isFluidCodeDetails, } from "@fluidframework/container-definitions";
|
|
10
10
|
import { DataCorruptionError, extractSafePropertiesFromMessage, GenericError, UsageError, } from "@fluidframework/container-utils";
|
|
11
11
|
import { readAndParse, OnlineStatus, isOnline, ensureFluidResolvedUrl, combineAppAndProtocolSummary, runWithRetry, isFluidResolvedUrl, isRuntimeMessage, isUnpackedRuntimeMessage, } from "@fluidframework/driver-utils";
|
|
12
|
-
import { ProtocolOpHandlerWithClientValidation, } from "@fluidframework/protocol-base";
|
|
13
12
|
import { MessageType, SummaryType, } from "@fluidframework/protocol-definitions";
|
|
14
13
|
import { ChildLogger, EventEmitterWithErrorHandling, PerformanceEvent, raiseConnectedEvent, TelemetryLogger, connectedEventName, disconnectedEventName, normalizeError, loggerToMonitoringContext, wrapError, } from "@fluidframework/telemetry-utils";
|
|
15
14
|
import { Audience } from "./audience";
|
|
@@ -28,6 +27,7 @@ import { initQuorumValuesFromCodeDetails, getCodeDetailsFromQuorumValues, Quorum
|
|
|
28
27
|
import { CollabWindowTracker } from "./collabWindowTracker";
|
|
29
28
|
import { ConnectionManager } from "./connectionManager";
|
|
30
29
|
import { ConnectionState } from "./connectionState";
|
|
30
|
+
import { ProtocolHandler, } from "./protocol";
|
|
31
31
|
const detachedContainerRefSeqNumber = 0;
|
|
32
32
|
const dirtyContainerEvent = "dirty";
|
|
33
33
|
const savedContainerEvent = "saved";
|
|
@@ -57,6 +57,10 @@ export async function waitContainerToCatchUp(container) {
|
|
|
57
57
|
: new GenericError(baseMessage));
|
|
58
58
|
};
|
|
59
59
|
container.on("closed", closedCallback);
|
|
60
|
+
// Depending on config, transition to "connected" state may include the guarantee
|
|
61
|
+
// that all known ops have been processed. If so, we may introduce additional wait here.
|
|
62
|
+
// Waiting for "connected" state in either case gets us at least to our own Join op
|
|
63
|
+
// which is a reasonable approximation of "caught up"
|
|
60
64
|
const waitForOps = () => {
|
|
61
65
|
assert(container.connectionState === ConnectionState.CatchingUp
|
|
62
66
|
|| container.connectionState === ConnectionState.Connected, 0x0cd /* "Container disconnected while waiting for ops!" */);
|
|
@@ -98,9 +102,22 @@ export async function waitContainerToCatchUp(container) {
|
|
|
98
102
|
const getCodeProposal =
|
|
99
103
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
100
104
|
(quorum) => { var _a; return (_a = quorum.get("code")) !== null && _a !== void 0 ? _a : quorum.get("code2"); };
|
|
105
|
+
/**
|
|
106
|
+
* Helper function to report to telemetry cases where operation takes longer than expected (1s)
|
|
107
|
+
* @param logger - logger to use
|
|
108
|
+
* @param eventName - event name
|
|
109
|
+
* @param action - functor to call and measure
|
|
110
|
+
*/
|
|
111
|
+
async function ReportIfTooLong(logger, eventName, action) {
|
|
112
|
+
const event = PerformanceEvent.start(logger, { eventName });
|
|
113
|
+
const props = await action();
|
|
114
|
+
if (event.duration > 1000) {
|
|
115
|
+
event.end(props);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
101
118
|
const summarizerClientType = "summarizer";
|
|
102
119
|
export class Container extends EventEmitterWithErrorHandling {
|
|
103
|
-
constructor(loader, config) {
|
|
120
|
+
constructor(loader, config, protocolHandlerBuilder) {
|
|
104
121
|
var _a, _b;
|
|
105
122
|
super((name, error) => {
|
|
106
123
|
this.mc.logger.sendErrorEvent({
|
|
@@ -109,6 +126,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
109
126
|
}, error);
|
|
110
127
|
});
|
|
111
128
|
this.loader = loader;
|
|
129
|
+
this.protocolHandlerBuilder = protocolHandlerBuilder;
|
|
112
130
|
// Tells if container can reconnect on losing fist connection
|
|
113
131
|
// If false, container gets closed on loss of connection.
|
|
114
132
|
this._canReconnect = true;
|
|
@@ -122,7 +140,6 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
122
140
|
this.attachStarted = false;
|
|
123
141
|
this._dirtyContainer = false;
|
|
124
142
|
this.setAutoReconnectTime = performance.now();
|
|
125
|
-
this._audience = new Audience();
|
|
126
143
|
this.clientDetailsOverride = config.clientDetailsOverride;
|
|
127
144
|
this._resolvedUrl = config.resolvedUrl;
|
|
128
145
|
if (config.canReconnect !== undefined) {
|
|
@@ -142,6 +159,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
142
159
|
containerAttachState: () => this._attachState,
|
|
143
160
|
containerLifecycleState: () => this._lifecycleState,
|
|
144
161
|
containerConnectionState: () => ConnectionState[this.connectionState],
|
|
162
|
+
serializedContainer: config.serializedContainerState !== undefined,
|
|
145
163
|
},
|
|
146
164
|
// we need to be judicious with our logging here to avoid generating too much data
|
|
147
165
|
// all data logged here should be broadly applicable, and not specific to a
|
|
@@ -154,6 +172,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
154
172
|
containerLoadedFromVersionId: () => { var _a; return (_a = this.loadedFromVersion) === null || _a === void 0 ? void 0 : _a.id; },
|
|
155
173
|
containerLoadedFromVersionDate: () => { var _a; return (_a = this.loadedFromVersion) === null || _a === void 0 ? void 0 : _a.date; },
|
|
156
174
|
// message information to associate errors with the specific execution state
|
|
175
|
+
// dmLastMsqSeqNumber: if present, same as dmLastProcessedSeqNumber
|
|
157
176
|
dmLastMsqSeqNumber: () => { var _a, _b; return (_b = (_a = this.deltaManager) === null || _a === void 0 ? void 0 : _a.lastMessage) === null || _b === void 0 ? void 0 : _b.sequenceNumber; },
|
|
158
177
|
dmLastMsqSeqTimestamp: () => { var _a, _b; return (_b = (_a = this.deltaManager) === null || _a === void 0 ? void 0 : _a.lastMessage) === null || _b === void 0 ? void 0 : _b.timestamp; },
|
|
159
178
|
dmLastMsqSeqClientId: () => { var _a, _b; return (_b = (_a = this.deltaManager) === null || _a === void 0 ? void 0 : _a.lastMessage) === null || _b === void 0 ? void 0 : _b.clientId; },
|
|
@@ -253,13 +272,13 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
253
272
|
/**
|
|
254
273
|
* Load an existing container.
|
|
255
274
|
*/
|
|
256
|
-
static async load(loader, loadOptions, pendingLocalState) {
|
|
275
|
+
static async load(loader, loadOptions, pendingLocalState, protocolHandlerBuilder) {
|
|
257
276
|
const container = new Container(loader, {
|
|
258
277
|
clientDetailsOverride: loadOptions.clientDetailsOverride,
|
|
259
278
|
resolvedUrl: loadOptions.resolvedUrl,
|
|
260
279
|
canReconnect: loadOptions.canReconnect,
|
|
261
280
|
serializedContainerState: pendingLocalState,
|
|
262
|
-
});
|
|
281
|
+
}, protocolHandlerBuilder);
|
|
263
282
|
return PerformanceEvent.timedExecAsync(container.mc.logger, { eventName: "Load" }, async (event) => new Promise((resolve, reject) => {
|
|
264
283
|
var _a, _b;
|
|
265
284
|
const version = loadOptions.version;
|
|
@@ -293,8 +312,8 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
293
312
|
/**
|
|
294
313
|
* Create a new container in a detached state.
|
|
295
314
|
*/
|
|
296
|
-
static async createDetached(loader, codeDetails) {
|
|
297
|
-
const container = new Container(loader, {});
|
|
315
|
+
static async createDetached(loader, codeDetails, protocolHandlerBuilder) {
|
|
316
|
+
const container = new Container(loader, {}, protocolHandlerBuilder);
|
|
298
317
|
return PerformanceEvent.timedExecAsync(container.mc.logger, { eventName: "CreateDetached" }, async (_event) => {
|
|
299
318
|
await container.createDetached(codeDetails);
|
|
300
319
|
return container;
|
|
@@ -304,8 +323,8 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
304
323
|
* Create a new container in a detached state that is initialized with a
|
|
305
324
|
* snapshot from a previous detached container.
|
|
306
325
|
*/
|
|
307
|
-
static async rehydrateDetachedFromSnapshot(loader, snapshot) {
|
|
308
|
-
const container = new Container(loader, {});
|
|
326
|
+
static async rehydrateDetachedFromSnapshot(loader, snapshot, protocolHandlerBuilder) {
|
|
327
|
+
const container = new Container(loader, {}, protocolHandlerBuilder);
|
|
309
328
|
return PerformanceEvent.timedExecAsync(container.mc.logger, { eventName: "RehydrateDetachedFromSnapshot" }, async (_event) => {
|
|
310
329
|
const deserializedSummary = JSON.parse(snapshot);
|
|
311
330
|
await container.rehydrateDetachedFromSnapshot(deserializedSummary);
|
|
@@ -418,12 +437,12 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
418
437
|
* Retrieves the audience associated with the document
|
|
419
438
|
*/
|
|
420
439
|
get audience() {
|
|
421
|
-
return this.
|
|
440
|
+
return this.protocolHandler.audience;
|
|
422
441
|
}
|
|
423
442
|
/**
|
|
424
443
|
* Returns true if container is dirty.
|
|
425
444
|
* Which means data loss if container is closed at that same moment
|
|
426
|
-
* Most likely that happens when there is no network connection to
|
|
445
|
+
* Most likely that happens when there is no network connection to Relay Service
|
|
427
446
|
*/
|
|
428
447
|
get isDirty() {
|
|
429
448
|
return this._dirtyContainer;
|
|
@@ -489,7 +508,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
489
508
|
assert(this.attachState === AttachState.Attached, 0x0d1 /* "Container should be attached before close" */);
|
|
490
509
|
assert(this.resolvedUrl !== undefined && this.resolvedUrl.type === "fluid", 0x0d2 /* "resolved url should be valid Fluid url" */);
|
|
491
510
|
assert(!!this._protocolHandler, 0x2e3 /* "Must have a valid protocol handler instance" */);
|
|
492
|
-
assert(this._protocolHandler.attributes.term !== undefined,
|
|
511
|
+
assert(this._protocolHandler.attributes.term !== undefined, "Must have a valid protocol handler instance");
|
|
493
512
|
const pendingState = {
|
|
494
513
|
pendingRuntimeState: this.context.getPendingLocalState(),
|
|
495
514
|
url: this.resolvedUrl.url,
|
|
@@ -788,20 +807,21 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
788
807
|
// ...load in the existing quorum
|
|
789
808
|
// Initialize the protocol handler
|
|
790
809
|
this._protocolHandler = pendingLocalState === undefined
|
|
791
|
-
? await this.initializeProtocolStateFromSnapshot(attributes, this.storageService, snapshot)
|
|
792
|
-
:
|
|
810
|
+
? await this.initializeProtocolStateFromSnapshot(attributes, this.storageService, snapshot) : await this.initializeProtocolState(attributes, {
|
|
811
|
+
members: pendingLocalState.protocol.members,
|
|
812
|
+
proposals: pendingLocalState.protocol.proposals,
|
|
813
|
+
values: pendingLocalState.protocol.values,
|
|
814
|
+
});
|
|
793
815
|
const codeDetails = this.getCodeDetailsFromQuorum();
|
|
794
816
|
await this.instantiateContext(true, // existing
|
|
795
817
|
codeDetails, snapshot, pendingLocalState === null || pendingLocalState === void 0 ? void 0 : pendingLocalState.pendingRuntimeState);
|
|
796
|
-
// Internal context is fully loaded at this point
|
|
797
|
-
this.setLoaded();
|
|
798
818
|
// We might have hit some failure that did not manifest itself in exception in this flow,
|
|
799
819
|
// do not start op processing in such case - static version of Container.load() will handle it correctly.
|
|
800
820
|
if (!this.closed) {
|
|
801
821
|
if (opsBeforeReturnP !== undefined) {
|
|
802
822
|
this._deltaManager.inbound.resume();
|
|
803
|
-
await opsBeforeReturnP;
|
|
804
|
-
await this._deltaManager.inbound.waitTillProcessingDone();
|
|
823
|
+
await ReportIfTooLong(this.mc.logger, "WaitOps", async () => { await opsBeforeReturnP; return {}; });
|
|
824
|
+
await ReportIfTooLong(this.mc.logger, "WaitOpProcessing", async () => this._deltaManager.inbound.waitTillProcessingDone());
|
|
805
825
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
806
826
|
this._deltaManager.inbound.pause();
|
|
807
827
|
}
|
|
@@ -827,9 +847,13 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
827
847
|
if (this.closed) {
|
|
828
848
|
throw new Error("Container was closed while load()");
|
|
829
849
|
}
|
|
850
|
+
// Internal context is fully loaded at this point
|
|
851
|
+
this.setLoaded();
|
|
830
852
|
return {
|
|
831
853
|
sequenceNumber: attributes.sequenceNumber,
|
|
832
854
|
version: versionId,
|
|
855
|
+
dmLastProcessedSeqNumber: this._deltaManager.lastSequenceNumber,
|
|
856
|
+
dmLastKnownSeqNumber: this._deltaManager.lastKnownSeqNumber,
|
|
833
857
|
};
|
|
834
858
|
}
|
|
835
859
|
async createDetached(source) {
|
|
@@ -841,9 +865,11 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
841
865
|
await this.attachDeltaManagerOpHandler(attributes);
|
|
842
866
|
// Need to just seed the source data in the code quorum. Quorum itself is empty
|
|
843
867
|
const qValues = initQuorumValuesFromCodeDetails(source);
|
|
844
|
-
this._protocolHandler = await this.initializeProtocolState(attributes,
|
|
845
|
-
|
|
846
|
-
|
|
868
|
+
this._protocolHandler = await this.initializeProtocolState(attributes, {
|
|
869
|
+
members: [],
|
|
870
|
+
proposals: [],
|
|
871
|
+
values: qValues,
|
|
872
|
+
});
|
|
847
873
|
// The load context - given we seeded the quorum - will be great
|
|
848
874
|
await this.instantiateContextDetached(false);
|
|
849
875
|
this.setLoaded();
|
|
@@ -862,9 +888,11 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
862
888
|
const qValues = await readAndParse(this._storage, baseTree.blobs.quorumValues);
|
|
863
889
|
const codeDetails = getCodeDetailsFromQuorumValues(qValues);
|
|
864
890
|
this._protocolHandler =
|
|
865
|
-
await this.initializeProtocolState(attributes,
|
|
866
|
-
|
|
867
|
-
|
|
891
|
+
await this.initializeProtocolState(attributes, {
|
|
892
|
+
members: [],
|
|
893
|
+
proposals: [],
|
|
894
|
+
values: codeDetails !== undefined ? initQuorumValuesFromCodeDetails(codeDetails) : [],
|
|
895
|
+
});
|
|
868
896
|
await this.instantiateContextDetached(true, // existing
|
|
869
897
|
snapshotTree);
|
|
870
898
|
this.setLoaded();
|
|
@@ -906,22 +934,27 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
906
934
|
return attributes;
|
|
907
935
|
}
|
|
908
936
|
async initializeProtocolStateFromSnapshot(attributes, storage, snapshot) {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
937
|
+
const quorumSnapshot = {
|
|
938
|
+
members: [],
|
|
939
|
+
proposals: [],
|
|
940
|
+
values: [],
|
|
941
|
+
};
|
|
912
942
|
if (snapshot !== undefined) {
|
|
913
943
|
const baseTree = getProtocolSnapshotTree(snapshot);
|
|
914
|
-
[members, proposals, values] = await Promise.all([
|
|
944
|
+
[quorumSnapshot.members, quorumSnapshot.proposals, quorumSnapshot.values] = await Promise.all([
|
|
915
945
|
readAndParse(storage, baseTree.blobs.quorumMembers),
|
|
916
946
|
readAndParse(storage, baseTree.blobs.quorumProposals),
|
|
917
947
|
readAndParse(storage, baseTree.blobs.quorumValues),
|
|
918
948
|
]);
|
|
919
949
|
}
|
|
920
|
-
const protocolHandler = await this.initializeProtocolState(attributes,
|
|
950
|
+
const protocolHandler = await this.initializeProtocolState(attributes, quorumSnapshot);
|
|
921
951
|
return protocolHandler;
|
|
922
952
|
}
|
|
923
|
-
async initializeProtocolState(attributes,
|
|
924
|
-
|
|
953
|
+
async initializeProtocolState(attributes, quorumSnapshot) {
|
|
954
|
+
var _a, _b;
|
|
955
|
+
const protocolHandlerBuilder = (_a = this.protocolHandlerBuilder) !== null && _a !== void 0 ? _a : ((...args) => new ProtocolHandler(...args, new Audience()));
|
|
956
|
+
const protocol = protocolHandlerBuilder(attributes, quorumSnapshot, (key, value) => this.submitMessage(MessageType.Propose, { key, value }), (_b = this._initialClients) !== null && _b !== void 0 ? _b : []);
|
|
957
|
+
this._initialClients = undefined;
|
|
925
958
|
const protocolLogger = ChildLogger.create(this.subLogger, "ProtocolHandler");
|
|
926
959
|
protocol.quorum.on("error", (error) => {
|
|
927
960
|
protocolLogger.sendErrorEvent(error);
|
|
@@ -1015,14 +1048,25 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1015
1048
|
deltaManager.inbound.pause();
|
|
1016
1049
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1017
1050
|
deltaManager.inboundSignal.pause();
|
|
1018
|
-
deltaManager.on("connect", (details,
|
|
1051
|
+
deltaManager.on("connect", (details, _opsBehind) => {
|
|
1019
1052
|
var _a;
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
this.
|
|
1053
|
+
if (this._protocolHandler === undefined) {
|
|
1054
|
+
// Store the initial clients so that they can be submitted to the
|
|
1055
|
+
// protocol handler when it is created.
|
|
1056
|
+
this._initialClients = details.initialClients;
|
|
1024
1057
|
}
|
|
1025
|
-
|
|
1058
|
+
else {
|
|
1059
|
+
// When reconnecting, the protocol handler is already created,
|
|
1060
|
+
// so we can update the audience right now.
|
|
1061
|
+
this._protocolHandler.audience.clear();
|
|
1062
|
+
for (const priorClient of (_a = details.initialClients) !== null && _a !== void 0 ? _a : []) {
|
|
1063
|
+
this._protocolHandler.audience.addMember(priorClient.clientId, priorClient.client);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
const deltaManagerForCatchingUp = this.mc.config.getBoolean("Fluid.Container.CatchUpBeforeDeclaringConnected") === true ?
|
|
1067
|
+
this.deltaManager
|
|
1068
|
+
: undefined;
|
|
1069
|
+
this.connectionStateHandler.receivedConnectEvent(this.connectionMode, details, deltaManagerForCatchingUp);
|
|
1026
1070
|
});
|
|
1027
1071
|
deltaManager.on("disconnect", (reason) => {
|
|
1028
1072
|
var _a;
|
|
@@ -1194,15 +1238,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1194
1238
|
processSignal(message) {
|
|
1195
1239
|
// No clientId indicates a system signal message.
|
|
1196
1240
|
if (message.clientId === null) {
|
|
1197
|
-
|
|
1198
|
-
if (innerContent.type === MessageType.ClientJoin) {
|
|
1199
|
-
const newClient = innerContent.content;
|
|
1200
|
-
this._audience.addMember(newClient.clientId, newClient.client);
|
|
1201
|
-
}
|
|
1202
|
-
else if (innerContent.type === MessageType.ClientLeave) {
|
|
1203
|
-
const leftClientId = innerContent.content;
|
|
1204
|
-
this._audience.removeMember(leftClientId);
|
|
1205
|
-
}
|
|
1241
|
+
this.protocolHandler.processSignal(message);
|
|
1206
1242
|
}
|
|
1207
1243
|
else {
|
|
1208
1244
|
const local = this.clientId === message.clientId;
|