@fluidframework/container-loader 2.0.0-dev.1.4.6.106135 → 2.0.0-dev.2.3.0.115467
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/.eslintrc.js +21 -8
- package/README.md +21 -11
- package/dist/audience.d.ts +0 -4
- package/dist/audience.d.ts.map +1 -1
- package/dist/audience.js +11 -11
- package/dist/audience.js.map +1 -1
- package/dist/collabWindowTracker.js +5 -4
- package/dist/collabWindowTracker.js.map +1 -1
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +49 -7
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.d.ts +20 -11
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/connectionStateHandler.js +65 -36
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +8 -2
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +32 -36
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts +1 -1
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js +7 -3
- package/dist/containerContext.js.map +1 -1
- package/dist/containerStorageAdapter.js +1 -1
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/contracts.d.ts +8 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/deltaManager.d.ts +1 -3
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +40 -16
- 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 +8 -3
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +34 -8
- package/dist/protocol.js.map +1 -1
- package/dist/retriableDocumentStorageService.d.ts.map +1 -1
- package/dist/retriableDocumentStorageService.js +7 -3
- package/dist/retriableDocumentStorageService.js.map +1 -1
- package/lib/audience.d.ts +0 -4
- package/lib/audience.d.ts.map +1 -1
- package/lib/audience.js +11 -11
- package/lib/audience.js.map +1 -1
- package/lib/collabWindowTracker.js +5 -4
- package/lib/collabWindowTracker.js.map +1 -1
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +49 -7
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.d.ts +20 -11
- package/lib/connectionStateHandler.d.ts.map +1 -1
- package/lib/connectionStateHandler.js +65 -36
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +8 -2
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +31 -36
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts +1 -1
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js +7 -3
- package/lib/containerContext.js.map +1 -1
- package/lib/containerStorageAdapter.js +1 -1
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/contracts.d.ts +8 -0
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/deltaManager.d.ts +1 -3
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +43 -19
- 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 +8 -3
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +33 -7
- package/lib/protocol.js.map +1 -1
- package/lib/retriableDocumentStorageService.d.ts.map +1 -1
- package/lib/retriableDocumentStorageService.js +7 -3
- package/lib/retriableDocumentStorageService.js.map +1 -1
- package/package.json +27 -29
- package/prettier.config.cjs +8 -0
- package/src/audience.ts +11 -12
- package/src/collabWindowTracker.ts +5 -5
- package/src/connectionManager.ts +56 -11
- package/src/connectionStateHandler.ts +87 -39
- package/src/container.ts +36 -38
- package/src/containerContext.ts +10 -4
- package/src/containerStorageAdapter.ts +1 -1
- package/src/contracts.ts +8 -0
- package/src/deltaManager.ts +61 -39
- package/src/packageVersion.ts +1 -1
- package/src/protocol.ts +31 -8
- package/src/retriableDocumentStorageService.ts +7 -3
package/lib/container.js
CHANGED
|
@@ -111,10 +111,10 @@ const getCodeProposal =
|
|
|
111
111
|
* @param eventName - event name
|
|
112
112
|
* @param action - functor to call and measure
|
|
113
113
|
*/
|
|
114
|
-
async function ReportIfTooLong(logger, eventName, action) {
|
|
114
|
+
export async function ReportIfTooLong(logger, eventName, action) {
|
|
115
115
|
const event = PerformanceEvent.start(logger, { eventName });
|
|
116
116
|
const props = await action();
|
|
117
|
-
if (event.duration >
|
|
117
|
+
if (event.duration > 200) {
|
|
118
118
|
event.end(props);
|
|
119
119
|
}
|
|
120
120
|
}
|
|
@@ -184,7 +184,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
184
184
|
});
|
|
185
185
|
// Prefix all events in this file with container-loader
|
|
186
186
|
this.mc = loggerToMonitoringContext(ChildLogger.create(this.subLogger, "Container"));
|
|
187
|
-
const summarizeProtocolTree = (_a = this.mc.config.getBoolean("Fluid.Container.
|
|
187
|
+
const summarizeProtocolTree = (_a = this.mc.config.getBoolean("Fluid.Container.summarizeProtocolTree2")) !== null && _a !== void 0 ? _a : this.loader.services.options.summarizeProtocolTree;
|
|
188
188
|
this.options = Object.assign(Object.assign({}, this.loader.services.options), { summarizeProtocolTree });
|
|
189
189
|
this._deltaManager = this.createDeltaManager();
|
|
190
190
|
this._clientId = (_b = config.serializedContainerState) === null || _b === void 0 ? void 0 : _b.clientId;
|
|
@@ -196,15 +196,29 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
196
196
|
}
|
|
197
197
|
this.logConnectionStateChangeTelemetry(value, oldState, reason);
|
|
198
198
|
if (this._lifecycleState === "loaded") {
|
|
199
|
-
this.propagateConnectionState(false /* initial transition */);
|
|
199
|
+
this.propagateConnectionState(false /* initial transition */, value === ConnectionState.Disconnected ? reason : undefined /* disconnectedReason */);
|
|
200
200
|
}
|
|
201
201
|
},
|
|
202
202
|
shouldClientJoinWrite: () => this._deltaManager.connectionManager.shouldJoinWrite(),
|
|
203
203
|
maxClientLeaveWaitTime: this.loader.services.options.maxClientLeaveWaitTime,
|
|
204
204
|
logConnectionIssue: (eventName, details) => {
|
|
205
|
+
const mode = this.connectionMode;
|
|
205
206
|
// We get here when socket does not receive any ops on "write" connection, including
|
|
206
207
|
// its own join op. Attempt recovery option.
|
|
207
|
-
this._deltaManager.logConnectionIssue(Object.assign({ eventName,
|
|
208
|
+
this._deltaManager.logConnectionIssue(Object.assign({ eventName,
|
|
209
|
+
mode, duration: performance.now() - this.connectionTransitionTimes[ConnectionState.CatchingUp] }, (details === undefined ? {} : { details: JSON.stringify(details) })));
|
|
210
|
+
// If this is "write" connection, it took too long to receive join op. But in most cases that's due
|
|
211
|
+
// to very slow op fetches and we will eventually get there.
|
|
212
|
+
// For "read" connections, we get here due to self join signal not arriving on time. We will need to
|
|
213
|
+
// better understand when and why it may happen.
|
|
214
|
+
// For now, attempt to recover by reconnecting. In future, maybe we can query relay service for
|
|
215
|
+
// current state of audience.
|
|
216
|
+
// Other possible recovery path - move to connected state (i.e. ConnectionStateHandler.joinOpTimer
|
|
217
|
+
// to call this.applyForConnectedState("addMemberEvent") for "read" connections)
|
|
218
|
+
if (mode === "read") {
|
|
219
|
+
this.disconnect();
|
|
220
|
+
this.connect();
|
|
221
|
+
}
|
|
208
222
|
},
|
|
209
223
|
}, this.deltaManager, this._clientId);
|
|
210
224
|
this.on(savedContainerEvent, () => {
|
|
@@ -924,10 +938,9 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
924
938
|
this.initializeProtocolState(attributes, quorumSnapshot);
|
|
925
939
|
}
|
|
926
940
|
initializeProtocolState(attributes, quorumSnapshot) {
|
|
927
|
-
var _a
|
|
941
|
+
var _a;
|
|
928
942
|
const protocolHandlerBuilder = (_a = this.protocolHandlerBuilder) !== null && _a !== void 0 ? _a : ((...args) => new ProtocolHandler(...args, new Audience()));
|
|
929
|
-
const protocol = protocolHandlerBuilder(attributes, quorumSnapshot, (key, value) => this.submitMessage(MessageType.Propose, JSON.stringify({ key, value }))
|
|
930
|
-
this._initialClients = undefined;
|
|
943
|
+
const protocol = protocolHandlerBuilder(attributes, quorumSnapshot, (key, value) => this.submitMessage(MessageType.Propose, JSON.stringify({ key, value })));
|
|
931
944
|
const protocolLogger = ChildLogger.create(this.subLogger, "ProtocolHandler");
|
|
932
945
|
protocol.quorum.on("error", (error) => {
|
|
933
946
|
protocolLogger.sendErrorEvent(error);
|
|
@@ -1026,21 +1039,8 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1026
1039
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1027
1040
|
deltaManager.inboundSignal.pause();
|
|
1028
1041
|
deltaManager.on("connect", (details, _opsBehind) => {
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
// Store the initial clients so that they can be submitted to the
|
|
1032
|
-
// protocol handler when it is created.
|
|
1033
|
-
this._initialClients = details.initialClients;
|
|
1034
|
-
}
|
|
1035
|
-
else {
|
|
1036
|
-
// When reconnecting, the protocol handler is already created,
|
|
1037
|
-
// so we can update the audience right now.
|
|
1038
|
-
this._protocolHandler.audience.clear();
|
|
1039
|
-
for (const priorClient of (_a = details.initialClients) !== null && _a !== void 0 ? _a : []) {
|
|
1040
|
-
this._protocolHandler.audience.addMember(priorClient.clientId, priorClient.client);
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
this.connectionStateHandler.receivedConnectEvent(this.connectionMode, details);
|
|
1042
|
+
assert(this.connectionMode === details.mode, 0x4b7 /* mismatch */);
|
|
1043
|
+
this.connectionStateHandler.receivedConnectEvent(details);
|
|
1044
1044
|
});
|
|
1045
1045
|
deltaManager.on("disconnect", (reason) => {
|
|
1046
1046
|
var _a;
|
|
@@ -1052,7 +1052,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1052
1052
|
// Some "warning" events come from outside the container and are logged
|
|
1053
1053
|
// elsewhere (e.g. summarizing container). We shouldn't log these here.
|
|
1054
1054
|
if (warn.logged !== true) {
|
|
1055
|
-
this.
|
|
1055
|
+
this.mc.logger.sendTelemetryEvent({ eventName: "ContainerWarning" }, warn);
|
|
1056
1056
|
}
|
|
1057
1057
|
this.emit("warning", warn);
|
|
1058
1058
|
});
|
|
@@ -1111,7 +1111,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1111
1111
|
this.firstConnection = false;
|
|
1112
1112
|
}
|
|
1113
1113
|
}
|
|
1114
|
-
propagateConnectionState(initialTransition) {
|
|
1114
|
+
propagateConnectionState(initialTransition, disconnectedReason) {
|
|
1115
1115
|
var _a;
|
|
1116
1116
|
// When container loaded, we want to propagate initial connection state.
|
|
1117
1117
|
// After that, we communicate only transitions to Connected & Disconnected states, skipping all other states.
|
|
@@ -1131,7 +1131,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1131
1131
|
// Both protocol and context should not be undefined if we got so far.
|
|
1132
1132
|
this.setContextConnectedState(state, (_a = this._deltaManager.connectionManager.readOnlyInfo.readonly) !== null && _a !== void 0 ? _a : false);
|
|
1133
1133
|
this.protocolHandler.setConnectionState(state, this.clientId);
|
|
1134
|
-
raiseConnectedEvent(this.mc.logger, this, state, this.clientId);
|
|
1134
|
+
raiseConnectedEvent(this.mc.logger, this, state, this.clientId, disconnectedReason);
|
|
1135
1135
|
if (logOpsOnReconnect) {
|
|
1136
1136
|
this.mc.logger.sendTelemetryEvent({ eventName: "OpsSentOnReconnect", count: this.messageCountAfterDisconnection });
|
|
1137
1137
|
}
|
|
@@ -1153,7 +1153,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1153
1153
|
let clientSequenceNumber = -1;
|
|
1154
1154
|
for (const message of batch) {
|
|
1155
1155
|
clientSequenceNumber = this.submitMessage(MessageType.Operation, message.contents, true, // batch
|
|
1156
|
-
message.metadata);
|
|
1156
|
+
message.metadata, message.compression);
|
|
1157
1157
|
}
|
|
1158
1158
|
this._deltaManager.flush();
|
|
1159
1159
|
return clientSequenceNumber;
|
|
@@ -1170,7 +1170,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1170
1170
|
this.options.summarizeProtocolTree === true;
|
|
1171
1171
|
return this.submitMessage(MessageType.Summarize, JSON.stringify(summary), false /* batch */);
|
|
1172
1172
|
}
|
|
1173
|
-
submitMessage(type, contents, batch, metadata) {
|
|
1173
|
+
submitMessage(type, contents, batch, metadata, compression) {
|
|
1174
1174
|
var _a;
|
|
1175
1175
|
if (this.connectionState !== ConnectionState.Connected) {
|
|
1176
1176
|
this.mc.logger.sendErrorEvent({ eventName: "SubmitMessageWithNoConnection", type });
|
|
@@ -1178,14 +1178,14 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1178
1178
|
}
|
|
1179
1179
|
this.messageCountAfterDisconnection += 1;
|
|
1180
1180
|
(_a = this.collabWindowTracker) === null || _a === void 0 ? void 0 : _a.stopSequenceNumberUpdate();
|
|
1181
|
-
return this._deltaManager.submit(type, contents, batch, metadata);
|
|
1181
|
+
return this._deltaManager.submit(type, contents, batch, metadata, compression);
|
|
1182
1182
|
}
|
|
1183
1183
|
processRemoteMessage(message) {
|
|
1184
1184
|
const local = this.clientId === message.clientId;
|
|
1185
1185
|
// Allow the protocol handler to process the message
|
|
1186
1186
|
const result = this.protocolHandler.processMessage(message, local);
|
|
1187
1187
|
// Forward messages to the loaded runtime for processing
|
|
1188
|
-
this.context.process(message, local
|
|
1188
|
+
this.context.process(message, local);
|
|
1189
1189
|
// Inactive (not in quorum or not writers) clients don't take part in the minimum sequence number calculation.
|
|
1190
1190
|
if (this.activeConnection()) {
|
|
1191
1191
|
if (this.collabWindowTracker === undefined) {
|
|
@@ -1196,9 +1196,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1196
1196
|
assert(this.serviceConfiguration !== undefined, 0x2e4 /* "there should be service config for active connection" */);
|
|
1197
1197
|
this.collabWindowTracker = new CollabWindowTracker((type) => {
|
|
1198
1198
|
assert(this.activeConnection(), 0x241 /* "disconnect should result in stopSequenceNumberUpdate() call" */);
|
|
1199
|
-
|
|
1200
|
-
// ops whose contents are undefined
|
|
1201
|
-
this.submitMessage(type, null);
|
|
1199
|
+
this.submitMessage(type);
|
|
1202
1200
|
}, this.serviceConfiguration.noopTimeFrequency, this.serviceConfiguration.noopCountFrequency);
|
|
1203
1201
|
}
|
|
1204
1202
|
this.collabWindowTracker.scheduleSequenceNumberUpdate(message, result.immediateNoOp === true);
|
|
@@ -1260,9 +1258,6 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1260
1258
|
this._dirtyContainer = dirty;
|
|
1261
1259
|
this.emit(dirty ? dirtyContainerEvent : savedContainerEvent);
|
|
1262
1260
|
}
|
|
1263
|
-
logContainerError(warning) {
|
|
1264
|
-
this.mc.logger.sendErrorEvent({ eventName: "ContainerWarning" }, warning);
|
|
1265
|
-
}
|
|
1266
1261
|
/**
|
|
1267
1262
|
* Set the connected state of the ContainerContext
|
|
1268
1263
|
* This controls the "connected" state of the ContainerRuntime as well
|