@fluidframework/container-runtime 2.0.0-internal.5.4.2 → 2.0.0-internal.6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/dist/batchTracker.d.ts +2 -1
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +4 -1
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +61 -26
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.js +10 -2
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +26 -11
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +177 -123
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.js +8 -2
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.js +23 -24
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +20 -4
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +107 -53
- package/dist/dataStores.js.map +1 -1
- package/dist/gc/garbageCollection.js +17 -20
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.js +13 -11
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcHelpers.js +4 -6
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +4 -6
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +55 -37
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/id-compressor/idCompressor.js +49 -51
- package/dist/id-compressor/idCompressor.js.map +1 -1
- package/dist/id-compressor/idRange.js +2 -2
- package/dist/id-compressor/idRange.js.map +1 -1
- package/dist/id-compressor/sessionIdNormalizer.js +11 -16
- package/dist/id-compressor/sessionIdNormalizer.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.js +10 -6
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/opCompressor.js +6 -1
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +11 -9
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +13 -5
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.js +10 -6
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.js +1 -2
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/opProperties.js +1 -2
- package/dist/opProperties.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 +2 -2
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +22 -22
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.js +14 -10
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +2 -1
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +17 -18
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runningSummarizer.js +32 -38
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.js +4 -7
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.js +5 -9
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.js +8 -12
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +22 -15
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js +2 -4
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +17 -16
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summaryCollection.js +3 -5
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.js +1 -2
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.js +62 -20
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.js +3 -5
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/batchTracker.d.ts +2 -1
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +4 -1
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +61 -26
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.js +10 -2
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +26 -11
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +177 -123
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.js +8 -2
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.js +23 -24
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +20 -4
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +107 -53
- package/lib/dataStores.js.map +1 -1
- package/lib/gc/garbageCollection.js +17 -20
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.js +13 -11
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcHelpers.js +4 -6
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +4 -6
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +55 -37
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/id-compressor/idCompressor.js +49 -51
- package/lib/id-compressor/idCompressor.js.map +1 -1
- package/lib/id-compressor/idRange.js +2 -2
- package/lib/id-compressor/idRange.js.map +1 -1
- package/lib/id-compressor/sessionIdNormalizer.js +11 -16
- package/lib/id-compressor/sessionIdNormalizer.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/batchManager.js +10 -6
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/opCompressor.js +6 -1
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +11 -9
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +13 -5
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.js +10 -6
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.js +1 -2
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/opProperties.js +1 -2
- package/lib/opProperties.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 +2 -2
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +22 -22
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.js +14 -10
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +2 -1
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +17 -18
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runningSummarizer.js +32 -38
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.js +4 -7
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.js +5 -9
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.js +8 -12
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +22 -15
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js +2 -4
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +17 -16
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summaryCollection.js +3 -5
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.js +1 -2
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.js +62 -20
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.js +3 -5
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +17 -17
- package/src/batchTracker.ts +2 -1
- package/src/blobManager.ts +43 -2
- package/src/containerRuntime.ts +74 -51
- package/src/dataStore.ts +7 -1
- package/src/dataStores.ts +95 -55
- package/src/gc/gcTelemetry.ts +1 -2
- package/src/index.ts +0 -1
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +12 -15
- package/src/summary/orderedClientElection.ts +2 -1
package/dist/containerRuntime.js
CHANGED
|
@@ -18,17 +18,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
18
18
|
__setModuleDefault(result, mod);
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
22
|
-
var t = {};
|
|
23
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
24
|
-
t[p] = s[p];
|
|
25
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
26
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
27
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
28
|
-
t[p[i]] = s[p[i]];
|
|
29
|
-
}
|
|
30
|
-
return t;
|
|
31
|
-
};
|
|
32
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
22
|
exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.RuntimeMessage = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.TombstoneResponseHeaderKey = exports.AllowTombstoneRequestHeaderKey = exports.RuntimeHeaders = exports.DefaultSummaryConfiguration = exports.ContainerMessageType = void 0;
|
|
34
23
|
const container_definitions_1 = require("@fluidframework/container-definitions");
|
|
@@ -174,7 +163,7 @@ function getDeviceSpec() {
|
|
|
174
163
|
};
|
|
175
164
|
}
|
|
176
165
|
}
|
|
177
|
-
catch
|
|
166
|
+
catch { }
|
|
178
167
|
return {};
|
|
179
168
|
}
|
|
180
169
|
exports.getDeviceSpec = getDeviceSpec;
|
|
@@ -201,9 +190,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
201
190
|
/**
|
|
202
191
|
* @internal
|
|
203
192
|
*/
|
|
204
|
-
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, idCompressor, requestHandler, summaryConfiguration
|
|
205
|
-
|
|
206
|
-
|
|
193
|
+
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, idCompressor, requestHandler, summaryConfiguration = {
|
|
194
|
+
// the defaults
|
|
195
|
+
...exports.DefaultSummaryConfiguration,
|
|
196
|
+
// the runtime configuration overrides
|
|
197
|
+
...runtimeOptions.summaryOptions?.summaryConfigOverrides,
|
|
198
|
+
}, initializeEntryPoint) {
|
|
207
199
|
super();
|
|
208
200
|
this.registry = registry;
|
|
209
201
|
this.runtimeOptions = runtimeOptions;
|
|
@@ -273,7 +265,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
273
265
|
this.options = options;
|
|
274
266
|
this.clientDetails = clientDetails;
|
|
275
267
|
this.isSummarizerClient = this.clientDetails.type === summary_1.summarizerClientType;
|
|
276
|
-
this.loadedFromVersionId =
|
|
268
|
+
this.loadedFromVersionId = context.getLoadedFromVersion()?.id;
|
|
277
269
|
this._getClientId = () => context.clientId;
|
|
278
270
|
this._getAttachState = () => context.attachState;
|
|
279
271
|
this.getAbsoluteUrl = async (relativeUrl) => {
|
|
@@ -290,15 +282,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
290
282
|
this.on("dirty", () => context.updateDirtyContainerState(true));
|
|
291
283
|
this.on("saved", () => context.updateDirtyContainerState(false));
|
|
292
284
|
// In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
|
|
293
|
-
this.disposeFn = disposeFn
|
|
285
|
+
this.disposeFn = disposeFn ?? closeFn;
|
|
294
286
|
// In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
|
|
295
|
-
this.closeFn = this.isSummarizerClient
|
|
296
|
-
? this.disposeFn
|
|
297
|
-
: (error) => {
|
|
298
|
-
closeFn(error);
|
|
299
|
-
// Also call disposeFn to retain functionality of runtime being disposed on close
|
|
300
|
-
disposeFn === null || disposeFn === void 0 ? void 0 : disposeFn(error);
|
|
301
|
-
};
|
|
287
|
+
this.closeFn = this.isSummarizerClient ? this.disposeFn : closeFn;
|
|
302
288
|
this.mc = (0, telemetry_utils_1.createChildMonitoringContext)({
|
|
303
289
|
logger: this.logger,
|
|
304
290
|
namespace: "ContainerRuntime",
|
|
@@ -308,15 +294,15 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
308
294
|
// get the values from the metadata blob.
|
|
309
295
|
if (existing) {
|
|
310
296
|
this.createContainerMetadata = {
|
|
311
|
-
createContainerRuntimeVersion: metadata
|
|
312
|
-
createContainerTimestamp: metadata
|
|
297
|
+
createContainerRuntimeVersion: metadata?.createContainerRuntimeVersion,
|
|
298
|
+
createContainerTimestamp: metadata?.createContainerTimestamp,
|
|
313
299
|
};
|
|
314
300
|
// summaryNumber was renamed from summaryCount. For older docs that haven't been opened for a long time,
|
|
315
301
|
// the count is reset to 0.
|
|
316
|
-
loadSummaryNumber =
|
|
302
|
+
loadSummaryNumber = metadata?.summaryNumber ?? 0;
|
|
317
303
|
// Enabling the IdCompressor is a one-way operation and we only want to
|
|
318
304
|
// allow new containers to turn it on
|
|
319
|
-
this.idCompressorEnabled =
|
|
305
|
+
this.idCompressorEnabled = metadata?.idCompressorEnabled ?? false;
|
|
320
306
|
}
|
|
321
307
|
else {
|
|
322
308
|
this.createContainerMetadata = {
|
|
@@ -325,22 +311,23 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
325
311
|
};
|
|
326
312
|
loadSummaryNumber = 0;
|
|
327
313
|
this.idCompressorEnabled =
|
|
328
|
-
|
|
314
|
+
this.mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled") ??
|
|
315
|
+
idCompressor !== undefined;
|
|
329
316
|
}
|
|
330
317
|
this.nextSummaryNumber = loadSummaryNumber + 1;
|
|
331
|
-
this.messageAtLastSummary = metadata
|
|
318
|
+
this.messageAtLastSummary = metadata?.message;
|
|
332
319
|
// Note that we only need to pull the *initial* connected state from the context.
|
|
333
320
|
// Later updates come through calls to setConnectionState.
|
|
334
321
|
this._connected = connected;
|
|
335
|
-
this.gcTombstoneEnforcementAllowed = (0, gc_1.shouldAllowGcTombstoneEnforcement)(
|
|
322
|
+
this.gcTombstoneEnforcementAllowed = (0, gc_1.shouldAllowGcTombstoneEnforcement)(metadata?.gcFeatureMatrix?.tombstoneGeneration /* persisted */, this.runtimeOptions.gcOptions[gc_1.gcTombstoneGenerationOptionName] /* current */);
|
|
336
323
|
this.mc.logger.sendTelemetryEvent({
|
|
337
324
|
eventName: "GCFeatureMatrix",
|
|
338
|
-
metadataValue: JSON.stringify(metadata
|
|
325
|
+
metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
|
|
339
326
|
inputs: JSON.stringify({
|
|
340
327
|
gcOptions_gcTombstoneGeneration: this.runtimeOptions.gcOptions[gc_1.gcTombstoneGenerationOptionName],
|
|
341
328
|
}),
|
|
342
329
|
});
|
|
343
|
-
this.telemetryDocumentId =
|
|
330
|
+
this.telemetryDocumentId = metadata?.telemetryDocumentId ?? (0, uuid_1.v4)();
|
|
344
331
|
this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
|
|
345
332
|
const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionChunkingDisabled");
|
|
346
333
|
const opGroupingManager = new opLifecycle_1.OpGroupingManager(this.groupedBatchingEnabled);
|
|
@@ -363,9 +350,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
363
350
|
this.idCompressor = idCompressor;
|
|
364
351
|
}
|
|
365
352
|
this.maxConsecutiveReconnects =
|
|
366
|
-
|
|
353
|
+
this.mc.config.getNumber(maxConsecutiveReconnectsKey) ??
|
|
354
|
+
this.defaultMaxConsecutiveReconnects;
|
|
367
355
|
if (runtimeOptions.flushMode === runtime_definitions_1.FlushModeExperimental.Async &&
|
|
368
|
-
|
|
356
|
+
supportedFeatures?.get("referenceSequenceNumbers") !== true) {
|
|
369
357
|
// The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
|
|
370
358
|
this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
|
|
371
359
|
this._flushMode = runtime_definitions_1.FlushMode.TurnBased;
|
|
@@ -374,7 +362,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
374
362
|
this._flushMode = runtimeOptions.flushMode;
|
|
375
363
|
}
|
|
376
364
|
const pendingRuntimeState = pendingLocalState;
|
|
377
|
-
const maxSnapshotCacheDurationMs =
|
|
365
|
+
const maxSnapshotCacheDurationMs = this._storage?.policies?.maximumCacheDurationMs;
|
|
378
366
|
if (maxSnapshotCacheDurationMs !== undefined &&
|
|
379
367
|
maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
|
|
380
368
|
// This is a runtime enforcement of what's already explicit in the policy's type itself,
|
|
@@ -392,7 +380,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
392
380
|
createContainerMetadata: this.createContainerMetadata,
|
|
393
381
|
isSummarizerClient: this.isSummarizerClient,
|
|
394
382
|
getNodePackagePath: async (nodePath) => this.getGCNodePackagePath(nodePath),
|
|
395
|
-
getLastSummaryTimestampMs: () =>
|
|
383
|
+
getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
|
|
396
384
|
readAndParseBlob: async (id) => (0, driver_utils_1.readAndParse)(this.storage, id),
|
|
397
385
|
// GC runs in summarizer client and needs access to the real (non-proxy) active information. The proxy
|
|
398
386
|
// delta manager would always return false for summarizer client.
|
|
@@ -430,7 +418,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
430
418
|
blobId,
|
|
431
419
|
});
|
|
432
420
|
}
|
|
433
|
-
}, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState
|
|
421
|
+
}, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState?.pendingAttachmentBlobs, (error) => this.closeFn(error));
|
|
434
422
|
this.scheduleManager = new scheduleManager_1.ScheduleManager(this.innerDeltaManager, this, () => this.clientId, (0, telemetry_utils_1.createChildLogger)({ logger: this.logger, namespace: "ScheduleManager" }));
|
|
435
423
|
this.pendingStateManager = new pendingStateManager_1.PendingStateManager({
|
|
436
424
|
applyStashedOp: this.applyStashedOp.bind(this),
|
|
@@ -440,7 +428,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
440
428
|
reSubmit: this.reSubmit.bind(this),
|
|
441
429
|
reSubmitBatch: this.reSubmitBatch.bind(this),
|
|
442
430
|
isActiveConnection: () => this.innerDeltaManager.active,
|
|
443
|
-
}, pendingRuntimeState
|
|
431
|
+
}, pendingRuntimeState?.pending, this.logger);
|
|
444
432
|
const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
|
|
445
433
|
const compressionOptions = disableCompression === true
|
|
446
434
|
? {
|
|
@@ -481,9 +469,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
481
469
|
this._audience = audience;
|
|
482
470
|
this.summaryStateUpdateMethod = this.mc.config.getString("Fluid.ContainerRuntime.Test.SummaryStateUpdateMethodV2");
|
|
483
471
|
const closeSummarizerDelayOverride = this.mc.config.getNumber("Fluid.ContainerRuntime.Test.CloseSummarizerDelayOverrideMs");
|
|
484
|
-
this.closeSummarizerDelayMs = closeSummarizerDelayOverride
|
|
472
|
+
this.closeSummarizerDelayMs = closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
|
|
485
473
|
this.validateSummaryBeforeUpload =
|
|
486
|
-
|
|
474
|
+
this.mc.config.getBoolean("Fluid.ContainerRuntime.Test.ValidateSummaryBeforeUpload") ??
|
|
475
|
+
false;
|
|
487
476
|
this.summaryCollection = new summary_1.SummaryCollection(this.deltaManager, this.logger);
|
|
488
477
|
this.dirtyContainer =
|
|
489
478
|
this.attachState !== container_definitions_1.AttachState.Attached ||
|
|
@@ -498,7 +487,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
498
487
|
namespace: "OrderedClientElection",
|
|
499
488
|
});
|
|
500
489
|
const orderedClientCollection = new summary_1.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
|
|
501
|
-
const orderedClientElectionForSummarizer = new summary_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData
|
|
490
|
+
const orderedClientElectionForSummarizer = new summary_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, summary_1.SummarizerClientElection.isClientEligible);
|
|
502
491
|
this.summarizerClientElection = new summary_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
|
|
503
492
|
if (this.isSummarizerClient) {
|
|
504
493
|
this._summarizer = new summary_1.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => summary_1.RunWhileConnectedCoordinator.create(runtime,
|
|
@@ -559,8 +548,20 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
559
548
|
this.replayPendingStates();
|
|
560
549
|
});
|
|
561
550
|
// logging hardware telemetry
|
|
562
|
-
logger.sendTelemetryEvent(
|
|
563
|
-
|
|
551
|
+
logger.sendTelemetryEvent({
|
|
552
|
+
eventName: "DeviceSpec",
|
|
553
|
+
...getDeviceSpec(),
|
|
554
|
+
});
|
|
555
|
+
this.mc.logger.sendTelemetryEvent({
|
|
556
|
+
eventName: "ContainerLoadStats",
|
|
557
|
+
...this.createContainerMetadata,
|
|
558
|
+
...this.dataStores.containerLoadStats,
|
|
559
|
+
summaryNumber: loadSummaryNumber,
|
|
560
|
+
summaryFormatVersion: metadata?.summaryFormatVersion,
|
|
561
|
+
disableIsolatedChannels: metadata?.disableIsolatedChannels,
|
|
562
|
+
gcVersion: metadata?.gcFeature,
|
|
563
|
+
options: JSON.stringify(runtimeOptions),
|
|
564
|
+
featureGates: JSON.stringify({
|
|
564
565
|
disableCompression,
|
|
565
566
|
disableOpReentryCheck,
|
|
566
567
|
disableChunking,
|
|
@@ -569,7 +570,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
569
570
|
idCompressorEnabled: this.idCompressorEnabled,
|
|
570
571
|
summaryStateUpdateMethod: this.summaryStateUpdateMethod,
|
|
571
572
|
closeSummarizerDelayOverride,
|
|
572
|
-
}),
|
|
573
|
+
}),
|
|
574
|
+
telemetryDocumentId: this.telemetryDocumentId,
|
|
575
|
+
groupedBatchingEnabled: this.groupedBatchingEnabled,
|
|
576
|
+
});
|
|
573
577
|
(0, connectionTelemetry_1.ReportOpPerfTelemetry)(this.clientId, this.deltaManager, this.logger);
|
|
574
578
|
(0, batchTracker_1.BindBatchTracker)(this, this.logger);
|
|
575
579
|
this.entryPoint = new core_utils_1.LazyPromise(async () => {
|
|
@@ -577,9 +581,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
577
581
|
(0, common_utils_1.assert)(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
|
|
578
582
|
return this._summarizer;
|
|
579
583
|
}
|
|
580
|
-
return initializeEntryPoint
|
|
584
|
+
return initializeEntryPoint?.(this);
|
|
581
585
|
});
|
|
582
586
|
}
|
|
587
|
+
/**
|
|
588
|
+
* @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
|
|
589
|
+
*/
|
|
583
590
|
get IFluidRouter() {
|
|
584
591
|
return this;
|
|
585
592
|
}
|
|
@@ -625,12 +632,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
625
632
|
* This object should provide all the functionality that the Container is expected to provide to the loader layer.
|
|
626
633
|
*/
|
|
627
634
|
static async loadRuntime(params) {
|
|
628
|
-
var _a, _b, _c, _d, _e, _f;
|
|
629
635
|
const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, initializeEntryPoint, } = params;
|
|
630
636
|
// If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
|
|
631
637
|
// back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
|
|
632
638
|
const backCompatContext = context;
|
|
633
|
-
const passLogger =
|
|
639
|
+
const passLogger = backCompatContext.taggedLogger ??
|
|
640
|
+
new telemetry_utils_1.TaggedLoggerAdapter(backCompatContext.logger);
|
|
634
641
|
const logger = (0, telemetry_utils_1.createChildLogger)({
|
|
635
642
|
logger: passLogger,
|
|
636
643
|
properties: {
|
|
@@ -642,8 +649,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
642
649
|
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor = false, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
|
|
643
650
|
const registry = new dataStoreRegistry_1.FluidDataStoreRegistry(registryEntries);
|
|
644
651
|
const tryFetchBlob = async (blobName) => {
|
|
645
|
-
|
|
646
|
-
const blobId = (_a = context.baseSnapshot) === null || _a === void 0 ? void 0 : _a.blobs[blobName];
|
|
652
|
+
const blobId = context.baseSnapshot?.blobs[blobName];
|
|
647
653
|
if (context.baseSnapshot && blobId) {
|
|
648
654
|
// IContainerContext storage api return type still has undefined in 0.39 package version.
|
|
649
655
|
// So once we release 0.40 container-defn package we can remove this check.
|
|
@@ -658,16 +664,15 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
658
664
|
tryFetchBlob(summary_1.aliasBlobName),
|
|
659
665
|
tryFetchBlob(summary_1.idCompressorBlobName),
|
|
660
666
|
]);
|
|
661
|
-
const loadExisting = existing === true || context.existing === true;
|
|
662
667
|
// read snapshot blobs needed for BlobManager to load
|
|
663
|
-
const blobManagerSnapshot = await blobManager_1.BlobManager.load(
|
|
668
|
+
const blobManagerSnapshot = await blobManager_1.BlobManager.load(context.baseSnapshot?.trees[summary_1.blobsTreeName], async (id) => {
|
|
664
669
|
// IContainerContext storage api return type still has undefined in 0.39 package version.
|
|
665
670
|
// So once we release 0.40 container-defn package we can remove this check.
|
|
666
671
|
(0, common_utils_1.assert)(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
|
|
667
672
|
return (0, driver_utils_1.readAndParse)(context.storage, id);
|
|
668
673
|
});
|
|
669
674
|
// Verify summary runtime sequence number matches protocol sequence number.
|
|
670
|
-
const runtimeSequenceNumber =
|
|
675
|
+
const runtimeSequenceNumber = metadata?.message?.sequenceNumber;
|
|
671
676
|
// When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
|
|
672
677
|
if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
|
|
673
678
|
const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
|
|
@@ -682,13 +687,11 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
682
687
|
logger.sendErrorEvent({ eventName: "SequenceNumberMismatch" }, error);
|
|
683
688
|
}
|
|
684
689
|
else {
|
|
685
|
-
// Call both close and dispose as closeFn implementation will no longer dispose runtime in future
|
|
686
690
|
context.closeFn(error);
|
|
687
|
-
(_d = context.disposeFn) === null || _d === void 0 ? void 0 : _d.call(context, error);
|
|
688
691
|
}
|
|
689
692
|
}
|
|
690
693
|
}
|
|
691
|
-
const idCompressorEnabled =
|
|
694
|
+
const idCompressorEnabled = metadata?.idCompressorEnabled ?? runtimeOptions.enableRuntimeIdCompressor ?? false;
|
|
692
695
|
let idCompressor;
|
|
693
696
|
if (idCompressorEnabled) {
|
|
694
697
|
const { IdCompressor, createSessionId } = await Promise.resolve().then(() => __importStar(require("./id-compressor")));
|
|
@@ -697,7 +700,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
697
700
|
? IdCompressor.deserialize(serializedIdCompressor, createSessionId())
|
|
698
701
|
: new IdCompressor(createSessionId(), logger);
|
|
699
702
|
}
|
|
700
|
-
const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks
|
|
703
|
+
const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
|
|
701
704
|
summaryOptions,
|
|
702
705
|
gcOptions,
|
|
703
706
|
loadSequenceNumberVerification,
|
|
@@ -708,7 +711,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
708
711
|
enableRuntimeIdCompressor,
|
|
709
712
|
enableOpReentryCheck,
|
|
710
713
|
enableGroupedBatching,
|
|
711
|
-
}, containerScope, logger,
|
|
714
|
+
}, containerScope, logger, existing, blobManagerSnapshot, context.storage, idCompressor, requestHandler, undefined, // summaryConfiguration
|
|
712
715
|
initializeEntryPoint);
|
|
713
716
|
// It's possible to have ops with a reference sequence number of 0. Op sequence numbers start
|
|
714
717
|
// at 1, so we won't see a replayed saved op with a sequence number of 0.
|
|
@@ -764,8 +767,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
764
767
|
}
|
|
765
768
|
/** clientId of parent (non-summarizing) container that owns summarizer container */
|
|
766
769
|
get summarizerClientId() {
|
|
767
|
-
|
|
768
|
-
return (_a = this.summarizerClientElection) === null || _a === void 0 ? void 0 : _a.electedClientId;
|
|
770
|
+
return this.summarizerClientElection?.electedClientId;
|
|
769
771
|
}
|
|
770
772
|
get disposed() {
|
|
771
773
|
return this._disposed;
|
|
@@ -802,7 +804,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
802
804
|
await this.garbageCollector.initializeBaseState();
|
|
803
805
|
}
|
|
804
806
|
dispose(error) {
|
|
805
|
-
var _a;
|
|
806
807
|
if (this._disposed) {
|
|
807
808
|
return;
|
|
808
809
|
}
|
|
@@ -817,7 +818,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
817
818
|
this.summaryManager.dispose();
|
|
818
819
|
}
|
|
819
820
|
this.garbageCollector.dispose();
|
|
820
|
-
|
|
821
|
+
this._summarizer?.dispose();
|
|
821
822
|
this.dataStores.dispose();
|
|
822
823
|
this.pendingStateManager.dispose();
|
|
823
824
|
this.emit("dispose");
|
|
@@ -826,6 +827,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
826
827
|
/**
|
|
827
828
|
* Notifies this object about the request made to the container.
|
|
828
829
|
* @param request - Request made to the handler.
|
|
830
|
+
* @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
|
|
829
831
|
*/
|
|
830
832
|
async request(request) {
|
|
831
833
|
try {
|
|
@@ -892,19 +894,17 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
892
894
|
return this.entryPoint;
|
|
893
895
|
}
|
|
894
896
|
internalId(maybeAlias) {
|
|
895
|
-
|
|
896
|
-
return (_a = this.dataStores.aliases.get(maybeAlias)) !== null && _a !== void 0 ? _a : maybeAlias;
|
|
897
|
+
return this.dataStores.aliases.get(maybeAlias) ?? maybeAlias;
|
|
897
898
|
}
|
|
898
899
|
async getDataStoreFromRequest(id, request) {
|
|
899
|
-
var _a, _b, _c;
|
|
900
900
|
const headerData = {};
|
|
901
|
-
if (typeof
|
|
901
|
+
if (typeof request.headers?.[RuntimeHeaders.wait] === "boolean") {
|
|
902
902
|
headerData.wait = request.headers[RuntimeHeaders.wait];
|
|
903
903
|
}
|
|
904
|
-
if (typeof
|
|
904
|
+
if (typeof request.headers?.[RuntimeHeaders.viaHandle] === "boolean") {
|
|
905
905
|
headerData.viaHandle = request.headers[RuntimeHeaders.viaHandle];
|
|
906
906
|
}
|
|
907
|
-
if (typeof
|
|
907
|
+
if (typeof request.headers?.[exports.AllowTombstoneRequestHeaderKey] === "boolean") {
|
|
908
908
|
headerData.allowTombstone = request.headers[exports.AllowTombstoneRequestHeaderKey];
|
|
909
909
|
}
|
|
910
910
|
await this.dataStores.waitIfPendingAlias(id);
|
|
@@ -914,22 +914,27 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
914
914
|
// Remove query params, leading and trailing slashes from the url. This is done to make sure the format is
|
|
915
915
|
// the same as GC nodes id.
|
|
916
916
|
const urlWithoutQuery = (0, gc_1.trimLeadingAndTrailingSlashes)(request.url.split("?")[0]);
|
|
917
|
-
this.garbageCollector.nodeUpdated(`/${urlWithoutQuery}`, "Loaded", undefined /* timestampMs */, dataStoreContext.packagePath, request
|
|
917
|
+
this.garbageCollector.nodeUpdated(`/${urlWithoutQuery}`, "Loaded", undefined /* timestampMs */, dataStoreContext.packagePath, request?.headers);
|
|
918
918
|
return dataStoreChannel;
|
|
919
919
|
}
|
|
920
920
|
/** Adds the container's metadata to the given summary tree. */
|
|
921
921
|
addMetadataToSummary(summaryTree) {
|
|
922
|
-
|
|
923
|
-
|
|
922
|
+
const metadata = {
|
|
923
|
+
...this.createContainerMetadata,
|
|
924
924
|
// Increment the summary number for the next summary that will be generated.
|
|
925
|
-
summaryNumber: this.nextSummaryNumber++,
|
|
925
|
+
summaryNumber: this.nextSummaryNumber++,
|
|
926
|
+
summaryFormatVersion: 1,
|
|
927
|
+
...this.garbageCollector.getMetadata(),
|
|
926
928
|
// The last message processed at the time of summary. If there are no new messages, use the message from the
|
|
927
929
|
// last summary.
|
|
928
|
-
message: (
|
|
930
|
+
message: (0, summary_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage) ??
|
|
931
|
+
this.messageAtLastSummary,
|
|
932
|
+
telemetryDocumentId: this.telemetryDocumentId,
|
|
933
|
+
idCompressorEnabled: this.idCompressorEnabled ? true : undefined,
|
|
934
|
+
};
|
|
929
935
|
(0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.metadataBlobName, JSON.stringify(metadata));
|
|
930
936
|
}
|
|
931
937
|
addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
|
|
932
|
-
var _a;
|
|
933
938
|
this.addMetadataToSummary(summaryTree);
|
|
934
939
|
if (this.idCompressorEnabled) {
|
|
935
940
|
(0, common_utils_1.assert)(this.idCompressor !== undefined, 0x67a /* IdCompressor should be defined if enabled */);
|
|
@@ -945,7 +950,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
945
950
|
(0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
|
|
946
951
|
}
|
|
947
952
|
if (this.summarizerClientElection) {
|
|
948
|
-
const electedSummarizerContent = JSON.stringify(
|
|
953
|
+
const electedSummarizerContent = JSON.stringify(this.summarizerClientElection?.serialize());
|
|
949
954
|
(0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.electedSummarizerBlobName, electedSummarizerContent);
|
|
950
955
|
}
|
|
951
956
|
const blobManagerSummary = this.blobManager.summarize();
|
|
@@ -992,7 +997,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
992
997
|
// in their own batches before the originating batch is sent.
|
|
993
998
|
// Therefore, receiving them while attempting to send the originating batch
|
|
994
999
|
// does not mean that the container is making any progress.
|
|
995
|
-
if (
|
|
1000
|
+
if (message?.type !== ContainerMessageType.ChunkedOp) {
|
|
996
1001
|
this.consecutiveReconnects = 0;
|
|
997
1002
|
}
|
|
998
1003
|
}
|
|
@@ -1147,7 +1152,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1147
1152
|
// or something different, like a system message.
|
|
1148
1153
|
const runtimeMessage = messageArg.type === protocol_definitions_1.MessageType.Operation;
|
|
1149
1154
|
// Do shallow copy of message, as the processing flow will modify it.
|
|
1150
|
-
const messageCopy =
|
|
1155
|
+
const messageCopy = { ...messageArg };
|
|
1151
1156
|
for (const message of this.remoteMessageProcessor.process(messageCopy)) {
|
|
1152
1157
|
this.processCore(message, local, runtimeMessage);
|
|
1153
1158
|
}
|
|
@@ -1159,7 +1164,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1159
1164
|
* @param runtimeMessage - Does this appear like a current ContainerRuntimeMessage? If true, certain validation will occur.
|
|
1160
1165
|
*/
|
|
1161
1166
|
processCore(message, local, runtimeMessage) {
|
|
1162
|
-
var _a;
|
|
1163
1167
|
// Surround the actual processing of the operation with messages to the schedule manager indicating
|
|
1164
1168
|
// the beginning and end. This allows it to emit appropriate events and/or pause the processing of new
|
|
1165
1169
|
// messages once a batch has been fully processed.
|
|
@@ -1204,7 +1208,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1204
1208
|
local,
|
|
1205
1209
|
type: message.type,
|
|
1206
1210
|
contentType: typeof message.contents,
|
|
1207
|
-
batch:
|
|
1211
|
+
batch: message.metadata?.batch,
|
|
1208
1212
|
compression: message.compression,
|
|
1209
1213
|
});
|
|
1210
1214
|
this.closeFn(error);
|
|
@@ -1281,6 +1285,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1281
1285
|
}
|
|
1282
1286
|
this.dataStores.processSignal(envelope.address, transformed, local);
|
|
1283
1287
|
}
|
|
1288
|
+
/**
|
|
1289
|
+
* Returns the runtime of the data store.
|
|
1290
|
+
* @param id - Id supplied during creating the data store.
|
|
1291
|
+
* @param wait - True if you want to wait for it.
|
|
1292
|
+
* @deprecated - Use getAliasedDataStoreEntryPoint instead to get an aliased data store's entry point.
|
|
1293
|
+
*/
|
|
1284
1294
|
async getRootDataStore(id, wait = true) {
|
|
1285
1295
|
return this.getRootDataStoreChannel(id, wait);
|
|
1286
1296
|
}
|
|
@@ -1342,9 +1352,25 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1342
1352
|
}
|
|
1343
1353
|
return result;
|
|
1344
1354
|
}
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1355
|
+
/**
|
|
1356
|
+
* Returns the aliased data store's entryPoint, given the alias.
|
|
1357
|
+
* @param alias - The alias for the data store.
|
|
1358
|
+
* @returns - The data store's entry point (IFluidHandle) if it exists and is aliased. Returns undefined if no
|
|
1359
|
+
* data store has been assigned the given alias.
|
|
1360
|
+
*/
|
|
1361
|
+
async getAliasedDataStoreEntryPoint(alias) {
|
|
1362
|
+
await this.dataStores.waitIfPendingAlias(alias);
|
|
1363
|
+
const internalId = this.internalId(alias);
|
|
1364
|
+
const context = await this.dataStores.getDataStoreIfAvailable(internalId, { wait: false });
|
|
1365
|
+
// If the data store is not available or not an alias, return undefined.
|
|
1366
|
+
if (context === undefined || !(await context.isRoot())) {
|
|
1367
|
+
return undefined;
|
|
1368
|
+
}
|
|
1369
|
+
const channel = await context.realize();
|
|
1370
|
+
if (channel.entryPoint === undefined) {
|
|
1371
|
+
throw new container_utils_1.UsageError("entryPoint must be defined on data store runtime for using getAliasedDataStoreEntryPoint");
|
|
1372
|
+
}
|
|
1373
|
+
return channel.entryPoint;
|
|
1348
1374
|
}
|
|
1349
1375
|
createDetachedRootDataStore(pkg, rootDataStoreId) {
|
|
1350
1376
|
if (rootDataStoreId.includes("/")) {
|
|
@@ -1355,16 +1381,20 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1355
1381
|
createDetachedDataStore(pkg) {
|
|
1356
1382
|
return this.dataStores.createDetachedDataStoreCore(pkg, false);
|
|
1357
1383
|
}
|
|
1358
|
-
async
|
|
1359
|
-
const
|
|
1360
|
-
|
|
1361
|
-
.
|
|
1362
|
-
|
|
1384
|
+
async createDataStore(pkg) {
|
|
1385
|
+
const id = (0, uuid_1.v4)();
|
|
1386
|
+
return (0, dataStore_1.channelToDataStore)(await this.dataStores
|
|
1387
|
+
._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id)
|
|
1388
|
+
.realize(), id, this, this.dataStores, this.mc.logger);
|
|
1363
1389
|
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1390
|
+
/**
|
|
1391
|
+
* @deprecated 0.16 Issue #1537, #3631
|
|
1392
|
+
* @internal
|
|
1393
|
+
*/
|
|
1394
|
+
async _createDataStoreWithProps(pkg, props, id = (0, uuid_1.v4)()) {
|
|
1395
|
+
return (0, dataStore_1.channelToDataStore)(await this.dataStores
|
|
1366
1396
|
._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props)
|
|
1367
|
-
.realize();
|
|
1397
|
+
.realize(), id, this, this.dataStores, this.mc.logger);
|
|
1368
1398
|
}
|
|
1369
1399
|
canSendOps() {
|
|
1370
1400
|
// Note that the real (non-proxy) delta manager is needed here to get the readonly info. This is because
|
|
@@ -1473,7 +1503,11 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1473
1503
|
(0, summary_1.wrapSummaryInChannelsTree)(summarizeResult);
|
|
1474
1504
|
const pathPartsForChildren = [runtime_definitions_1.channelsTreeName];
|
|
1475
1505
|
this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
|
|
1476
|
-
return
|
|
1506
|
+
return {
|
|
1507
|
+
...summarizeResult,
|
|
1508
|
+
id: "",
|
|
1509
|
+
pathPartsForChildren,
|
|
1510
|
+
};
|
|
1477
1511
|
}
|
|
1478
1512
|
/**
|
|
1479
1513
|
* Returns a summary of the runtime at the current sequence number.
|
|
@@ -1491,13 +1525,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1491
1525
|
runSweep,
|
|
1492
1526
|
});
|
|
1493
1527
|
try {
|
|
1494
|
-
let gcStats;
|
|
1495
1528
|
if (runGC) {
|
|
1496
|
-
|
|
1529
|
+
await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC }, telemetryContext);
|
|
1497
1530
|
}
|
|
1498
1531
|
const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
|
|
1499
1532
|
(0, common_utils_1.assert)(summary.type === protocol_definitions_1.SummaryType.Tree, 0x12f /* "Container Runtime's summarize should always return a tree" */);
|
|
1500
|
-
return { stats, summary
|
|
1533
|
+
return { stats, summary };
|
|
1501
1534
|
}
|
|
1502
1535
|
finally {
|
|
1503
1536
|
this.mc.logger.sendTelemetryEvent({
|
|
@@ -1582,21 +1615,19 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1582
1615
|
* Returns a server generated referenced timestamp to be used to track unreferenced nodes by GC.
|
|
1583
1616
|
*/
|
|
1584
1617
|
getCurrentReferenceTimestampMs() {
|
|
1585
|
-
var _a, _b, _c;
|
|
1586
1618
|
// Use the timestamp of the last message seen by this client as that is server generated. If no messages have
|
|
1587
1619
|
// been processed, use the timestamp of the message from the last summary.
|
|
1588
|
-
return
|
|
1620
|
+
return this.deltaManager.lastMessage?.timestamp ?? this.messageAtLastSummary?.timestamp;
|
|
1589
1621
|
}
|
|
1590
1622
|
/**
|
|
1591
1623
|
* Returns the type of the GC node. Currently, there are nodes that belong to the root ("/"), data stores or
|
|
1592
1624
|
* blob manager.
|
|
1593
1625
|
*/
|
|
1594
1626
|
getNodeType(nodePath) {
|
|
1595
|
-
var _a;
|
|
1596
1627
|
if (this.isBlobPath(nodePath)) {
|
|
1597
1628
|
return gc_1.GCNodeType.Blob;
|
|
1598
1629
|
}
|
|
1599
|
-
return
|
|
1630
|
+
return this.dataStores.getGCNodeType(nodePath) ?? gc_1.GCNodeType.Other;
|
|
1600
1631
|
}
|
|
1601
1632
|
/**
|
|
1602
1633
|
* Called by GC to retrieve the package path of the node with the given path. The node should belong to a
|
|
@@ -1667,7 +1698,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1667
1698
|
* @param options - options controlling how the summary is generated or submitted
|
|
1668
1699
|
*/
|
|
1669
1700
|
async submitSummary(options) {
|
|
1670
|
-
var _a, _b;
|
|
1671
1701
|
const { fullTree = false, refreshLatestAck, summaryLogger } = options;
|
|
1672
1702
|
// The summary number for this summary. This will be updated during the summary process, so get it now and
|
|
1673
1703
|
// use it for all events logged during this summary.
|
|
@@ -1705,7 +1735,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1705
1735
|
this.summarizerNode.startSummary(summaryRefSeqNum, summaryNumberLogger);
|
|
1706
1736
|
// Helper function to check whether we should still continue between each async step.
|
|
1707
1737
|
const checkContinue = () => {
|
|
1708
|
-
var _a;
|
|
1709
1738
|
// Do not check for loss of connectivity directly! Instead leave it up to
|
|
1710
1739
|
// RunWhileConnectedCoordinator to control policy in a single place.
|
|
1711
1740
|
// This will allow easier change of design if we chose to. For example, we may chose to allow
|
|
@@ -1728,7 +1757,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1728
1757
|
error: `lastSequenceNumber changed before uploading to storage. ${this.deltaManager.lastSequenceNumber} !== ${summaryRefSeqNum}`,
|
|
1729
1758
|
};
|
|
1730
1759
|
}
|
|
1731
|
-
(0, common_utils_1.assert)(summaryRefSeqNum ===
|
|
1760
|
+
(0, common_utils_1.assert)(summaryRefSeqNum === this.deltaManager.lastMessage?.sequenceNumber, 0x395 /* it's one and the same thing */);
|
|
1732
1761
|
if (lastAck !== this.summaryCollection.latestAck) {
|
|
1733
1762
|
return {
|
|
1734
1763
|
continue: false,
|
|
@@ -1779,7 +1808,15 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1779
1808
|
const gcSummaryTreeStats = summaryTree.tree[runtime_definitions_1.gcTreeKey]
|
|
1780
1809
|
? (0, runtime_utils_1.calculateStats)(summaryTree.tree[runtime_definitions_1.gcTreeKey])
|
|
1781
1810
|
: undefined;
|
|
1782
|
-
const summaryStats =
|
|
1811
|
+
const summaryStats = {
|
|
1812
|
+
dataStoreCount: this.dataStores.size,
|
|
1813
|
+
summarizedDataStoreCount: this.dataStores.size - handleCount,
|
|
1814
|
+
gcStateUpdatedDataStoreCount: this.garbageCollector.updatedDSCountSinceLastSummary,
|
|
1815
|
+
gcBlobNodeCount: gcSummaryTreeStats?.blobNodeCount,
|
|
1816
|
+
gcTotalBlobsSize: gcSummaryTreeStats?.totalBlobSize,
|
|
1817
|
+
summaryNumber,
|
|
1818
|
+
...partialStats,
|
|
1819
|
+
};
|
|
1783
1820
|
const generateSummaryData = {
|
|
1784
1821
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
1785
1822
|
minimumSequenceNumber,
|
|
@@ -1793,14 +1830,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1793
1830
|
if (this.validateSummaryBeforeUpload) {
|
|
1794
1831
|
const validateResult = this.summarizerNode.validateSummary();
|
|
1795
1832
|
if (!validateResult.success) {
|
|
1796
|
-
const { success
|
|
1797
|
-
const error = new summary_1.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds,
|
|
1798
|
-
return
|
|
1833
|
+
const { success, ...loggingProps } = validateResult;
|
|
1834
|
+
const error = new summary_1.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
|
|
1835
|
+
return { stage: "base", ...generateSummaryData, error };
|
|
1799
1836
|
}
|
|
1800
1837
|
}
|
|
1801
1838
|
continueResult = checkContinue();
|
|
1802
1839
|
if (!continueResult.continue) {
|
|
1803
|
-
return
|
|
1840
|
+
return { stage: "generate", ...generateSummaryData, error: continueResult.error };
|
|
1804
1841
|
}
|
|
1805
1842
|
// It may happen that the lastAck it not correct due to missing summaryAck in case of single commit
|
|
1806
1843
|
// summary. So if the previous summarizer closes just after submitting the summary and before
|
|
@@ -1808,7 +1845,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1808
1845
|
// latestSnapshotVersionId from storage and it does not match with the lastAck ackHandle, then use
|
|
1809
1846
|
// the one fetched from storage as parent as that is the latest.
|
|
1810
1847
|
let summaryContext;
|
|
1811
|
-
if (
|
|
1848
|
+
if (lastAck?.summaryAck.contents.handle !== latestSnapshotVersionId &&
|
|
1812
1849
|
latestSnapshotVersionId !== undefined) {
|
|
1813
1850
|
summaryContext = {
|
|
1814
1851
|
proposalHandle: undefined,
|
|
@@ -1835,7 +1872,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1835
1872
|
handle = await this.storage.uploadSummaryWithContext(summarizeResult.summary, summaryContext);
|
|
1836
1873
|
}
|
|
1837
1874
|
catch (error) {
|
|
1838
|
-
return
|
|
1875
|
+
return { stage: "generate", ...generateSummaryData, error };
|
|
1839
1876
|
}
|
|
1840
1877
|
const parent = summaryContext.ackHandle;
|
|
1841
1878
|
const summaryMessage = {
|
|
@@ -1845,25 +1882,34 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1845
1882
|
message,
|
|
1846
1883
|
parents: parent ? [parent] : [],
|
|
1847
1884
|
};
|
|
1848
|
-
const uploadData =
|
|
1885
|
+
const uploadData = {
|
|
1886
|
+
...generateSummaryData,
|
|
1887
|
+
handle,
|
|
1888
|
+
uploadDuration: trace.trace().duration,
|
|
1889
|
+
};
|
|
1849
1890
|
continueResult = checkContinue();
|
|
1850
1891
|
if (!continueResult.continue) {
|
|
1851
|
-
return
|
|
1892
|
+
return { stage: "upload", ...uploadData, error: continueResult.error };
|
|
1852
1893
|
}
|
|
1853
1894
|
let clientSequenceNumber;
|
|
1854
1895
|
try {
|
|
1855
1896
|
clientSequenceNumber = this.submitSummaryMessage(summaryMessage, summaryRefSeqNum);
|
|
1856
1897
|
}
|
|
1857
1898
|
catch (error) {
|
|
1858
|
-
return
|
|
1899
|
+
return { stage: "upload", ...uploadData, error };
|
|
1859
1900
|
}
|
|
1860
|
-
const submitData =
|
|
1901
|
+
const submitData = {
|
|
1902
|
+
stage: "submit",
|
|
1903
|
+
...uploadData,
|
|
1904
|
+
clientSequenceNumber,
|
|
1905
|
+
submitOpDuration: trace.trace().duration,
|
|
1906
|
+
};
|
|
1861
1907
|
try {
|
|
1862
1908
|
// If validateSummaryBeforeUpload is false, the summary should be validated in this step.
|
|
1863
1909
|
this.summarizerNode.completeSummary(handle, !this.validateSummaryBeforeUpload /* validate */);
|
|
1864
1910
|
}
|
|
1865
1911
|
catch (error) {
|
|
1866
|
-
return
|
|
1912
|
+
return { stage: "upload", ...uploadData, error };
|
|
1867
1913
|
}
|
|
1868
1914
|
return submitData;
|
|
1869
1915
|
}
|
|
@@ -1871,7 +1917,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1871
1917
|
// Cleanup wip summary in case of failure
|
|
1872
1918
|
this.summarizerNode.clearSummary();
|
|
1873
1919
|
// ! This needs to happen before we resume inbound queues to ensure heuristics are tracked correctly
|
|
1874
|
-
|
|
1920
|
+
this._summarizer?.recordSummaryAttempt?.(summaryRefSeqNum);
|
|
1875
1921
|
// Restart the delta manager
|
|
1876
1922
|
this.deltaManager.inbound.resume();
|
|
1877
1923
|
if (shouldPauseInboundSignal) {
|
|
@@ -1917,7 +1963,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1917
1963
|
return this.blobManager.createBlob(blob, signal);
|
|
1918
1964
|
}
|
|
1919
1965
|
maybeSubmitIdAllocationOp(type) {
|
|
1920
|
-
var _a, _b;
|
|
1921
1966
|
if (type !== ContainerMessageType.IdAllocation) {
|
|
1922
1967
|
let idAllocationBatchMessage;
|
|
1923
1968
|
let idRange;
|
|
@@ -1925,7 +1970,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1925
1970
|
(0, common_utils_1.assert)(this.idCompressor !== undefined, 0x67d /* IdCompressor should be defined if enabled */);
|
|
1926
1971
|
idRange = this.idCompressor.takeNextCreationRange();
|
|
1927
1972
|
// Don't include the idRange if there weren't any Ids allocated
|
|
1928
|
-
idRange =
|
|
1973
|
+
idRange = idRange?.ids?.first !== undefined ? idRange : undefined;
|
|
1929
1974
|
}
|
|
1930
1975
|
if (idRange !== undefined) {
|
|
1931
1976
|
const idAllocationMessage = {
|
|
@@ -1936,7 +1981,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1936
1981
|
contents: JSON.stringify(idAllocationMessage),
|
|
1937
1982
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
1938
1983
|
metadata: undefined,
|
|
1939
|
-
localOpMetadata:
|
|
1984
|
+
localOpMetadata: this.idCompressor?.serialize(true),
|
|
1940
1985
|
type: ContainerMessageType.IdAllocation,
|
|
1941
1986
|
};
|
|
1942
1987
|
}
|
|
@@ -2214,7 +2259,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
2214
2259
|
summaryRefSeq,
|
|
2215
2260
|
fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
|
|
2216
2261
|
});
|
|
2217
|
-
this.
|
|
2262
|
+
this.disposeFn(error);
|
|
2218
2263
|
throw error;
|
|
2219
2264
|
}
|
|
2220
2265
|
// In case we had to retrieve the latest snapshot and it is different than summaryRefSeq,
|
|
@@ -2253,7 +2298,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
2253
2298
|
return this.fetchSnapshotFromStorageAndClose(logger, event, readAndParseBlob, null /* latest */);
|
|
2254
2299
|
}
|
|
2255
2300
|
async fetchSnapshotFromStorageAndClose(logger, event, readAndParseBlob, versionId) {
|
|
2256
|
-
var _a;
|
|
2257
2301
|
const snapshotResults = await telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
|
|
2258
2302
|
const stats = {};
|
|
2259
2303
|
const trace = common_utils_1.Trace.start();
|
|
@@ -2277,26 +2321,36 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
2277
2321
|
// situations which the main client (which is likely to be re-elected as the leader again)
|
|
2278
2322
|
// loads the summarizer from cache.
|
|
2279
2323
|
if (this.summaryStateUpdateMethod !== "refreshFromSnapshot") {
|
|
2280
|
-
this.mc.logger.sendTelemetryEvent(
|
|
2324
|
+
this.mc.logger.sendTelemetryEvent({
|
|
2325
|
+
...event,
|
|
2326
|
+
eventName: "ClosingSummarizerOnSummaryStale",
|
|
2327
|
+
codePath: event.eventName,
|
|
2328
|
+
message: "Stopping fetch from storage",
|
|
2329
|
+
versionId: versionId != null ? versionId : undefined,
|
|
2330
|
+
closeSummarizerDelayMs: this.closeSummarizerDelayMs,
|
|
2331
|
+
}, new container_utils_1.GenericError("Restarting summarizer instead of refreshing"));
|
|
2281
2332
|
// Delay before restarting summarizer to prevent the summarizer from restarting too frequently.
|
|
2282
2333
|
await (0, common_utils_1.delay)(this.closeSummarizerDelayMs);
|
|
2283
|
-
|
|
2334
|
+
this._summarizer?.stop("latestSummaryStateStale");
|
|
2284
2335
|
this.disposeFn();
|
|
2285
2336
|
}
|
|
2286
2337
|
return snapshotResults;
|
|
2287
2338
|
}
|
|
2288
2339
|
notifyAttaching() { } // do nothing (deprecated method)
|
|
2289
|
-
getPendingLocalState() {
|
|
2340
|
+
async getPendingLocalState(props) {
|
|
2341
|
+
this.verifyNotClosed();
|
|
2342
|
+
const waitBlobsToAttach = props?.notifyImminentClosure;
|
|
2290
2343
|
if (this._orderSequentiallyCalls !== 0) {
|
|
2291
2344
|
throw new container_utils_1.UsageError("can't get state during orderSequentially");
|
|
2292
2345
|
}
|
|
2346
|
+
const pendingAttachmentBlobs = await this.blobManager.getPendingBlobs(waitBlobsToAttach);
|
|
2293
2347
|
// Flush pending batch.
|
|
2294
2348
|
// getPendingLocalState() is only exposed through Container.closeAndGetPendingLocalState(), so it's safe
|
|
2295
2349
|
// to close current batch.
|
|
2296
2350
|
this.flush();
|
|
2297
2351
|
return {
|
|
2298
2352
|
pending: this.pendingStateManager.getLocalState(),
|
|
2299
|
-
pendingAttachmentBlobs
|
|
2353
|
+
pendingAttachmentBlobs,
|
|
2300
2354
|
};
|
|
2301
2355
|
}
|
|
2302
2356
|
/**
|