@fluidframework/container-loader 2.0.0-internal.6.0.0 → 2.0.0-internal.6.1.1
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 +27 -39
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts +6 -1
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js +8 -1
- package/dist/containerContext.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 +28 -40
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts +6 -1
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js +8 -1
- package/lib/containerContext.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 +14 -14
- package/src/connectionManager.ts +46 -31
- package/src/connectionStateHandler.ts +28 -36
- package/src/container.ts +47 -51
- package/src/containerContext.ts +8 -0
- 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/dist/container.js
CHANGED
|
@@ -194,7 +194,8 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
194
194
|
this.scope = scope;
|
|
195
195
|
this.detachedBlobStorage = detachedBlobStorage;
|
|
196
196
|
this.protocolHandlerBuilder =
|
|
197
|
-
protocolHandlerBuilder ??
|
|
197
|
+
protocolHandlerBuilder ??
|
|
198
|
+
((attributes, quorumSnapshot, sendProposal) => new protocol_1.ProtocolHandler(attributes, quorumSnapshot, sendProposal, new audience_1.Audience(), (clientId) => this.clientsWhoShouldHaveLeft.has(clientId)));
|
|
198
199
|
// Note that we capture the createProps here so we can replicate the creation call when we want to clone.
|
|
199
200
|
this.clone = async (_loadProps, createParamOverrides) => {
|
|
200
201
|
return Container.load(_loadProps, {
|
|
@@ -247,11 +248,11 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
247
248
|
this._deltaManager = this.createDeltaManager();
|
|
248
249
|
this.connectionStateHandler = (0, connectionStateHandler_1.createConnectionStateHandler)({
|
|
249
250
|
logger: this.mc.logger,
|
|
250
|
-
connectionStateChanged: (value, oldState, reason
|
|
251
|
+
connectionStateChanged: (value, oldState, reason) => {
|
|
251
252
|
if (value === connectionState_1.ConnectionState.Connected) {
|
|
252
253
|
this._clientId = this.connectionStateHandler.pendingClientId;
|
|
253
254
|
}
|
|
254
|
-
this.logConnectionStateChangeTelemetry(value, oldState, reason
|
|
255
|
+
this.logConnectionStateChangeTelemetry(value, oldState, reason);
|
|
255
256
|
if (this._lifecycleState === "loaded") {
|
|
256
257
|
this.propagateConnectionState(false /* initial transition */, value === connectionState_1.ConnectionState.Disconnected
|
|
257
258
|
? reason
|
|
@@ -284,8 +285,9 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
284
285
|
// Other possible recovery path - move to connected state (i.e. ConnectionStateHandler.joinOpTimer
|
|
285
286
|
// to call this.applyForConnectedState("addMemberEvent") for "read" connections)
|
|
286
287
|
if (mode === "read") {
|
|
287
|
-
|
|
288
|
-
this.
|
|
288
|
+
const reason = { text: "NoJoinSignal" };
|
|
289
|
+
this.disconnectInternal(reason);
|
|
290
|
+
this.connectInternal({ reason, fetchOpsFromStorage: false });
|
|
289
291
|
}
|
|
290
292
|
},
|
|
291
293
|
clientShouldHaveLeft: (clientId) => {
|
|
@@ -620,7 +622,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
620
622
|
// runtime matches pending ops to successful ones by clientId and client seq num, so we need to close the
|
|
621
623
|
// container at the same time we get pending state, otherwise this container could reconnect and resubmit with
|
|
622
624
|
// a new clientId and a future container using stale pending state without the new clientId would resubmit them
|
|
623
|
-
this.
|
|
625
|
+
this.disconnectInternal({ text: "closeAndGetPendingLocalState" }); // TODO https://dev.azure.com/fluidframework/internal/_workitems/edit/5127
|
|
624
626
|
const pendingState = await this.getPendingLocalStateCore({ notifyImminentClosure: true });
|
|
625
627
|
this.close();
|
|
626
628
|
return pendingState;
|
|
@@ -754,7 +756,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
754
756
|
if (!this.closed) {
|
|
755
757
|
this.resumeInternal({
|
|
756
758
|
fetchOpsFromStorage: false,
|
|
757
|
-
reason: "createDetached",
|
|
759
|
+
reason: { text: "createDetached" },
|
|
758
760
|
});
|
|
759
761
|
}
|
|
760
762
|
}
|
|
@@ -770,7 +772,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
770
772
|
async request(path) {
|
|
771
773
|
return telemetry_utils_1.PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "Request" }, async () => this.runtime.request(path), { end: true, cancel: "error" });
|
|
772
774
|
}
|
|
773
|
-
setAutoReconnectInternal(mode) {
|
|
775
|
+
setAutoReconnectInternal(mode, reason) {
|
|
774
776
|
const currentMode = this._deltaManager.connectionManager.reconnectMode;
|
|
775
777
|
if (currentMode === mode) {
|
|
776
778
|
return;
|
|
@@ -784,7 +786,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
784
786
|
connectionState: connectionState_1.ConnectionState[this.connectionState],
|
|
785
787
|
duration,
|
|
786
788
|
});
|
|
787
|
-
this._deltaManager.connectionManager.setAutoReconnect(mode);
|
|
789
|
+
this._deltaManager.connectionManager.setAutoReconnect(mode, reason);
|
|
788
790
|
}
|
|
789
791
|
connect() {
|
|
790
792
|
if (this.closed) {
|
|
@@ -797,7 +799,10 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
797
799
|
// Note: no need to fetch ops as we do it preemptively as part of DeltaManager.attachOpHandler().
|
|
798
800
|
// If there is gap, we will learn about it once connected, but the gap should be small (if any),
|
|
799
801
|
// assuming that connect() is called quickly after initial container boot.
|
|
800
|
-
this.connectInternal({
|
|
802
|
+
this.connectInternal({
|
|
803
|
+
reason: { text: "DocumentConnect" },
|
|
804
|
+
fetchOpsFromStorage: false,
|
|
805
|
+
});
|
|
801
806
|
}
|
|
802
807
|
}
|
|
803
808
|
connectInternal(args) {
|
|
@@ -807,21 +812,21 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
807
812
|
this.resumeInternal(args);
|
|
808
813
|
// Set Auto Reconnect Mode
|
|
809
814
|
const mode = contracts_1.ReconnectMode.Enabled;
|
|
810
|
-
this.setAutoReconnectInternal(mode);
|
|
815
|
+
this.setAutoReconnectInternal(mode, args.reason);
|
|
811
816
|
}
|
|
812
817
|
disconnect() {
|
|
813
818
|
if (this.closed) {
|
|
814
819
|
throw new container_utils_1.UsageError(`The Container is closed and cannot be disconnected`);
|
|
815
820
|
}
|
|
816
821
|
else {
|
|
817
|
-
this.disconnectInternal();
|
|
822
|
+
this.disconnectInternal({ text: "DocumentDisconnect" });
|
|
818
823
|
}
|
|
819
824
|
}
|
|
820
|
-
disconnectInternal() {
|
|
825
|
+
disconnectInternal(reason) {
|
|
821
826
|
(0, common_utils_1.assert)(!this.closed, 0x2c7 /* "Attempting to disconnect() a closed Container" */);
|
|
822
827
|
// Set Auto Reconnect Mode
|
|
823
828
|
const mode = contracts_1.ReconnectMode.Disabled;
|
|
824
|
-
this.setAutoReconnectInternal(mode);
|
|
829
|
+
this.setAutoReconnectInternal(mode, reason);
|
|
825
830
|
}
|
|
826
831
|
resumeInternal(args) {
|
|
827
832
|
(0, common_utils_1.assert)(!this.closed, 0x0d9 /* "Attempting to connect() a closed DeltaManager" */);
|
|
@@ -923,7 +928,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
923
928
|
// A) creation flow breaks (as one of the clients "sees" file as existing, and hits #2 above)
|
|
924
929
|
// B) Once file is created, transition from view-only connection to write does not work - some bugs to be fixed.
|
|
925
930
|
const connectionArgs = {
|
|
926
|
-
reason: "DocumentOpen",
|
|
931
|
+
reason: { text: "DocumentOpen" },
|
|
927
932
|
mode: "write",
|
|
928
933
|
fetchOpsFromStorage: false,
|
|
929
934
|
};
|
|
@@ -1285,10 +1290,10 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1285
1290
|
deltaManager.on("cancelEstablishingConnection", (reason) => {
|
|
1286
1291
|
this.connectionStateHandler.cancelEstablishingConnection(reason);
|
|
1287
1292
|
});
|
|
1288
|
-
deltaManager.on("disconnect", (reason
|
|
1293
|
+
deltaManager.on("disconnect", (reason) => {
|
|
1289
1294
|
this.noopHeuristic?.notifyDisconnect();
|
|
1290
1295
|
if (!this.closed) {
|
|
1291
|
-
this.connectionStateHandler.receivedDisconnectEvent(reason
|
|
1296
|
+
this.connectionStateHandler.receivedDisconnectEvent(reason);
|
|
1292
1297
|
}
|
|
1293
1298
|
});
|
|
1294
1299
|
deltaManager.on("throttled", (warning) => {
|
|
@@ -1320,7 +1325,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1320
1325
|
},
|
|
1321
1326
|
}, prefetchType);
|
|
1322
1327
|
}
|
|
1323
|
-
logConnectionStateChangeTelemetry(value, oldState, reason
|
|
1328
|
+
logConnectionStateChangeTelemetry(value, oldState, reason) {
|
|
1324
1329
|
// Log actual event
|
|
1325
1330
|
const time = common_utils_1.performance.now();
|
|
1326
1331
|
this.connectionTransitionTimes[value] = time;
|
|
@@ -1355,7 +1360,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1355
1360
|
from: connectionState_1.ConnectionState[oldState],
|
|
1356
1361
|
duration,
|
|
1357
1362
|
durationFromDisconnected,
|
|
1358
|
-
reason,
|
|
1363
|
+
reason: reason?.text,
|
|
1359
1364
|
connectionInitiationReason,
|
|
1360
1365
|
pendingClientId: this.connectionStateHandler.pendingClientId,
|
|
1361
1366
|
clientId: this.clientId,
|
|
@@ -1369,7 +1374,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1369
1374
|
quorumSize: this._protocolHandler?.quorum.getMembers().size,
|
|
1370
1375
|
isDirty: this.isDirty,
|
|
1371
1376
|
...this._deltaManager.connectionProps,
|
|
1372
|
-
}, error);
|
|
1377
|
+
}, reason?.error);
|
|
1373
1378
|
if (value === connectionState_1.ConnectionState.Connected) {
|
|
1374
1379
|
this.firstConnection = false;
|
|
1375
1380
|
}
|
|
@@ -1387,7 +1392,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1387
1392
|
// Both protocol and context should not be undefined if we got so far.
|
|
1388
1393
|
this.setContextConnectedState(state, this.readOnlyInfo.readonly ?? false);
|
|
1389
1394
|
this.protocolHandler.setConnectionState(state, this.clientId);
|
|
1390
|
-
(0, telemetry_utils_1.raiseConnectedEvent)(this.mc.logger, this, state, this.clientId, disconnectedReason);
|
|
1395
|
+
(0, telemetry_utils_1.raiseConnectedEvent)(this.mc.logger, this, state, this.clientId, disconnectedReason?.text);
|
|
1391
1396
|
}
|
|
1392
1397
|
// back-compat: ADO #1385: Remove in the future, summary op should come through submitSummaryMessage()
|
|
1393
1398
|
submitContainerMessage(type, contents, batch, metadata) {
|
|
@@ -1437,23 +1442,6 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1437
1442
|
this.savedOps.push(message);
|
|
1438
1443
|
}
|
|
1439
1444
|
const local = this.clientId === message.clientId;
|
|
1440
|
-
// Check and report if we're getting messages from a clientId that we previously
|
|
1441
|
-
// flagged should have left, or from a client that's not in the quorum but should be
|
|
1442
|
-
if (message.clientId != null) {
|
|
1443
|
-
const client = this.protocolHandler.quorum.getMember(message.clientId);
|
|
1444
|
-
if (client === undefined && message.type !== protocol_definitions_1.MessageType.ClientJoin) {
|
|
1445
|
-
// pre-0.58 error message: messageClientIdMissingFromQuorum
|
|
1446
|
-
throw new Error("Remote message's clientId is missing from the quorum");
|
|
1447
|
-
}
|
|
1448
|
-
// Here checking canBeCoalescedByService is used as an approximation of "is benign to process despite being unexpected".
|
|
1449
|
-
// It's still not good to see these messages from unexpected clientIds, but since they don't harm the integrity of the
|
|
1450
|
-
// document we don't need to blow up aggressively.
|
|
1451
|
-
if (this.clientsWhoShouldHaveLeft.has(message.clientId) &&
|
|
1452
|
-
!(0, driver_utils_1.canBeCoalescedByService)(message)) {
|
|
1453
|
-
// pre-0.58 error message: messageClientIdShouldHaveLeft
|
|
1454
|
-
throw new Error("Remote message's clientId already should have left");
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
1445
|
// Allow the protocol handler to process the message
|
|
1458
1446
|
const result = this.protocolHandler.processMessage(message, local);
|
|
1459
1447
|
// Forward messages to the loaded runtime for processing
|
|
@@ -1541,7 +1529,7 @@ class Container extends telemetry_utils_1.EventEmitterWithErrorHandling {
|
|
|
1541
1529
|
const getSpecifiedCodeDetails = () => (this.protocolHandler.quorum.get("code") ??
|
|
1542
1530
|
this.protocolHandler.quorum.get("code2"));
|
|
1543
1531
|
const existing = snapshot !== undefined;
|
|
1544
|
-
const context = new containerContext_1.ContainerContext(this.options, this.scope, snapshot, this._loadedFromVersion, this._deltaManager, this.storageAdapter, this.protocolHandler.quorum, this.protocolHandler.audience, loader, (type, contents, batch, metadata) => this.submitContainerMessage(type, contents, batch, metadata), (summaryOp, referenceSequenceNumber) => this.submitSummaryMessage(summaryOp, referenceSequenceNumber), (batch, referenceSequenceNumber) => this.submitBatch(batch, referenceSequenceNumber), (message) => this.submitSignal(message), (error) => this.dispose(error), (error) => this.close(error), this.updateDirtyContainerState, this.getAbsoluteUrl, () => this.clientId, () => this.attachState, () => this.connected, getSpecifiedCodeDetails, this._deltaManager.clientDetails, existing, this.subLogger, pendingLocalState);
|
|
1532
|
+
const context = new containerContext_1.ContainerContext(this.options, this.scope, snapshot, this._loadedFromVersion, this._deltaManager, this.storageAdapter, this.protocolHandler.quorum, this.protocolHandler.audience, loader, (type, contents, batch, metadata) => this.submitContainerMessage(type, contents, batch, metadata), (summaryOp, referenceSequenceNumber) => this.submitSummaryMessage(summaryOp, referenceSequenceNumber), (batch, referenceSequenceNumber) => this.submitBatch(batch, referenceSequenceNumber), (message) => this.submitSignal(message), (error) => this.dispose(error), (error) => this.close(error), this.updateDirtyContainerState, this.getAbsoluteUrl, () => this.resolvedUrl?.id, () => this.clientId, () => this.attachState, () => this.connected, getSpecifiedCodeDetails, this._deltaManager.clientDetails, existing, this.subLogger, pendingLocalState);
|
|
1545
1533
|
this._runtime = await telemetry_utils_1.PerformanceEvent.timedExecAsync(this.subLogger, { eventName: "InstantiateRuntime" }, async () => runtimeFactory.instantiateRuntime(context, existing));
|
|
1546
1534
|
this._lifecycleEvents.emit("runtimeInstantiated");
|
|
1547
1535
|
this._loadedCodeDetails = codeDetails;
|