@fluidframework/container-runtime 2.0.0-dev-rc.4.0.0.261659 → 2.0.0-dev-rc.5.0.0.265721
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 +60 -29
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +9 -9
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +3 -5
- package/dist/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +8 -6
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +22 -11
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerHandleContext.d.ts +2 -1
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +14 -24
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +125 -140
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +13 -10
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +21 -8
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/{deltaManagerSummarizerProxy.d.ts → deltaManagerProxies.d.ts} +28 -3
- package/dist/deltaManagerProxies.d.ts.map +1 -0
- package/dist/{deltaManagerSummarizerProxy.js → deltaManagerProxies.js} +38 -2
- package/dist/deltaManagerProxies.js.map +1 -0
- package/dist/deltaScheduler.d.ts +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +1 -2
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +1 -1
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +14 -19
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +4 -22
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +3 -3
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +1 -2
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
- package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
- package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -1
- package/dist/gc/gcSummaryDefinitions.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +2 -2
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/dist/gc/index.d.ts +1 -1
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +2 -2
- package/dist/gc/index.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/opLifecycle/batchManager.d.ts +4 -0
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +1 -0
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +7 -20
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +6 -0
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +10 -1
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js.map +1 -1
- package/dist/storageServiceWithAttachBlobs.js.map +1 -1
- package/dist/summary/documentSchema.js +2 -2
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/index.d.ts +2 -2
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +4 -2
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +35 -13
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +0 -5
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +28 -113
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +1 -1
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +4 -1
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +1 -2
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js.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.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +16 -28
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +1 -1
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +2 -2
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +26 -6
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +7 -8
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +30 -25
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.js +5 -5
- package/dist/summary/summaryManager.js.map +1 -1
- package/dist/throttler.js.map +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +9 -9
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +4 -6
- package/lib/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +8 -6
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +23 -12
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerHandleContext.d.ts +2 -1
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +14 -24
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +125 -140
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +13 -10
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +23 -10
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/{deltaManagerSummarizerProxy.d.ts → deltaManagerProxies.d.ts} +28 -3
- package/lib/deltaManagerProxies.d.ts.map +1 -0
- package/lib/{deltaManagerSummarizerProxy.js → deltaManagerProxies.js} +36 -1
- package/lib/deltaManagerProxies.js.map +1 -0
- package/lib/deltaScheduler.d.ts +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +1 -2
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +1 -1
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +15 -20
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +4 -22
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +2 -2
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +1 -2
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -1
- package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
- package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -1
- package/lib/gc/gcSummaryDefinitions.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +2 -2
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/lib/gc/index.d.ts +1 -1
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -1
- package/lib/gc/index.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/opLifecycle/batchManager.d.ts +4 -0
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +1 -0
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +7 -20
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +6 -0
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +10 -1
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js.map +1 -1
- package/lib/storageServiceWithAttachBlobs.js.map +1 -1
- package/lib/summary/documentSchema.js +2 -2
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/index.d.ts +2 -2
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +4 -2
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +35 -13
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +0 -5
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +21 -106
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +1 -1
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +4 -1
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +1 -2
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js.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.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +16 -28
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +1 -1
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +2 -2
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +26 -6
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +1 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +7 -8
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +24 -19
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.js +1 -1
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/throttler.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/package.json +65 -26
- package/src/blobManager.ts +14 -13
- package/src/channelCollection.ts +34 -20
- package/src/connectionTelemetry.ts +1 -1
- package/src/containerHandleContext.ts +2 -1
- package/src/containerRuntime.ts +161 -170
- package/src/dataStore.ts +3 -2
- package/src/dataStoreContext.ts +62 -23
- package/src/{deltaManagerSummarizerProxy.ts → deltaManagerProxies.ts} +55 -3
- package/src/deltaScheduler.ts +1 -1
- package/src/gc/garbageCollection.md +0 -8
- package/src/gc/garbageCollection.ts +2 -1
- package/src/gc/gcConfigs.ts +12 -19
- package/src/gc/gcDefinitions.ts +5 -23
- package/src/gc/gcHelpers.ts +1 -1
- package/src/gc/gcSummaryDefinitions.ts +1 -1
- package/src/gc/gcSummaryStateTracker.ts +1 -1
- package/src/gc/gcTelemetry.ts +1 -1
- package/src/gc/index.ts +1 -1
- package/src/index.ts +6 -1
- package/src/messageTypes.ts +4 -2
- package/src/opLifecycle/batchManager.ts +5 -0
- package/src/opLifecycle/outbox.ts +7 -30
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +11 -1
- package/src/scheduleManager.ts +1 -1
- package/src/summary/documentSchema.ts +1 -1
- package/src/summary/index.ts +5 -1
- package/src/summary/orderedClientElection.ts +83 -12
- package/src/summary/runningSummarizer.ts +30 -114
- package/src/summary/summarizer.ts +5 -2
- package/src/summary/summarizerNode/summarizerNode.ts +0 -2
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +1 -3
- package/src/summary/summarizerTypes.ts +22 -29
- package/src/summary/summaryCollection.ts +1 -1
- package/src/summary/summaryFormat.ts +35 -6
- package/src/summary/summaryGenerator.ts +50 -27
- package/src/summary/summaryManager.ts +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts.map +0 -1
- package/dist/deltaManagerSummarizerProxy.js.map +0 -1
- 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");
|
|
@@ -50,13 +50,13 @@ function compatBehaviorAllowsMessageType(_unknownContainerRuntimeMessageType, co
|
|
|
50
50
|
exports.DefaultSummaryConfiguration = {
|
|
51
51
|
state: "enabled",
|
|
52
52
|
minIdleTime: 0,
|
|
53
|
-
maxIdleTime: 30 * 1000,
|
|
54
|
-
maxTime: 60 * 1000,
|
|
55
|
-
maxOps: 100,
|
|
53
|
+
maxIdleTime: 30 * 1000, // 30 secs.
|
|
54
|
+
maxTime: 60 * 1000, // 1 min.
|
|
55
|
+
maxOps: 100, // Summarize if 100 weighted ops received since last snapshot.
|
|
56
56
|
minOpsForLastSummaryAttempt: 10,
|
|
57
|
-
maxAckWaitTime: 3 * 60 * 1000,
|
|
57
|
+
maxAckWaitTime: 3 * 60 * 1000, // 3 mins.
|
|
58
58
|
maxOpsSinceLastSummary: 7000,
|
|
59
|
-
initialSummarizerDelayMs: 5 * 1000,
|
|
59
|
+
initialSummarizerDelayMs: 5 * 1000, // 5 secs.
|
|
60
60
|
nonRuntimeOpWeight: 0.1,
|
|
61
61
|
runtimeOpWeight: 1.0,
|
|
62
62
|
nonRuntimeHeuristicThreshold: 20,
|
|
@@ -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, enableGroupedBatching =
|
|
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];
|
|
@@ -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 opGroupingEnabled = disableGroupedBatching !== true && enableGroupedBatching;
|
|
381
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 ?? [], {
|
|
@@ -535,7 +532,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
535
532
|
return this.garbageCollector.throwOnTombstoneUsage;
|
|
536
533
|
}
|
|
537
534
|
/***/
|
|
538
|
-
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope,
|
|
535
|
+
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope,
|
|
536
|
+
// Create a custom ITelemetryBaseLogger to output telemetry events.
|
|
537
|
+
baseLogger, existing, blobManagerSnapshot, _storage, createIdCompressor, documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler, summaryConfiguration = {
|
|
539
538
|
// the defaults
|
|
540
539
|
...exports.DefaultSummaryConfiguration,
|
|
541
540
|
// the runtime configuration overrides
|
|
@@ -546,7 +545,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
546
545
|
this.metadata = metadata;
|
|
547
546
|
this.runtimeOptions = runtimeOptions;
|
|
548
547
|
this.containerScope = containerScope;
|
|
549
|
-
this.
|
|
548
|
+
this.baseLogger = baseLogger;
|
|
550
549
|
this._storage = _storage;
|
|
551
550
|
this.createIdCompressor = createIdCompressor;
|
|
552
551
|
this.documentsSchemaController = documentsSchemaController;
|
|
@@ -577,7 +576,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
577
576
|
this.snapshotCacheForLoadingGroupIds = new internal_2.PromiseCache({
|
|
578
577
|
expiry: { policy: "absolute", durationMs: 60000 },
|
|
579
578
|
});
|
|
580
|
-
const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, } = context;
|
|
579
|
+
const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, snapshotWithContents, } = context;
|
|
580
|
+
this.logger = (0, internal_7.createChildLogger)({ logger: this.baseLogger });
|
|
581
581
|
this.mc = (0, internal_7.createChildMonitoringContext)({
|
|
582
582
|
logger: this.logger,
|
|
583
583
|
namespace: "ContainerRuntime",
|
|
@@ -593,7 +593,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
593
593
|
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
594
594
|
};
|
|
595
595
|
this.innerDeltaManager = deltaManager;
|
|
596
|
-
this.deltaManager = new deltaManagerSummarizerProxy_js_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
|
|
597
596
|
// Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
|
|
598
597
|
// This makes ContainerRuntime the final gatekeeper for outgoing messages.
|
|
599
598
|
this.submitFn = submitFn;
|
|
@@ -667,6 +666,32 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
667
666
|
}, this.mc.logger);
|
|
668
667
|
const opSplitter = new index_js_2.OpSplitter(chunks, this.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
|
|
669
668
|
this.remoteMessageProcessor = new index_js_2.RemoteMessageProcessor(opSplitter, new index_js_2.OpDecompressor(this.mc.logger), opGroupingManager);
|
|
669
|
+
const pendingRuntimeState = pendingLocalState;
|
|
670
|
+
this.pendingStateManager = new pendingStateManager_js_1.PendingStateManager({
|
|
671
|
+
applyStashedOp: this.applyStashedOp.bind(this),
|
|
672
|
+
clientId: () => this.clientId,
|
|
673
|
+
close: this.closeFn,
|
|
674
|
+
connected: () => this.connected,
|
|
675
|
+
reSubmit: (message) => {
|
|
676
|
+
this.reSubmit(message);
|
|
677
|
+
this.flush();
|
|
678
|
+
},
|
|
679
|
+
reSubmitBatch: this.reSubmitBatch.bind(this),
|
|
680
|
+
isActiveConnection: () => this.innerDeltaManager.active,
|
|
681
|
+
isAttached: () => this.attachState !== container_definitions_1.AttachState.Detached,
|
|
682
|
+
}, pendingRuntimeState?.pending, this.logger);
|
|
683
|
+
let outerDeltaManager;
|
|
684
|
+
const useDeltaManagerOpsProxy = this.mc.config.getBoolean("Fluid.ContainerRuntime.DeltaManagerOpsProxy") !== false;
|
|
685
|
+
// The summarizerDeltaManager Proxy is used to lie to the summarizer to convince it is in the right state as a summarizer client.
|
|
686
|
+
const summarizerDeltaManagerProxy = new deltaManagerProxies_js_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
|
|
687
|
+
outerDeltaManager = summarizerDeltaManagerProxy;
|
|
688
|
+
// The DeltaManagerPendingOpsProxy is used to control the minimum sequence number
|
|
689
|
+
// It allows us to lie to the layers below so that they can maintain enough local state for rebasing ops.
|
|
690
|
+
if (useDeltaManagerOpsProxy) {
|
|
691
|
+
const pendingOpsDeltaManagerProxy = new deltaManagerProxies_js_1.DeltaManagerPendingOpsProxy(summarizerDeltaManagerProxy, this.pendingStateManager);
|
|
692
|
+
outerDeltaManager = pendingOpsDeltaManagerProxy;
|
|
693
|
+
}
|
|
694
|
+
this.deltaManager = outerDeltaManager;
|
|
670
695
|
this.handleContext = new containerHandleContext_js_1.ContainerFluidHandleContext("", this);
|
|
671
696
|
if (this.summaryConfiguration.state === "enabled") {
|
|
672
697
|
this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
|
|
@@ -686,7 +711,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
686
711
|
else {
|
|
687
712
|
this._flushMode = runtimeOptions.flushMode;
|
|
688
713
|
}
|
|
689
|
-
const pendingRuntimeState = pendingLocalState;
|
|
690
714
|
if (context.attachState === container_definitions_1.AttachState.Attached) {
|
|
691
715
|
const maxSnapshotCacheDurationMs = this._storage?.policies?.maximumCacheDurationMs;
|
|
692
716
|
if (maxSnapshotCacheDurationMs !== undefined &&
|
|
@@ -742,7 +766,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
742
766
|
const envelope2 = this.createNewSignalEnvelope(envelope1.address, type, envelope1.contents);
|
|
743
767
|
return this.submitSignalFn(envelope2, targetClientId);
|
|
744
768
|
};
|
|
745
|
-
|
|
769
|
+
let snapshot = (0, channelCollection_js_1.getSummaryForDatastores)(baseSnapshot, metadata);
|
|
770
|
+
if (snapshot !== undefined && snapshotWithContents !== undefined) {
|
|
771
|
+
snapshot = {
|
|
772
|
+
...snapshotWithContents,
|
|
773
|
+
snapshotTree: snapshot,
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
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);
|
|
746
777
|
this.blobManager = new blobManager_js_1.BlobManager({
|
|
747
778
|
routeContext: this.handleContext,
|
|
748
779
|
snapshot: blobManagerSnapshot,
|
|
@@ -765,19 +796,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
765
796
|
closeContainer: (error) => this.closeFn(error),
|
|
766
797
|
});
|
|
767
798
|
this.scheduleManager = new scheduleManager_js_1.ScheduleManager(this.innerDeltaManager, this, () => this.clientId, (0, internal_7.createChildLogger)({ logger: this.logger, namespace: "ScheduleManager" }));
|
|
768
|
-
this.pendingStateManager = new pendingStateManager_js_1.PendingStateManager({
|
|
769
|
-
applyStashedOp: this.applyStashedOp.bind(this),
|
|
770
|
-
clientId: () => this.clientId,
|
|
771
|
-
close: this.closeFn,
|
|
772
|
-
connected: () => this.connected,
|
|
773
|
-
reSubmit: (message) => {
|
|
774
|
-
this.reSubmit(message);
|
|
775
|
-
this.flush();
|
|
776
|
-
},
|
|
777
|
-
reSubmitBatch: this.reSubmitBatch.bind(this),
|
|
778
|
-
isActiveConnection: () => this.innerDeltaManager.active,
|
|
779
|
-
isAttached: () => this.attachState !== container_definitions_1.AttachState.Detached,
|
|
780
|
-
}, pendingRuntimeState?.pending, this.logger);
|
|
781
799
|
const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
|
|
782
800
|
const legacySendBatchFn = (0, exports.makeLegacySendBatchFn)(this.submitFn, this.innerDeltaManager);
|
|
783
801
|
this.outbox = new index_js_2.Outbox({
|
|
@@ -822,7 +840,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
822
840
|
let oldClientId = this.clientId;
|
|
823
841
|
this.on("connected", () => {
|
|
824
842
|
const clientId = this.clientId;
|
|
825
|
-
(0, internal_2.assert)(clientId !== undefined,
|
|
843
|
+
(0, internal_2.assert)(clientId !== undefined, 0x975 /* can't be undefined */);
|
|
826
844
|
audience.emit("selfChanged", { clientId: oldClientId }, { clientId, client: audience.getMember(clientId) });
|
|
827
845
|
oldClientId = clientId;
|
|
828
846
|
});
|
|
@@ -842,7 +860,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
842
860
|
namespace: "OrderedClientElection",
|
|
843
861
|
});
|
|
844
862
|
const orderedClientCollection = new index_js_3.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
|
|
845
|
-
const orderedClientElectionForSummarizer = new index_js_3.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, index_js_3.SummarizerClientElection.isClientEligible);
|
|
863
|
+
const orderedClientElectionForSummarizer = new index_js_3.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, index_js_3.SummarizerClientElection.isClientEligible, this.mc.config.getBoolean("Fluid.ContainerRuntime.OrderedClientElection.EnablePerformanceEvents"));
|
|
846
864
|
this.summarizerClientElection = new index_js_3.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
|
|
847
865
|
if (this.isSummarizerClient) {
|
|
848
866
|
this._summarizer = new index_js_3.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => index_js_3.RunWhileConnectedCoordinator.create(runtime,
|
|
@@ -886,7 +904,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
886
904
|
}
|
|
887
905
|
}
|
|
888
906
|
// logging hardware telemetry
|
|
889
|
-
logger.sendTelemetryEvent({
|
|
907
|
+
this.logger.sendTelemetryEvent({
|
|
890
908
|
eventName: "DeviceSpec",
|
|
891
909
|
...getDeviceSpec(),
|
|
892
910
|
});
|
|
@@ -1049,7 +1067,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1049
1067
|
const props = {
|
|
1050
1068
|
eventName: "GroupIdSnapshotCatchup",
|
|
1051
1069
|
loadingGroupIds: sortedLoadingGroupIds.join(","),
|
|
1052
|
-
targetSequenceNumber: snapshotSeqNumber,
|
|
1070
|
+
targetSequenceNumber: snapshotSeqNumber, // This is so we reuse some columns in telemetry
|
|
1053
1071
|
sequenceNumber: this.deltaManager.lastSequenceNumber, // This is so we reuse some columns in telemetry
|
|
1054
1072
|
};
|
|
1055
1073
|
const event = internal_7.PerformanceEvent.start(this.mc.logger, {
|
|
@@ -1263,6 +1281,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1263
1281
|
this.emitDirtyDocumentEvent = false;
|
|
1264
1282
|
let newState;
|
|
1265
1283
|
try {
|
|
1284
|
+
this.submitIdAllocationOpIfNeeded(true);
|
|
1266
1285
|
// replay the ops
|
|
1267
1286
|
this.pendingStateManager.replayPendingStates();
|
|
1268
1287
|
}
|
|
@@ -1310,8 +1329,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1310
1329
|
return;
|
|
1311
1330
|
case messageTypes_js_1.ContainerMessageType.BlobAttach:
|
|
1312
1331
|
return;
|
|
1313
|
-
case messageTypes_js_1.ContainerMessageType.ChunkedOp:
|
|
1314
|
-
throw new Error("chunkedOp not expected here");
|
|
1315
1332
|
case messageTypes_js_1.ContainerMessageType.Rejoin:
|
|
1316
1333
|
throw new Error("rejoin not expected here");
|
|
1317
1334
|
case messageTypes_js_1.ContainerMessageType.GC:
|
|
@@ -1323,7 +1340,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1323
1340
|
// e.g. if an app rolled back its container version
|
|
1324
1341
|
const compatBehavior = opContents.compatDetails?.behavior;
|
|
1325
1342
|
if (!compatBehaviorAllowsMessageType(opContents.type, compatBehavior)) {
|
|
1326
|
-
const error = internal_7.DataProcessingError.create("Stashed runtime message of
|
|
1343
|
+
const error = internal_7.DataProcessingError.create("Stashed runtime message of unexpected type", "applyStashedOp", undefined /* sequencedMessage */, {
|
|
1327
1344
|
messageDetails: JSON.stringify({
|
|
1328
1345
|
type: opContents.type,
|
|
1329
1346
|
compatBehavior,
|
|
@@ -1349,7 +1366,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1349
1366
|
for (const range of ops) {
|
|
1350
1367
|
compressor.finalizeCreationRange(range);
|
|
1351
1368
|
}
|
|
1352
|
-
(0, internal_2.assert)(this.pendingIdCompressorOps.length === 0,
|
|
1369
|
+
(0, internal_2.assert)(this.pendingIdCompressorOps.length === 0, 0x976 /* No new ops added */);
|
|
1353
1370
|
this._idCompressor = compressor;
|
|
1354
1371
|
})
|
|
1355
1372
|
.catch((error) => {
|
|
@@ -1362,8 +1379,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1362
1379
|
setConnectionState(connected, clientId) {
|
|
1363
1380
|
// Validate we have consistent state
|
|
1364
1381
|
const currentClientId = this._audience.getSelf()?.clientId;
|
|
1365
|
-
(0, internal_2.assert)(clientId === currentClientId,
|
|
1366
|
-
(0, internal_2.assert)(this.clientId === currentClientId,
|
|
1382
|
+
(0, internal_2.assert)(clientId === currentClientId, 0x977 /* input clientId does not match Audience */);
|
|
1383
|
+
(0, internal_2.assert)(this.clientId === currentClientId, 0x978 /* this.clientId does not match Audience */);
|
|
1367
1384
|
if (connected && this.idCompressorMode === "delayed") {
|
|
1368
1385
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1369
1386
|
this.loadIdCompressor();
|
|
@@ -1473,6 +1490,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1473
1490
|
*/
|
|
1474
1491
|
processCore(messageWithContext) {
|
|
1475
1492
|
const { message, local } = messageWithContext;
|
|
1493
|
+
// Intercept to reduce minimum sequence number to the delta manager's minimum sequence number.
|
|
1494
|
+
// Sequence numbers are not guaranteed to follow any sort of order. Re-entrancy is one of those situations
|
|
1495
|
+
if (this.deltaManager.minimumSequenceNumber <
|
|
1496
|
+
messageWithContext.message.minimumSequenceNumber) {
|
|
1497
|
+
messageWithContext.message.minimumSequenceNumber =
|
|
1498
|
+
this.deltaManager.minimumSequenceNumber;
|
|
1499
|
+
}
|
|
1476
1500
|
// Surround the actual processing of the operation with messages to the schedule manager indicating
|
|
1477
1501
|
// the beginning and end. This allows it to emit appropriate events and/or pause the processing of new
|
|
1478
1502
|
// messages once a batch has been fully processed.
|
|
@@ -1539,7 +1563,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1539
1563
|
this.pendingIdCompressorOps.push(range);
|
|
1540
1564
|
}
|
|
1541
1565
|
else {
|
|
1542
|
-
(0, internal_2.assert)(this.pendingIdCompressorOps.length === 0,
|
|
1566
|
+
(0, internal_2.assert)(this.pendingIdCompressorOps.length === 0, 0x979 /* there should be no pending ops! */);
|
|
1543
1567
|
this._idCompressor.finalizeCreationRange(range);
|
|
1544
1568
|
}
|
|
1545
1569
|
}
|
|
@@ -1900,7 +1924,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1900
1924
|
return { stats, summary };
|
|
1901
1925
|
}
|
|
1902
1926
|
finally {
|
|
1903
|
-
|
|
1927
|
+
summaryLogger.sendTelemetryEvent({
|
|
1904
1928
|
eventName: "SummarizeTelemetry",
|
|
1905
1929
|
details: telemetryContext.serialize(),
|
|
1906
1930
|
});
|
|
@@ -2059,7 +2083,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2059
2083
|
* @param options - options controlling how the summary is generated or submitted
|
|
2060
2084
|
*/
|
|
2061
2085
|
async submitSummary(options) {
|
|
2062
|
-
const { fullTree = false, finalAttempt = false,
|
|
2086
|
+
const { fullTree = false, finalAttempt = false, summaryLogger, latestSummaryRefSeqNum, } = options;
|
|
2063
2087
|
// The summary number for this summary. This will be updated during the summary process, so get it now and
|
|
2064
2088
|
// use it for all events logged during this summary.
|
|
2065
2089
|
const summaryNumber = this.nextSummaryNumber;
|
|
@@ -2074,13 +2098,6 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2074
2098
|
},
|
|
2075
2099
|
});
|
|
2076
2100
|
(0, internal_2.assert)(this.outbox.isEmpty, 0x3d1 /* Can't trigger summary in the middle of a batch */);
|
|
2077
|
-
// We close the summarizer and download a new snapshot and reload the container
|
|
2078
|
-
if (refreshLatestAck === true) {
|
|
2079
|
-
return this.prefetchLatestSummaryThenClose((0, internal_7.createChildLogger)({
|
|
2080
|
-
logger: summaryNumberLogger,
|
|
2081
|
-
properties: { all: { safeSummary: true } },
|
|
2082
|
-
}));
|
|
2083
|
-
}
|
|
2084
2101
|
// If the container is dirty, i.e., there are pending unacked ops, the summary will not be eventual consistent
|
|
2085
2102
|
// and it may even be incorrect. So, wait for the container to be saved with a timeout. If the container is not
|
|
2086
2103
|
// saved within the timeout, check if it should be failed or can continue.
|
|
@@ -2149,7 +2166,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2149
2166
|
stage: "base",
|
|
2150
2167
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
2151
2168
|
minimumSequenceNumber,
|
|
2152
|
-
error: new
|
|
2169
|
+
error: new index_js_3.RetriableSummaryError(`Summarizer node state inconsistent with summarizer state.`),
|
|
2153
2170
|
};
|
|
2154
2171
|
}
|
|
2155
2172
|
}
|
|
@@ -2192,7 +2209,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2192
2209
|
stage: "base",
|
|
2193
2210
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
2194
2211
|
minimumSequenceNumber,
|
|
2195
|
-
error: new
|
|
2212
|
+
error: new index_js_3.RetriableSummaryError(continueResult.error),
|
|
2196
2213
|
};
|
|
2197
2214
|
}
|
|
2198
2215
|
const trace = client_utils_1.Trace.start();
|
|
@@ -2213,7 +2230,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2213
2230
|
stage: "base",
|
|
2214
2231
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
2215
2232
|
minimumSequenceNumber,
|
|
2216
|
-
error: (0, internal_7.wrapError)(error, (msg) => new
|
|
2233
|
+
error: (0, internal_7.wrapError)(error, (msg) => new index_js_3.RetriableSummaryError(msg)),
|
|
2217
2234
|
};
|
|
2218
2235
|
}
|
|
2219
2236
|
// Validate that the summary generated by summarizer nodes is correct before uploading.
|
|
@@ -2268,7 +2285,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2268
2285
|
return {
|
|
2269
2286
|
stage: "generate",
|
|
2270
2287
|
...generateSummaryData,
|
|
2271
|
-
error: new
|
|
2288
|
+
error: new index_js_3.RetriableSummaryError(continueResult.error),
|
|
2272
2289
|
};
|
|
2273
2290
|
}
|
|
2274
2291
|
const summaryContext = lastAck === undefined
|
|
@@ -2290,7 +2307,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2290
2307
|
return {
|
|
2291
2308
|
stage: "generate",
|
|
2292
2309
|
...generateSummaryData,
|
|
2293
|
-
error: (0, internal_7.wrapError)(error, (msg) => new
|
|
2310
|
+
error: (0, internal_7.wrapError)(error, (msg) => new index_js_3.RetriableSummaryError(msg)),
|
|
2294
2311
|
};
|
|
2295
2312
|
}
|
|
2296
2313
|
const parent = summaryContext.ackHandle;
|
|
@@ -2311,7 +2328,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2311
2328
|
return {
|
|
2312
2329
|
stage: "upload",
|
|
2313
2330
|
...uploadData,
|
|
2314
|
-
error: new
|
|
2331
|
+
error: new index_js_3.RetriableSummaryError(continueResult.error),
|
|
2315
2332
|
};
|
|
2316
2333
|
}
|
|
2317
2334
|
let clientSequenceNumber;
|
|
@@ -2322,7 +2339,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2322
2339
|
return {
|
|
2323
2340
|
stage: "upload",
|
|
2324
2341
|
...uploadData,
|
|
2325
|
-
error: (0, internal_7.wrapError)(error, (msg) => new
|
|
2342
|
+
error: (0, internal_7.wrapError)(error, (msg) => new index_js_3.RetriableSummaryError(msg)),
|
|
2326
2343
|
};
|
|
2327
2344
|
}
|
|
2328
2345
|
const submitData = {
|
|
@@ -2338,7 +2355,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2338
2355
|
return {
|
|
2339
2356
|
stage: "upload",
|
|
2340
2357
|
...uploadData,
|
|
2341
|
-
error: (0, internal_7.wrapError)(error, (msg) => new
|
|
2358
|
+
error: (0, internal_7.wrapError)(error, (msg) => new index_js_3.RetriableSummaryError(msg)),
|
|
2342
2359
|
};
|
|
2343
2360
|
}
|
|
2344
2361
|
return submitData;
|
|
@@ -2428,11 +2445,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2428
2445
|
this.verifyNotClosed();
|
|
2429
2446
|
return this.blobManager.createBlob(blob, signal);
|
|
2430
2447
|
}
|
|
2431
|
-
submitIdAllocationOpIfNeeded() {
|
|
2448
|
+
submitIdAllocationOpIfNeeded(resubmitOutstandingRanges) {
|
|
2432
2449
|
if (this._idCompressor) {
|
|
2433
|
-
const idRange =
|
|
2450
|
+
const idRange = resubmitOutstandingRanges
|
|
2451
|
+
? this._idCompressor.takeUnfinalizedCreationRange()
|
|
2452
|
+
: this._idCompressor.takeNextCreationRange();
|
|
2434
2453
|
// Don't include the idRange if there weren't any Ids allocated
|
|
2435
|
-
if (idRange
|
|
2454
|
+
if (idRange.ids !== undefined) {
|
|
2436
2455
|
const idAllocationMessage = {
|
|
2437
2456
|
type: messageTypes_js_1.ContainerMessageType.IdAllocation,
|
|
2438
2457
|
contents: idRange,
|
|
@@ -2461,6 +2480,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2461
2480
|
});
|
|
2462
2481
|
}
|
|
2463
2482
|
const type = containerRuntimeMessage.type;
|
|
2483
|
+
(0, internal_2.assert)(type !== messageTypes_js_1.ContainerMessageType.IdAllocation, "IdAllocation should be submitted directly to outbox.");
|
|
2464
2484
|
const message = {
|
|
2465
2485
|
contents: serializedContent,
|
|
2466
2486
|
metadata,
|
|
@@ -2468,44 +2488,35 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2468
2488
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2469
2489
|
};
|
|
2470
2490
|
try {
|
|
2471
|
-
|
|
2472
|
-
//
|
|
2473
|
-
//
|
|
2474
|
-
//
|
|
2475
|
-
|
|
2476
|
-
|
|
2491
|
+
this.submitIdAllocationOpIfNeeded(false);
|
|
2492
|
+
// Allow document schema controller to send a message if it needs to propose change in document schema.
|
|
2493
|
+
// If it needs to send a message, it will call provided callback with payload of such message and rely
|
|
2494
|
+
// on this callback to do actual sending.
|
|
2495
|
+
const contents = this.documentsSchemaController.maybeSendSchemaMessage();
|
|
2496
|
+
if (contents) {
|
|
2497
|
+
this.logger.sendTelemetryEvent({
|
|
2498
|
+
eventName: "SchemaChangeProposal",
|
|
2499
|
+
refSeq: contents.refSeq,
|
|
2500
|
+
version: contents.version,
|
|
2501
|
+
newRuntimeSchema: JSON.stringify(contents.runtime),
|
|
2502
|
+
sessionRuntimeSchema: JSON.stringify(this.sessionSchema),
|
|
2503
|
+
oldRuntimeSchema: JSON.stringify(this.metadata?.documentSchema?.runtime),
|
|
2504
|
+
});
|
|
2505
|
+
const msg = {
|
|
2506
|
+
type: messageTypes_js_1.ContainerMessageType.DocumentSchemaChange,
|
|
2507
|
+
contents,
|
|
2508
|
+
};
|
|
2509
|
+
this.outbox.submit({
|
|
2510
|
+
contents: JSON.stringify(msg),
|
|
2511
|
+
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2512
|
+
});
|
|
2513
|
+
}
|
|
2514
|
+
if (type === messageTypes_js_1.ContainerMessageType.BlobAttach) {
|
|
2515
|
+
// BlobAttach ops must have their metadata visible and cannot be grouped (see opGroupingManager.ts)
|
|
2516
|
+
this.outbox.submitBlobAttach(message);
|
|
2477
2517
|
}
|
|
2478
2518
|
else {
|
|
2479
|
-
this.
|
|
2480
|
-
// Allow document schema controller to send a message if it needs to propose change in document schema.
|
|
2481
|
-
// If it needs to send a message, it will call provided callback with payload of such message and rely
|
|
2482
|
-
// on this callback to do actual sending.
|
|
2483
|
-
const contents = this.documentsSchemaController.maybeSendSchemaMessage();
|
|
2484
|
-
if (contents) {
|
|
2485
|
-
this.logger.sendTelemetryEvent({
|
|
2486
|
-
eventName: "SchemaChangeProposal",
|
|
2487
|
-
refSeq: contents.refSeq,
|
|
2488
|
-
version: contents.version,
|
|
2489
|
-
newRuntimeSchema: JSON.stringify(contents.runtime),
|
|
2490
|
-
sessionRuntimeSchema: JSON.stringify(this.sessionSchema),
|
|
2491
|
-
oldRuntimeSchema: JSON.stringify(this.metadata?.documentSchema?.runtime),
|
|
2492
|
-
});
|
|
2493
|
-
const msg = {
|
|
2494
|
-
type: messageTypes_js_1.ContainerMessageType.DocumentSchemaChange,
|
|
2495
|
-
contents,
|
|
2496
|
-
};
|
|
2497
|
-
this.outbox.submit({
|
|
2498
|
-
contents: JSON.stringify(msg),
|
|
2499
|
-
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2500
|
-
});
|
|
2501
|
-
}
|
|
2502
|
-
if (type === messageTypes_js_1.ContainerMessageType.BlobAttach) {
|
|
2503
|
-
// BlobAttach ops must have their metadata visible and cannot be grouped (see opGroupingManager.ts)
|
|
2504
|
-
this.outbox.submitBlobAttach(message);
|
|
2505
|
-
}
|
|
2506
|
-
else {
|
|
2507
|
-
this.outbox.submit(message);
|
|
2508
|
-
}
|
|
2519
|
+
this.outbox.submit(message);
|
|
2509
2520
|
}
|
|
2510
2521
|
if (!this.currentlyBatching()) {
|
|
2511
2522
|
this.flush();
|
|
@@ -2605,11 +2616,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2605
2616
|
this.channelCollection.reSubmit(message.type, message.contents, localOpMetadata);
|
|
2606
2617
|
break;
|
|
2607
2618
|
case messageTypes_js_1.ContainerMessageType.IdAllocation: {
|
|
2608
|
-
|
|
2619
|
+
// Allocation ops are never resubmitted/rebased. This is because they require special handling to
|
|
2620
|
+
// avoid being submitted out of order. For example, if the pending state manager contained
|
|
2621
|
+
// [idOp1, dataOp1, idOp2, dataOp2] and the resubmission of dataOp1 generated idOp3, that would be
|
|
2622
|
+
// placed into the outbox in the same batch as idOp1, but before idOp2 is resubmitted.
|
|
2623
|
+
// To avoid this, allocation ops are simply never resubmitted. Prior to invoking the pending state
|
|
2624
|
+
// manager to replay pending ops, the runtime will always submit a new allocation range that includes
|
|
2625
|
+
// all pending IDs. The resubmitted allocation ops are then ignored here.
|
|
2609
2626
|
break;
|
|
2610
2627
|
}
|
|
2611
|
-
case messageTypes_js_1.ContainerMessageType.ChunkedOp:
|
|
2612
|
-
throw new Error(`chunkedOp not expected here`);
|
|
2613
2628
|
case messageTypes_js_1.ContainerMessageType.BlobAttach:
|
|
2614
2629
|
this.blobManager.reSubmit(opMetadata);
|
|
2615
2630
|
break;
|
|
@@ -2636,7 +2651,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2636
2651
|
});
|
|
2637
2652
|
}
|
|
2638
2653
|
else {
|
|
2639
|
-
const error = internal_7.DataProcessingError.create("Resubmitting runtime message of
|
|
2654
|
+
const error = internal_7.DataProcessingError.create("Resubmitting runtime message of unexpected type", "reSubmitCore", undefined /* sequencedMessage */, {
|
|
2640
2655
|
messageDetails: JSON.stringify({
|
|
2641
2656
|
type: message.type,
|
|
2642
2657
|
compatBehavior,
|
|
@@ -2676,51 +2691,23 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2676
2691
|
* and then close as the current main client is likely to be re-elected as the parent summarizer again.
|
|
2677
2692
|
*/
|
|
2678
2693
|
if (!result.isSummaryTracked && result.isSummaryNewer) {
|
|
2679
|
-
await this.
|
|
2694
|
+
await this.fetchLatestSnapshotAndClose(summaryLogger, {
|
|
2680
2695
|
eventName: "RefreshLatestSummaryAckFetch",
|
|
2681
2696
|
ackHandle,
|
|
2682
2697
|
targetSequenceNumber: summaryRefSeq,
|
|
2683
2698
|
}, readAndParseBlob);
|
|
2684
|
-
await this.closeStaleSummarizer();
|
|
2685
2699
|
return;
|
|
2686
2700
|
}
|
|
2687
2701
|
// Notify the garbage collector so it can update its latest summary state.
|
|
2688
2702
|
await this.garbageCollector.refreshLatestSummary(result);
|
|
2689
2703
|
}
|
|
2690
2704
|
/**
|
|
2691
|
-
* Fetches the latest snapshot from storage
|
|
2692
|
-
*
|
|
2693
|
-
*
|
|
2694
|
-
* @returns a generic summarization error
|
|
2705
|
+
* Fetches the latest snapshot from storage and closes the container. This is done in cases where
|
|
2706
|
+
* the last known snapshot is older than the latest one. This will ensure that the latest snapshot
|
|
2707
|
+
* is downloaded and we don't end up loading snapshot from cache.
|
|
2695
2708
|
*/
|
|
2696
|
-
async
|
|
2697
|
-
|
|
2698
|
-
// This is a performance optimization as the same parent is likely to be elected again, and would use its
|
|
2699
|
-
// cache to fetch the snapshot instead of the network.
|
|
2700
|
-
await this.fetchLatestSnapshotFromStorage(summaryLogger, {
|
|
2701
|
-
eventName: "RefreshLatestSummaryFromServerFetch",
|
|
2702
|
-
}, readAndParseBlob);
|
|
2703
|
-
await this.closeStaleSummarizer();
|
|
2704
|
-
return {
|
|
2705
|
-
stage: "base",
|
|
2706
|
-
error: new internal_7.LoggingError("summary state stale - Unsupported option 'refreshLatestAck'"),
|
|
2707
|
-
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
2708
|
-
minimumSequenceNumber: this.deltaManager.minimumSequenceNumber,
|
|
2709
|
-
};
|
|
2710
|
-
}
|
|
2711
|
-
async closeStaleSummarizer() {
|
|
2712
|
-
// Delay before restarting summarizer to prevent the summarizer from restarting too frequently.
|
|
2713
|
-
await (0, internal_2.delay)(this.closeSummarizerDelayMs);
|
|
2714
|
-
this._summarizer?.stop("latestSummaryStateStale");
|
|
2715
|
-
this.disposeFn();
|
|
2716
|
-
}
|
|
2717
|
-
/**
|
|
2718
|
-
* Downloads the latest snapshot from storage.
|
|
2719
|
-
* By default, it also closes the container after downloading the snapshot. However, this may be
|
|
2720
|
-
* overridden via options.
|
|
2721
|
-
*/
|
|
2722
|
-
async fetchLatestSnapshotFromStorage(logger, event, readAndParseBlob) {
|
|
2723
|
-
return internal_7.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
|
|
2709
|
+
async fetchLatestSnapshotAndClose(logger, event, readAndParseBlob) {
|
|
2710
|
+
await internal_7.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
|
|
2724
2711
|
const stats = {};
|
|
2725
2712
|
const trace = client_utils_1.Trace.start();
|
|
2726
2713
|
const versions = await this.storage.getVersions(null, 1, "prefetchLatestSummaryBeforeClose", internal_3.FetchSource.noCache);
|
|
@@ -2733,12 +2720,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2733
2720
|
stats.snapshotRefSeq = latestSnapshotRefSeq;
|
|
2734
2721
|
stats.snapshotVersion = versions[0].id;
|
|
2735
2722
|
perfEvent.end(stats);
|
|
2736
|
-
return {
|
|
2737
|
-
snapshotTree: maybeSnapshot,
|
|
2738
|
-
versionId: versions[0].id,
|
|
2739
|
-
latestSnapshotRefSeq,
|
|
2740
|
-
};
|
|
2741
2723
|
});
|
|
2724
|
+
await (0, internal_2.delay)(this.closeSummarizerDelayMs);
|
|
2725
|
+
this._summarizer?.stop("latestSummaryStateStale");
|
|
2726
|
+
this.disposeFn();
|
|
2742
2727
|
}
|
|
2743
2728
|
getPendingLocalState(props) {
|
|
2744
2729
|
this.verifyNotClosed();
|