@fluidframework/container-loader 1.0.0 → 1.1.0-76254
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/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +3 -1
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.d.ts +44 -10
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/connectionStateHandler.js +90 -35
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +2 -2
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +48 -70
- 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 +4 -4
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/contracts.d.ts +1 -1
- package/dist/contracts.js +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +9 -1
- package/dist/deltaManager.js.map +1 -1
- package/dist/deltaQueue.d.ts.map +1 -1
- package/dist/deltaQueue.js +8 -3
- package/dist/deltaQueue.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/protocolTreeDocumentStorageService.d.ts +2 -2
- 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 +4 -4
- package/dist/retriableDocumentStorageService.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +3 -2
- package/dist/utils.js.map +1 -1
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +4 -2
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.d.ts +44 -10
- package/lib/connectionStateHandler.d.ts.map +1 -1
- package/lib/connectionStateHandler.js +90 -35
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +2 -2
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +49 -71
- 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 +4 -4
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/contracts.d.ts +1 -1
- package/lib/contracts.js +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +9 -1
- package/lib/deltaManager.js.map +1 -1
- package/lib/deltaQueue.d.ts.map +1 -1
- package/lib/deltaQueue.js +8 -3
- package/lib/deltaQueue.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/protocolTreeDocumentStorageService.d.ts +2 -2
- 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 +4 -4
- package/lib/retriableDocumentStorageService.js.map +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +3 -2
- package/lib/utils.js.map +1 -1
- package/package.json +15 -28
- package/src/connectionManager.ts +4 -6
- package/src/connectionStateHandler.ts +113 -54
- package/src/container.ts +66 -89
- package/src/containerStorageAdapter.ts +4 -4
- package/src/contracts.ts +1 -1
- package/src/deltaManager.ts +8 -2
- package/src/deltaQueue.ts +7 -3
- package/src/packageVersion.ts +1 -1
- package/src/retriableDocumentStorageService.ts +4 -4
- package/src/utils.ts +3 -2
package/dist/container.js
CHANGED
|
@@ -117,7 +117,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
117
117
|
// Tells if container can reconnect on losing fist connection
|
|
118
118
|
// If false, container gets closed on loss of connection.
|
|
119
119
|
this._canReconnect = true;
|
|
120
|
-
this._lifecycleState = "
|
|
120
|
+
this._lifecycleState = "loading";
|
|
121
121
|
this._attachState = container_definitions_1.AttachState.Detached;
|
|
122
122
|
this.resumedOpProcessingAfterLoad = false;
|
|
123
123
|
this.firstConnection = true;
|
|
@@ -173,16 +173,14 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
173
173
|
logConnectionStateChangeTelemetry: (value, oldState, reason) => this.logConnectionStateChangeTelemetry(value, oldState, reason),
|
|
174
174
|
shouldClientJoinWrite: () => this._deltaManager.connectionManager.shouldJoinWrite(),
|
|
175
175
|
maxClientLeaveWaitTime: this.loader.services.options.maxClientLeaveWaitTime,
|
|
176
|
-
logConnectionIssue: (eventName) => {
|
|
176
|
+
logConnectionIssue: (eventName, details) => {
|
|
177
177
|
// We get here when socket does not receive any ops on "write" connection, including
|
|
178
178
|
// its own join op. Attempt recovery option.
|
|
179
|
-
this._deltaManager.logConnectionIssue({
|
|
180
|
-
eventName,
|
|
181
|
-
duration: common_utils_1.performance.now() - this.connectionTransitionTimes[connectionState_1.ConnectionState.CatchingUp],
|
|
182
|
-
});
|
|
179
|
+
this._deltaManager.logConnectionIssue(Object.assign({ eventName, duration: common_utils_1.performance.now() - this.connectionTransitionTimes[connectionState_1.ConnectionState.CatchingUp] }, (details === undefined ? {} : { details: JSON.stringify(details) })));
|
|
183
180
|
},
|
|
184
181
|
connectionStateChanged: () => {
|
|
185
|
-
if
|
|
182
|
+
// Fire events only if container is fully loaded and not closed
|
|
183
|
+
if (this._lifecycleState === "loaded") {
|
|
186
184
|
this.propagateConnectionState();
|
|
187
185
|
}
|
|
188
186
|
},
|
|
@@ -268,7 +266,6 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
268
266
|
});
|
|
269
267
|
return telemetry_utils_1.PerformanceEvent.timedExecAsync(container.mc.logger, { eventName: "Load" }, async (event) => new Promise((resolve, reject) => {
|
|
270
268
|
var _a, _b;
|
|
271
|
-
container._lifecycleState = "loading";
|
|
272
269
|
const version = loadOptions.version;
|
|
273
270
|
const defaultMode = { opsBeforeReturn: "cached" };
|
|
274
271
|
// if we have pendingLocalState, anything we cached is not useful and we shouldn't wait for connection
|
|
@@ -303,7 +300,6 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
303
300
|
static async createDetached(loader, codeDetails) {
|
|
304
301
|
const container = new Container(loader, {});
|
|
305
302
|
return telemetry_utils_1.PerformanceEvent.timedExecAsync(container.mc.logger, { eventName: "CreateDetached" }, async (_event) => {
|
|
306
|
-
container._lifecycleState = "loading";
|
|
307
303
|
await container.createDetached(codeDetails);
|
|
308
304
|
return container;
|
|
309
305
|
}, { start: true, end: true, cancel: "generic" });
|
|
@@ -316,20 +312,16 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
316
312
|
const container = new Container(loader, {});
|
|
317
313
|
return telemetry_utils_1.PerformanceEvent.timedExecAsync(container.mc.logger, { eventName: "RehydrateDetachedFromSnapshot" }, async (_event) => {
|
|
318
314
|
const deserializedSummary = JSON.parse(snapshot);
|
|
319
|
-
container._lifecycleState = "loading";
|
|
320
315
|
await container.rehydrateDetachedFromSnapshot(deserializedSummary);
|
|
321
316
|
return container;
|
|
322
317
|
}, { start: true, end: true, cancel: "generic" });
|
|
323
318
|
}
|
|
324
|
-
|
|
325
|
-
return (this._lifecycleState !== "created" && this._lifecycleState !== "loading");
|
|
326
|
-
}
|
|
327
|
-
set loaded(t) {
|
|
328
|
-
(0, common_utils_1.assert)(t, 0x27d /* "Setting loaded state to false is not supported" */);
|
|
329
|
-
(0, common_utils_1.assert)(this._lifecycleState !== "created", 0x27e /* "Must go through loading state before loaded" */);
|
|
319
|
+
setLoaded() {
|
|
330
320
|
// It's conceivable the container could be closed when this is called
|
|
331
321
|
// Only transition states if currently loading
|
|
332
322
|
if (this._lifecycleState === "loading") {
|
|
323
|
+
// Propagate current connection state through the system.
|
|
324
|
+
this.propagateConnectionState();
|
|
333
325
|
this._lifecycleState = "loaded";
|
|
334
326
|
}
|
|
335
327
|
}
|
|
@@ -451,19 +443,30 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
451
443
|
return this.protocolHandler.quorum;
|
|
452
444
|
}
|
|
453
445
|
close(error) {
|
|
446
|
+
// 1. Ensure that close sequence is exactly the same no matter if it's initiated by host or by DeltaManager
|
|
447
|
+
// 2. We need to ensure that we deliver disconnect event to runtime properly. See connectionStateChanged
|
|
448
|
+
// handler. We only deliver events if container fully loaded. Transitioning from "loading" ->
|
|
449
|
+
// "closing" will lose that info (can also solve by tracking extra state).
|
|
450
|
+
this._deltaManager.close(error);
|
|
451
|
+
(0, common_utils_1.assert)(this.connectionState === connectionState_1.ConnectionState.Disconnected, 0x0cf /* "disconnect event was not raised!" */);
|
|
452
|
+
(0, common_utils_1.assert)(this._lifecycleState === "closed", 0x314 /* Container properly closed */);
|
|
453
|
+
}
|
|
454
|
+
closeCore(error) {
|
|
454
455
|
var _a, _b, _c, _d;
|
|
455
|
-
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
456
|
+
(0, common_utils_1.assert)(!this.closed, 0x315 /* re-entrancy */);
|
|
458
457
|
try {
|
|
459
|
-
this._lifecycleState = "closing";
|
|
460
458
|
// Ensure that we raise all key events even if one of these throws
|
|
461
459
|
try {
|
|
462
|
-
|
|
460
|
+
// Raise event first, to ensure we capture _lifecycleState before transition.
|
|
461
|
+
// This gives us a chance to know what errors happened on open vs. on fully loaded container.
|
|
462
|
+
this.mc.logger.sendTelemetryEvent({
|
|
463
|
+
eventName: "ContainerClose",
|
|
464
|
+
category: error === undefined ? "generic" : "error",
|
|
465
|
+
}, error);
|
|
466
|
+
this._lifecycleState = "closing";
|
|
463
467
|
(_a = this._protocolHandler) === null || _a === void 0 ? void 0 : _a.close();
|
|
464
468
|
this.connectionStateHandler.dispose();
|
|
465
469
|
(_b = this._context) === null || _b === void 0 ? void 0 : _b.dispose(error !== undefined ? new Error(error.message) : undefined);
|
|
466
|
-
(0, common_utils_1.assert)(this.connectionState === connectionState_1.ConnectionState.Disconnected, 0x0cf /* "disconnect event was not raised!" */);
|
|
467
470
|
(_c = this._storageService) === null || _c === void 0 ? void 0 : _c.dispose();
|
|
468
471
|
// Notify storage about critical errors. They may be due to disconnect between client & server knowledge
|
|
469
472
|
// about file, like file being overwritten in storage, but client having stale local cache.
|
|
@@ -473,10 +476,6 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
473
476
|
catch (exception) {
|
|
474
477
|
this.mc.logger.sendErrorEvent({ eventName: "ContainerCloseException" }, exception);
|
|
475
478
|
}
|
|
476
|
-
this.mc.logger.sendTelemetryEvent({
|
|
477
|
-
eventName: "ContainerClose",
|
|
478
|
-
category: error === undefined ? "generic" : "error",
|
|
479
|
-
}, error);
|
|
480
479
|
this.emit("closed", error);
|
|
481
480
|
this.removeAllListeners();
|
|
482
481
|
if (this.visibilityEventHandler !== undefined) {
|
|
@@ -494,11 +493,12 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
494
493
|
(0, common_utils_1.assert)(this.attachState === container_definitions_1.AttachState.Attached, 0x0d1 /* "Container should be attached before close" */);
|
|
495
494
|
(0, common_utils_1.assert)(this.resolvedUrl !== undefined && this.resolvedUrl.type === "fluid", 0x0d2 /* "resolved url should be valid Fluid url" */);
|
|
496
495
|
(0, common_utils_1.assert)(!!this._protocolHandler, 0x2e3 /* "Must have a valid protocol handler instance" */);
|
|
496
|
+
(0, common_utils_1.assert)(this._protocolHandler.attributes.term !== undefined, 0x30b /* Must have a valid protocol handler instance */);
|
|
497
497
|
const pendingState = {
|
|
498
498
|
pendingRuntimeState: this.context.getPendingLocalState(),
|
|
499
499
|
url: this.resolvedUrl.url,
|
|
500
|
-
protocol: this.
|
|
501
|
-
term: this._protocolHandler.term,
|
|
500
|
+
protocol: this.protocolHandler.getProtocolState(),
|
|
501
|
+
term: this._protocolHandler.attributes.term,
|
|
502
502
|
clientId: this.clientId,
|
|
503
503
|
};
|
|
504
504
|
this.close();
|
|
@@ -797,10 +797,8 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
797
797
|
const codeDetails = this.getCodeDetailsFromQuorum();
|
|
798
798
|
await this.instantiateContext(true, // existing
|
|
799
799
|
codeDetails, snapshot, pendingLocalState === null || pendingLocalState === void 0 ? void 0 : pendingLocalState.pendingRuntimeState);
|
|
800
|
-
// Propagate current connection state through the system.
|
|
801
|
-
this.propagateConnectionState();
|
|
802
800
|
// Internal context is fully loaded at this point
|
|
803
|
-
this.
|
|
801
|
+
this.setLoaded();
|
|
804
802
|
// We might have hit some failure that did not manifest itself in exception in this flow,
|
|
805
803
|
// do not start op processing in such case - static version of Container.load() will handle it correctly.
|
|
806
804
|
if (!this.closed) {
|
|
@@ -856,8 +854,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
856
854
|
qValues);
|
|
857
855
|
// The load context - given we seeded the quorum - will be great
|
|
858
856
|
await this.instantiateContextDetached(false);
|
|
859
|
-
this.
|
|
860
|
-
this.loaded = true;
|
|
857
|
+
this.setLoaded();
|
|
861
858
|
}
|
|
862
859
|
async rehydrateDetachedFromSnapshot(detachedContainerSnapshot) {
|
|
863
860
|
if (detachedContainerSnapshot.tree[".hasAttachmentBlobs"] !== undefined) {
|
|
@@ -878,8 +875,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
878
875
|
codeDetails !== undefined ? (0, quorum_1.initQuorumValuesFromCodeDetails)(codeDetails) : []);
|
|
879
876
|
await this.instantiateContextDetached(true, // existing
|
|
880
877
|
snapshotTree);
|
|
881
|
-
this.
|
|
882
|
-
this.propagateConnectionState();
|
|
878
|
+
this.setLoaded();
|
|
883
879
|
}
|
|
884
880
|
async connectStorageService() {
|
|
885
881
|
var _a, _b;
|
|
@@ -933,7 +929,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
933
929
|
return protocolHandler;
|
|
934
930
|
}
|
|
935
931
|
async initializeProtocolState(attributes, members, proposals, values) {
|
|
936
|
-
const protocol = new protocol_base_1.
|
|
932
|
+
const protocol = new protocol_base_1.ProtocolOpHandlerWithClientValidation(attributes.minimumSequenceNumber, attributes.sequenceNumber, attributes.term, members, proposals, values, (key, value) => this.submitMessage(protocol_definitions_1.MessageType.Propose, { key, value }));
|
|
937
933
|
const protocolLogger = telemetry_utils_1.ChildLogger.create(this.subLogger, "ProtocolHandler");
|
|
938
934
|
protocol.quorum.on("error", (error) => {
|
|
939
935
|
protocolLogger.sendErrorEvent(error);
|
|
@@ -961,17 +957,11 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
961
957
|
return protocol;
|
|
962
958
|
}
|
|
963
959
|
captureProtocolSummary() {
|
|
964
|
-
const quorumSnapshot = this.protocolHandler.
|
|
965
|
-
// Save attributes for the document
|
|
966
|
-
const documentAttributes = {
|
|
967
|
-
minimumSequenceNumber: this.protocolHandler.minimumSequenceNumber,
|
|
968
|
-
sequenceNumber: this.protocolHandler.sequenceNumber,
|
|
969
|
-
term: this.protocolHandler.term,
|
|
970
|
-
};
|
|
960
|
+
const quorumSnapshot = this.protocolHandler.snapshot();
|
|
971
961
|
const summary = {
|
|
972
962
|
tree: {
|
|
973
963
|
attributes: {
|
|
974
|
-
content: JSON.stringify(
|
|
964
|
+
content: JSON.stringify(this.protocolHandler.attributes),
|
|
975
965
|
type: protocol_definitions_1.SummaryType.Blob,
|
|
976
966
|
},
|
|
977
967
|
quorumMembers: {
|
|
@@ -1060,7 +1050,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1060
1050
|
this.emit("readonly", readonly);
|
|
1061
1051
|
});
|
|
1062
1052
|
deltaManager.on("closed", (error) => {
|
|
1063
|
-
this.
|
|
1053
|
+
this.closeCore(error);
|
|
1064
1054
|
});
|
|
1065
1055
|
return deltaManager;
|
|
1066
1056
|
}
|
|
@@ -1116,6 +1106,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1116
1106
|
}
|
|
1117
1107
|
}
|
|
1118
1108
|
propagateConnectionState() {
|
|
1109
|
+
var _a;
|
|
1119
1110
|
const logOpsOnReconnect = this.connectionState === connectionState_1.ConnectionState.Connected &&
|
|
1120
1111
|
!this.firstConnection &&
|
|
1121
1112
|
this.connectionMode === "write";
|
|
@@ -1123,11 +1114,11 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1123
1114
|
this.messageCountAfterDisconnection = 0;
|
|
1124
1115
|
}
|
|
1125
1116
|
const state = this.connectionState === connectionState_1.ConnectionState.Connected;
|
|
1126
|
-
if
|
|
1117
|
+
// Both protocol and context should not be undefined if we got so far.
|
|
1118
|
+
if (((_a = this._context) === null || _a === void 0 ? void 0 : _a.disposed) === false) {
|
|
1127
1119
|
this.context.setConnectionState(state, this.clientId);
|
|
1128
1120
|
}
|
|
1129
|
-
(
|
|
1130
|
-
this.protocolHandler.quorum.setConnectionState(state, this.clientId);
|
|
1121
|
+
this.protocolHandler.setConnectionState(state, this.clientId);
|
|
1131
1122
|
(0, telemetry_utils_1.raiseConnectedEvent)(this.mc.logger, this, state, this.clientId);
|
|
1132
1123
|
if (logOpsOnReconnect) {
|
|
1133
1124
|
this.mc.logger.sendTelemetryEvent({ eventName: "OpsSentOnReconnect", count: this.messageCountAfterDisconnection });
|
|
@@ -1169,32 +1160,19 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1169
1160
|
return this._deltaManager.submit(type, contents, batch, metadata);
|
|
1170
1161
|
}
|
|
1171
1162
|
processRemoteMessage(message) {
|
|
1172
|
-
var _a, _b;
|
|
1173
|
-
// Check and report if we're getting messages from a clientId that we previously
|
|
1174
|
-
// flagged as shouldHaveLeft, or from a client that's not in the quorum but should be
|
|
1175
|
-
if (message.clientId != null) {
|
|
1176
|
-
let errorMsg;
|
|
1177
|
-
const client = this.getQuorum().getMember(message.clientId);
|
|
1178
|
-
if (client === undefined && message.type !== protocol_definitions_1.MessageType.ClientJoin) {
|
|
1179
|
-
// pre-0.58 error message: messageClientIdMissingFromQuorum
|
|
1180
|
-
errorMsg = "Remote message's clientId is missing from the quorum";
|
|
1181
|
-
}
|
|
1182
|
-
else if ((client === null || client === void 0 ? void 0 : client.shouldHaveLeft) === true && message.type !== protocol_definitions_1.MessageType.NoOp) {
|
|
1183
|
-
// pre-0.58 error message: messageClientIdShouldHaveLeft
|
|
1184
|
-
errorMsg = "Remote message's clientId already should have left";
|
|
1185
|
-
}
|
|
1186
|
-
if (errorMsg !== undefined) {
|
|
1187
|
-
const error = new container_utils_1.DataCorruptionError(errorMsg, (0, container_utils_1.extractSafePropertiesFromMessage)(message));
|
|
1188
|
-
this.close((0, telemetry_utils_1.normalizeError)(error));
|
|
1189
|
-
}
|
|
1190
|
-
}
|
|
1191
1163
|
const local = this.clientId === message.clientId;
|
|
1164
|
+
// Allow the protocol handler to process the message
|
|
1165
|
+
let result = { immediateNoOp: false };
|
|
1166
|
+
try {
|
|
1167
|
+
result = this.protocolHandler.processMessage(message, local);
|
|
1168
|
+
}
|
|
1169
|
+
catch (error) {
|
|
1170
|
+
this.close((0, telemetry_utils_1.wrapError)(error, (errorMessage) => new container_utils_1.DataCorruptionError(errorMessage, (0, container_utils_1.extractSafePropertiesFromMessage)(message))));
|
|
1171
|
+
}
|
|
1192
1172
|
// Forward non system messages to the loaded runtime for processing
|
|
1193
1173
|
if (!(0, protocol_base_1.isSystemMessage)(message)) {
|
|
1194
1174
|
this.context.process(message, local, undefined);
|
|
1195
1175
|
}
|
|
1196
|
-
// Allow the protocol handler to process the message
|
|
1197
|
-
const result = this.protocolHandler.processMessage(message, local);
|
|
1198
1176
|
// Inactive (not in quorum or not writers) clients don't take part in the minimum sequence number calculation.
|
|
1199
1177
|
if (this.activeConnection()) {
|
|
1200
1178
|
if (this.collabWindowTracker === undefined) {
|
|
@@ -1206,7 +1184,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1206
1184
|
this.collabWindowTracker = new collabWindowTracker_1.CollabWindowTracker((type, contents) => {
|
|
1207
1185
|
(0, common_utils_1.assert)(this.activeConnection(), 0x241 /* "disconnect should result in stopSequenceNumberUpdate() call" */);
|
|
1208
1186
|
this.submitMessage(type, contents);
|
|
1209
|
-
},
|
|
1187
|
+
}, this.serviceConfiguration.noopTimeFrequency, this.serviceConfiguration.noopCountFrequency);
|
|
1210
1188
|
}
|
|
1211
1189
|
this.collabWindowTracker.scheduleSequenceNumberUpdate(message, result.immediateNoOp === true);
|
|
1212
1190
|
}
|