@fluidframework/container-loader 0.47.0-36699 → 0.48.0-38142
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/container.d.ts.map +1 -1
- package/dist/container.js +21 -27
- package/dist/container.js.map +1 -1
- package/dist/deltaManager.d.ts +1 -2
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +76 -39
- 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/utils.d.ts.map +1 -1
- package/dist/utils.js +0 -3
- package/dist/utils.js.map +1 -1
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +21 -27
- package/lib/container.js.map +1 -1
- package/lib/deltaManager.d.ts +1 -2
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +76 -39
- 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/utils.d.ts.map +1 -1
- package/lib/utils.js +1 -4
- package/lib/utils.js.map +1 -1
- package/package.json +7 -7
- package/src/container.ts +28 -31
- package/src/deltaManager.ts +87 -34
- package/src/packageVersion.ts +1 -1
- package/src/utils.ts +0 -4
package/lib/deltaManager.d.ts
CHANGED
|
@@ -166,8 +166,7 @@ export declare class DeltaManager extends TypedEventEmitter<IDeltaManagerInterna
|
|
|
166
166
|
/**
|
|
167
167
|
* Sets the sequence number from which inbound messages should be returned
|
|
168
168
|
*/
|
|
169
|
-
attachOpHandler(minSequenceNumber: number, sequenceNumber: number, term: number, handler: IDeltaHandlerStrategy): void
|
|
170
|
-
preFetchOps(cacheOnly: boolean): Promise<void>;
|
|
169
|
+
attachOpHandler(minSequenceNumber: number, sequenceNumber: number, term: number, handler: IDeltaHandlerStrategy, prefetchType?: "cached" | "all" | "none"): Promise<void>;
|
|
171
170
|
private static detailsFromConnection;
|
|
172
171
|
connect(args: IConnectionArgs): Promise<IConnectionDetails>;
|
|
173
172
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deltaManager.d.ts","sourceRoot":"","sources":["../src/deltaManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAEH,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACH,kBAAkB,EAClB,qBAAqB,EACrB,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,uBAAuB,EACvB,kBAAkB,EAClB,YAAY,EACf,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAuB,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEtF,OAAO,EAEH,gBAAgB,EAKnB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACH,cAAc,EACd,OAAO,EACP,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAGhB,yBAAyB,EAEzB,cAAc,EAGd,WAAW,EAEd,MAAM,sCAAsC,CAAC;AAsC9C,MAAM,WAAW,eAAe;IAC5B,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,oBAAY,aAAa;IACrB,KAAK,UAAU;IACf,QAAQ,aAAa;IACrB,OAAO,YAAY;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,2BAA4B,SAAQ,mBAAmB;IACpE,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,OAAE;IACpE,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,uBAAuB,KAAK,IAAI,OAAE;CAC1E;AA8CD;;;GAGG;AACH,qBAAa,YACT,SAAQ,iBAAiB,CAAC,2BAA2B,CACrD,YACA,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,EAC1D,cAAc,CAAC,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"deltaManager.d.ts","sourceRoot":"","sources":["../src/deltaManager.ts"],"names":[],"mappings":"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"}
|
package/lib/deltaManager.js
CHANGED
|
@@ -132,14 +132,7 @@ export class DeltaManager extends TypedEventEmitter {
|
|
|
132
132
|
// check message.content for Back-compat with old service.
|
|
133
133
|
const reconnectInfo = message.content !== undefined
|
|
134
134
|
? getNackReconnectInfo(message.content) :
|
|
135
|
-
createGenericNetworkError(
|
|
136
|
-
if (this.reconnectMode !== ReconnectMode.Enabled) {
|
|
137
|
-
this.logger.sendErrorEvent({
|
|
138
|
-
eventName: "NackWithNoReconnect",
|
|
139
|
-
reason: reconnectInfo.message,
|
|
140
|
-
mode: this.connectionMode,
|
|
141
|
-
});
|
|
142
|
-
}
|
|
135
|
+
createGenericNetworkError("nack:UnknownReason", true);
|
|
143
136
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
144
137
|
this.reconnectOnError("write", reconnectInfo);
|
|
145
138
|
};
|
|
@@ -321,17 +314,16 @@ export class DeltaManager extends TypedEventEmitter {
|
|
|
321
314
|
* about current or last connection (if there is no connection at the moment)
|
|
322
315
|
*/
|
|
323
316
|
connectionProps() {
|
|
317
|
+
const common = {
|
|
318
|
+
sequenceNumber: this.lastSequenceNumber,
|
|
319
|
+
};
|
|
324
320
|
if (this.connection !== undefined) {
|
|
325
|
-
return {
|
|
326
|
-
sequenceNumber: this.lastSequenceNumber,
|
|
327
|
-
connectionMode: this.connectionMode,
|
|
328
|
-
};
|
|
321
|
+
return Object.assign(Object.assign({}, common), { connectionMode: this.connectionMode });
|
|
329
322
|
}
|
|
330
323
|
else {
|
|
331
|
-
return {
|
|
324
|
+
return Object.assign(Object.assign({}, common), {
|
|
332
325
|
// Report how many ops this client sent in last disconnected session
|
|
333
|
-
sentOps: this.clientSequenceNumber
|
|
334
|
-
};
|
|
326
|
+
sentOps: this.clientSequenceNumber });
|
|
335
327
|
}
|
|
336
328
|
}
|
|
337
329
|
/**
|
|
@@ -418,7 +410,7 @@ export class DeltaManager extends TypedEventEmitter {
|
|
|
418
410
|
/**
|
|
419
411
|
* Sets the sequence number from which inbound messages should be returned
|
|
420
412
|
*/
|
|
421
|
-
attachOpHandler(minSequenceNumber, sequenceNumber, term, handler) {
|
|
413
|
+
async attachOpHandler(minSequenceNumber, sequenceNumber, term, handler, prefetchType = "none") {
|
|
422
414
|
this.initSequenceNumber = sequenceNumber;
|
|
423
415
|
this.lastProcessedSequenceNumber = sequenceNumber;
|
|
424
416
|
this.baseTerm = term;
|
|
@@ -430,22 +422,31 @@ export class DeltaManager extends TypedEventEmitter {
|
|
|
430
422
|
this.handler = handler;
|
|
431
423
|
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
432
424
|
assert(!!this.handler, 0x0e3 /* "Newly set op handler is null/undefined!" */);
|
|
425
|
+
// There should be no pending fetch!
|
|
426
|
+
// This API is called right after attachOpHandler by Container.load().
|
|
427
|
+
// We might have connection already and it might have called fetchMissingDeltas() from
|
|
428
|
+
// setupNewSuccessfulConnection. But it should do nothing, because there is no way to fetch ops before
|
|
429
|
+
// we know snapshot sequence number that is set in attachOpHandler. So all such calls should be noop.
|
|
430
|
+
assert(this.fetchReason === undefined, "There can't be pending fetch that early in boot sequence!");
|
|
431
|
+
if (this.closed) {
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
433
434
|
this._inbound.resume();
|
|
434
435
|
this._inboundSignal.resume();
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
if (this.connection === undefined) {
|
|
447
|
-
return this.fetchMissingDeltasCore("DocumentOpen", cacheOnly, this.lastQueuedSequenceNumber, undefined);
|
|
436
|
+
if (prefetchType !== "none") {
|
|
437
|
+
const cacheOnly = prefetchType === "cached";
|
|
438
|
+
await this.fetchMissingDeltasCore("DocumentOpen", cacheOnly, this.lastQueuedSequenceNumber);
|
|
439
|
+
// Keep going with fetching ops from storage once we have all cached ops in.
|
|
440
|
+
// But do not block load and make this request async / not blocking this api.
|
|
441
|
+
// Ops processing will start once cached ops are in and and will stop when queue is empty
|
|
442
|
+
// (which in most cases will happen when we are done processing cached ops)
|
|
443
|
+
if (cacheOnly) {
|
|
444
|
+
// fire and forget
|
|
445
|
+
this.fetchMissingDeltas("DocumentOpen", this.lastQueuedSequenceNumber);
|
|
446
|
+
}
|
|
448
447
|
}
|
|
448
|
+
// Ensure there is no need to call this.processPendingOps() at the end of boot sequence
|
|
449
|
+
assert(this.fetchReason !== undefined || this.pending.length === 0, "pending ops are not dropped");
|
|
449
450
|
}
|
|
450
451
|
static detailsFromConnection(connection) {
|
|
451
452
|
return {
|
|
@@ -484,6 +485,7 @@ export class DeltaManager extends TypedEventEmitter {
|
|
|
484
485
|
}
|
|
485
486
|
async connectCore(args) {
|
|
486
487
|
var _a, _b, _c;
|
|
488
|
+
assert(!this.closed, "not closed");
|
|
487
489
|
if (this.connection !== undefined) {
|
|
488
490
|
return this.connection;
|
|
489
491
|
}
|
|
@@ -511,7 +513,7 @@ export class DeltaManager extends TypedEventEmitter {
|
|
|
511
513
|
// on the wire, we might be always behind.
|
|
512
514
|
// See comment at the end of setupNewSuccessfulConnection()
|
|
513
515
|
logIfFalse(this.handler !== undefined || !fetchOpsFromStorage, this.logger, "CantFetchWithoutBaseline"); // can't fetch if no baseline
|
|
514
|
-
if (fetchOpsFromStorage
|
|
516
|
+
if (fetchOpsFromStorage) {
|
|
515
517
|
this.fetchMissingDeltas(args.reason, this.lastQueuedSequenceNumber);
|
|
516
518
|
}
|
|
517
519
|
const docService = this.serviceProvider();
|
|
@@ -1065,7 +1067,7 @@ export class DeltaManager extends TypedEventEmitter {
|
|
|
1065
1067
|
const message1 = this.comparableMessagePayload(this.previouslyProcessedMessage);
|
|
1066
1068
|
const message2 = this.comparableMessagePayload(message);
|
|
1067
1069
|
if (message1 !== message2) {
|
|
1068
|
-
const error = new NonRetryableError("
|
|
1070
|
+
const error = new NonRetryableError("twoMessagesWithSameSeqNumAndDifferentPayload", DriverErrorType.fileOverwrittenInStorage, {
|
|
1069
1071
|
clientId: (_c = this.connection) === null || _c === void 0 ? void 0 : _c.clientId,
|
|
1070
1072
|
sequenceNumber: message.sequenceNumber,
|
|
1071
1073
|
message1,
|
|
@@ -1134,6 +1136,8 @@ export class DeltaManager extends TypedEventEmitter {
|
|
|
1134
1136
|
throw new DataCorruptionError("nonSequentialSequenceNumber", Object.assign(Object.assign({}, extractLogSafeMessageProperties(message)), { clientId: (_b = this.connection) === null || _b === void 0 ? void 0 : _b.clientId }));
|
|
1135
1137
|
}
|
|
1136
1138
|
this.lastProcessedSequenceNumber = message.sequenceNumber;
|
|
1139
|
+
// a bunch of code assumes that this is true
|
|
1140
|
+
assert(this.lastProcessedSequenceNumber <= this.lastObservedSeqNumber, 0x267 /* "lastObservedSeqNumber should be updated first" */);
|
|
1137
1141
|
// Back-compat for older server with no term
|
|
1138
1142
|
if (message.term === undefined) {
|
|
1139
1143
|
message.term = 1;
|
|
@@ -1144,14 +1148,17 @@ export class DeltaManager extends TypedEventEmitter {
|
|
|
1144
1148
|
}
|
|
1145
1149
|
this.handler.process(message);
|
|
1146
1150
|
const endTime = Date.now();
|
|
1151
|
+
// Should be last, after changing this.lastProcessedSequenceNumber above, as many callers
|
|
1152
|
+
// test this.lastProcessedSequenceNumber instead of using op.sequenceNumber itself.
|
|
1147
1153
|
this.emit("op", message, endTime - startTime);
|
|
1148
1154
|
}
|
|
1149
1155
|
/**
|
|
1150
1156
|
* Retrieves the missing deltas between the given sequence numbers
|
|
1151
1157
|
*/
|
|
1152
1158
|
fetchMissingDeltas(reasonArg, lastKnowOp, to) {
|
|
1153
|
-
|
|
1154
|
-
|
|
1159
|
+
this.fetchMissingDeltasCore(reasonArg, false /* cacheOnly */, lastKnowOp, to).catch((error) => {
|
|
1160
|
+
this.logger.sendErrorEvent({ eventName: "fetchMissingDeltasException" }, error);
|
|
1161
|
+
});
|
|
1155
1162
|
}
|
|
1156
1163
|
/**
|
|
1157
1164
|
* Retrieves the missing deltas between the given sequence numbers
|
|
@@ -1166,6 +1173,11 @@ export class DeltaManager extends TypedEventEmitter {
|
|
|
1166
1173
|
this.logger.sendTelemetryEvent({ eventName: "fetchMissingDeltasClosedConnection", reason });
|
|
1167
1174
|
return;
|
|
1168
1175
|
}
|
|
1176
|
+
if (this.handler === undefined) {
|
|
1177
|
+
// We do not poses yet any information
|
|
1178
|
+
assert(lastKnowOp === 0, "initial state");
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1169
1181
|
try {
|
|
1170
1182
|
assert(lastKnowOp === this.lastQueuedSequenceNumber, 0x0f1 /* "from arg" */);
|
|
1171
1183
|
let from = lastKnowOp + 1;
|
|
@@ -1201,12 +1213,37 @@ export class DeltaManager extends TypedEventEmitter {
|
|
|
1201
1213
|
* Sorts pending ops and attempts to apply them
|
|
1202
1214
|
*/
|
|
1203
1215
|
processPendingOps(reason) {
|
|
1204
|
-
if (this.
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1216
|
+
if (this.closed) {
|
|
1217
|
+
return;
|
|
1218
|
+
}
|
|
1219
|
+
assert(this.handler !== undefined, "handler should be installed");
|
|
1220
|
+
const pendingSorted = this.pending.sort((a, b) => a.sequenceNumber - b.sequenceNumber);
|
|
1221
|
+
this.pending = [];
|
|
1222
|
+
// Given that we do not track where these ops came from any more, it's not very
|
|
1223
|
+
// actionably to report gaps in this range.
|
|
1224
|
+
this.enqueueMessages(pendingSorted, `${reason}_pending`, true /* allowGaps */);
|
|
1225
|
+
// Re-entrancy is ignored by fetchMissingDeltas, execution will come here when it's over
|
|
1226
|
+
if (this.fetchReason === undefined) {
|
|
1227
|
+
// See issue #7312 for more details
|
|
1228
|
+
// We observe cases where client gets into situation where it is not aware of missing ops
|
|
1229
|
+
// (i.e. client being behind), and as such, does not attempt to fetch them.
|
|
1230
|
+
// In some cases client may not have enough signal (example - "read" connection that is silent -
|
|
1231
|
+
// there is no easy way for client to realize it's behind, see a bit of commentary / logic at the
|
|
1232
|
+
// end of setupNewSuccessfulConnection). In other cases it should be able to learn that info ("write"
|
|
1233
|
+
// connection, learn by receiving its own join op), but data suggest it does not happen.
|
|
1234
|
+
// In 50% of these cases we do know we are behind through checkpointSequenceNumber on connection object
|
|
1235
|
+
// and thus can leverage that to trigger recovery. But this is not going to solve all the problems
|
|
1236
|
+
// (the other 50%), and thus these errors below should be looked at even if code below results in
|
|
1237
|
+
// recovery.
|
|
1238
|
+
if (this.lastQueuedSequenceNumber < this.lastObservedSeqNumber) {
|
|
1239
|
+
// connectionMode === "read" case is too noisy, so not log it.
|
|
1240
|
+
// It happens because fetch in setupNewSuccessfulConnection get cancelled due to other fetch, and we
|
|
1241
|
+
// never retry (other than here)
|
|
1242
|
+
if (this.connectionMode === "write") {
|
|
1243
|
+
this.logConnectionIssue({ eventName: "OpsBehind" });
|
|
1244
|
+
}
|
|
1245
|
+
this.fetchMissingDeltas("OpsBehind", this.lastQueuedSequenceNumber);
|
|
1246
|
+
}
|
|
1210
1247
|
}
|
|
1211
1248
|
}
|
|
1212
1249
|
updateLatestKnownOpSeqNumber(seq) {
|