@fluidframework/container-runtime 2.0.0-dev.4.2.0.153917 → 2.0.0-dev.4.3.0.158678
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/containerRuntime.d.ts +33 -3
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +187 -58
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +2 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +3 -0
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +5 -5
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +3 -6
- package/dist/dataStores.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +5 -5
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +1 -3
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.js +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/id-compressor/appendOnlySortedMap.d.ts +146 -0
- package/dist/id-compressor/appendOnlySortedMap.d.ts.map +1 -0
- package/dist/id-compressor/appendOnlySortedMap.js +360 -0
- package/dist/id-compressor/appendOnlySortedMap.js.map +1 -0
- package/dist/id-compressor/idCompressor.d.ts +279 -0
- package/dist/id-compressor/idCompressor.d.ts.map +1 -0
- package/dist/id-compressor/idCompressor.js +1258 -0
- package/dist/id-compressor/idCompressor.js.map +1 -0
- package/dist/id-compressor/idRange.d.ts +11 -0
- package/dist/id-compressor/idRange.d.ts.map +1 -0
- package/dist/id-compressor/idRange.js +29 -0
- package/dist/id-compressor/idRange.js.map +1 -0
- package/dist/id-compressor/index.d.ts +14 -0
- package/dist/id-compressor/index.d.ts.map +1 -0
- package/dist/id-compressor/index.js +38 -0
- package/dist/id-compressor/index.js.map +1 -0
- package/dist/id-compressor/numericUuid.d.ts +59 -0
- package/dist/id-compressor/numericUuid.d.ts.map +1 -0
- package/dist/id-compressor/numericUuid.js +325 -0
- package/dist/id-compressor/numericUuid.js.map +1 -0
- package/dist/id-compressor/sessionIdNormalizer.d.ts +138 -0
- package/dist/id-compressor/sessionIdNormalizer.d.ts.map +1 -0
- package/dist/id-compressor/sessionIdNormalizer.js +488 -0
- package/dist/id-compressor/sessionIdNormalizer.js.map +1 -0
- package/dist/id-compressor/utils.d.ts +57 -0
- package/dist/id-compressor/utils.d.ts.map +1 -0
- package/dist/id-compressor/utils.js +90 -0
- package/dist/id-compressor/utils.js.map +1 -0
- package/dist/id-compressor/uuidUtilities.d.ts +30 -0
- package/dist/id-compressor/uuidUtilities.d.ts.map +1 -0
- package/dist/id-compressor/uuidUtilities.js +106 -0
- package/dist/id-compressor/uuidUtilities.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +9 -2
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +21 -2
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +5 -0
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +2 -2
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +34 -22
- package/dist/opLifecycle/outbox.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/pendingStateManager.d.ts +1 -1
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +11 -3
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/summary/index.d.ts +1 -1
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +2 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +1 -0
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +17 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +0 -1
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +1 -17
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +3 -0
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +3 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +2 -0
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +33 -3
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +170 -60
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +2 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +3 -0
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +5 -5
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +3 -6
- package/lib/dataStores.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +5 -5
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +1 -3
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.js +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/id-compressor/appendOnlySortedMap.d.ts +146 -0
- package/lib/id-compressor/appendOnlySortedMap.d.ts.map +1 -0
- package/lib/id-compressor/appendOnlySortedMap.js +355 -0
- package/lib/id-compressor/appendOnlySortedMap.js.map +1 -0
- package/lib/id-compressor/idCompressor.d.ts +279 -0
- package/lib/id-compressor/idCompressor.d.ts.map +1 -0
- package/lib/id-compressor/idCompressor.js +1248 -0
- package/lib/id-compressor/idCompressor.js.map +1 -0
- package/lib/id-compressor/idRange.d.ts +11 -0
- package/lib/id-compressor/idRange.d.ts.map +1 -0
- package/lib/id-compressor/idRange.js +25 -0
- package/lib/id-compressor/idRange.js.map +1 -0
- package/lib/id-compressor/index.d.ts +14 -0
- package/lib/id-compressor/index.d.ts.map +1 -0
- package/lib/id-compressor/index.js +14 -0
- package/lib/id-compressor/index.js.map +1 -0
- package/lib/id-compressor/numericUuid.d.ts +59 -0
- package/lib/id-compressor/numericUuid.d.ts.map +1 -0
- package/lib/id-compressor/numericUuid.js +315 -0
- package/lib/id-compressor/numericUuid.js.map +1 -0
- package/lib/id-compressor/sessionIdNormalizer.d.ts +138 -0
- package/lib/id-compressor/sessionIdNormalizer.d.ts.map +1 -0
- package/lib/id-compressor/sessionIdNormalizer.js +484 -0
- package/lib/id-compressor/sessionIdNormalizer.js.map +1 -0
- package/lib/id-compressor/utils.d.ts +57 -0
- package/lib/id-compressor/utils.d.ts.map +1 -0
- package/lib/id-compressor/utils.js +79 -0
- package/lib/id-compressor/utils.js.map +1 -0
- package/lib/id-compressor/uuidUtilities.d.ts +30 -0
- package/lib/id-compressor/uuidUtilities.d.ts.map +1 -0
- package/lib/id-compressor/uuidUtilities.js +98 -0
- package/lib/id-compressor/uuidUtilities.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +9 -2
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +19 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +5 -0
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +2 -2
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +35 -23
- package/lib/opLifecycle/outbox.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/pendingStateManager.d.ts +1 -1
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +11 -3
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/summary/index.d.ts +1 -1
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -1
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +1 -0
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +17 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +0 -1
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +1 -17
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +3 -0
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +2 -0
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +2 -0
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +27 -18
- package/src/containerRuntime.ts +256 -88
- package/src/dataStoreContext.ts +6 -0
- package/src/dataStores.ts +4 -7
- package/src/gc/garbageCollection.ts +7 -6
- package/src/gc/gcConfigs.ts +1 -3
- package/src/gc/gcDefinitions.ts +1 -1
- package/src/id-compressor/README.md +3 -0
- package/src/id-compressor/appendOnlySortedMap.ts +427 -0
- package/src/id-compressor/idCompressor.ts +1854 -0
- package/src/id-compressor/idRange.ts +35 -0
- package/src/id-compressor/index.ts +35 -0
- package/src/id-compressor/numericUuid.ts +383 -0
- package/src/id-compressor/sessionIdNormalizer.ts +609 -0
- package/src/id-compressor/utils.ts +114 -0
- package/src/id-compressor/uuidUtilities.ts +123 -0
- package/src/index.ts +1 -0
- package/src/opLifecycle/README.md +13 -0
- package/src/opLifecycle/batchManager.ts +35 -2
- package/src/opLifecycle/index.ts +1 -1
- package/src/opLifecycle/opGroupingManager.ts +5 -1
- package/src/opLifecycle/outbox.ts +57 -23
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +21 -7
- package/src/summary/index.ts +1 -0
- package/src/summary/orderedClientElection.ts +15 -2
- package/src/summary/runningSummarizer.ts +3 -24
- package/src/summary/summaryFormat.ts +4 -0
- package/src/summary/summaryManager.ts +2 -0
package/lib/containerRuntime.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AttachState, LoaderHeader, } from "@fluidframework/container-definitions";
|
|
2
|
-
import { assert, LazyPromise, Trace, TypedEventEmitter, unreachableCase, } from "@fluidframework/common-utils";
|
|
2
|
+
import { assert, delay, LazyPromise, Trace, TypedEventEmitter, unreachableCase, } from "@fluidframework/common-utils";
|
|
3
3
|
import { ChildLogger, raiseConnectedEvent, PerformanceEvent, TaggedLoggerAdapter, loggerToMonitoringContext, wrapError, } from "@fluidframework/telemetry-utils";
|
|
4
4
|
import { DriverHeader, FetchSource, } from "@fluidframework/driver-definitions";
|
|
5
5
|
import { readAndParse } from "@fluidframework/driver-utils";
|
|
@@ -15,7 +15,7 @@ import { PendingStateManager } from "./pendingStateManager";
|
|
|
15
15
|
import { pkgVersion } from "./packageVersion";
|
|
16
16
|
import { BlobManager } from "./blobManager";
|
|
17
17
|
import { DataStores, getSummaryForDatastores } from "./dataStores";
|
|
18
|
-
import { aliasBlobName, blobsTreeName, chunksBlobName, createRootSummarizerNodeWithGC, electedSummarizerBlobName, extractSummaryMetadataMessage, metadataBlobName, Summarizer, SummaryManager, wrapSummaryInChannelsTree, SummaryCollection, OrderedClientCollection, OrderedClientElection, SummarizerClientElection, summarizerClientType, RunWhileConnectedCoordinator, } from "./summary";
|
|
18
|
+
import { aliasBlobName, blobsTreeName, chunksBlobName, createRootSummarizerNodeWithGC, electedSummarizerBlobName, extractSummaryMetadataMessage, idCompressorBlobName, metadataBlobName, Summarizer, SummaryManager, wrapSummaryInChannelsTree, SummaryCollection, OrderedClientCollection, OrderedClientElection, SummarizerClientElection, summarizerClientType, RunWhileConnectedCoordinator, } from "./summary";
|
|
19
19
|
import { formExponentialFn, Throttler } from "./throttler";
|
|
20
20
|
import { GarbageCollector, GCNodeType, gcTombstoneGenerationOptionName, shouldAllowGcTombstoneEnforcement, trimLeadingAndTrailingSlashes, } from "./gc";
|
|
21
21
|
import { channelToDataStore, isDataStoreAliasMessage } from "./dataStore";
|
|
@@ -37,6 +37,12 @@ export var ContainerMessageType;
|
|
|
37
37
|
ContainerMessageType["Rejoin"] = "rejoin";
|
|
38
38
|
// Sets the alias of a root data store
|
|
39
39
|
ContainerMessageType["Alias"] = "alias";
|
|
40
|
+
/**
|
|
41
|
+
* An op containing an IdRange of Ids allocated using the runtime's IdCompressor since
|
|
42
|
+
* the last allocation op was sent.
|
|
43
|
+
* See the [IdCompressor README](./id-compressor/README.md) for more details.
|
|
44
|
+
*/
|
|
45
|
+
ContainerMessageType["IdAllocation"] = "idAllocation";
|
|
40
46
|
})(ContainerMessageType || (ContainerMessageType = {}));
|
|
41
47
|
export const DefaultSummaryConfiguration = {
|
|
42
48
|
state: "enabled",
|
|
@@ -92,6 +98,12 @@ const defaultCompressionConfig = {
|
|
|
92
98
|
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
93
99
|
};
|
|
94
100
|
const defaultChunkSizeInBytes = 204800;
|
|
101
|
+
/**
|
|
102
|
+
* Instead of refreshing from latest because we do not have 100% confidence in the state
|
|
103
|
+
* of the current system, we should close the summarizer and let it recover.
|
|
104
|
+
* This delay's goal is to prevent tight restart loops
|
|
105
|
+
*/
|
|
106
|
+
const defaultCloseSummarizerDelayMs = 10000; // 10 seconds
|
|
95
107
|
/**
|
|
96
108
|
* @deprecated - use ContainerRuntimeMessage instead
|
|
97
109
|
*/
|
|
@@ -138,8 +150,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
138
150
|
/**
|
|
139
151
|
* @internal
|
|
140
152
|
*/
|
|
141
|
-
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, requestHandler, summaryConfiguration, initializeEntryPoint) {
|
|
142
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
153
|
+
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, idCompressor, requestHandler, summaryConfiguration, initializeEntryPoint) {
|
|
154
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
143
155
|
if (summaryConfiguration === void 0) { summaryConfiguration = Object.assign(Object.assign({}, DefaultSummaryConfiguration), (_a = runtimeOptions.summaryOptions) === null || _a === void 0 ? void 0 : _a.summaryConfigOverrides); }
|
|
144
156
|
super();
|
|
145
157
|
this.context = context;
|
|
@@ -201,6 +213,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
201
213
|
};
|
|
202
214
|
this.innerDeltaManager = context.deltaManager;
|
|
203
215
|
this.deltaManager = new DeltaManagerSummarizerProxy(context.deltaManager);
|
|
216
|
+
this.mc = loggerToMonitoringContext(ChildLogger.create(this.logger, "ContainerRuntime"));
|
|
204
217
|
let loadSummaryNumber;
|
|
205
218
|
// Get the container creation metadata. For new container, we initialize these. For existing containers,
|
|
206
219
|
// get the values from the metadata blob.
|
|
@@ -212,6 +225,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
212
225
|
// summaryNumber was renamed from summaryCount. For older docs that haven't been opened for a long time,
|
|
213
226
|
// the count is reset to 0.
|
|
214
227
|
loadSummaryNumber = (_b = metadata === null || metadata === void 0 ? void 0 : metadata.summaryNumber) !== null && _b !== void 0 ? _b : 0;
|
|
228
|
+
// Enabling the IdCompressor is a one-way operation and we only want to
|
|
229
|
+
// allow new containers to turn it on
|
|
230
|
+
this.idCompressorEnabled = (_c = metadata === null || metadata === void 0 ? void 0 : metadata.idCompressorEnabled) !== null && _c !== void 0 ? _c : false;
|
|
215
231
|
}
|
|
216
232
|
else {
|
|
217
233
|
this.createContainerMetadata = {
|
|
@@ -219,12 +235,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
219
235
|
createContainerTimestamp: Date.now(),
|
|
220
236
|
};
|
|
221
237
|
loadSummaryNumber = 0;
|
|
238
|
+
this.idCompressorEnabled =
|
|
239
|
+
(_d = this.mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) !== null && _d !== void 0 ? _d : idCompressor !== undefined;
|
|
222
240
|
}
|
|
223
241
|
this.nextSummaryNumber = loadSummaryNumber + 1;
|
|
224
242
|
this.messageAtLastSummary = metadata === null || metadata === void 0 ? void 0 : metadata.message;
|
|
225
243
|
this._connected = this.context.connected;
|
|
226
|
-
this.gcTombstoneEnforcementAllowed = shouldAllowGcTombstoneEnforcement((
|
|
227
|
-
this.mc = loggerToMonitoringContext(ChildLogger.create(this.logger, "ContainerRuntime"));
|
|
244
|
+
this.gcTombstoneEnforcementAllowed = shouldAllowGcTombstoneEnforcement((_e = metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix) === null || _e === void 0 ? void 0 : _e.tombstoneGeneration /* persisted */, this.runtimeOptions.gcOptions[gcTombstoneGenerationOptionName] /* current */);
|
|
228
245
|
this.mc.logger.sendTelemetryEvent({
|
|
229
246
|
eventName: "GCFeatureMatrix",
|
|
230
247
|
metadataValue: JSON.stringify(metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix),
|
|
@@ -232,7 +249,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
232
249
|
gcOptions_gcTombstoneGeneration: this.runtimeOptions.gcOptions[gcTombstoneGenerationOptionName],
|
|
233
250
|
}),
|
|
234
251
|
});
|
|
235
|
-
this.telemetryDocumentId = (
|
|
252
|
+
this.telemetryDocumentId = (_f = metadata === null || metadata === void 0 ? void 0 : metadata.telemetryDocumentId) !== null && _f !== void 0 ? _f : uuid();
|
|
236
253
|
this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
|
|
237
254
|
const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionChunkingDisabled");
|
|
238
255
|
const opGroupingManager = new OpGroupingManager(this.groupedBatchingEnabled);
|
|
@@ -251,10 +268,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
251
268
|
this.heuristicsDisabled = this.isHeuristicsDisabled();
|
|
252
269
|
this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
|
|
253
270
|
this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
|
|
271
|
+
if (this.idCompressorEnabled) {
|
|
272
|
+
this.idCompressor = idCompressor;
|
|
273
|
+
}
|
|
254
274
|
this.maxConsecutiveReconnects =
|
|
255
|
-
(
|
|
275
|
+
(_g = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _g !== void 0 ? _g : this.defaultMaxConsecutiveReconnects;
|
|
256
276
|
if (runtimeOptions.flushMode === FlushModeExperimental.Async &&
|
|
257
|
-
((
|
|
277
|
+
((_h = context.supportedFeatures) === null || _h === void 0 ? void 0 : _h.get("referenceSequenceNumbers")) !== true) {
|
|
258
278
|
// The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
|
|
259
279
|
this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
|
|
260
280
|
this._flushMode = FlushMode.TurnBased;
|
|
@@ -263,7 +283,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
263
283
|
this._flushMode = runtimeOptions.flushMode;
|
|
264
284
|
}
|
|
265
285
|
const pendingRuntimeState = context.pendingLocalState;
|
|
266
|
-
const maxSnapshotCacheDurationMs = (
|
|
286
|
+
const maxSnapshotCacheDurationMs = (_k = (_j = this._storage) === null || _j === void 0 ? void 0 : _j.policies) === null || _k === void 0 ? void 0 : _k.maximumCacheDurationMs;
|
|
267
287
|
if (maxSnapshotCacheDurationMs !== undefined &&
|
|
268
288
|
maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
|
|
269
289
|
// This is a runtime enforcement of what's already explicit in the policy's type itself,
|
|
@@ -315,15 +335,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
315
335
|
this.dataStores = new DataStores(getSummaryForDatastores(context.baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn), (id) => this.summarizerNode.deleteChild(id), this.mc.logger, (path, timestampMs, packagePath) => this.garbageCollector.nodeUpdated(path, "Changed", timestampMs, packagePath), (path) => this.garbageCollector.isNodeDeleted(path), new Map(dataStoreAliasMap));
|
|
316
336
|
this.blobManager = new BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
|
|
317
337
|
if (!this.disposed) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
this.flush();
|
|
322
|
-
this.submit(ContainerMessageType.BlobAttach, undefined, undefined, {
|
|
323
|
-
localId,
|
|
324
|
-
blobId,
|
|
325
|
-
});
|
|
326
|
-
this.flush();
|
|
338
|
+
this.submit(ContainerMessageType.BlobAttach, undefined, undefined, {
|
|
339
|
+
localId,
|
|
340
|
+
blobId,
|
|
327
341
|
});
|
|
328
342
|
}
|
|
329
343
|
}, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs, (error) => this.closeFn(error));
|
|
@@ -358,10 +372,17 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
358
372
|
},
|
|
359
373
|
logger: this.mc.logger,
|
|
360
374
|
groupingManager: opGroupingManager,
|
|
375
|
+
getCurrentSequenceNumbers: () => ({
|
|
376
|
+
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
377
|
+
clientSequenceNumber: this._processedClientSequenceNumber,
|
|
378
|
+
}),
|
|
361
379
|
});
|
|
362
380
|
this.context.quorum.on("removeMember", (clientId) => {
|
|
363
381
|
this.remoteMessageProcessor.clearPartialMessagesFor(clientId);
|
|
364
382
|
});
|
|
383
|
+
this.summaryStateUpdateMethod = this.mc.config.getString("Fluid.ContainerRuntime.Test.SummaryStateUpdateMethod");
|
|
384
|
+
const closeSummarizerDelayOverride = this.mc.config.getNumber("Fluid.ContainerRuntime.Test.CloseSummarizerDelayOverrideMs");
|
|
385
|
+
this.closeSummarizerDelayMs = closeSummarizerDelayOverride !== null && closeSummarizerDelayOverride !== void 0 ? closeSummarizerDelayOverride : defaultCloseSummarizerDelayMs;
|
|
365
386
|
this.summaryCollection = new SummaryCollection(this.deltaManager, this.logger);
|
|
366
387
|
this.dirtyContainer =
|
|
367
388
|
this.context.attachState !== AttachState.Attached ||
|
|
@@ -439,6 +460,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
439
460
|
disableChunking,
|
|
440
461
|
disableAttachReorder: this.disableAttachReorder,
|
|
441
462
|
disablePartialFlush,
|
|
463
|
+
idCompressorEnabled: this.idCompressorEnabled,
|
|
464
|
+
summaryStateUpdateMethod: this.summaryStateUpdateMethod,
|
|
465
|
+
closeSummarizerDelayOverride,
|
|
442
466
|
}), telemetryDocumentId: this.telemetryDocumentId, groupedBatchingEnabled: this.groupedBatchingEnabled }));
|
|
443
467
|
ReportOpPerfTelemetry(this.context.clientId, this.deltaManager, this.logger);
|
|
444
468
|
BindBatchTracker(this, this.logger);
|
|
@@ -498,7 +522,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
498
522
|
* This object should provide all the functionality that the Container is expected to provide to the loader layer.
|
|
499
523
|
*/
|
|
500
524
|
static async loadRuntime(params) {
|
|
501
|
-
var _a, _b, _c, _d;
|
|
525
|
+
var _a, _b, _c, _d, _e, _f;
|
|
502
526
|
const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, initializeEntryPoint, } = params;
|
|
503
527
|
// If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
|
|
504
528
|
// back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
|
|
@@ -509,7 +533,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
509
533
|
runtimeVersion: pkgVersion,
|
|
510
534
|
},
|
|
511
535
|
});
|
|
512
|
-
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
|
|
536
|
+
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor = false, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
|
|
513
537
|
const registry = new FluidDataStoreRegistry(registryEntries);
|
|
514
538
|
const tryFetchBlob = async (blobName) => {
|
|
515
539
|
var _a;
|
|
@@ -521,11 +545,12 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
521
545
|
return readAndParse(context.storage, blobId);
|
|
522
546
|
}
|
|
523
547
|
};
|
|
524
|
-
const [chunks, metadata, electedSummarizerData, aliases] = await Promise.all([
|
|
548
|
+
const [chunks, metadata, electedSummarizerData, aliases, serializedIdCompressor] = await Promise.all([
|
|
525
549
|
tryFetchBlob(chunksBlobName),
|
|
526
550
|
tryFetchBlob(metadataBlobName),
|
|
527
551
|
tryFetchBlob(electedSummarizerBlobName),
|
|
528
552
|
tryFetchBlob(aliasBlobName),
|
|
553
|
+
tryFetchBlob(idCompressorBlobName),
|
|
529
554
|
]);
|
|
530
555
|
const loadExisting = existing === true || context.existing === true;
|
|
531
556
|
// read snapshot blobs needed for BlobManager to load
|
|
@@ -557,6 +582,15 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
557
582
|
}
|
|
558
583
|
}
|
|
559
584
|
}
|
|
585
|
+
const idCompressorEnabled = (_f = (_e = metadata === null || metadata === void 0 ? void 0 : metadata.idCompressorEnabled) !== null && _e !== void 0 ? _e : runtimeOptions.enableRuntimeIdCompressor) !== null && _f !== void 0 ? _f : false;
|
|
586
|
+
let idCompressor;
|
|
587
|
+
if (idCompressorEnabled) {
|
|
588
|
+
const { IdCompressor, createSessionId } = await import("./id-compressor");
|
|
589
|
+
idCompressor =
|
|
590
|
+
serializedIdCompressor !== undefined
|
|
591
|
+
? IdCompressor.deserialize(serializedIdCompressor, createSessionId())
|
|
592
|
+
: new IdCompressor(createSessionId(), logger);
|
|
593
|
+
}
|
|
560
594
|
const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks !== null && chunks !== void 0 ? chunks : [], aliases !== null && aliases !== void 0 ? aliases : [], {
|
|
561
595
|
summaryOptions,
|
|
562
596
|
gcOptions,
|
|
@@ -565,9 +599,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
565
599
|
compressionOptions,
|
|
566
600
|
maxBatchSizeInBytes,
|
|
567
601
|
chunkSizeInBytes,
|
|
602
|
+
enableRuntimeIdCompressor,
|
|
568
603
|
enableOpReentryCheck,
|
|
569
604
|
enableGroupedBatching,
|
|
570
|
-
}, containerScope, logger, loadExisting, blobManagerSnapshot, context.storage, requestHandler, undefined, // summaryConfiguration
|
|
605
|
+
}, containerScope, logger, loadExisting, blobManagerSnapshot, context.storage, idCompressor, requestHandler, undefined, // summaryConfiguration
|
|
571
606
|
initializeEntryPoint);
|
|
572
607
|
// It's possible to have ops with a reference sequence number of 0. Op sequence numbers start
|
|
573
608
|
// at 1, so we won't see a replayed saved op with a sequence number of 0.
|
|
@@ -803,12 +838,17 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
803
838
|
summaryNumber: this.nextSummaryNumber++, summaryFormatVersion: 1 }), this.garbageCollector.getMetadata()), {
|
|
804
839
|
// The last message processed at the time of summary. If there are no new messages, use the message from the
|
|
805
840
|
// last summary.
|
|
806
|
-
message: (_a = extractSummaryMetadataMessage(this.deltaManager.lastMessage)) !== null && _a !== void 0 ? _a : this.messageAtLastSummary, telemetryDocumentId: this.telemetryDocumentId });
|
|
841
|
+
message: (_a = extractSummaryMetadataMessage(this.deltaManager.lastMessage)) !== null && _a !== void 0 ? _a : this.messageAtLastSummary, telemetryDocumentId: this.telemetryDocumentId, idCompressorEnabled: this.idCompressorEnabled ? true : undefined });
|
|
807
842
|
addBlobToSummary(summaryTree, metadataBlobName, JSON.stringify(metadata));
|
|
808
843
|
}
|
|
809
844
|
addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
|
|
810
845
|
var _a;
|
|
811
846
|
this.addMetadataToSummary(summaryTree);
|
|
847
|
+
if (this.idCompressorEnabled) {
|
|
848
|
+
assert(this.idCompressor !== undefined, 0x67a /* IdCompressor should be defined if enabled */);
|
|
849
|
+
const idCompressorState = JSON.stringify(this.idCompressor.serialize(false));
|
|
850
|
+
addBlobToSummary(summaryTree, idCompressorBlobName, idCompressorState);
|
|
851
|
+
}
|
|
812
852
|
if (this.remoteMessageProcessor.partialMessages.size > 0) {
|
|
813
853
|
const content = JSON.stringify([...this.remoteMessageProcessor.partialMessages]);
|
|
814
854
|
addBlobToSummary(summaryTree, chunksBlobName, content);
|
|
@@ -890,12 +930,28 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
890
930
|
// Officially transition from the old state to the new state.
|
|
891
931
|
this.updateDocumentDirtyState(newState);
|
|
892
932
|
}
|
|
893
|
-
|
|
933
|
+
/**
|
|
934
|
+
* Updates the runtime's IdCompressor with the stashed state present in the given op. This is a bit of a
|
|
935
|
+
* hack and is unnecessarily expensive. As it stands, every locally stashed op (all ops that get stored in
|
|
936
|
+
* the PendingStateManager) will store their serialized representation locally until ack'd. Upon receiving
|
|
937
|
+
* this stashed state, the IdCompressor blindly deserializes to the stashed state and assumes the session.
|
|
938
|
+
* Technically only the last stashed state is needed to do this correctly, but we would have to write some
|
|
939
|
+
* more hacky code to modify the batch before it gets sent out.
|
|
940
|
+
* @param content - An IdAllocationOp with "stashedState", which is a representation of un-ack'd local state.
|
|
941
|
+
*/
|
|
942
|
+
async applyStashedIdAllocationOp(op) {
|
|
943
|
+
const { IdCompressor } = await import("./id-compressor");
|
|
944
|
+
this.idCompressor = IdCompressor.deserialize(op.stashedState);
|
|
945
|
+
}
|
|
946
|
+
async applyStashedOp(type, contents) {
|
|
894
947
|
switch (type) {
|
|
895
948
|
case ContainerMessageType.FluidDataStoreOp:
|
|
896
|
-
return this.dataStores.applyStashedOp(
|
|
949
|
+
return this.dataStores.applyStashedOp(contents);
|
|
897
950
|
case ContainerMessageType.Attach:
|
|
898
|
-
return this.dataStores.applyStashedAttachOp(
|
|
951
|
+
return this.dataStores.applyStashedAttachOp(contents);
|
|
952
|
+
case ContainerMessageType.IdAllocation:
|
|
953
|
+
assert(this.idCompressor !== undefined, 0x67b /* IdCompressor should be defined if enabled */);
|
|
954
|
+
return this.applyStashedIdAllocationOp(contents);
|
|
899
955
|
case ContainerMessageType.Alias:
|
|
900
956
|
case ContainerMessageType.BlobAttach:
|
|
901
957
|
return;
|
|
@@ -991,6 +1047,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
991
1047
|
// the beginning and end. This allows it to emit appropriate events and/or pause the processing of new
|
|
992
1048
|
// messages once a batch has been fully processed.
|
|
993
1049
|
this.scheduleManager.beforeOpProcessing(message);
|
|
1050
|
+
this._processedClientSequenceNumber = message.clientSequenceNumber;
|
|
994
1051
|
try {
|
|
995
1052
|
let localOpMetadata;
|
|
996
1053
|
if (local && runtimeMessage && message.type !== ContainerMessageType.ChunkedOp) {
|
|
@@ -1015,6 +1072,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1015
1072
|
case ContainerMessageType.BlobAttach:
|
|
1016
1073
|
this.blobManager.processBlobAttachOp(message, local);
|
|
1017
1074
|
break;
|
|
1075
|
+
case ContainerMessageType.IdAllocation:
|
|
1076
|
+
assert(this.idCompressor !== undefined, 0x67c /* IdCompressor should be defined if enabled */);
|
|
1077
|
+
this.idCompressor.finalizeCreationRange(message.contents);
|
|
1078
|
+
break;
|
|
1018
1079
|
case ContainerMessageType.ChunkedOp:
|
|
1019
1080
|
case ContainerMessageType.Rejoin:
|
|
1020
1081
|
break;
|
|
@@ -1324,17 +1385,21 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1324
1385
|
fullGC,
|
|
1325
1386
|
runSweep,
|
|
1326
1387
|
});
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1388
|
+
try {
|
|
1389
|
+
let gcStats;
|
|
1390
|
+
if (runGC) {
|
|
1391
|
+
gcStats = await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC }, telemetryContext);
|
|
1392
|
+
}
|
|
1393
|
+
const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
|
|
1394
|
+
assert(summary.type === SummaryType.Tree, 0x12f /* "Container Runtime's summarize should always return a tree" */);
|
|
1395
|
+
return { stats, summary, gcStats };
|
|
1396
|
+
}
|
|
1397
|
+
finally {
|
|
1398
|
+
this.logger.sendTelemetryEvent({
|
|
1399
|
+
eventName: "SummarizeTelemetry",
|
|
1400
|
+
details: telemetryContext.serialize(),
|
|
1401
|
+
});
|
|
1330
1402
|
}
|
|
1331
|
-
const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
|
|
1332
|
-
this.logger.sendTelemetryEvent({
|
|
1333
|
-
eventName: "SummarizeTelemetry",
|
|
1334
|
-
details: telemetryContext.serialize(),
|
|
1335
|
-
});
|
|
1336
|
-
assert(summary.type === SummaryType.Tree, 0x12f /* "Container Runtime's summarize should always return a tree" */);
|
|
1337
|
-
return { stats, summary, gcStats };
|
|
1338
1403
|
}
|
|
1339
1404
|
/**
|
|
1340
1405
|
* Before GC runs, called by the garbage collector to update any pending GC state. This is mainly used to notify
|
|
@@ -1721,6 +1786,35 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1721
1786
|
this.verifyNotClosed();
|
|
1722
1787
|
return this.blobManager.createBlob(blob);
|
|
1723
1788
|
}
|
|
1789
|
+
maybeSubmitIdAllocationOp(type) {
|
|
1790
|
+
var _a, _b;
|
|
1791
|
+
if (type !== ContainerMessageType.IdAllocation) {
|
|
1792
|
+
let idAllocationBatchMessage;
|
|
1793
|
+
let idRange;
|
|
1794
|
+
if (this.idCompressorEnabled) {
|
|
1795
|
+
assert(this.idCompressor !== undefined, 0x67d /* IdCompressor should be defined if enabled */);
|
|
1796
|
+
idRange = this.idCompressor.takeNextCreationRange();
|
|
1797
|
+
// Don't include the idRange if there weren't any Ids allocated
|
|
1798
|
+
idRange = ((_a = idRange === null || idRange === void 0 ? void 0 : idRange.ids) === null || _a === void 0 ? void 0 : _a.first) !== undefined ? idRange : undefined;
|
|
1799
|
+
}
|
|
1800
|
+
if (idRange !== undefined) {
|
|
1801
|
+
const idAllocationMessage = {
|
|
1802
|
+
type: ContainerMessageType.IdAllocation,
|
|
1803
|
+
contents: idRange,
|
|
1804
|
+
};
|
|
1805
|
+
idAllocationBatchMessage = {
|
|
1806
|
+
contents: JSON.stringify(idAllocationMessage),
|
|
1807
|
+
deserializedContent: idAllocationMessage,
|
|
1808
|
+
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
1809
|
+
metadata: undefined,
|
|
1810
|
+
localOpMetadata: (_b = this.idCompressor) === null || _b === void 0 ? void 0 : _b.serialize(true),
|
|
1811
|
+
};
|
|
1812
|
+
}
|
|
1813
|
+
if (idAllocationBatchMessage !== undefined) {
|
|
1814
|
+
this.outbox.submit(idAllocationBatchMessage);
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1724
1818
|
submit(type, contents, localOpMetadata = undefined, metadata = undefined) {
|
|
1725
1819
|
this.verifyNotClosed();
|
|
1726
1820
|
this.verifyCanSubmitOps();
|
|
@@ -1743,6 +1837,11 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1743
1837
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
1744
1838
|
};
|
|
1745
1839
|
try {
|
|
1840
|
+
// Submit an IdAllocation op if any Ids have been generated since
|
|
1841
|
+
// the last op was submitted. Don't submit another if it's an IdAllocation
|
|
1842
|
+
// op as that means we're in resubmission flow and we don't want to send
|
|
1843
|
+
// IdRanges out of order.
|
|
1844
|
+
this.maybeSubmitIdAllocationOp(type);
|
|
1746
1845
|
// If this is attach message for new data store, and we are in a batch, send this op out of order
|
|
1747
1846
|
// Is it safe:
|
|
1748
1847
|
// Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
|
|
@@ -1879,6 +1978,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1879
1978
|
break;
|
|
1880
1979
|
case ContainerMessageType.Attach:
|
|
1881
1980
|
case ContainerMessageType.Alias:
|
|
1981
|
+
case ContainerMessageType.IdAllocation:
|
|
1882
1982
|
this.submit(type, content, localOpMetadata);
|
|
1883
1983
|
break;
|
|
1884
1984
|
case ContainerMessageType.ChunkedOp:
|
|
@@ -1928,6 +2028,19 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1928
2028
|
ackHandle,
|
|
1929
2029
|
targetSequenceNumber: summaryRefSeq,
|
|
1930
2030
|
}, readAndParseBlob);
|
|
2031
|
+
/**
|
|
2032
|
+
* back-compat - Older loaders and drivers (pre 2.0.0-internal.1.4) don't have fetchSource as a param in the
|
|
2033
|
+
* getVersions API. So, they will not fetch the latest snapshot from network in the previous fetch call. For
|
|
2034
|
+
* these scenarios, fetch the snapshot corresponding to the ack handle to have the same behavior before the
|
|
2035
|
+
* change that started fetching latest snapshot always.
|
|
2036
|
+
*/
|
|
2037
|
+
if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
|
|
2038
|
+
fetchResult = await this.fetchSnapshotFromStorage(summaryLogger, {
|
|
2039
|
+
eventName: "RefreshLatestSummaryAckFetchBackCompat",
|
|
2040
|
+
ackHandle,
|
|
2041
|
+
targetSequenceNumber: summaryRefSeq,
|
|
2042
|
+
}, readAndParseBlob, ackHandle);
|
|
2043
|
+
}
|
|
1931
2044
|
/**
|
|
1932
2045
|
* If the fetched snapshot is older than the one for which the ack was received, close the container.
|
|
1933
2046
|
* This should never happen because an ack should be sent after the latest summary is updated in the server.
|
|
@@ -1939,21 +2052,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1939
2052
|
* state.
|
|
1940
2053
|
*/
|
|
1941
2054
|
if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
|
|
1942
|
-
|
|
1943
|
-
fetchResult = await this.fetchSnapshotFromStorage(summaryLogger, {
|
|
1944
|
-
eventName: "RefreshLatestSummaryAckFetch",
|
|
2055
|
+
const error = DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
|
|
1945
2056
|
ackHandle,
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
summaryRefSeq,
|
|
1952
|
-
fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
|
|
1953
|
-
});
|
|
1954
|
-
this.closeFn(error);
|
|
1955
|
-
throw error;
|
|
1956
|
-
}
|
|
2057
|
+
summaryRefSeq,
|
|
2058
|
+
fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
|
|
2059
|
+
});
|
|
2060
|
+
this.closeFn(error);
|
|
2061
|
+
throw error;
|
|
1957
2062
|
}
|
|
1958
2063
|
// In case we had to retrieve the latest snapshot and it is different than summaryRefSeq,
|
|
1959
2064
|
// wait for the delta manager to catch up before refreshing the latest Summary.
|
|
@@ -1992,15 +2097,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1992
2097
|
}
|
|
1993
2098
|
async fetchSnapshotFromStorage(logger, event, readAndParseBlob, versionId) {
|
|
1994
2099
|
var _a;
|
|
1995
|
-
const
|
|
1996
|
-
if (recoveryMethod === "restart") {
|
|
1997
|
-
const error = new GenericError("Restarting summarizer instead of refreshing");
|
|
1998
|
-
this.mc.logger.sendTelemetryEvent(Object.assign(Object.assign({}, event), { eventName: "ClosingSummarizerOnSummaryStale", codePath: event.eventName, message: "Stopping fetch from storage", versionId: versionId != null ? versionId : undefined }), error);
|
|
1999
|
-
(_a = this._summarizer) === null || _a === void 0 ? void 0 : _a.stop("latestSummaryStateStale");
|
|
2000
|
-
this.closeFn();
|
|
2001
|
-
throw error;
|
|
2002
|
-
}
|
|
2003
|
-
return PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
|
|
2100
|
+
const snapshotResults = await PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
|
|
2004
2101
|
const stats = {};
|
|
2005
2102
|
const trace = Trace.start();
|
|
2006
2103
|
const versions = await this.storage.getVersions(versionId, 1, "refreshLatestSummaryAckFromServer", versionId === null ? FetchSource.noCache : undefined);
|
|
@@ -2019,6 +2116,19 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2019
2116
|
latestSnapshotRefSeq,
|
|
2020
2117
|
};
|
|
2021
2118
|
});
|
|
2119
|
+
// We choose to close the summarizer after the snapshot cache is updated to avoid
|
|
2120
|
+
// situations which the main client (which is likely to be re-elected as the leader again)
|
|
2121
|
+
// loads the summarizer from cache.
|
|
2122
|
+
if (this.summaryStateUpdateMethod === "restart") {
|
|
2123
|
+
const error = new GenericError("Restarting summarizer instead of refreshing");
|
|
2124
|
+
this.mc.logger.sendTelemetryEvent(Object.assign(Object.assign({}, event), { eventName: "ClosingSummarizerOnSummaryStale", codePath: event.eventName, message: "Stopping fetch from storage", versionId: versionId != null ? versionId : undefined, closeSummarizerDelayMs: this.closeSummarizerDelayMs }), error);
|
|
2125
|
+
// Delay 10 seconds before restarting summarizer to prevent the summarizer from restarting too frequently.
|
|
2126
|
+
await delay(this.closeSummarizerDelayMs);
|
|
2127
|
+
(_a = this._summarizer) === null || _a === void 0 ? void 0 : _a.stop("latestSummaryStateStale");
|
|
2128
|
+
this.closeFn();
|
|
2129
|
+
throw error;
|
|
2130
|
+
}
|
|
2131
|
+
return snapshotResults;
|
|
2022
2132
|
}
|
|
2023
2133
|
notifyAttaching() { } // do nothing (deprecated method)
|
|
2024
2134
|
getPendingLocalState() {
|