@fluidframework/container-runtime 2.0.0-rc.3.0.3 → 2.0.0-rc.4.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 +46 -0
- package/api-report/container-runtime.api.md +72 -34
- package/dist/batchTracker.d.ts +1 -1
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +7 -7
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +2 -4
- package/dist/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +6 -4
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +20 -7
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +2 -2
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +54 -5
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +17 -35
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +194 -163
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +9 -6
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +19 -5
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/deltaManagerProxies.d.ts +81 -0
- package/dist/deltaManagerProxies.d.ts.map +1 -0
- package/dist/{deltaManagerSummarizerProxy.js → deltaManagerProxies.js} +75 -20
- package/dist/deltaManagerProxies.js.map +1 -0
- package/dist/deltaScheduler.d.ts +2 -2
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +1 -1
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +1 -2
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.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/legacy.d.ts +6 -1
- package/dist/messageTypes.d.ts +5 -2
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js.map +1 -1
- package/dist/metadata.d.ts +2 -2
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +4 -1
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +0 -10
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +0 -4
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +7 -38
- 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 +9 -2
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +26 -10
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts +2 -2
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/documentSchema.d.ts +3 -1
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js +25 -7
- package/dist/summary/documentSchema.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.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +2 -2
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runningSummarizer.js +10 -10
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +1 -2
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +1 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.d.ts +1 -1
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +4 -3
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +4 -10
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -3
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -2
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +2 -9
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +3 -5
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +2 -2
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +25 -5
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +1 -2
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +12 -11
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +5 -5
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/batchTracker.d.ts +1 -1
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +7 -7
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +3 -5
- package/lib/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +6 -4
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +21 -8
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +2 -2
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +49 -0
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +17 -35
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +195 -164
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +1 -1
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +9 -6
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +21 -7
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/deltaManagerProxies.d.ts +81 -0
- package/lib/deltaManagerProxies.d.ts.map +1 -0
- package/lib/{deltaManagerSummarizerProxy.js → deltaManagerProxies.js} +72 -19
- package/lib/deltaManagerProxies.js.map +1 -0
- package/lib/deltaScheduler.d.ts +2 -2
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +1 -1
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +1 -2
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.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/legacy.d.ts +6 -1
- package/lib/messageTypes.d.ts +5 -2
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js.map +1 -1
- package/lib/metadata.d.ts +2 -2
- package/lib/metadata.d.ts.map +1 -1
- package/lib/metadata.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +4 -1
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +0 -10
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +0 -4
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +7 -38
- 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 +9 -2
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +27 -11
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts +2 -2
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/documentSchema.d.ts +3 -1
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js +25 -7
- package/lib/summary/documentSchema.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.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +2 -2
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runningSummarizer.js +1 -1
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +1 -2
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +1 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.d.ts +1 -1
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +4 -3
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +4 -10
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -3
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -2
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +2 -9
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +3 -5
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +2 -2
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +25 -5
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +1 -2
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +5 -4
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +2 -2
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/package.json +28 -50
- package/src/batchTracker.ts +1 -2
- package/src/blobManager.ts +11 -10
- package/src/channelCollection.ts +30 -12
- package/src/connectionTelemetry.ts +59 -4
- package/src/containerRuntime.ts +262 -239
- package/src/dataStore.ts +7 -4
- package/src/dataStoreContext.ts +57 -16
- package/src/dataStoreContexts.ts +1 -2
- package/src/{deltaManagerSummarizerProxy.ts → deltaManagerProxies.ts} +98 -24
- package/src/deltaScheduler.ts +2 -3
- package/src/gc/garbageCollection.ts +1 -1
- package/src/gc/gcDefinitions.ts +1 -1
- package/src/gc/gcTelemetry.ts +1 -3
- package/src/index.ts +5 -0
- package/src/messageTypes.ts +4 -2
- package/src/metadata.ts +2 -2
- package/src/opLifecycle/README.md +4 -4
- package/src/opLifecycle/batchManager.ts +5 -14
- package/src/opLifecycle/outbox.ts +7 -53
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +38 -15
- package/src/scheduleManager.ts +2 -2
- package/src/summary/documentSchema.ts +37 -12
- package/src/summary/index.ts +4 -0
- package/src/summary/orderedClientElection.ts +6 -3
- package/src/summary/runningSummarizer.ts +1 -1
- package/src/summary/summarizer.ts +1 -1
- package/src/summary/summarizerClientElection.ts +1 -1
- package/src/summary/summarizerHeuristics.ts +1 -1
- package/src/summary/summarizerNode/summarizerNode.ts +3 -12
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +2 -3
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +1 -10
- package/src/summary/summarizerTypes.ts +6 -5
- package/src/summary/summaryCollection.ts +2 -2
- package/src/summary/summaryFormat.ts +30 -4
- package/src/summary/summaryGenerator.ts +20 -9
- package/src/summary/summaryManager.ts +6 -3
- package/dist/deltaManagerSummarizerProxy.d.ts +0 -44
- package/dist/deltaManagerSummarizerProxy.d.ts.map +0 -1
- package/dist/deltaManagerSummarizerProxy.js.map +0 -1
- package/lib/deltaManagerSummarizerProxy.d.ts +0 -44
- package/lib/deltaManagerSummarizerProxy.d.ts.map +0 -1
- package/lib/deltaManagerSummarizerProxy.js.map +0 -1
package/dist/containerRuntime.js
CHANGED
|
@@ -23,7 +23,7 @@ const connectionTelemetry_js_1 = require("./connectionTelemetry.js");
|
|
|
23
23
|
const containerHandleContext_js_1 = require("./containerHandleContext.js");
|
|
24
24
|
const dataStore_js_1 = require("./dataStore.js");
|
|
25
25
|
const dataStoreRegistry_js_1 = require("./dataStoreRegistry.js");
|
|
26
|
-
const
|
|
26
|
+
const deltaManagerProxies_js_1 = require("./deltaManagerProxies.js");
|
|
27
27
|
const index_js_1 = require("./gc/index.js");
|
|
28
28
|
const messageTypes_js_1 = require("./messageTypes.js");
|
|
29
29
|
const index_js_2 = require("./opLifecycle/index.js");
|
|
@@ -250,7 +250,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
250
250
|
},
|
|
251
251
|
});
|
|
252
252
|
const mc = (0, internal_7.loggerToMonitoringContext)(logger);
|
|
253
|
-
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes,
|
|
253
|
+
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes, enableGroupedBatching = true, explicitSchemaControl = false, } = runtimeOptions;
|
|
254
254
|
const registry = new dataStoreRegistry_js_1.FluidDataStoreRegistry(registryEntries);
|
|
255
255
|
const tryFetchBlob = async (blobName) => {
|
|
256
256
|
const blobId = context.baseSnapshot?.blobs[blobName];
|
|
@@ -278,9 +278,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
278
278
|
const messageAtLastSummary = lastMessageFromMetadata(metadata);
|
|
279
279
|
// Verify summary runtime sequence number matches protocol sequence number.
|
|
280
280
|
const runtimeSequenceNumber = messageAtLastSummary?.sequenceNumber;
|
|
281
|
+
const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
|
|
281
282
|
// When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
|
|
282
283
|
if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
|
|
283
|
-
const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
|
|
284
284
|
// Unless bypass is explicitly set, then take action when sequence numbers mismatch.
|
|
285
285
|
if (loadSequenceNumberVerification !== "bypass" &&
|
|
286
286
|
runtimeSequenceNumber !== protocolSequenceNumber) {
|
|
@@ -372,23 +372,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
372
372
|
return createIdCompressor(compressorLogger);
|
|
373
373
|
}
|
|
374
374
|
};
|
|
375
|
-
const disableGroupedBatching = mc.config.getBoolean("Fluid.ContainerRuntime.DisableGroupedBatching");
|
|
376
375
|
const disableCompression = mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
|
|
377
376
|
const compressionLz4 = disableCompression !== true &&
|
|
378
377
|
compressionOptions.minimumBatchSizeInBytes !== Infinity &&
|
|
379
378
|
compressionOptions.compressionAlgorithm === "lz4";
|
|
380
|
-
const
|
|
381
|
-
const documentSchemaController = new index_js_3.DocumentsSchemaController(existing, metadata?.documentSchema, {
|
|
379
|
+
const documentSchemaController = new index_js_3.DocumentsSchemaController(existing, protocolSequenceNumber, metadata?.documentSchema, {
|
|
382
380
|
explicitSchemaControl,
|
|
383
381
|
compressionLz4,
|
|
384
382
|
idCompressorMode,
|
|
385
|
-
opGroupingEnabled,
|
|
383
|
+
opGroupingEnabled: enableGroupedBatching,
|
|
386
384
|
disallowedVersions: [],
|
|
387
385
|
}, (schema) => {
|
|
388
386
|
runtime.onSchemaChange(schema);
|
|
389
387
|
});
|
|
390
388
|
const featureGatesForTelemetry = {
|
|
391
|
-
disableGroupedBatching,
|
|
392
389
|
disableCompression,
|
|
393
390
|
};
|
|
394
391
|
const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
|
|
@@ -401,7 +398,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
401
398
|
chunkSizeInBytes,
|
|
402
399
|
// Requires<> drops undefined from IdCompressorType
|
|
403
400
|
enableRuntimeIdCompressor: enableRuntimeIdCompressor,
|
|
404
|
-
enableOpReentryCheck,
|
|
405
401
|
enableGroupedBatching,
|
|
406
402
|
explicitSchemaControl,
|
|
407
403
|
}, containerScope, logger, existing, blobManagerSnapshot, context.storage, createIdCompressorFn, documentSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, undefined);
|
|
@@ -440,11 +436,21 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
440
436
|
get attachState() {
|
|
441
437
|
return this._getAttachState();
|
|
442
438
|
}
|
|
443
|
-
|
|
439
|
+
/**
|
|
440
|
+
* Current session schema - defines what options are on & off.
|
|
441
|
+
* It's overlap of document schema (controlled by summary & ops) and options controlling this session.
|
|
442
|
+
* For example, document schema might have compression ON, but feature gates / runtime options turn it Off.
|
|
443
|
+
* In such case it will be off in session schema (i.e. this session should not use compression), but this client
|
|
444
|
+
* has to deal with compressed ops as other clients might send them.
|
|
445
|
+
* And in reverse, session schema can have compression Off, but feature gates / runtime options want it On.
|
|
446
|
+
* In such case it will be off in session schema, however this client will propose change to schema, and once / if
|
|
447
|
+
* this op rountrips, compression will be On. Client can't send compressed ops until it's change in schema.
|
|
448
|
+
*/
|
|
449
|
+
get sessionSchema() {
|
|
444
450
|
return this.documentsSchemaController.sessionSchema.runtime;
|
|
445
451
|
}
|
|
446
452
|
get idCompressorMode() {
|
|
447
|
-
return this.
|
|
453
|
+
return this.sessionSchema.idCompressorMode;
|
|
448
454
|
}
|
|
449
455
|
/**
|
|
450
456
|
* See IContainerRuntimeBase.idCompressor() for details.
|
|
@@ -552,13 +558,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
552
558
|
this.flushTaskExists = false;
|
|
553
559
|
this.consecutiveReconnects = 0;
|
|
554
560
|
this.ensureNoDataModelChangesCalls = 0;
|
|
555
|
-
/**
|
|
556
|
-
* Tracks the number of detected reentrant ops to report,
|
|
557
|
-
* in order to self-throttle the telemetry events.
|
|
558
|
-
*
|
|
559
|
-
* This should be removed as part of ADO:2322
|
|
560
|
-
*/
|
|
561
|
-
this.opReentryCallsToReport = 5;
|
|
562
561
|
this._disposed = false;
|
|
563
562
|
this.emitDirtyDocumentEvent = true;
|
|
564
563
|
this.defaultTelemetrySignalSampleCount = 100;
|
|
@@ -575,7 +574,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
575
574
|
this.snapshotCacheForLoadingGroupIds = new internal_2.PromiseCache({
|
|
576
575
|
expiry: { policy: "absolute", durationMs: 60000 },
|
|
577
576
|
});
|
|
578
|
-
const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, } = context;
|
|
577
|
+
const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, snapshotWithContents, } = context;
|
|
579
578
|
this.mc = (0, internal_7.createChildMonitoringContext)({
|
|
580
579
|
logger: this.logger,
|
|
581
580
|
namespace: "ContainerRuntime",
|
|
@@ -585,13 +584,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
585
584
|
// If it's not in the list, then we will need to either use no compression, or fallback to some other (supported by format)
|
|
586
585
|
// compression.
|
|
587
586
|
const compressionOptions = {
|
|
588
|
-
minimumBatchSizeInBytes: this.
|
|
587
|
+
minimumBatchSizeInBytes: this.sessionSchema.compressionLz4
|
|
589
588
|
? runtimeOptions.compressionOptions.minimumBatchSizeInBytes
|
|
590
589
|
: Number.POSITIVE_INFINITY,
|
|
591
590
|
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
592
591
|
};
|
|
593
592
|
this.innerDeltaManager = deltaManager;
|
|
594
|
-
this.deltaManager = new deltaManagerSummarizerProxy_js_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
|
|
595
593
|
// Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
|
|
596
594
|
// This makes ContainerRuntime the final gatekeeper for outgoing messages.
|
|
597
595
|
this.submitFn = submitFn;
|
|
@@ -665,15 +663,36 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
665
663
|
}, this.mc.logger);
|
|
666
664
|
const opSplitter = new index_js_2.OpSplitter(chunks, this.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
|
|
667
665
|
this.remoteMessageProcessor = new index_js_2.RemoteMessageProcessor(opSplitter, new index_js_2.OpDecompressor(this.mc.logger), opGroupingManager);
|
|
666
|
+
const pendingRuntimeState = pendingLocalState;
|
|
667
|
+
this.pendingStateManager = new pendingStateManager_js_1.PendingStateManager({
|
|
668
|
+
applyStashedOp: this.applyStashedOp.bind(this),
|
|
669
|
+
clientId: () => this.clientId,
|
|
670
|
+
close: this.closeFn,
|
|
671
|
+
connected: () => this.connected,
|
|
672
|
+
reSubmit: (message) => {
|
|
673
|
+
this.reSubmit(message);
|
|
674
|
+
this.flush();
|
|
675
|
+
},
|
|
676
|
+
reSubmitBatch: this.reSubmitBatch.bind(this),
|
|
677
|
+
isActiveConnection: () => this.innerDeltaManager.active,
|
|
678
|
+
isAttached: () => this.attachState !== container_definitions_1.AttachState.Detached,
|
|
679
|
+
}, pendingRuntimeState?.pending, this.logger);
|
|
680
|
+
let outerDeltaManager;
|
|
681
|
+
const useDeltaManagerOpsProxy = this.mc.config.getBoolean("Fluid.ContainerRuntime.DeltaManagerOpsProxy") !== false;
|
|
682
|
+
// The summarizerDeltaManager Proxy is used to lie to the summarizer to convince it is in the right state as a summarizer client.
|
|
683
|
+
const summarizerDeltaManagerProxy = new deltaManagerProxies_js_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
|
|
684
|
+
outerDeltaManager = summarizerDeltaManagerProxy;
|
|
685
|
+
// The DeltaManagerPendingOpsProxy is used to control the minimum sequence number
|
|
686
|
+
// It allows us to lie to the layers below so that they can maintain enough local state for rebasing ops.
|
|
687
|
+
if (useDeltaManagerOpsProxy) {
|
|
688
|
+
const pendingOpsDeltaManagerProxy = new deltaManagerProxies_js_1.DeltaManagerPendingOpsProxy(summarizerDeltaManagerProxy, this.pendingStateManager);
|
|
689
|
+
outerDeltaManager = pendingOpsDeltaManagerProxy;
|
|
690
|
+
}
|
|
691
|
+
this.deltaManager = outerDeltaManager;
|
|
668
692
|
this.handleContext = new containerHandleContext_js_1.ContainerFluidHandleContext("", this);
|
|
669
693
|
if (this.summaryConfiguration.state === "enabled") {
|
|
670
694
|
this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
|
|
671
695
|
}
|
|
672
|
-
const disableOpReentryCheck = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableOpReentryCheck");
|
|
673
|
-
this.enableOpReentryCheck =
|
|
674
|
-
runtimeOptions.enableOpReentryCheck === true &&
|
|
675
|
-
// Allow for a break-glass config to override the options
|
|
676
|
-
disableOpReentryCheck !== true;
|
|
677
696
|
this.summariesDisabled = this.isSummariesDisabled();
|
|
678
697
|
this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
|
|
679
698
|
this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
|
|
@@ -689,7 +708,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
689
708
|
else {
|
|
690
709
|
this._flushMode = runtimeOptions.flushMode;
|
|
691
710
|
}
|
|
692
|
-
const pendingRuntimeState = pendingLocalState;
|
|
693
711
|
if (context.attachState === container_definitions_1.AttachState.Attached) {
|
|
694
712
|
const maxSnapshotCacheDurationMs = this._storage?.policies?.maximumCacheDurationMs;
|
|
695
713
|
if (maxSnapshotCacheDurationMs !== undefined &&
|
|
@@ -745,7 +763,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
745
763
|
const envelope2 = this.createNewSignalEnvelope(envelope1.address, type, envelope1.contents);
|
|
746
764
|
return this.submitSignalFn(envelope2, targetClientId);
|
|
747
765
|
};
|
|
748
|
-
|
|
766
|
+
let snapshot = (0, channelCollection_js_1.getSummaryForDatastores)(baseSnapshot, metadata);
|
|
767
|
+
if (snapshot !== undefined && snapshotWithContents !== undefined) {
|
|
768
|
+
snapshot = {
|
|
769
|
+
...snapshotWithContents,
|
|
770
|
+
snapshotTree: snapshot,
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
this.channelCollection = new channelCollection_js_1.ChannelCollection(snapshot, parentContext, this.mc.logger, (props) => this.garbageCollector.nodeUpdated(props), (path) => this.garbageCollector.isNodeDeleted(path), new Map(dataStoreAliasMap), async (runtime) => provideEntryPoint);
|
|
749
774
|
this.blobManager = new blobManager_js_1.BlobManager({
|
|
750
775
|
routeContext: this.handleContext,
|
|
751
776
|
snapshot: blobManagerSnapshot,
|
|
@@ -768,19 +793,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
768
793
|
closeContainer: (error) => this.closeFn(error),
|
|
769
794
|
});
|
|
770
795
|
this.scheduleManager = new scheduleManager_js_1.ScheduleManager(this.innerDeltaManager, this, () => this.clientId, (0, internal_7.createChildLogger)({ logger: this.logger, namespace: "ScheduleManager" }));
|
|
771
|
-
this.pendingStateManager = new pendingStateManager_js_1.PendingStateManager({
|
|
772
|
-
applyStashedOp: this.applyStashedOp.bind(this),
|
|
773
|
-
clientId: () => this.clientId,
|
|
774
|
-
close: this.closeFn,
|
|
775
|
-
connected: () => this.connected,
|
|
776
|
-
reSubmit: (message) => {
|
|
777
|
-
this.reSubmit(message);
|
|
778
|
-
this.flush();
|
|
779
|
-
},
|
|
780
|
-
reSubmitBatch: this.reSubmitBatch.bind(this),
|
|
781
|
-
isActiveConnection: () => this.innerDeltaManager.active,
|
|
782
|
-
isAttached: () => this.attachState !== container_definitions_1.AttachState.Detached,
|
|
783
|
-
}, pendingRuntimeState?.pending, this.logger);
|
|
784
796
|
const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
|
|
785
797
|
const legacySendBatchFn = (0, exports.makeLegacySendBatchFn)(this.submitFn, this.innerDeltaManager);
|
|
786
798
|
this.outbox = new index_js_2.Outbox({
|
|
@@ -809,12 +821,29 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
809
821
|
this._quorum.on("removeMember", (clientId) => {
|
|
810
822
|
this.remoteMessageProcessor.clearPartialMessagesFor(clientId);
|
|
811
823
|
});
|
|
812
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
813
824
|
this._audience = audience;
|
|
825
|
+
if (audience.getSelf === undefined) {
|
|
826
|
+
// back-compat, added in 2.0 RC3.
|
|
827
|
+
// Purpose: deal with cases when we run against old loader that does not have newly added capabilities
|
|
828
|
+
audience.getSelf = () => {
|
|
829
|
+
const clientId = this._getClientId();
|
|
830
|
+
return clientId === undefined
|
|
831
|
+
? undefined
|
|
832
|
+
: ({
|
|
833
|
+
clientId,
|
|
834
|
+
client: audience.getMember(clientId),
|
|
835
|
+
});
|
|
836
|
+
};
|
|
837
|
+
let oldClientId = this.clientId;
|
|
838
|
+
this.on("connected", () => {
|
|
839
|
+
const clientId = this.clientId;
|
|
840
|
+
(0, internal_2.assert)(clientId !== undefined, 0x975 /* can't be undefined */);
|
|
841
|
+
audience.emit("selfChanged", { clientId: oldClientId }, { clientId, client: audience.getMember(clientId) });
|
|
842
|
+
oldClientId = clientId;
|
|
843
|
+
});
|
|
844
|
+
}
|
|
814
845
|
const closeSummarizerDelayOverride = this.mc.config.getNumber("Fluid.ContainerRuntime.Test.CloseSummarizerDelayOverrideMs");
|
|
815
846
|
this.closeSummarizerDelayMs = closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
|
|
816
|
-
this.validateSummaryBeforeUpload =
|
|
817
|
-
this.mc.config.getBoolean("Fluid.Summarizer.ValidateSummaryBeforeUpload") ?? false;
|
|
818
847
|
this.summaryCollection = new index_js_3.SummaryCollection(this.deltaManager, this.logger);
|
|
819
848
|
this.dirtyContainer =
|
|
820
849
|
this.attachState !== container_definitions_1.AttachState.Attached || this.hasPendingMessages();
|
|
@@ -887,9 +916,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
887
916
|
options: JSON.stringify(runtimeOptions),
|
|
888
917
|
idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
|
|
889
918
|
idCompressorMode: this.idCompressorMode,
|
|
919
|
+
sessionRuntimeSchema: JSON.stringify(this.sessionSchema),
|
|
890
920
|
featureGates: JSON.stringify({
|
|
891
921
|
...featureGatesForTelemetry,
|
|
892
|
-
disableOpReentryCheck,
|
|
893
922
|
disableChunking,
|
|
894
923
|
disableAttachReorder: this.disableAttachReorder,
|
|
895
924
|
disablePartialFlush,
|
|
@@ -897,6 +926,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
897
926
|
}),
|
|
898
927
|
telemetryDocumentId: this.telemetryDocumentId,
|
|
899
928
|
groupedBatchingEnabled: this.groupedBatchingEnabled,
|
|
929
|
+
initialSequenceNumber: this.deltaManager.initialSequenceNumber,
|
|
900
930
|
});
|
|
901
931
|
(0, connectionTelemetry_js_1.ReportOpPerfTelemetry)(this.clientId, this.deltaManager, this, this.logger);
|
|
902
932
|
(0, batchTracker_js_1.BindBatchTracker)(this, this.logger);
|
|
@@ -912,6 +942,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
912
942
|
this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
|
|
913
943
|
}
|
|
914
944
|
onSchemaChange(schema) {
|
|
945
|
+
this.logger.sendTelemetryEvent({
|
|
946
|
+
eventName: "SchemaChangeAccept",
|
|
947
|
+
sessionRuntimeSchema: JSON.stringify(schema),
|
|
948
|
+
});
|
|
915
949
|
// Most of the settings will be picked up only by new sessions (i.e. after reload).
|
|
916
950
|
// We can make it better in the future (i.e. start to use op compression right away), but for simplicity
|
|
917
951
|
// this is not done.
|
|
@@ -944,9 +978,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
944
978
|
async initializeBaseState() {
|
|
945
979
|
if (this.idCompressorMode === "on" ||
|
|
946
980
|
(this.idCompressorMode === "delayed" && this.connected)) {
|
|
981
|
+
this._idCompressor = await this.createIdCompressor();
|
|
947
982
|
// This is called from loadRuntime(), long before we process any ops, so there should be no ops accumulated yet.
|
|
948
983
|
(0, internal_2.assert)(this.pendingIdCompressorOps.length === 0, 0x8ec /* no pending ops */);
|
|
949
|
-
this._idCompressor = await this.createIdCompressor();
|
|
950
984
|
}
|
|
951
985
|
await this.garbageCollector.initializeBaseState();
|
|
952
986
|
}
|
|
@@ -1244,6 +1278,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1244
1278
|
this.emitDirtyDocumentEvent = false;
|
|
1245
1279
|
let newState;
|
|
1246
1280
|
try {
|
|
1281
|
+
this.submitIdAllocationOpIfNeeded(true);
|
|
1247
1282
|
// replay the ops
|
|
1248
1283
|
this.pendingStateManager.replayPendingStates();
|
|
1249
1284
|
}
|
|
@@ -1291,8 +1326,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1291
1326
|
return;
|
|
1292
1327
|
case messageTypes_js_1.ContainerMessageType.BlobAttach:
|
|
1293
1328
|
return;
|
|
1294
|
-
case messageTypes_js_1.ContainerMessageType.ChunkedOp:
|
|
1295
|
-
throw new Error("chunkedOp not expected here");
|
|
1296
1329
|
case messageTypes_js_1.ContainerMessageType.Rejoin:
|
|
1297
1330
|
throw new Error("rejoin not expected here");
|
|
1298
1331
|
case messageTypes_js_1.ContainerMessageType.GC:
|
|
@@ -1304,7 +1337,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1304
1337
|
// e.g. if an app rolled back its container version
|
|
1305
1338
|
const compatBehavior = opContents.compatDetails?.behavior;
|
|
1306
1339
|
if (!compatBehaviorAllowsMessageType(opContents.type, compatBehavior)) {
|
|
1307
|
-
const error = internal_7.DataProcessingError.create("Stashed runtime message of
|
|
1340
|
+
const error = internal_7.DataProcessingError.create("Stashed runtime message of unexpected type", "applyStashedOp", undefined /* sequencedMessage */, {
|
|
1308
1341
|
messageDetails: JSON.stringify({
|
|
1309
1342
|
type: opContents.type,
|
|
1310
1343
|
compatBehavior,
|
|
@@ -1324,12 +1357,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1324
1357
|
this._loadIdCompressor === undefined) {
|
|
1325
1358
|
this._loadIdCompressor = this.createIdCompressor()
|
|
1326
1359
|
.then((compressor) => {
|
|
1327
|
-
this._idCompressor = compressor;
|
|
1328
1360
|
// Finalize any ranges we received while the compressor was turned off.
|
|
1329
|
-
|
|
1330
|
-
this._idCompressor.finalizeCreationRange(range);
|
|
1331
|
-
}
|
|
1361
|
+
const ops = this.pendingIdCompressorOps;
|
|
1332
1362
|
this.pendingIdCompressorOps = [];
|
|
1363
|
+
for (const range of ops) {
|
|
1364
|
+
compressor.finalizeCreationRange(range);
|
|
1365
|
+
}
|
|
1366
|
+
(0, internal_2.assert)(this.pendingIdCompressorOps.length === 0, 0x976 /* No new ops added */);
|
|
1367
|
+
this._idCompressor = compressor;
|
|
1333
1368
|
})
|
|
1334
1369
|
.catch((error) => {
|
|
1335
1370
|
this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
|
|
@@ -1339,6 +1374,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1339
1374
|
return this._loadIdCompressor;
|
|
1340
1375
|
}
|
|
1341
1376
|
setConnectionState(connected, clientId) {
|
|
1377
|
+
// Validate we have consistent state
|
|
1378
|
+
const currentClientId = this._audience.getSelf()?.clientId;
|
|
1379
|
+
(0, internal_2.assert)(clientId === currentClientId, 0x977 /* input clientId does not match Audience */);
|
|
1380
|
+
(0, internal_2.assert)(this.clientId === currentClientId, 0x978 /* this.clientId does not match Audience */);
|
|
1342
1381
|
if (connected && this.idCompressorMode === "delayed") {
|
|
1343
1382
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1344
1383
|
this.loadIdCompressor();
|
|
@@ -1420,9 +1459,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1420
1459
|
// We do not need to make a deep copy. Each layer will just replace message.contents itself,
|
|
1421
1460
|
// but will not modify the contents object (likely it will replace it on the message).
|
|
1422
1461
|
const messageCopy = { ...messageArg };
|
|
1462
|
+
const savedOp = messageCopy.metadata?.savedOp;
|
|
1423
1463
|
for (const message of this.remoteMessageProcessor.process(messageCopy)) {
|
|
1424
|
-
|
|
1425
|
-
|
|
1464
|
+
const msg = modernRuntimeMessage
|
|
1465
|
+
? {
|
|
1426
1466
|
// Cast it since we expect it to be this based on modernRuntimeMessage computation above.
|
|
1427
1467
|
// There is nothing really ensuring that anytime original message.type is Operation that
|
|
1428
1468
|
// the result messages will be so. In the end modern bool being true only directs to
|
|
@@ -1430,12 +1470,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1430
1470
|
message: message,
|
|
1431
1471
|
local,
|
|
1432
1472
|
modernRuntimeMessage,
|
|
1433
|
-
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1473
|
+
}
|
|
1474
|
+
: // Unrecognized message will be ignored.
|
|
1475
|
+
{
|
|
1476
|
+
message,
|
|
1477
|
+
local,
|
|
1478
|
+
modernRuntimeMessage,
|
|
1479
|
+
};
|
|
1480
|
+
msg.savedOp = savedOp;
|
|
1481
|
+
// ensure that we observe any re-entrancy, and if needed, rebase ops
|
|
1482
|
+
this.ensureNoDataModelChanges(() => this.processCore(msg));
|
|
1439
1483
|
}
|
|
1440
1484
|
}
|
|
1441
1485
|
/**
|
|
@@ -1443,6 +1487,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1443
1487
|
*/
|
|
1444
1488
|
processCore(messageWithContext) {
|
|
1445
1489
|
const { message, local } = messageWithContext;
|
|
1490
|
+
// Intercept to reduce minimum sequence number to the delta manager's minimum sequence number.
|
|
1491
|
+
// Sequence numbers are not guaranteed to follow any sort of order. Re-entrancy is one of those situations
|
|
1492
|
+
if (this.deltaManager.minimumSequenceNumber <
|
|
1493
|
+
messageWithContext.message.minimumSequenceNumber) {
|
|
1494
|
+
messageWithContext.message.minimumSequenceNumber =
|
|
1495
|
+
this.deltaManager.minimumSequenceNumber;
|
|
1496
|
+
}
|
|
1446
1497
|
// Surround the actual processing of the operation with messages to the schedule manager indicating
|
|
1447
1498
|
// the beginning and end. This allows it to emit appropriate events and/or pause the processing of new
|
|
1448
1499
|
// messages once a batch has been fully processed.
|
|
@@ -1500,9 +1551,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1500
1551
|
// stashed ops flow. The compressor is stashed with these ops already processed.
|
|
1501
1552
|
// That said, in idCompressorMode === "delayed", we might not serialize ID compressor, and
|
|
1502
1553
|
// thus we need to process all the ops.
|
|
1503
|
-
if (!(this.skipSavedCompressorOps &&
|
|
1504
|
-
messageWithContext.message.metadata?.savedOp ===
|
|
1505
|
-
true)) {
|
|
1554
|
+
if (!(this.skipSavedCompressorOps && messageWithContext.savedOp === true)) {
|
|
1506
1555
|
const range = messageWithContext.message.contents;
|
|
1507
1556
|
// Some other client turned on the id compressor. If we have not turned it on,
|
|
1508
1557
|
// put it in a pending queue and delay finalization.
|
|
@@ -1511,6 +1560,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1511
1560
|
this.pendingIdCompressorOps.push(range);
|
|
1512
1561
|
}
|
|
1513
1562
|
else {
|
|
1563
|
+
(0, internal_2.assert)(this.pendingIdCompressorOps.length === 0, 0x979 /* there should be no pending ops! */);
|
|
1514
1564
|
this._idCompressor.finalizeCreationRange(range);
|
|
1515
1565
|
}
|
|
1516
1566
|
}
|
|
@@ -1631,9 +1681,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1631
1681
|
let checkpoint;
|
|
1632
1682
|
let result;
|
|
1633
1683
|
if (this.mc.config.getBoolean("Fluid.ContainerRuntime.EnableRollback")) {
|
|
1634
|
-
// Note: we are not touching
|
|
1635
|
-
// 1. It would not help, as
|
|
1636
|
-
// 2. There is no way to undo process of data store creation.
|
|
1684
|
+
// Note: we are not touching any batches other than mainBatch here, for two reasons:
|
|
1685
|
+
// 1. It would not help, as other batches are flushed independently from main batch.
|
|
1686
|
+
// 2. There is no way to undo process of data store creation, blob creation, ID compressor ops, or other things tracked by other batches.
|
|
1637
1687
|
checkpoint = this.outbox.checkpoint().mainBatch;
|
|
1638
1688
|
}
|
|
1639
1689
|
try {
|
|
@@ -2034,10 +2084,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2034
2084
|
// The summary number for this summary. This will be updated during the summary process, so get it now and
|
|
2035
2085
|
// use it for all events logged during this summary.
|
|
2036
2086
|
const summaryNumber = this.nextSummaryNumber;
|
|
2087
|
+
let summaryRefSeqNum;
|
|
2037
2088
|
const summaryNumberLogger = (0, internal_7.createChildLogger)({
|
|
2038
2089
|
logger: summaryLogger,
|
|
2039
2090
|
properties: {
|
|
2040
|
-
all: {
|
|
2091
|
+
all: {
|
|
2092
|
+
summaryNumber,
|
|
2093
|
+
referenceSequenceNumber: () => summaryRefSeqNum,
|
|
2094
|
+
},
|
|
2041
2095
|
},
|
|
2042
2096
|
});
|
|
2043
2097
|
(0, internal_2.assert)(this.outbox.isEmpty, 0x3d1 /* Can't trigger summary in the middle of a batch */);
|
|
@@ -2051,7 +2105,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2051
2105
|
// If the container is dirty, i.e., there are pending unacked ops, the summary will not be eventual consistent
|
|
2052
2106
|
// and it may even be incorrect. So, wait for the container to be saved with a timeout. If the container is not
|
|
2053
2107
|
// saved within the timeout, check if it should be failed or can continue.
|
|
2054
|
-
if (this.
|
|
2108
|
+
if (this.isDirty) {
|
|
2055
2109
|
const countBefore = this.pendingMessagesCount;
|
|
2056
2110
|
// The timeout for waiting for pending ops can be overridden via configurations.
|
|
2057
2111
|
const pendingOpsTimeout = this.mc.config.getNumber("Fluid.Summarizer.waitForPendingOpsTimeoutMs") ??
|
|
@@ -2084,7 +2138,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2084
2138
|
}
|
|
2085
2139
|
const shouldPauseInboundSignal = this.mc.config.getBoolean("Fluid.ContainerRuntime.SubmitSummary.disableInboundSignalPause") !== true;
|
|
2086
2140
|
const shouldValidatePreSummaryState = this.mc.config.getBoolean("Fluid.ContainerRuntime.SubmitSummary.shouldValidatePreSummaryState") === true;
|
|
2087
|
-
let summaryRefSeqNum;
|
|
2088
2141
|
try {
|
|
2089
2142
|
await this.deltaManager.inbound.pause();
|
|
2090
2143
|
if (shouldPauseInboundSignal) {
|
|
@@ -2117,7 +2170,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2117
2170
|
stage: "base",
|
|
2118
2171
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
2119
2172
|
minimumSequenceNumber,
|
|
2120
|
-
error: `Summarizer node state inconsistent with summarizer state
|
|
2173
|
+
error: new internal_7.LoggingError(`Summarizer node state inconsistent with summarizer state.`),
|
|
2121
2174
|
};
|
|
2122
2175
|
}
|
|
2123
2176
|
}
|
|
@@ -2160,7 +2213,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2160
2213
|
stage: "base",
|
|
2161
2214
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
2162
2215
|
minimumSequenceNumber,
|
|
2163
|
-
error: continueResult.error,
|
|
2216
|
+
error: new internal_7.LoggingError(continueResult.error),
|
|
2164
2217
|
};
|
|
2165
2218
|
}
|
|
2166
2219
|
const trace = client_utils_1.Trace.start();
|
|
@@ -2177,6 +2230,18 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2177
2230
|
});
|
|
2178
2231
|
}
|
|
2179
2232
|
catch (error) {
|
|
2233
|
+
return {
|
|
2234
|
+
stage: "base",
|
|
2235
|
+
referenceSequenceNumber: summaryRefSeqNum,
|
|
2236
|
+
minimumSequenceNumber,
|
|
2237
|
+
error: (0, internal_7.wrapError)(error, (msg) => new internal_7.LoggingError(msg)),
|
|
2238
|
+
};
|
|
2239
|
+
}
|
|
2240
|
+
// Validate that the summary generated by summarizer nodes is correct before uploading.
|
|
2241
|
+
const validateResult = this.summarizerNode.validateSummary();
|
|
2242
|
+
if (!validateResult.success) {
|
|
2243
|
+
const { success, ...loggingProps } = validateResult;
|
|
2244
|
+
const error = new index_js_3.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
|
|
2180
2245
|
return {
|
|
2181
2246
|
stage: "base",
|
|
2182
2247
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
@@ -2184,24 +2249,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2184
2249
|
error,
|
|
2185
2250
|
};
|
|
2186
2251
|
}
|
|
2187
|
-
// If
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
const { success, ...loggingProps } = validateResult;
|
|
2193
|
-
const error = new index_js_3.RetriableSummaryError(validateResult.reason, validateResult.retryAfterSeconds, { ...loggingProps });
|
|
2194
|
-
return {
|
|
2195
|
-
stage: "base",
|
|
2196
|
-
referenceSequenceNumber: summaryRefSeqNum,
|
|
2197
|
-
minimumSequenceNumber,
|
|
2198
|
-
error,
|
|
2199
|
-
};
|
|
2200
|
-
}
|
|
2201
|
-
const pendingMessagesFailResult = await this.shouldFailSummaryOnPendingOps(summaryNumberLogger, summaryRefSeqNum, minimumSequenceNumber, finalAttempt, false /* beforeSummaryGeneration */);
|
|
2202
|
-
if (pendingMessagesFailResult !== undefined) {
|
|
2203
|
-
return pendingMessagesFailResult;
|
|
2204
|
-
}
|
|
2252
|
+
// If there are pending unacked ops, this summary attempt may fail as the uploaded
|
|
2253
|
+
// summary would be eventually inconsistent.
|
|
2254
|
+
const pendingMessagesFailResult = await this.shouldFailSummaryOnPendingOps(summaryNumberLogger, summaryRefSeqNum, minimumSequenceNumber, finalAttempt, false /* beforeSummaryGeneration */);
|
|
2255
|
+
if (pendingMessagesFailResult !== undefined) {
|
|
2256
|
+
return pendingMessagesFailResult;
|
|
2205
2257
|
}
|
|
2206
2258
|
const { summary: summaryTree, stats: partialStats } = summarizeResult;
|
|
2207
2259
|
// Now that we have generated the summary, update the message at last summary to the last message processed.
|
|
@@ -2234,7 +2286,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2234
2286
|
};
|
|
2235
2287
|
continueResult = checkContinue();
|
|
2236
2288
|
if (!continueResult.continue) {
|
|
2237
|
-
return {
|
|
2289
|
+
return {
|
|
2290
|
+
stage: "generate",
|
|
2291
|
+
...generateSummaryData,
|
|
2292
|
+
error: new internal_7.LoggingError(continueResult.error),
|
|
2293
|
+
};
|
|
2238
2294
|
}
|
|
2239
2295
|
const summaryContext = lastAck === undefined
|
|
2240
2296
|
? {
|
|
@@ -2252,7 +2308,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2252
2308
|
handle = await this.storage.uploadSummaryWithContext(summarizeResult.summary, summaryContext);
|
|
2253
2309
|
}
|
|
2254
2310
|
catch (error) {
|
|
2255
|
-
return {
|
|
2311
|
+
return {
|
|
2312
|
+
stage: "generate",
|
|
2313
|
+
...generateSummaryData,
|
|
2314
|
+
error: (0, internal_7.wrapError)(error, (msg) => new internal_7.LoggingError(msg)),
|
|
2315
|
+
};
|
|
2256
2316
|
}
|
|
2257
2317
|
const parent = summaryContext.ackHandle;
|
|
2258
2318
|
const summaryMessage = {
|
|
@@ -2269,14 +2329,22 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2269
2329
|
};
|
|
2270
2330
|
continueResult = checkContinue();
|
|
2271
2331
|
if (!continueResult.continue) {
|
|
2272
|
-
return {
|
|
2332
|
+
return {
|
|
2333
|
+
stage: "upload",
|
|
2334
|
+
...uploadData,
|
|
2335
|
+
error: new internal_7.LoggingError(continueResult.error),
|
|
2336
|
+
};
|
|
2273
2337
|
}
|
|
2274
2338
|
let clientSequenceNumber;
|
|
2275
2339
|
try {
|
|
2276
2340
|
clientSequenceNumber = this.submitSummaryMessage(summaryMessage, summaryRefSeqNum);
|
|
2277
2341
|
}
|
|
2278
2342
|
catch (error) {
|
|
2279
|
-
return {
|
|
2343
|
+
return {
|
|
2344
|
+
stage: "upload",
|
|
2345
|
+
...uploadData,
|
|
2346
|
+
error: (0, internal_7.wrapError)(error, (msg) => new internal_7.LoggingError(msg)),
|
|
2347
|
+
};
|
|
2280
2348
|
}
|
|
2281
2349
|
const submitData = {
|
|
2282
2350
|
stage: "submit",
|
|
@@ -2285,11 +2353,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2285
2353
|
submitOpDuration: trace.trace().duration,
|
|
2286
2354
|
};
|
|
2287
2355
|
try {
|
|
2288
|
-
|
|
2289
|
-
this.summarizerNode.completeSummary(handle, !this.validateSummaryBeforeUpload /* validate */);
|
|
2356
|
+
this.summarizerNode.completeSummary(handle);
|
|
2290
2357
|
}
|
|
2291
2358
|
catch (error) {
|
|
2292
|
-
return {
|
|
2359
|
+
return {
|
|
2360
|
+
stage: "upload",
|
|
2361
|
+
...uploadData,
|
|
2362
|
+
error: (0, internal_7.wrapError)(error, (msg) => new internal_7.LoggingError(msg)),
|
|
2363
|
+
};
|
|
2293
2364
|
}
|
|
2294
2365
|
return submitData;
|
|
2295
2366
|
}
|
|
@@ -2378,9 +2449,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2378
2449
|
this.verifyNotClosed();
|
|
2379
2450
|
return this.blobManager.createBlob(blob, signal);
|
|
2380
2451
|
}
|
|
2381
|
-
submitIdAllocationOpIfNeeded() {
|
|
2452
|
+
submitIdAllocationOpIfNeeded(resubmitOutstandingRanges = false) {
|
|
2382
2453
|
if (this._idCompressor) {
|
|
2383
|
-
const idRange =
|
|
2454
|
+
const idRange = resubmitOutstandingRanges
|
|
2455
|
+
? this.idCompressor?.takeUnfinalizedCreationRange()
|
|
2456
|
+
: this._idCompressor.takeNextCreationRange();
|
|
2384
2457
|
// Don't include the idRange if there weren't any Ids allocated
|
|
2385
2458
|
if (idRange?.ids !== undefined) {
|
|
2386
2459
|
const idAllocationMessage = {
|
|
@@ -2397,7 +2470,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2397
2470
|
}
|
|
2398
2471
|
submit(containerRuntimeMessage, localOpMetadata = undefined, metadata) {
|
|
2399
2472
|
this.verifyNotClosed();
|
|
2400
|
-
this.verifyCanSubmitOps();
|
|
2401
2473
|
// There should be no ops in detached container state!
|
|
2402
2474
|
(0, internal_2.assert)(this.attachState !== container_definitions_1.AttachState.Detached, 0x132 /* "sending ops in detached container" */);
|
|
2403
2475
|
(0, internal_2.assert)(metadata === undefined ||
|
|
@@ -2433,6 +2505,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2433
2505
|
// on this callback to do actual sending.
|
|
2434
2506
|
const contents = this.documentsSchemaController.maybeSendSchemaMessage();
|
|
2435
2507
|
if (contents) {
|
|
2508
|
+
this.logger.sendTelemetryEvent({
|
|
2509
|
+
eventName: "SchemaChangeProposal",
|
|
2510
|
+
refSeq: contents.refSeq,
|
|
2511
|
+
version: contents.version,
|
|
2512
|
+
newRuntimeSchema: JSON.stringify(contents.runtime),
|
|
2513
|
+
sessionRuntimeSchema: JSON.stringify(this.sessionSchema),
|
|
2514
|
+
oldRuntimeSchema: JSON.stringify(this.metadata?.documentSchema?.runtime),
|
|
2515
|
+
});
|
|
2436
2516
|
const msg = {
|
|
2437
2517
|
type: messageTypes_js_1.ContainerMessageType.DocumentSchemaChange,
|
|
2438
2518
|
contents,
|
|
@@ -2442,32 +2522,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2442
2522
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2443
2523
|
});
|
|
2444
2524
|
}
|
|
2445
|
-
|
|
2446
|
-
// Is it safe:
|
|
2447
|
-
// Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
|
|
2448
|
-
// They become visible only when aliased, or handle to some sub-element of newly created datastore
|
|
2449
|
-
// is stored in some DDS, i.e. only after some other op.
|
|
2450
|
-
// Why:
|
|
2451
|
-
// Attach ops are large, and expensive to process. Plus there are scenarios where a lot of new data
|
|
2452
|
-
// stores are created, causing issues like relay service throttling (too many ops) and catastrophic
|
|
2453
|
-
// failure (batch is too large). Pushing them earlier and outside of main batch should alleviate
|
|
2454
|
-
// these issues.
|
|
2455
|
-
// Cons:
|
|
2456
|
-
// 1. With large batches, relay service may throttle clients. Clients may disconnect while throttled.
|
|
2457
|
-
// This change creates new possibility of a lot of newly created data stores never being referenced
|
|
2458
|
-
// because client died before it had a change to submit the rest of the ops. This will create more
|
|
2459
|
-
// garbage that needs to be collected leveraging GC (Garbage Collection) feature.
|
|
2460
|
-
// 2. Sending ops out of order means they are excluded from rollback functionality. This is not an issue
|
|
2461
|
-
// today as rollback can't undo creation of data store. To some extent not sending them is a bigger
|
|
2462
|
-
// issue than sending.
|
|
2463
|
-
// Please note that this does not change file format, so it can be disabled in the future if this
|
|
2464
|
-
// optimization no longer makes sense (for example, batch compression may make it less appealing).
|
|
2465
|
-
if (this.currentlyBatching() &&
|
|
2466
|
-
type === messageTypes_js_1.ContainerMessageType.Attach &&
|
|
2467
|
-
this.disableAttachReorder !== true) {
|
|
2468
|
-
this.outbox.submitAttach(message);
|
|
2469
|
-
}
|
|
2470
|
-
else if (type === messageTypes_js_1.ContainerMessageType.BlobAttach) {
|
|
2525
|
+
if (type === messageTypes_js_1.ContainerMessageType.BlobAttach) {
|
|
2471
2526
|
// BlobAttach ops must have their metadata visible and cannot be grouped (see opGroupingManager.ts)
|
|
2472
2527
|
this.outbox.submitBlobAttach(message);
|
|
2473
2528
|
}
|
|
@@ -2542,32 +2597,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2542
2597
|
throw new Error("Runtime is closed");
|
|
2543
2598
|
}
|
|
2544
2599
|
}
|
|
2545
|
-
verifyCanSubmitOps() {
|
|
2546
|
-
if (this.ensureNoDataModelChangesCalls > 0) {
|
|
2547
|
-
const errorMessage = "Op was submitted from within a `ensureNoDataModelChanges` callback";
|
|
2548
|
-
if (this.opReentryCallsToReport > 0) {
|
|
2549
|
-
this.mc.logger.sendTelemetryEvent({ eventName: "OpReentry" },
|
|
2550
|
-
// We need to capture the call stack in order to inspect the source of this usage pattern
|
|
2551
|
-
(0, index_js_2.getLongStack)(() => new internal_7.UsageError(errorMessage)));
|
|
2552
|
-
this.opReentryCallsToReport--;
|
|
2553
|
-
}
|
|
2554
|
-
// Creating ops while processing ops can lead
|
|
2555
|
-
// to undefined behavior and events observed in the wrong order.
|
|
2556
|
-
// For example, we have two callbacks registered for a DDS, A and B.
|
|
2557
|
-
// Then if on change #1 callback A creates change #2, the invocation flow will be:
|
|
2558
|
-
//
|
|
2559
|
-
// A because of #1
|
|
2560
|
-
// A because of #2
|
|
2561
|
-
// B because of #2
|
|
2562
|
-
// B because of #1
|
|
2563
|
-
//
|
|
2564
|
-
// The runtime must enforce op coherence by not allowing ops to be submitted
|
|
2565
|
-
// while ops are being processed.
|
|
2566
|
-
if (this.enableOpReentryCheck) {
|
|
2567
|
-
throw new internal_7.UsageError(errorMessage);
|
|
2568
|
-
}
|
|
2569
|
-
}
|
|
2570
|
-
}
|
|
2571
2600
|
reSubmitBatch(batch) {
|
|
2572
2601
|
this.orderSequentially(() => {
|
|
2573
2602
|
for (const message of batch) {
|
|
@@ -2599,11 +2628,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2599
2628
|
this.channelCollection.reSubmit(message.type, message.contents, localOpMetadata);
|
|
2600
2629
|
break;
|
|
2601
2630
|
case messageTypes_js_1.ContainerMessageType.IdAllocation: {
|
|
2602
|
-
|
|
2631
|
+
// Allocation ops are never resubmitted/rebased. This is because they require special handling to
|
|
2632
|
+
// avoid being submitted out of order. For example, if the pending state manager contained
|
|
2633
|
+
// [idOp1, dataOp1, idOp2, dataOp2] and the resubmission of dataOp1 generated idOp3, that would be
|
|
2634
|
+
// placed into the outbox in the same batch as idOp1, but before idOp2 is resubmitted.
|
|
2635
|
+
// To avoid this, allocation ops are simply never resubmitted. Prior to invoking the pending state
|
|
2636
|
+
// manager to replay pending ops, the runtime will always submit a new allocation range that includes
|
|
2637
|
+
// all pending IDs. The resubmitted allocation ops are then ignored here.
|
|
2603
2638
|
break;
|
|
2604
2639
|
}
|
|
2605
|
-
case messageTypes_js_1.ContainerMessageType.ChunkedOp:
|
|
2606
|
-
throw new Error(`chunkedOp not expected here`);
|
|
2607
2640
|
case messageTypes_js_1.ContainerMessageType.BlobAttach:
|
|
2608
2641
|
this.blobManager.reSubmit(opMetadata);
|
|
2609
2642
|
break;
|
|
@@ -2630,7 +2663,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2630
2663
|
});
|
|
2631
2664
|
}
|
|
2632
2665
|
else {
|
|
2633
|
-
const error = internal_7.DataProcessingError.create("Resubmitting runtime message of
|
|
2666
|
+
const error = internal_7.DataProcessingError.create("Resubmitting runtime message of unexpected type", "reSubmitCore", undefined /* sequencedMessage */, {
|
|
2634
2667
|
messageDetails: JSON.stringify({
|
|
2635
2668
|
type: message.type,
|
|
2636
2669
|
compatBehavior,
|
|
@@ -2697,7 +2730,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2697
2730
|
await this.closeStaleSummarizer();
|
|
2698
2731
|
return {
|
|
2699
2732
|
stage: "base",
|
|
2700
|
-
error: "summary state stale - Unsupported option 'refreshLatestAck'",
|
|
2733
|
+
error: new internal_7.LoggingError("summary state stale - Unsupported option 'refreshLatestAck'"),
|
|
2701
2734
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2702
2735
|
minimumSequenceNumber: this.deltaManager.minimumSequenceNumber,
|
|
2703
2736
|
};
|
|
@@ -2741,16 +2774,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2741
2774
|
}
|
|
2742
2775
|
this.imminentClosure || (this.imminentClosure = props?.notifyImminentClosure ?? false);
|
|
2743
2776
|
const getSyncState = (pendingAttachmentBlobs) => {
|
|
2744
|
-
const pending = this.pendingStateManager.getLocalState();
|
|
2745
|
-
|
|
2746
|
-
return; // no pending state to save
|
|
2747
|
-
}
|
|
2777
|
+
const pending = this.pendingStateManager.getLocalState(props?.snapshotSequenceNumber);
|
|
2778
|
+
const sessionExpiryTimerStarted = props?.sessionExpiryTimerStarted ?? this.garbageCollector.sessionExpiryTimerStarted;
|
|
2748
2779
|
const pendingIdCompressorState = this._idCompressor?.serialize(true);
|
|
2749
2780
|
return {
|
|
2750
2781
|
pending,
|
|
2751
2782
|
pendingIdCompressorState,
|
|
2752
2783
|
pendingAttachmentBlobs,
|
|
2753
|
-
sessionExpiryTimerStarted
|
|
2784
|
+
sessionExpiryTimerStarted,
|
|
2754
2785
|
};
|
|
2755
2786
|
};
|
|
2756
2787
|
const perfEvent = {
|
|
@@ -2820,7 +2851,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2820
2851
|
}
|
|
2821
2852
|
}
|
|
2822
2853
|
get groupedBatchingEnabled() {
|
|
2823
|
-
return this.
|
|
2854
|
+
return this.sessionSchema.opGroupingEnabled === true;
|
|
2824
2855
|
}
|
|
2825
2856
|
}
|
|
2826
2857
|
exports.ContainerRuntime = ContainerRuntime;
|