@fluidframework/container-runtime 2.0.0-internal.2.2.1 → 2.0.0-internal.2.3.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/.eslintrc.js +19 -8
- package/dist/batchTracker.d.ts +1 -2
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +45 -34
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +135 -102
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +54 -8
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +143 -72
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +6 -8
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +12 -9
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +41 -35
- package/dist/dataStores.js.map +1 -1
- package/dist/garbageCollection.d.ts +41 -20
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +205 -150
- package/dist/garbageCollection.js.map +1 -1
- package/dist/garbageCollectionConstants.d.ts +7 -3
- package/dist/garbageCollectionConstants.d.ts.map +1 -1
- package/dist/garbageCollectionConstants.js +10 -8
- package/dist/garbageCollectionConstants.js.map +1 -1
- package/dist/garbageCollectionTombstoneUtils.d.ts +14 -0
- package/dist/garbageCollectionTombstoneUtils.d.ts.map +1 -0
- package/dist/garbageCollectionTombstoneUtils.js +23 -0
- package/dist/garbageCollectionTombstoneUtils.js.map +1 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +13 -1
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +35 -1
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +25 -1
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +2 -2
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +2 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +24 -10
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +2 -1
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +30 -17
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +34 -2
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +114 -5
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +5 -0
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +24 -14
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +17 -2
- package/dist/opLifecycle/remoteMessageProcessor.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/runningSummarizer.d.ts.map +1 -1
- package/dist/runningSummarizer.js +0 -1
- package/dist/runningSummarizer.js.map +1 -1
- package/dist/scheduleManager.d.ts +0 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +9 -20
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summarizer.d.ts +0 -1
- package/dist/summarizer.d.ts.map +1 -1
- package/dist/summarizer.js +2 -1
- package/dist/summarizer.js.map +1 -1
- package/dist/summarizerTypes.d.ts +1 -0
- package/dist/summarizerTypes.d.ts.map +1 -1
- package/dist/summarizerTypes.js.map +1 -1
- package/dist/summaryFormat.d.ts.map +1 -1
- package/dist/summaryFormat.js +1 -2
- package/dist/summaryFormat.js.map +1 -1
- package/lib/batchTracker.d.ts +1 -2
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +45 -34
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +137 -104
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +54 -8
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +140 -69
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +7 -9
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +12 -9
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +44 -38
- package/lib/dataStores.js.map +1 -1
- package/lib/garbageCollection.d.ts +41 -20
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +201 -146
- package/lib/garbageCollection.js.map +1 -1
- package/lib/garbageCollectionConstants.d.ts +7 -3
- package/lib/garbageCollectionConstants.d.ts.map +1 -1
- package/lib/garbageCollectionConstants.js +9 -7
- package/lib/garbageCollectionConstants.js.map +1 -1
- package/lib/garbageCollectionTombstoneUtils.d.ts +14 -0
- package/lib/garbageCollectionTombstoneUtils.d.ts.map +1 -0
- package/lib/garbageCollectionTombstoneUtils.js +19 -0
- package/lib/garbageCollectionTombstoneUtils.js.map +1 -0
- package/lib/index.d.ts +1 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -2
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +13 -1
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +35 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +25 -1
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +2 -2
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +24 -10
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +2 -1
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +30 -17
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +34 -2
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +112 -4
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +5 -0
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +24 -14
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +17 -2
- package/lib/opLifecycle/remoteMessageProcessor.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/runningSummarizer.d.ts.map +1 -1
- package/lib/runningSummarizer.js +0 -1
- package/lib/runningSummarizer.js.map +1 -1
- package/lib/scheduleManager.d.ts +0 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +9 -20
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summarizer.d.ts +0 -1
- package/lib/summarizer.d.ts.map +1 -1
- package/lib/summarizer.js +2 -1
- package/lib/summarizer.js.map +1 -1
- package/lib/summarizerTypes.d.ts +1 -0
- package/lib/summarizerTypes.d.ts.map +1 -1
- package/lib/summarizerTypes.js.map +1 -1
- package/lib/summaryFormat.d.ts.map +1 -1
- package/lib/summaryFormat.js +1 -2
- package/lib/summaryFormat.js.map +1 -1
- package/package.json +20 -19
- package/src/batchTracker.ts +1 -1
- package/src/blobManager.ts +159 -111
- package/src/containerRuntime.ts +202 -73
- package/src/dataStoreContext.ts +15 -16
- package/src/dataStores.ts +61 -45
- package/src/garbageCollection.ts +258 -183
- package/src/garbageCollectionConstants.ts +10 -7
- package/src/garbageCollectionTombstoneUtils.ts +28 -0
- package/src/index.ts +2 -5
- package/src/opLifecycle/batchManager.ts +59 -1
- package/src/opLifecycle/definitions.ts +27 -1
- package/src/opLifecycle/index.ts +2 -1
- package/src/opLifecycle/opCompressor.ts +29 -12
- package/src/opLifecycle/opDecompressor.ts +39 -18
- package/src/opLifecycle/opSplitter.ts +141 -7
- package/src/opLifecycle/outbox.ts +32 -16
- package/src/opLifecycle/remoteMessageProcessor.ts +19 -3
- package/src/packageVersion.ts +1 -1
- package/src/runningSummarizer.ts +0 -1
- package/src/scheduleManager.ts +19 -30
- package/src/summarizer.ts +1 -1
- package/src/summarizerTypes.ts +1 -0
- package/src/summaryFormat.ts +1 -2
package/dist/containerRuntime.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ContainerRuntime = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.RuntimeMessage = exports.CompressionAlgorithms = exports.RuntimeHeaders = exports.DefaultSummaryConfiguration = exports.ContainerMessageType = void 0;
|
|
3
|
+
exports.ContainerRuntime = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.RuntimeMessage = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.TombstoneResponseHeaderKey = exports.AllowTombstoneRequestHeaderKey = exports.RuntimeHeaders = exports.DefaultSummaryConfiguration = exports.ContainerMessageType = void 0;
|
|
4
4
|
const container_definitions_1 = require("@fluidframework/container-definitions");
|
|
5
5
|
const common_utils_1 = require("@fluidframework/common-utils");
|
|
6
6
|
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
@@ -28,7 +28,6 @@ const summarizerClientElection_1 = require("./summarizerClientElection");
|
|
|
28
28
|
const throttler_1 = require("./throttler");
|
|
29
29
|
const runWhileConnectedCoordinator_1 = require("./runWhileConnectedCoordinator");
|
|
30
30
|
const garbageCollection_1 = require("./garbageCollection");
|
|
31
|
-
const garbageCollectionConstants_1 = require("./garbageCollectionConstants");
|
|
32
31
|
const dataStore_1 = require("./dataStore");
|
|
33
32
|
const batchTracker_1 = require("./batchTracker");
|
|
34
33
|
const serializedSnapshotStorage_1 = require("./serializedSnapshotStorage");
|
|
@@ -79,6 +78,17 @@ var RuntimeHeaders;
|
|
|
79
78
|
/** True if the request is coming from an IFluidHandle. */
|
|
80
79
|
RuntimeHeaders["viaHandle"] = "viaHandle";
|
|
81
80
|
})(RuntimeHeaders = exports.RuntimeHeaders || (exports.RuntimeHeaders = {}));
|
|
81
|
+
/** True if a tombstoned object should be returned without erroring */
|
|
82
|
+
exports.AllowTombstoneRequestHeaderKey = "allowTombstone"; // Belongs in the enum above, but avoiding the breaking change
|
|
83
|
+
/** Tombstone error responses will have this header set to true */
|
|
84
|
+
exports.TombstoneResponseHeaderKey = "isTombstoned";
|
|
85
|
+
/** Default values for Runtime Headers */
|
|
86
|
+
exports.defaultRuntimeHeaderData = {
|
|
87
|
+
wait: true,
|
|
88
|
+
externalRequest: false,
|
|
89
|
+
viaHandle: false,
|
|
90
|
+
allowTombstone: false,
|
|
91
|
+
};
|
|
82
92
|
/**
|
|
83
93
|
* Available compression algorithms for op compression.
|
|
84
94
|
*/
|
|
@@ -218,12 +228,17 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
218
228
|
this.nextSummaryNumber = loadSummaryNumber + 1;
|
|
219
229
|
this.messageAtLastSummary = metadata === null || metadata === void 0 ? void 0 : metadata.message;
|
|
220
230
|
this._connected = this.context.connected;
|
|
221
|
-
this.remoteMessageProcessor = new opLifecycle_1.RemoteMessageProcessor(new opLifecycle_1.OpSplitter(chunks), new opLifecycle_1.OpDecompressor());
|
|
222
|
-
this.handleContext = new containerHandleContext_1.ContainerFluidHandleContext("", this);
|
|
223
231
|
this.mc = (0, telemetry_utils_1.loggerToMonitoringContext)(telemetry_utils_1.ChildLogger.create(this.logger, "ContainerRuntime"));
|
|
232
|
+
const opSplitter = new opLifecycle_1.OpSplitter(chunks, this.context.submitBatchFn, this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompressionChunking") === true ?
|
|
233
|
+
Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
|
|
234
|
+
this.remoteMessageProcessor = new opLifecycle_1.RemoteMessageProcessor(opSplitter, new opLifecycle_1.OpDecompressor());
|
|
235
|
+
this.handleContext = new containerHandleContext_1.ContainerFluidHandleContext("", this);
|
|
224
236
|
if (this.summaryConfiguration.state === "enabled") {
|
|
225
237
|
this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
|
|
226
238
|
}
|
|
239
|
+
this.enableOpReentryCheck = runtimeOptions.enableOpReentryCheck === true
|
|
240
|
+
// Allow for a break-glass config to override the options
|
|
241
|
+
&& this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableOpReentryCheck") !== true;
|
|
227
242
|
this.summariesDisabled = this.isSummariesDisabled();
|
|
228
243
|
this.heuristicsDisabled = this.isHeuristicsDisabled();
|
|
229
244
|
this.summarizerClientElectionEnabled = this.isSummarizerClientElectionEnabled();
|
|
@@ -272,16 +287,20 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
272
287
|
throwOnFailure: true,
|
|
273
288
|
// If GC should not run, let the summarizer node know so that it does not track GC state.
|
|
274
289
|
gcDisabled: !this.garbageCollector.shouldRunGC,
|
|
275
|
-
}
|
|
290
|
+
},
|
|
291
|
+
// Function to get GC data if needed. This will always be called by the root summarizer node to get GC data.
|
|
292
|
+
async (fullGC) => this.getGCDataInternal(fullGC),
|
|
293
|
+
// Function to get the GC details from the base snapshot we loaded from.
|
|
294
|
+
async () => this.garbageCollector.getBaseGCDetails());
|
|
276
295
|
if (baseSnapshot) {
|
|
277
296
|
this.summarizerNode.updateBaseSummaryState(baseSnapshot);
|
|
278
297
|
}
|
|
279
298
|
this.dataStores = new dataStores_1.DataStores((0, dataStores_1.getSummaryForDatastores)(baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn, getBaseGCDetailsFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn, getBaseGCDetailsFn), (id) => this.summarizerNode.deleteChild(id), this.mc.logger, async () => this.garbageCollector.getBaseGCDetails(), (path, timestampMs, packagePath) => this.garbageCollector.nodeUpdated(path, "Changed", timestampMs, packagePath), new Map(dataStoreAliasMap));
|
|
280
|
-
this.blobManager = new blobManager_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (
|
|
299
|
+
this.blobManager = new blobManager_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
|
|
281
300
|
if (!this.disposed) {
|
|
282
|
-
this.submit(ContainerMessageType.BlobAttach, undefined, undefined, {
|
|
301
|
+
this.submit(ContainerMessageType.BlobAttach, undefined, undefined, { localId, blobId });
|
|
283
302
|
}
|
|
284
|
-
}, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs);
|
|
303
|
+
}, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (fromPath, toPath) => this.garbageCollector.addedOutboundReference(fromPath, toPath), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs);
|
|
285
304
|
this.scheduleManager = new scheduleManager_1.ScheduleManager(context.deltaManager, this, () => this.clientId, telemetry_utils_1.ChildLogger.create(this.logger, "ScheduleManager"));
|
|
286
305
|
this.pendingStateManager = new pendingStateManager_1.PendingStateManager({
|
|
287
306
|
applyStashedOp: this.applyStashedOp.bind(this),
|
|
@@ -293,15 +312,23 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
293
312
|
rollback: this.rollback.bind(this),
|
|
294
313
|
orderSequentially: this.orderSequentially.bind(this),
|
|
295
314
|
}, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pending);
|
|
315
|
+
const compressionOptions = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompression") === true ?
|
|
316
|
+
{
|
|
317
|
+
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
|
|
318
|
+
compressionAlgorithm: CompressionAlgorithms.lz4
|
|
319
|
+
} : runtimeOptions.compressionOptions;
|
|
296
320
|
this.outbox = new opLifecycle_1.Outbox({
|
|
297
321
|
shouldSend: () => this.canSendOps(),
|
|
298
322
|
pendingStateManager: this.pendingStateManager,
|
|
299
323
|
containerContext: this.context,
|
|
300
324
|
compressor: new opLifecycle_1.OpCompressor(this.mc.logger),
|
|
325
|
+
splitter: opSplitter,
|
|
301
326
|
config: {
|
|
302
|
-
compressionOptions
|
|
327
|
+
compressionOptions,
|
|
303
328
|
maxBatchSizeInBytes: runtimeOptions.maxBatchSizeInBytes,
|
|
329
|
+
enableOpReentryCheck: this.enableOpReentryCheck,
|
|
304
330
|
},
|
|
331
|
+
logger: this.mc.logger,
|
|
305
332
|
});
|
|
306
333
|
this.context.quorum.on("removeMember", (clientId) => {
|
|
307
334
|
this.remoteMessageProcessor.clearPartialMessagesFor(clientId);
|
|
@@ -389,7 +416,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
389
416
|
* allows mixin classes to leverage this method to define their own async initializer.
|
|
390
417
|
*/
|
|
391
418
|
static async load(context, registryEntries, requestHandler, runtimeOptions = {}, containerScope = context.scope, existing, containerRuntimeCtor = ContainerRuntime) {
|
|
392
|
-
var _a, _b, _c;
|
|
419
|
+
var _a, _b, _c, _d;
|
|
393
420
|
// If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
|
|
394
421
|
// back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
|
|
395
422
|
const backCompatContext = context;
|
|
@@ -402,7 +429,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
402
429
|
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, enableOfflineLoad = false, compressionOptions = {
|
|
403
430
|
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
|
|
404
431
|
compressionAlgorithm: CompressionAlgorithms.lz4
|
|
405
|
-
}, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, } = runtimeOptions;
|
|
432
|
+
}, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, chunkSizeInBytes = Number.POSITIVE_INFINITY, enableOpReentryCheck = false, } = runtimeOptions;
|
|
406
433
|
const pendingRuntimeState = context.pendingLocalState;
|
|
407
434
|
const baseSnapshot = (_b = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _b !== void 0 ? _b : context.baseSnapshot;
|
|
408
435
|
const storage = !pendingRuntimeState ?
|
|
@@ -447,7 +474,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
447
474
|
logger.sendErrorEvent({ eventName: "SequenceNumberMismatch" }, error);
|
|
448
475
|
}
|
|
449
476
|
else {
|
|
477
|
+
// Call both close and dispose as close implementation will no longer dispose runtime in future (2.0.0-internal.3.0.0)
|
|
450
478
|
context.closeFn(error);
|
|
479
|
+
(_d = context.disposeFn) === null || _d === void 0 ? void 0 : _d.call(context, error);
|
|
451
480
|
}
|
|
452
481
|
}
|
|
453
482
|
}
|
|
@@ -459,6 +488,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
459
488
|
enableOfflineLoad,
|
|
460
489
|
compressionOptions,
|
|
461
490
|
maxBatchSizeInBytes,
|
|
491
|
+
chunkSizeInBytes,
|
|
492
|
+
enableOpReentryCheck,
|
|
462
493
|
}, containerScope, logger, loadExisting, blobManagerSnapshot, storage, requestHandler);
|
|
463
494
|
if (pendingRuntimeState) {
|
|
464
495
|
await runtime.processSavedOps(pendingRuntimeState);
|
|
@@ -488,8 +519,18 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
488
519
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
489
520
|
return this.reSubmit;
|
|
490
521
|
}
|
|
522
|
+
get disposeFn() {
|
|
523
|
+
var _a;
|
|
524
|
+
// In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
|
|
525
|
+
return (_a = this.context.disposeFn) !== null && _a !== void 0 ? _a : this.context.closeFn;
|
|
526
|
+
}
|
|
491
527
|
get closeFn() {
|
|
492
|
-
|
|
528
|
+
// Also call disposeFn to retain functionality of runtime being disposed on close
|
|
529
|
+
return (error) => {
|
|
530
|
+
var _a, _b;
|
|
531
|
+
this.context.closeFn(error);
|
|
532
|
+
(_b = (_a = this.context).disposeFn) === null || _b === void 0 ? void 0 : _b.call(_a, error);
|
|
533
|
+
};
|
|
493
534
|
}
|
|
494
535
|
get flushMode() {
|
|
495
536
|
return this._flushMode;
|
|
@@ -675,16 +716,20 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
675
716
|
return (_a = this.dataStores.aliases.get(maybeAlias)) !== null && _a !== void 0 ? _a : maybeAlias;
|
|
676
717
|
}
|
|
677
718
|
async getDataStoreFromRequest(id, request) {
|
|
678
|
-
var _a, _b, _c, _d
|
|
679
|
-
const
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
719
|
+
var _a, _b, _c, _d;
|
|
720
|
+
const headerData = {};
|
|
721
|
+
if (typeof ((_a = request.headers) === null || _a === void 0 ? void 0 : _a[RuntimeHeaders.wait]) === "boolean") {
|
|
722
|
+
headerData.wait = request.headers[RuntimeHeaders.wait];
|
|
723
|
+
}
|
|
724
|
+
if (typeof ((_b = request.headers) === null || _b === void 0 ? void 0 : _b[RuntimeHeaders.viaHandle]) === "boolean") {
|
|
725
|
+
headerData.viaHandle = request.headers[RuntimeHeaders.viaHandle];
|
|
726
|
+
}
|
|
727
|
+
if (typeof ((_c = request.headers) === null || _c === void 0 ? void 0 : _c[exports.AllowTombstoneRequestHeaderKey]) === "boolean") {
|
|
728
|
+
headerData.allowTombstone = request.headers[exports.AllowTombstoneRequestHeaderKey];
|
|
729
|
+
}
|
|
685
730
|
await this.dataStores.waitIfPendingAlias(id);
|
|
686
731
|
const internalId = this.internalId(id);
|
|
687
|
-
const dataStoreContext = await this.dataStores.getDataStore(internalId,
|
|
732
|
+
const dataStoreContext = await this.dataStores.getDataStore(internalId, headerData);
|
|
688
733
|
/**
|
|
689
734
|
* If GC should run and this an external app request with "externalRequest" header, we need to return
|
|
690
735
|
* an error if the data store being requested is marked as unreferenced as per the data store's base
|
|
@@ -693,7 +738,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
693
738
|
* This is a workaround to handle scenarios where a data store shared with an external app is deleted
|
|
694
739
|
* and marked as unreferenced by GC. Returning an error will fail to load the data store for the app.
|
|
695
740
|
*/
|
|
696
|
-
if (((
|
|
741
|
+
if (((_d = request.headers) === null || _d === void 0 ? void 0 : _d[RuntimeHeaders.externalRequest]) && this.garbageCollector.shouldRunGC) {
|
|
697
742
|
// The data store is referenced if used routes in the base summary has a route to self.
|
|
698
743
|
// Older documents may not have used routes in the summary. They are considered referenced.
|
|
699
744
|
const usedRoutes = (await dataStoreContext.getBaseGCDetails()).usedRoutes;
|
|
@@ -742,7 +787,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
742
787
|
}
|
|
743
788
|
const gcSummary = this.garbageCollector.summarize(fullTree, trackState, telemetryContext);
|
|
744
789
|
if (gcSummary !== undefined) {
|
|
745
|
-
(0, runtime_utils_1.addSummarizeResultToSummary)(summaryTree,
|
|
790
|
+
(0, runtime_utils_1.addSummarizeResultToSummary)(summaryTree, runtime_definitions_1.gcTreeKey, gcSummary);
|
|
746
791
|
}
|
|
747
792
|
}
|
|
748
793
|
// Track how many times the container tries to reconnect with pending messages.
|
|
@@ -867,9 +912,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
867
912
|
if (reconnection) {
|
|
868
913
|
this.consecutiveReconnects++;
|
|
869
914
|
if (!this.shouldContinueReconnecting()) {
|
|
870
|
-
this.closeFn(container_utils_1.DataProcessingError.create(
|
|
871
|
-
// eslint-disable-next-line max-len
|
|
872
|
-
"Runtime detected too many reconnects with no progress syncing local ops. Batch of ops is likely too large (over 1Mb)", "setConnectionState", undefined, {
|
|
915
|
+
this.closeFn(container_utils_1.DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops. Batch of ops is likely too large (over 1Mb)", "setConnectionState", undefined, {
|
|
873
916
|
dataLoss: 1,
|
|
874
917
|
attempts: this.consecutiveReconnects,
|
|
875
918
|
pendingMessages: this.pendingStateManager.pendingMessagesCount,
|
|
@@ -903,7 +946,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
903
946
|
this.scheduleManager.beforeOpProcessing(message);
|
|
904
947
|
try {
|
|
905
948
|
let localOpMetadata;
|
|
906
|
-
if (local && runtimeMessage) {
|
|
949
|
+
if (local && runtimeMessage && message.type !== ContainerMessageType.ChunkedOp) {
|
|
907
950
|
localOpMetadata = this.pendingStateManager.processPendingLocalMessage(message);
|
|
908
951
|
}
|
|
909
952
|
// If there are no more pending messages after processing a local message,
|
|
@@ -1005,7 +1048,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1005
1048
|
async getRootDataStoreChannel(id, wait = true) {
|
|
1006
1049
|
await this.dataStores.waitIfPendingAlias(id);
|
|
1007
1050
|
const internalId = this.internalId(id);
|
|
1008
|
-
const context = await this.dataStores.getDataStore(internalId, wait
|
|
1051
|
+
const context = await this.dataStores.getDataStore(internalId, { wait });
|
|
1009
1052
|
(0, common_utils_1.assert)(await context.isRoot(), 0x12b /* "did not get root data store" */);
|
|
1010
1053
|
return context.realize();
|
|
1011
1054
|
}
|
|
@@ -1020,6 +1063,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1020
1063
|
}
|
|
1021
1064
|
orderSequentially(callback) {
|
|
1022
1065
|
let checkpoint;
|
|
1066
|
+
let result;
|
|
1023
1067
|
if (this.mc.config.getBoolean("Fluid.ContainerRuntime.EnableRollback")) {
|
|
1024
1068
|
// Note: we are not touching this.pendingAttachBatch here, for two reasons:
|
|
1025
1069
|
// 1. It would not help, as we flush attach ops as they become available.
|
|
@@ -1028,7 +1072,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1028
1072
|
}
|
|
1029
1073
|
try {
|
|
1030
1074
|
this._orderSequentiallyCalls++;
|
|
1031
|
-
callback();
|
|
1075
|
+
result = callback();
|
|
1032
1076
|
}
|
|
1033
1077
|
catch (error) {
|
|
1034
1078
|
if (checkpoint) {
|
|
@@ -1056,6 +1100,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1056
1100
|
if (this.flushMode === runtime_definitions_1.FlushMode.Immediate && this._orderSequentiallyCalls === 0) {
|
|
1057
1101
|
this.flush();
|
|
1058
1102
|
}
|
|
1103
|
+
return result;
|
|
1059
1104
|
}
|
|
1060
1105
|
async createDataStore(pkg) {
|
|
1061
1106
|
const internalId = (0, uuid_1.v4)();
|
|
@@ -1221,6 +1266,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1221
1266
|
async updateStateBeforeGC() {
|
|
1222
1267
|
return this.dataStores.updateStateBeforeGC();
|
|
1223
1268
|
}
|
|
1269
|
+
async getGCDataInternal(fullGC) {
|
|
1270
|
+
return this.dataStores.getGCData(fullGC);
|
|
1271
|
+
}
|
|
1224
1272
|
/**
|
|
1225
1273
|
* Implementation of IGarbageCollectionRuntime::getGCData.
|
|
1226
1274
|
* Generates and returns the GC data for this container.
|
|
@@ -1228,7 +1276,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1228
1276
|
*/
|
|
1229
1277
|
async getGCData(fullGC) {
|
|
1230
1278
|
const builder = new garbage_collector_1.GCDataBuilder();
|
|
1231
|
-
const dsGCData = await this.
|
|
1279
|
+
const dsGCData = await this.summarizerNode.getGCData(fullGC);
|
|
1232
1280
|
builder.addNodes(dsGCData.gcNodes);
|
|
1233
1281
|
const blobsGCData = this.blobManager.getGCData(fullGC);
|
|
1234
1282
|
builder.addNodes(blobsGCData.gcNodes);
|
|
@@ -1244,39 +1292,26 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1244
1292
|
// summarizing is required and asserted by the the summarizer node. We are the root and are
|
|
1245
1293
|
// always referenced, so the used routes is only self-route (empty string).
|
|
1246
1294
|
this.summarizerNode.updateUsedRoutes([""]);
|
|
1247
|
-
const
|
|
1248
|
-
|
|
1249
|
-
for (const route of usedRoutes) {
|
|
1250
|
-
if (this.isBlobPath(route)) {
|
|
1251
|
-
blobManagerUsedRoutes.push(route);
|
|
1252
|
-
}
|
|
1253
|
-
else {
|
|
1254
|
-
dataStoreUsedRoutes.push(route);
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
this.blobManager.updateUsedRoutes(blobManagerUsedRoutes);
|
|
1258
|
-
this.dataStores.updateUsedRoutes(dataStoreUsedRoutes);
|
|
1295
|
+
const { dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(usedRoutes);
|
|
1296
|
+
this.dataStores.updateUsedRoutes(dataStoreRoutes);
|
|
1259
1297
|
}
|
|
1260
1298
|
/**
|
|
1261
|
-
* This is called to update objects whose routes are unused.
|
|
1262
|
-
*
|
|
1263
|
-
* @param unusedRoutes - The routes that are unused in all data stores and attachment blobs in this Container.
|
|
1264
|
-
* @param tombstone - if true, the objects corresponding to unused routes are marked tombstones. Otherwise, they
|
|
1265
|
-
* are deleted.
|
|
1299
|
+
* This is called to update objects whose routes are unused.
|
|
1300
|
+
* @param unusedRoutes - Data store and attachment blob routes that are unused in this Container.
|
|
1266
1301
|
*/
|
|
1267
|
-
updateUnusedRoutes(unusedRoutes
|
|
1268
|
-
const
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
}
|
|
1278
|
-
this.blobManager.
|
|
1279
|
-
this.dataStores.
|
|
1302
|
+
updateUnusedRoutes(unusedRoutes) {
|
|
1303
|
+
const { blobManagerRoutes, dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(unusedRoutes);
|
|
1304
|
+
this.blobManager.updateUnusedRoutes(blobManagerRoutes);
|
|
1305
|
+
this.dataStores.updateUnusedRoutes(dataStoreRoutes);
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* This is called to update objects that are tombstones.
|
|
1309
|
+
* @param tombstonedRoutes - Data store and attachment blob routes that are tombstones in this Container.
|
|
1310
|
+
*/
|
|
1311
|
+
updateTombstonedRoutes(tombstonedRoutes) {
|
|
1312
|
+
const { blobManagerRoutes, dataStoreRoutes } = this.getDataStoreAndBlobManagerRoutes(tombstonedRoutes);
|
|
1313
|
+
this.blobManager.updateTombstonedRoutes(blobManagerRoutes);
|
|
1314
|
+
this.dataStores.updateTombstonedRoutes(dataStoreRoutes);
|
|
1280
1315
|
}
|
|
1281
1316
|
/**
|
|
1282
1317
|
* Returns a server generated referenced timestamp to be used to track unreferenced nodes by GC.
|
|
@@ -1305,7 +1340,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1305
1340
|
async getGCNodePackagePath(nodePath) {
|
|
1306
1341
|
switch (this.getNodeType(nodePath)) {
|
|
1307
1342
|
case garbageCollection_1.GCNodeType.Blob:
|
|
1308
|
-
return [
|
|
1343
|
+
return [blobManager_1.BlobManager.basePath];
|
|
1309
1344
|
case garbageCollection_1.GCNodeType.DataStore:
|
|
1310
1345
|
case garbageCollection_1.GCNodeType.SubDataStore:
|
|
1311
1346
|
return this.dataStores.getDataStorePackagePath(nodePath);
|
|
@@ -1323,6 +1358,25 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1323
1358
|
}
|
|
1324
1359
|
return true;
|
|
1325
1360
|
}
|
|
1361
|
+
/**
|
|
1362
|
+
* From a given list of routes, separate and return routes that belong to blob manager and data stores.
|
|
1363
|
+
* @param routes - A list of routes that can belong to data stores or blob manager.
|
|
1364
|
+
* @returns - Two route lists - One that contains routes for blob manager and another one that contains routes
|
|
1365
|
+
* for data stores.
|
|
1366
|
+
*/
|
|
1367
|
+
getDataStoreAndBlobManagerRoutes(routes) {
|
|
1368
|
+
const blobManagerRoutes = [];
|
|
1369
|
+
const dataStoreRoutes = [];
|
|
1370
|
+
for (const route of routes) {
|
|
1371
|
+
if (this.isBlobPath(route)) {
|
|
1372
|
+
blobManagerRoutes.push(route);
|
|
1373
|
+
}
|
|
1374
|
+
else {
|
|
1375
|
+
dataStoreRoutes.push(route);
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
return { blobManagerRoutes, dataStoreRoutes };
|
|
1379
|
+
}
|
|
1326
1380
|
/**
|
|
1327
1381
|
* Runs garbage collection and updates the reference / used state of the nodes in the container.
|
|
1328
1382
|
* @returns the statistics of the garbage collection run; undefined if GC did not run.
|
|
@@ -1394,7 +1448,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1394
1448
|
if (this.deltaManager.lastSequenceNumber !== summaryRefSeqNum) {
|
|
1395
1449
|
return {
|
|
1396
1450
|
continue: false,
|
|
1397
|
-
// eslint-disable-next-line max-len
|
|
1398
1451
|
error: `lastSequenceNumber changed before uploading to storage. ${this.deltaManager.lastSequenceNumber} !== ${summaryRefSeqNum}`,
|
|
1399
1452
|
};
|
|
1400
1453
|
}
|
|
@@ -1402,7 +1455,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1402
1455
|
if (lastAck !== this.summaryCollection.latestAck) {
|
|
1403
1456
|
return {
|
|
1404
1457
|
continue: false,
|
|
1405
|
-
// eslint-disable-next-line max-len
|
|
1406
1458
|
error: `Last summary changed while summarizing. ${this.summaryCollection.latestAck} !== ${lastAck}`,
|
|
1407
1459
|
};
|
|
1408
1460
|
}
|
|
@@ -1447,8 +1499,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1447
1499
|
const dataStoreTree = summaryTree.tree[runtime_definitions_1.channelsTreeName];
|
|
1448
1500
|
(0, common_utils_1.assert)(dataStoreTree.type === protocol_definitions_1.SummaryType.Tree, 0x1fc /* "summary is not a tree" */);
|
|
1449
1501
|
const handleCount = Object.values(dataStoreTree.tree).filter((value) => value.type === protocol_definitions_1.SummaryType.Handle).length;
|
|
1450
|
-
const gcSummaryTreeStats = summaryTree.tree[
|
|
1451
|
-
? (0, runtime_utils_1.calculateStats)(summaryTree.tree[
|
|
1502
|
+
const gcSummaryTreeStats = summaryTree.tree[runtime_definitions_1.gcTreeKey]
|
|
1503
|
+
? (0, runtime_utils_1.calculateStats)(summaryTree.tree[runtime_definitions_1.gcTreeKey])
|
|
1452
1504
|
: undefined;
|
|
1453
1505
|
const summaryStats = Object.assign({ dataStoreCount: this.dataStores.size, summarizedDataStoreCount: this.dataStores.size - handleCount, gcStateUpdatedDataStoreCount: (_a = summarizeResult.gcStats) === null || _a === void 0 ? void 0 : _a.updatedDataStoreCount, gcBlobNodeCount: gcSummaryTreeStats === null || gcSummaryTreeStats === void 0 ? void 0 : gcSummaryTreeStats.blobNodeCount, gcTotalBlobsSize: gcSummaryTreeStats === null || gcSummaryTreeStats === void 0 ? void 0 : gcSummaryTreeStats.totalBlobSize, summaryNumber }, partialStats);
|
|
1454
1506
|
const generateSummaryData = {
|
|
@@ -1617,7 +1669,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1617
1669
|
else if (!this.flushMicroTaskExists) {
|
|
1618
1670
|
this.flushMicroTaskExists = true;
|
|
1619
1671
|
// Queue a microtask to detect the end of the turn and force a flush.
|
|
1620
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1621
1672
|
Promise.resolve().then(() => {
|
|
1622
1673
|
this.flushMicroTaskExists = false;
|
|
1623
1674
|
this.flush();
|
|
@@ -1710,13 +1761,32 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1710
1761
|
// It should only be done by the summarizerNode, if required.
|
|
1711
1762
|
// When fetching from storage we will always get the latest version and do not use the ackHandle.
|
|
1712
1763
|
const snapshotTreeFetcher = async () => {
|
|
1713
|
-
const fetchResult = await this.
|
|
1764
|
+
const fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
|
|
1714
1765
|
eventName: "RefreshLatestSummaryGetSnapshot",
|
|
1715
1766
|
ackHandle,
|
|
1716
1767
|
summaryRefSeq,
|
|
1717
1768
|
fetchLatest: true,
|
|
1718
1769
|
});
|
|
1719
1770
|
const latestSnapshotRefSeq = await (0, runtime_utils_1.seqFromTree)(fetchResult.snapshotTree, readAndParseBlob);
|
|
1771
|
+
/**
|
|
1772
|
+
* If the fetched snapshot is older than the one for which the ack was received, close the container.
|
|
1773
|
+
* This should never happen because an ack should be sent after the latest summary is updated in the server.
|
|
1774
|
+
* However, there are couple of scenarios where it's possible:
|
|
1775
|
+
* 1. A file was modified externally resulting in modifying the snapshot's sequence number. This can lead to
|
|
1776
|
+
* the document being unusable and we should not proceed.
|
|
1777
|
+
* 2. The server DB failed after the ack was sent which may delete the corresponding snapshot. Ideally, in
|
|
1778
|
+
* such cases, the file will be rolled back along with the ack and we will eventually reach a consistent
|
|
1779
|
+
* state.
|
|
1780
|
+
*/
|
|
1781
|
+
if (latestSnapshotRefSeq < summaryRefSeq) {
|
|
1782
|
+
const error = container_utils_1.DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
|
|
1783
|
+
ackHandle,
|
|
1784
|
+
summaryRefSeq,
|
|
1785
|
+
latestSnapshotRefSeq,
|
|
1786
|
+
});
|
|
1787
|
+
this.closeFn(error);
|
|
1788
|
+
throw error;
|
|
1789
|
+
}
|
|
1720
1790
|
summaryLogger.sendTelemetryEvent({
|
|
1721
1791
|
eventName: "LatestSummaryRetrieved",
|
|
1722
1792
|
ackHandle,
|
|
@@ -1730,7 +1800,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1730
1800
|
};
|
|
1731
1801
|
const result = await this.summarizerNode.refreshLatestSummary(proposalHandle, summaryRefSeq, snapshotTreeFetcher, readAndParseBlob, summaryLogger);
|
|
1732
1802
|
// Notify the garbage collector so it can update its latest summary state.
|
|
1733
|
-
await this.garbageCollector.
|
|
1803
|
+
await this.garbageCollector.refreshLatestSummary(result, proposalHandle, summaryRefSeq, readAndParseBlob);
|
|
1734
1804
|
}
|
|
1735
1805
|
/**
|
|
1736
1806
|
* Fetches the latest snapshot from storage and uses it to refresh SummarizerNode's
|
|
@@ -1739,22 +1809,22 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1739
1809
|
* @returns downloaded snapshot's reference sequence number
|
|
1740
1810
|
*/
|
|
1741
1811
|
async refreshLatestSummaryAckFromServer(summaryLogger) {
|
|
1742
|
-
const { snapshotTree, versionId } = await this.
|
|
1812
|
+
const { snapshotTree, versionId } = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
|
|
1743
1813
|
eventName: "RefreshLatestSummaryGetSnapshot",
|
|
1744
1814
|
fetchLatest: true,
|
|
1745
|
-
}
|
|
1815
|
+
});
|
|
1746
1816
|
const readAndParseBlob = async (id) => (0, driver_utils_1.readAndParse)(this.storage, id);
|
|
1747
1817
|
const latestSnapshotRefSeq = await (0, runtime_utils_1.seqFromTree)(snapshotTree, readAndParseBlob);
|
|
1748
1818
|
const result = await this.summarizerNode.refreshLatestSummary(undefined, latestSnapshotRefSeq, async () => snapshotTree, readAndParseBlob, summaryLogger);
|
|
1749
1819
|
// Notify the garbage collector so it can update its latest summary state.
|
|
1750
|
-
await this.garbageCollector.
|
|
1820
|
+
await this.garbageCollector.refreshLatestSummary(result, undefined, latestSnapshotRefSeq, readAndParseBlob);
|
|
1751
1821
|
return { latestSnapshotRefSeq, latestSnapshotVersionId: versionId };
|
|
1752
1822
|
}
|
|
1753
|
-
async
|
|
1823
|
+
async fetchLatestSnapshotFromStorage(logger, event) {
|
|
1754
1824
|
return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
|
|
1755
1825
|
const stats = {};
|
|
1756
1826
|
const trace = common_utils_1.Trace.start();
|
|
1757
|
-
const versions = await this.storage.getVersions(
|
|
1827
|
+
const versions = await this.storage.getVersions(null, 1, "refreshLatestSummaryAckFromServer", driver_definitions_1.FetchSource.noCache);
|
|
1758
1828
|
(0, common_utils_1.assert)(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
|
|
1759
1829
|
stats.getVersionDuration = trace.trace().duration;
|
|
1760
1830
|
const maybeSnapshot = await this.storage.getSnapshotTree(versions[0]);
|
|
@@ -1871,6 +1941,7 @@ exports.ContainerRuntime = ContainerRuntime;
|
|
|
1871
1941
|
const waitForSeq = async (deltaManager, targetSeq) => new Promise((resolve, reject) => {
|
|
1872
1942
|
// TODO: remove cast to any when actual event is determined
|
|
1873
1943
|
deltaManager.on("closed", reject);
|
|
1944
|
+
deltaManager.on("disposed", reject);
|
|
1874
1945
|
// If we already reached target sequence number, simply resolve the promise.
|
|
1875
1946
|
if (deltaManager.lastSequenceNumber >= targetSeq) {
|
|
1876
1947
|
resolve();
|