@fluidframework/container-runtime 2.13.0 → 2.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +71 -5
- package/CHANGELOG.md +84 -0
- package/api-report/container-runtime.legacy.alpha.api.md +38 -232
- package/dist/batchTracker.d.ts +1 -2
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager/blobManager.d.ts +5 -1
- package/dist/blobManager/blobManager.d.ts.map +1 -1
- package/dist/blobManager/blobManager.js +30 -13
- package/dist/blobManager/blobManager.js.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.d.ts +1 -0
- package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.js +7 -5
- package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
- package/dist/channelCollection.d.ts +23 -12
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +85 -53
- 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 +10 -6
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerHandleContext.d.ts +1 -1
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +87 -94
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +312 -226
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts +7 -3
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +8 -4
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +41 -25
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +47 -29
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +6 -2
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +7 -2
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.d.ts +1 -1
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/deltaManagerProxies.d.ts +1 -17
- package/dist/deltaManagerProxies.d.ts.map +1 -1
- package/dist/deltaManagerProxies.js.map +1 -1
- package/dist/deltaScheduler.d.ts +9 -6
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +95 -89
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +21 -7
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +48 -19
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts +11 -0
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +5 -2
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +218 -70
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +40 -13
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +6 -2
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +14 -7
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
- package/dist/gc/gcSummaryDefinitions.d.ts +18 -6
- package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -1
- package/dist/gc/gcSummaryDefinitions.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +2 -1
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +33 -11
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +35 -17
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.d.ts +42 -13
- package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.js +27 -9
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/dist/gc/index.d.ts +1 -0
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +3 -1
- package/dist/gc/index.js.map +1 -1
- package/dist/inboundBatchAggregator.d.ts +34 -0
- package/dist/inboundBatchAggregator.d.ts.map +1 -0
- package/dist/inboundBatchAggregator.js +185 -0
- package/dist/inboundBatchAggregator.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/layerCompatState.d.ts +19 -0
- package/dist/layerCompatState.d.ts.map +1 -0
- package/dist/layerCompatState.js +64 -0
- package/dist/layerCompatState.js.map +1 -0
- package/dist/legacy.d.ts +0 -4
- package/dist/messageTypes.d.ts +14 -5
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js.map +1 -1
- package/dist/metadata.d.ts +12 -4
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +6 -2
- package/dist/metadata.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +9 -3
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +3 -1
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/duplicateBatchDetector.d.ts +9 -3
- package/dist/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
- package/dist/opLifecycle/duplicateBatchDetector.js +11 -5
- package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts +3 -2
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +13 -19
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +6 -1
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +16 -8
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +1 -2
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +9 -6
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +13 -10
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +16 -11
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +4 -4
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +17 -16
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +9 -3
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +3 -1
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/package.json +2 -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 +22 -11
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +24 -15
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/summary/documentSchema.d.ts +7 -0
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js +8 -4
- 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 +94 -31
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +28 -16
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -0
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js +7 -2
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +17 -6
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +48 -19
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +10 -5
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +26 -11
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js +1 -0
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.d.ts +6 -2
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summary/summarizerHeuristics.js +13 -5
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/index.d.ts.map +1 -1
- package/dist/summary/summarizerNode/index.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +24 -8
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +45 -36
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +48 -16
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js +3 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +13 -5
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +15 -7
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +253 -135
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +3 -4
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +10 -8
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +28 -9
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +3 -2
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +9 -3
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +22 -9
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +8 -4
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +20 -9
- package/dist/summary/summaryManager.js.map +1 -1
- package/dist/throttler.d.ts +26 -10
- package/dist/throttler.d.ts.map +1 -1
- package/dist/throttler.js +12 -4
- package/dist/throttler.js.map +1 -1
- package/lib/batchTracker.d.ts +1 -2
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +2 -2
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager/blobManager.d.ts +5 -1
- package/lib/blobManager/blobManager.d.ts.map +1 -1
- package/lib/blobManager/blobManager.js +30 -13
- package/lib/blobManager/blobManager.js.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.d.ts +1 -0
- package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.js +7 -5
- package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
- package/lib/channelCollection.d.ts +23 -12
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +88 -54
- 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 +11 -7
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerHandleContext.d.ts +1 -1
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +87 -94
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +319 -228
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts +7 -3
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +8 -4
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +41 -25
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +47 -29
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +6 -2
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +7 -2
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.d.ts +1 -1
- package/lib/dataStoreRegistry.d.ts.map +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/deltaManagerProxies.d.ts +1 -17
- package/lib/deltaManagerProxies.d.ts.map +1 -1
- package/lib/deltaManagerProxies.js.map +1 -1
- package/lib/deltaScheduler.d.ts +9 -6
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +96 -90
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +21 -7
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +51 -20
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts +11 -0
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +4 -2
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +218 -70
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +40 -13
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +6 -2
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +14 -7
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -1
- package/lib/gc/gcSummaryDefinitions.d.ts +18 -6
- package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -1
- package/lib/gc/gcSummaryDefinitions.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +2 -1
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +33 -11
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +38 -18
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.d.ts +42 -13
- package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js +27 -9
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/lib/gc/index.d.ts +1 -0
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -0
- package/lib/gc/index.js.map +1 -1
- package/lib/inboundBatchAggregator.d.ts +34 -0
- package/lib/inboundBatchAggregator.d.ts.map +1 -0
- package/lib/inboundBatchAggregator.js +181 -0
- package/lib/inboundBatchAggregator.js.map +1 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/layerCompatState.d.ts +19 -0
- package/lib/layerCompatState.d.ts.map +1 -0
- package/lib/layerCompatState.js +60 -0
- package/lib/layerCompatState.js.map +1 -0
- package/lib/legacy.d.ts +0 -4
- package/lib/messageTypes.d.ts +14 -5
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js.map +1 -1
- package/lib/metadata.d.ts +12 -4
- package/lib/metadata.d.ts.map +1 -1
- package/lib/metadata.js +6 -2
- package/lib/metadata.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +9 -3
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +3 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/duplicateBatchDetector.d.ts +9 -3
- package/lib/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
- package/lib/opLifecycle/duplicateBatchDetector.js +11 -5
- package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts +3 -2
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +14 -20
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +6 -1
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +17 -9
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +1 -2
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +10 -7
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +13 -10
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +16 -11
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +4 -4
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +17 -16
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +9 -3
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +3 -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 +22 -11
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +25 -16
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/summary/documentSchema.d.ts +7 -0
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js +8 -4
- 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 +94 -31
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +28 -16
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -0
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js +7 -2
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +17 -6
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +48 -19
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +10 -5
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +26 -11
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js +1 -0
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.d.ts +6 -2
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summary/summarizerHeuristics.js +13 -5
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/index.d.ts.map +1 -1
- package/lib/summary/summarizerNode/index.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +24 -8
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +45 -36
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +48 -16
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js +3 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +13 -5
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +15 -7
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +253 -135
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +3 -4
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +10 -8
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +28 -9
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +2 -2
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +9 -3
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +22 -9
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +8 -4
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +20 -9
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/throttler.d.ts +26 -10
- package/lib/throttler.d.ts.map +1 -1
- package/lib/throttler.js +12 -4
- package/lib/throttler.js.map +1 -1
- package/package.json +22 -31
- package/src/batchTracker.ts +34 -36
- package/src/blobManager/blobManager.ts +54 -33
- package/src/blobManager/blobManagerSnapSum.ts +10 -10
- package/src/channelCollection.ts +108 -82
- package/src/connectionTelemetry.ts +43 -19
- package/src/containerHandleContext.ts +2 -2
- package/src/containerRuntime.ts +492 -364
- package/src/dataStore.ts +17 -9
- package/src/dataStoreContext.ts +94 -73
- package/src/dataStoreContexts.ts +17 -12
- package/src/dataStoreRegistry.ts +1 -1
- package/src/deltaManagerProxies.ts +5 -5
- package/src/deltaScheduler.ts +24 -18
- package/src/gc/garbageCollection.ts +89 -40
- package/src/gc/gcConfigs.ts +13 -5
- package/src/gc/gcDefinitions.ts +224 -70
- package/src/gc/gcHelpers.ts +22 -11
- package/src/gc/gcReferenceGraphAlgorithm.ts +1 -1
- package/src/gc/gcSummaryDefinitions.ts +18 -6
- package/src/gc/gcSummaryStateTracker.ts +7 -3
- package/src/gc/gcTelemetry.ts +73 -30
- package/src/gc/gcUnreferencedStateTracker.ts +40 -16
- package/src/gc/index.ts +1 -0
- package/src/{scheduleManager.ts → inboundBatchAggregator.ts} +55 -122
- package/src/index.ts +0 -3
- package/src/layerCompatState.ts +75 -0
- package/src/messageTypes.ts +16 -5
- package/src/metadata.ts +12 -4
- package/src/opLifecycle/README.md +43 -34
- package/src/opLifecycle/batchManager.ts +12 -6
- package/src/opLifecycle/duplicateBatchDetector.ts +12 -6
- package/src/opLifecycle/opCompressor.ts +22 -25
- package/src/opLifecycle/opDecompressor.ts +23 -11
- package/src/opLifecycle/opGroupingManager.ts +16 -11
- package/src/opLifecycle/opSplitter.ts +24 -18
- package/src/opLifecycle/outbox.ts +35 -33
- package/src/opLifecycle/remoteMessageProcessor.ts +13 -5
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +49 -26
- package/src/summary/documentSchema.ts +41 -22
- package/src/summary/index.ts +0 -3
- package/src/summary/orderedClientElection.ts +114 -49
- package/src/summary/runWhileConnectedCoordinator.ts +12 -3
- package/src/summary/runningSummarizer.ts +79 -36
- package/src/summary/summarizer.ts +51 -25
- package/src/summary/summarizerClientElection.ts +4 -2
- package/src/summary/summarizerHeuristics.ts +23 -12
- package/src/summary/summarizerNode/index.ts +1 -0
- package/src/summary/summarizerNode/summarizerNode.ts +54 -43
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +48 -16
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +25 -15
- package/src/summary/summarizerTypes.ts +253 -139
- package/src/summary/summaryCollection.ts +41 -31
- package/src/summary/summaryFormat.ts +34 -13
- package/src/summary/summaryGenerator.ts +39 -18
- package/src/summary/summaryManager.ts +36 -24
- package/src/throttler.ts +23 -11
- package/container-runtime.test-files.tar +0 -0
- package/dist/scheduleManager.d.ts +0 -28
- package/dist/scheduleManager.d.ts.map +0 -1
- package/dist/scheduleManager.js +0 -233
- package/dist/scheduleManager.js.map +0 -1
- package/lib/scheduleManager.d.ts +0 -28
- package/lib/scheduleManager.d.ts.map +0 -1
- package/lib/scheduleManager.js +0 -229
- package/lib/scheduleManager.js.map +0 -1
package/lib/containerRuntime.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { Trace, TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
5
|
+
import { Trace, TypedEventEmitter, } from "@fluid-internal/client-utils";
|
|
6
6
|
import { AttachState, } from "@fluidframework/container-definitions";
|
|
7
7
|
import { LoaderHeader, isIDeltaManagerFull, } from "@fluidframework/container-definitions/internal";
|
|
8
8
|
import { assert, Deferred, LazyPromise, PromiseCache, delay, } from "@fluidframework/core-utils/internal";
|
|
@@ -23,13 +23,21 @@ import { ContainerFluidHandleContext } from "./containerHandleContext.js";
|
|
|
23
23
|
import { channelToDataStore } from "./dataStore.js";
|
|
24
24
|
import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
|
|
25
25
|
import { DeltaManagerPendingOpsProxy, DeltaManagerSummarizerProxy, } from "./deltaManagerProxies.js";
|
|
26
|
-
import {
|
|
26
|
+
import { DeltaScheduler } from "./deltaScheduler.js";
|
|
27
|
+
import {
|
|
28
|
+
// eslint-disable-next-line import/no-deprecated
|
|
29
|
+
GCNodeType, GarbageCollector, gcGenerationOptionName, } from "./gc/index.js";
|
|
30
|
+
import { InboundBatchAggregator } from "./inboundBatchAggregator.js";
|
|
31
|
+
import { RuntimeCompatDetails, validateLoaderCompatibility } from "./layerCompatState.js";
|
|
27
32
|
import { ContainerMessageType, } from "./messageTypes.js";
|
|
28
33
|
import { DuplicateBatchDetector, ensureContentsDeserialized, OpCompressor, OpDecompressor, OpGroupingManager, OpSplitter, Outbox, RemoteMessageProcessor, serializeOpContents, } from "./opLifecycle/index.js";
|
|
29
34
|
import { pkgVersion } from "./packageVersion.js";
|
|
30
35
|
import { PendingStateManager, } from "./pendingStateManager.js";
|
|
31
|
-
import {
|
|
32
|
-
|
|
36
|
+
import {
|
|
37
|
+
// eslint-disable-next-line import/no-deprecated
|
|
38
|
+
DocumentsSchemaController, OrderedClientCollection, OrderedClientElection, RetriableSummaryError, RunWhileConnectedCoordinator,
|
|
39
|
+
// eslint-disable-next-line import/no-deprecated
|
|
40
|
+
Summarizer, SummarizerClientElection, SummaryCollection, SummaryManager, aliasBlobName, chunksBlobName, recentBatchInfoBlobName, createRootSummarizerNodeWithGC, electedSummarizerBlobName, extractSummaryMetadataMessage, idCompressorBlobName, metadataBlobName, rootHasIsolatedChannels, summarizerClientType, wrapSummaryInChannelsTree, } from "./summary/index.js";
|
|
33
41
|
import { Throttler, formExponentialFn } from "./throttler.js";
|
|
34
42
|
/**
|
|
35
43
|
* Creates an error object to be thrown / passed to Container's close fn in case of an unknown message type.
|
|
@@ -50,6 +58,9 @@ function getUnknownMessageTypeError(unknownContainerRuntimeMessageType, codePath
|
|
|
50
58
|
},
|
|
51
59
|
});
|
|
52
60
|
}
|
|
61
|
+
export function isSummariesDisabled(config) {
|
|
62
|
+
return config.state === "disabled";
|
|
63
|
+
}
|
|
53
64
|
/**
|
|
54
65
|
* @legacy
|
|
55
66
|
* @alpha
|
|
@@ -65,13 +76,14 @@ export const DefaultSummaryConfiguration = {
|
|
|
65
76
|
maxOpsSinceLastSummary: 7000,
|
|
66
77
|
initialSummarizerDelayMs: 5 * 1000, // 5 secs.
|
|
67
78
|
nonRuntimeOpWeight: 0.1,
|
|
68
|
-
runtimeOpWeight: 1
|
|
79
|
+
runtimeOpWeight: 1,
|
|
69
80
|
nonRuntimeHeuristicThreshold: 20,
|
|
70
81
|
};
|
|
71
82
|
/**
|
|
72
83
|
* Error responses when requesting a deleted object will have this header set to true
|
|
73
84
|
* @legacy
|
|
74
85
|
* @alpha
|
|
86
|
+
* @deprecated This type will be moved to internal in 2.30. External usage is not necessary or supported.
|
|
75
87
|
*/
|
|
76
88
|
export const DeletedResponseHeaderKey = "wasDeleted";
|
|
77
89
|
/**
|
|
@@ -89,7 +101,9 @@ export const TombstoneResponseHeaderKey = "isTombstoned";
|
|
|
89
101
|
* to this was experimental and is no longer supported.
|
|
90
102
|
*/
|
|
91
103
|
export const InactiveResponseHeaderKey = "isInactive";
|
|
92
|
-
/**
|
|
104
|
+
/**
|
|
105
|
+
* Default values for Runtime Headers
|
|
106
|
+
*/
|
|
93
107
|
export const defaultRuntimeHeaderData = {
|
|
94
108
|
wait: true,
|
|
95
109
|
viaHandle: false,
|
|
@@ -109,7 +123,7 @@ export var CompressionAlgorithms;
|
|
|
109
123
|
* @alpha
|
|
110
124
|
*/
|
|
111
125
|
export const disabledCompressionConfig = {
|
|
112
|
-
minimumBatchSizeInBytes:
|
|
126
|
+
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
|
|
113
127
|
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
114
128
|
};
|
|
115
129
|
const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
|
|
@@ -125,9 +139,13 @@ const defaultCompressionConfig = {
|
|
|
125
139
|
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
126
140
|
};
|
|
127
141
|
const defaultChunkSizeInBytes = 204800;
|
|
128
|
-
/**
|
|
142
|
+
/**
|
|
143
|
+
* The default time to wait for pending ops to be processed during summarization
|
|
144
|
+
*/
|
|
129
145
|
export const defaultPendingOpsWaitTimeoutMs = 1000;
|
|
130
|
-
/**
|
|
146
|
+
/**
|
|
147
|
+
* The default time to delay a summarization retry attempt when there are pending ops
|
|
148
|
+
*/
|
|
131
149
|
export const defaultPendingOpsRetryDelayMs = 1000;
|
|
132
150
|
/**
|
|
133
151
|
* Instead of refreshing from latest because we do not have 100% confidence in the state
|
|
@@ -153,12 +171,15 @@ export function getDeviceSpec() {
|
|
|
153
171
|
try {
|
|
154
172
|
if (typeof navigator === "object" && navigator !== null) {
|
|
155
173
|
return {
|
|
174
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
|
156
175
|
deviceMemory: navigator.deviceMemory,
|
|
157
176
|
hardwareConcurrency: navigator.hardwareConcurrency,
|
|
158
177
|
};
|
|
159
178
|
}
|
|
160
179
|
}
|
|
161
|
-
catch {
|
|
180
|
+
catch {
|
|
181
|
+
// Eat the error
|
|
182
|
+
}
|
|
162
183
|
return {};
|
|
163
184
|
}
|
|
164
185
|
/**
|
|
@@ -199,18 +220,20 @@ async function createSummarizer(loader, url) {
|
|
|
199
220
|
let fluidObject;
|
|
200
221
|
// Older containers may not have the "getEntryPoint" API
|
|
201
222
|
// ! This check will need to stay until LTS of loader moves past 2.0.0-internal.7.0.0
|
|
202
|
-
if (resolvedContainer.getEntryPoint
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
else {
|
|
206
|
-
const response = await resolvedContainer.request({
|
|
223
|
+
if (resolvedContainer.getEntryPoint === undefined) {
|
|
224
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any
|
|
225
|
+
const response = (await resolvedContainer.request({
|
|
207
226
|
url: `/${summarizerRequestUrl}`,
|
|
208
|
-
});
|
|
227
|
+
}));
|
|
209
228
|
if (response.status !== 200 || response.mimeType !== "fluid/object") {
|
|
210
229
|
throw responseToException(response, request);
|
|
211
230
|
}
|
|
231
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
212
232
|
fluidObject = response.value;
|
|
213
233
|
}
|
|
234
|
+
else {
|
|
235
|
+
fluidObject = await resolvedContainer.getEntryPoint();
|
|
236
|
+
}
|
|
214
237
|
if (fluidObject?.ISummarizer === undefined) {
|
|
215
238
|
throw new UsageError("Fluid object does not implement ISummarizer");
|
|
216
239
|
}
|
|
@@ -222,7 +245,9 @@ async function createSummarizer(loader, url) {
|
|
|
222
245
|
* This allows new runtime to make documents not openable for old runtimes, one explicit document schema control is enabled.
|
|
223
246
|
* Please see addMetadataToSummary() as well
|
|
224
247
|
*/
|
|
225
|
-
function lastMessageFromMetadata(
|
|
248
|
+
function lastMessageFromMetadata(
|
|
249
|
+
// eslint-disable-next-line import/no-deprecated
|
|
250
|
+
metadata) {
|
|
226
251
|
return metadata?.documentSchema?.runtime?.explicitSchemaControl
|
|
227
252
|
? metadata?.lastMessage
|
|
228
253
|
: metadata?.message;
|
|
@@ -239,6 +264,7 @@ export let getSingleUseLegacyLogCallback = (logger, type) => {
|
|
|
239
264
|
details: { codePath, type },
|
|
240
265
|
});
|
|
241
266
|
// Now that we've logged, prevent future logging (globally).
|
|
267
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
242
268
|
getSingleUseLegacyLogCallback = () => () => { };
|
|
243
269
|
};
|
|
244
270
|
};
|
|
@@ -252,15 +278,13 @@ export let getSingleUseLegacyLogCallback = (logger, type) => {
|
|
|
252
278
|
export async function loadContainerRuntime(params) {
|
|
253
279
|
return ContainerRuntime.loadRuntime(params);
|
|
254
280
|
}
|
|
281
|
+
const defaultMaxConsecutiveReconnects = 7;
|
|
282
|
+
const defaultTelemetrySignalSampleCount = 100;
|
|
255
283
|
/**
|
|
256
284
|
* Represents the runtime of the container. Contains helper functions/state of the container.
|
|
257
285
|
* It will define the store level mappings.
|
|
258
286
|
*
|
|
259
|
-
* @
|
|
260
|
-
* Use the loadContainerRuntime function and interfaces IContainerRuntime / IRuntime instead.
|
|
261
|
-
*
|
|
262
|
-
* @legacy
|
|
263
|
-
* @alpha
|
|
287
|
+
* @internal
|
|
264
288
|
*/
|
|
265
289
|
export class ContainerRuntime extends TypedEventEmitter {
|
|
266
290
|
/**
|
|
@@ -295,7 +319,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
295
319
|
},
|
|
296
320
|
});
|
|
297
321
|
const mc = loggerToMonitoringContext(logger);
|
|
298
|
-
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions =
|
|
322
|
+
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = runtimeOptions.enableGroupedBatching === false
|
|
323
|
+
? disabledCompressionConfig // Compression must be disabled if Grouping is disabled
|
|
324
|
+
: defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes, enableGroupedBatching = true, explicitSchemaControl = false, } = runtimeOptions;
|
|
299
325
|
const registry = new FluidDataStoreRegistry(registryEntries);
|
|
300
326
|
const tryFetchBlob = async (blobName) => {
|
|
301
327
|
const blobId = context.baseSnapshot?.blobs[blobName];
|
|
@@ -309,7 +335,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
309
335
|
const [chunks, recentBatchInfo, metadata, electedSummarizerData, aliases, serializedIdCompressor,] = await Promise.all([
|
|
310
336
|
tryFetchBlob(chunksBlobName),
|
|
311
337
|
tryFetchBlob(recentBatchInfoBlobName),
|
|
338
|
+
// eslint-disable-next-line import/no-deprecated
|
|
312
339
|
tryFetchBlob(metadataBlobName),
|
|
340
|
+
// eslint-disable-next-line import/no-deprecated
|
|
313
341
|
tryFetchBlob(electedSummarizerBlobName),
|
|
314
342
|
tryFetchBlob(aliasBlobName),
|
|
315
343
|
tryFetchBlob(idCompressorBlobName),
|
|
@@ -323,6 +351,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
323
351
|
// When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
|
|
324
352
|
if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
|
|
325
353
|
// Unless bypass is explicitly set, then take action when sequence numbers mismatch.
|
|
354
|
+
// eslint-disable-next-line unicorn/no-lonely-if -- Separate if statements make flow easier to parse
|
|
326
355
|
if (loadSequenceNumberVerification !== "bypass" &&
|
|
327
356
|
runtimeSequenceNumber !== protocolSequenceNumber) {
|
|
328
357
|
// Message to OCEs:
|
|
@@ -345,15 +374,18 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
345
374
|
}
|
|
346
375
|
let desiredIdCompressorMode;
|
|
347
376
|
switch (mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) {
|
|
348
|
-
case true:
|
|
377
|
+
case true: {
|
|
349
378
|
desiredIdCompressorMode = "on";
|
|
350
379
|
break;
|
|
351
|
-
|
|
380
|
+
}
|
|
381
|
+
case false: {
|
|
352
382
|
desiredIdCompressorMode = undefined;
|
|
353
383
|
break;
|
|
354
|
-
|
|
384
|
+
}
|
|
385
|
+
default: {
|
|
355
386
|
desiredIdCompressorMode = enableRuntimeIdCompressor;
|
|
356
387
|
break;
|
|
388
|
+
}
|
|
357
389
|
}
|
|
358
390
|
// Enabling the IdCompressor is a one-way operation and we only want to
|
|
359
391
|
// allow new containers to turn it on.
|
|
@@ -406,15 +438,16 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
406
438
|
if (pendingLocalState?.pendingIdCompressorState !== undefined) {
|
|
407
439
|
return deserializeIdCompressor(pendingLocalState.pendingIdCompressorState, compressorLogger);
|
|
408
440
|
}
|
|
409
|
-
else if (serializedIdCompressor
|
|
410
|
-
return
|
|
441
|
+
else if (serializedIdCompressor === undefined) {
|
|
442
|
+
return createIdCompressor(compressorLogger);
|
|
411
443
|
}
|
|
412
444
|
else {
|
|
413
|
-
return
|
|
445
|
+
return deserializeIdCompressor(serializedIdCompressor, createSessionId(), compressorLogger);
|
|
414
446
|
}
|
|
415
447
|
};
|
|
416
|
-
const compressionLz4 = compressionOptions.minimumBatchSizeInBytes !==
|
|
448
|
+
const compressionLz4 = compressionOptions.minimumBatchSizeInBytes !== Number.POSITIVE_INFINITY &&
|
|
417
449
|
compressionOptions.compressionAlgorithm === "lz4";
|
|
450
|
+
// eslint-disable-next-line import/no-deprecated
|
|
418
451
|
const documentSchemaController = new DocumentsSchemaController(existing, protocolSequenceNumber, metadata?.documentSchema, {
|
|
419
452
|
explicitSchemaControl,
|
|
420
453
|
compressionLz4,
|
|
@@ -424,6 +457,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
424
457
|
}, (schema) => {
|
|
425
458
|
runtime.onSchemaChange(schema);
|
|
426
459
|
});
|
|
460
|
+
if (compressionLz4 && !enableGroupedBatching) {
|
|
461
|
+
throw new UsageError("If compression is enabled, op grouping must be enabled too");
|
|
462
|
+
}
|
|
427
463
|
const featureGatesForTelemetry = {};
|
|
428
464
|
// Make sure we've got all the options including internal ones
|
|
429
465
|
const internalRuntimeOptions = {
|
|
@@ -484,29 +520,26 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
484
520
|
* has to deal with compressed ops as other clients might send them.
|
|
485
521
|
* And in reverse, session schema can have compression Off, but feature gates / runtime options want it On.
|
|
486
522
|
* In such case it will be off in session schema, however this client will propose change to schema, and once / if
|
|
487
|
-
* this op
|
|
523
|
+
* this op roundtrips, compression will be On. Client can't send compressed ops until it's change in schema.
|
|
488
524
|
*/
|
|
489
525
|
get sessionSchema() {
|
|
490
526
|
return this.documentsSchemaController.sessionSchema.runtime;
|
|
491
527
|
}
|
|
492
|
-
get idCompressorMode() {
|
|
493
|
-
return this.sessionSchema.idCompressorMode;
|
|
494
|
-
}
|
|
495
528
|
/**
|
|
496
|
-
*
|
|
529
|
+
* {@inheritDoc @fluidframework/runtime-definitions#IContainerRuntimeBase.idCompressor}
|
|
497
530
|
*/
|
|
498
531
|
get idCompressor() {
|
|
499
532
|
// Expose ID Compressor only if it's On from the start.
|
|
500
533
|
// If container uses delayed mode, then we can only expose generateDocumentUniqueId() and nothing else.
|
|
501
534
|
// That's because any other usage will require immidiate loading of ID Compressor in next sessions in order
|
|
502
535
|
// to reason over such things as session ID space.
|
|
503
|
-
if (this.idCompressorMode === "on") {
|
|
536
|
+
if (this.sessionSchema.idCompressorMode === "on") {
|
|
504
537
|
assert(this._idCompressor !== undefined, 0x8ea /* compressor should have been loaded */);
|
|
505
538
|
return this._idCompressor;
|
|
506
539
|
}
|
|
507
540
|
}
|
|
508
541
|
/**
|
|
509
|
-
*
|
|
542
|
+
* {@inheritDoc @fluidframework/runtime-definitions#IContainerRuntimeBase.generateDocumentUniqueId}
|
|
510
543
|
*/
|
|
511
544
|
generateDocumentUniqueId() {
|
|
512
545
|
return this._idCompressor?.generateDocumentUniqueId() ?? uuid();
|
|
@@ -542,35 +575,15 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
542
575
|
get connected() {
|
|
543
576
|
return this._connected;
|
|
544
577
|
}
|
|
545
|
-
/**
|
|
578
|
+
/**
|
|
579
|
+
* clientId of parent (non-summarizing) container that owns summarizer container
|
|
580
|
+
*/
|
|
546
581
|
get summarizerClientId() {
|
|
547
582
|
return this.summarizerClientElection?.electedClientId;
|
|
548
583
|
}
|
|
549
584
|
get disposed() {
|
|
550
585
|
return this._disposed;
|
|
551
586
|
}
|
|
552
|
-
get summarizer() {
|
|
553
|
-
assert(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
|
|
554
|
-
return this._summarizer;
|
|
555
|
-
}
|
|
556
|
-
isSummariesDisabled() {
|
|
557
|
-
return this.summaryConfiguration.state === "disabled";
|
|
558
|
-
}
|
|
559
|
-
getMaxOpsSinceLastSummary() {
|
|
560
|
-
return this.summaryConfiguration.state !== "disabled"
|
|
561
|
-
? this.summaryConfiguration.maxOpsSinceLastSummary
|
|
562
|
-
: 0;
|
|
563
|
-
}
|
|
564
|
-
getInitialSummarizerDelayMs() {
|
|
565
|
-
// back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
|
|
566
|
-
// to ISummaryConfiguration in 0.60.
|
|
567
|
-
if (this.runtimeOptions.summaryOptions.initialSummarizerDelayMs !== undefined) {
|
|
568
|
-
return this.runtimeOptions.summaryOptions.initialSummarizerDelayMs;
|
|
569
|
-
}
|
|
570
|
-
return this.summaryConfiguration.state !== "disabled"
|
|
571
|
-
? this.summaryConfiguration.initialSummarizerDelayMs
|
|
572
|
-
: 0;
|
|
573
|
-
}
|
|
574
587
|
/**
|
|
575
588
|
* If false, loading or using a Tombstoned object should merely log, not fail.
|
|
576
589
|
* @deprecated NOT SUPPORTED - hardcoded to return false since it's deprecated.
|
|
@@ -587,14 +600,27 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
587
600
|
get gcThrowOnTombstoneUsage() {
|
|
588
601
|
return false;
|
|
589
602
|
}
|
|
603
|
+
get ILayerCompatDetails() {
|
|
604
|
+
return RuntimeCompatDetails;
|
|
605
|
+
}
|
|
590
606
|
/***/
|
|
591
|
-
constructor(context, registry,
|
|
607
|
+
constructor(context, registry,
|
|
608
|
+
// eslint-disable-next-line import/no-deprecated
|
|
609
|
+
metadata,
|
|
610
|
+
// eslint-disable-next-line import/no-deprecated
|
|
611
|
+
electedSummarizerData, chunks, dataStoreAliasMap, baseRuntimeOptions, containerScope,
|
|
592
612
|
// Create a custom ITelemetryBaseLogger to output telemetry events.
|
|
593
|
-
baseLogger, existing,
|
|
613
|
+
baseLogger, existing,
|
|
614
|
+
// eslint-disable-next-line import/no-deprecated
|
|
615
|
+
blobManagerSnapshot, _storage, createIdCompressor,
|
|
616
|
+
// eslint-disable-next-line import/no-deprecated
|
|
617
|
+
documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler,
|
|
618
|
+
// eslint-disable-next-line unicorn/no-object-as-default-parameter
|
|
619
|
+
summaryConfiguration = {
|
|
594
620
|
// the defaults
|
|
595
621
|
...DefaultSummaryConfiguration,
|
|
596
622
|
// the runtime configuration overrides
|
|
597
|
-
...
|
|
623
|
+
...baseRuntimeOptions.summaryOptions?.summaryConfigOverrides,
|
|
598
624
|
}, recentBatchInfo) {
|
|
599
625
|
super();
|
|
600
626
|
this.registry = registry;
|
|
@@ -605,19 +631,16 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
605
631
|
this.createIdCompressor = createIdCompressor;
|
|
606
632
|
this.documentsSchemaController = documentsSchemaController;
|
|
607
633
|
this.requestHandler = requestHandler;
|
|
608
|
-
this.summaryConfiguration = summaryConfiguration;
|
|
609
634
|
this.imminentClosure = false;
|
|
610
635
|
// We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
|
|
611
636
|
// Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
|
|
612
637
|
this.pendingIdCompressorOps = [];
|
|
613
|
-
this.defaultMaxConsecutiveReconnects = 7;
|
|
614
638
|
this._orderSequentiallyCalls = 0;
|
|
615
639
|
this.flushTaskExists = false;
|
|
616
640
|
this.consecutiveReconnects = 0;
|
|
617
641
|
this.ensureNoDataModelChangesCalls = 0;
|
|
618
642
|
this._disposed = false;
|
|
619
643
|
this.emitDirtyDocumentEvent = true;
|
|
620
|
-
this.defaultTelemetrySignalSampleCount = 100;
|
|
621
644
|
this._signalTracking = {
|
|
622
645
|
totalSignalsSentInLatencyWindow: 0,
|
|
623
646
|
signalsLost: 0,
|
|
@@ -636,16 +659,19 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
636
659
|
this.snapshotCacheForLoadingGroupIds = new PromiseCache({
|
|
637
660
|
expiry: { policy: "absolute", durationMs: 60000 },
|
|
638
661
|
});
|
|
662
|
+
this.readAndParseBlob = async (id) => readAndParse(this.storage, id);
|
|
639
663
|
const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, snapshotWithContents, } = context;
|
|
664
|
+
// In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
|
|
665
|
+
this.disposeFn = disposeFn ?? closeFn;
|
|
666
|
+
const maybeLoaderCompatDetails = context;
|
|
667
|
+
validateLoaderCompatibility(maybeLoaderCompatDetails.ILayerCompatDetails, this.disposeFn);
|
|
640
668
|
// Backfill in defaults for the internal runtimeOptions, since they may not be present on the provided runtimeOptions object
|
|
641
|
-
|
|
669
|
+
const runtimeOptions = {
|
|
642
670
|
flushMode: defaultFlushMode,
|
|
643
|
-
|
|
644
|
-
...runtimeOptions,
|
|
671
|
+
...baseRuntimeOptions,
|
|
645
672
|
};
|
|
646
|
-
this.logger = createChildLogger({ logger: this.baseLogger });
|
|
647
673
|
this.mc = createChildMonitoringContext({
|
|
648
|
-
logger: this.
|
|
674
|
+
logger: this.baseLogger,
|
|
649
675
|
namespace: "ContainerRuntime",
|
|
650
676
|
});
|
|
651
677
|
// If we support multiple algorithms in the future, then we would need to manage it here carefully.
|
|
@@ -662,19 +688,23 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
662
688
|
this.innerDeltaManager = deltaManager;
|
|
663
689
|
// Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
|
|
664
690
|
// This makes ContainerRuntime the final gatekeeper for outgoing messages.
|
|
665
|
-
this
|
|
666
|
-
this.
|
|
667
|
-
|
|
691
|
+
// back-compat: ADO #1385: Make this call unconditional in the future
|
|
692
|
+
this.submitSummaryFn =
|
|
693
|
+
submitSummaryFn ??
|
|
694
|
+
((summaryOp, refseq) => submitFn(MessageType.Summarize, summaryOp, false));
|
|
668
695
|
this.submitSignalFn = submitSignalFn;
|
|
669
696
|
// TODO: After IContainerContext.options is removed, we'll just create a new blank object {} here.
|
|
670
697
|
// Values are generally expected to be set from the runtime side.
|
|
671
698
|
this.options = options ?? {};
|
|
672
699
|
this.clientDetails = clientDetails;
|
|
673
|
-
|
|
700
|
+
const isSummarizerClient = this.clientDetails.type === summarizerClientType;
|
|
674
701
|
this.loadedFromVersionId = context.getLoadedFromVersion()?.id;
|
|
702
|
+
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
675
703
|
this._getClientId = () => context.clientId;
|
|
704
|
+
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
676
705
|
this._getAttachState = () => context.attachState;
|
|
677
706
|
this.getAbsoluteUrl = async (relativeUrl) => {
|
|
707
|
+
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
678
708
|
if (context.getAbsoluteUrl === undefined) {
|
|
679
709
|
throw new Error("Driver does not implement getAbsoluteUrl");
|
|
680
710
|
}
|
|
@@ -687,10 +717,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
687
717
|
// customer should observe dirty state on the runtime (the owner of dirty state) directly, rather than on the IContainer.
|
|
688
718
|
this.on("dirty", () => context.updateDirtyContainerState(true));
|
|
689
719
|
this.on("saved", () => context.updateDirtyContainerState(false));
|
|
690
|
-
// In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
|
|
691
|
-
this.disposeFn = disposeFn ?? closeFn;
|
|
692
720
|
// In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
|
|
693
|
-
this.closeFn =
|
|
721
|
+
this.closeFn = isSummarizerClient ? this.disposeFn : closeFn;
|
|
694
722
|
let loadSummaryNumber;
|
|
695
723
|
// Get the container creation metadata. For new container, we initialize these. For existing containers,
|
|
696
724
|
// get the values from the metadata blob.
|
|
@@ -719,18 +747,15 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
719
747
|
eventName: "GCFeatureMatrix",
|
|
720
748
|
metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
|
|
721
749
|
inputs: JSON.stringify({
|
|
722
|
-
|
|
750
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
751
|
+
gcOptions_gcGeneration: runtimeOptions.gcOptions[gcGenerationOptionName],
|
|
723
752
|
}),
|
|
724
753
|
});
|
|
725
754
|
this.telemetryDocumentId = metadata?.telemetryDocumentId ?? uuid();
|
|
726
|
-
this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
|
|
727
755
|
const opGroupingManager = new OpGroupingManager({
|
|
728
756
|
groupedBatchingEnabled: this.groupedBatchingEnabled,
|
|
729
|
-
opCountThreshold: this.mc.config.getNumber("Fluid.ContainerRuntime.GroupedBatchingOpCount") ?? 2,
|
|
730
|
-
reentrantBatchGroupingEnabled: this.mc.config.getBoolean("Fluid.ContainerRuntime.GroupedBatchingReentrancy") ??
|
|
731
|
-
true,
|
|
732
757
|
}, this.mc.logger);
|
|
733
|
-
const opSplitter = new OpSplitter(chunks,
|
|
758
|
+
const opSplitter = new OpSplitter(chunks, submitBatchFn, runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
|
|
734
759
|
this.remoteMessageProcessor = new RemoteMessageProcessor(opSplitter, new OpDecompressor(this.mc.logger), opGroupingManager);
|
|
735
760
|
const pendingRuntimeState = pendingLocalState;
|
|
736
761
|
this.pendingStateManager = new PendingStateManager({
|
|
@@ -740,7 +765,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
740
765
|
reSubmitBatch: this.reSubmitBatch.bind(this),
|
|
741
766
|
isActiveConnection: () => this.innerDeltaManager.active,
|
|
742
767
|
isAttached: () => this.attachState !== AttachState.Detached,
|
|
743
|
-
}, pendingRuntimeState?.pending, this.
|
|
768
|
+
}, pendingRuntimeState?.pending, this.baseLogger);
|
|
744
769
|
let outerDeltaManager;
|
|
745
770
|
this.useDeltaManagerOpsProxy =
|
|
746
771
|
this.mc.config.getBoolean("Fluid.ContainerRuntime.DeltaManagerOpsProxy") === true;
|
|
@@ -755,24 +780,35 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
755
780
|
}
|
|
756
781
|
this._deltaManager = outerDeltaManager;
|
|
757
782
|
this.handleContext = new ContainerFluidHandleContext("", this);
|
|
758
|
-
if (
|
|
759
|
-
this.validateSummaryHeuristicConfiguration(
|
|
760
|
-
}
|
|
761
|
-
this.summariesDisabled =
|
|
762
|
-
|
|
763
|
-
|
|
783
|
+
if (summaryConfiguration.state === "enabled") {
|
|
784
|
+
this.validateSummaryHeuristicConfiguration(summaryConfiguration);
|
|
785
|
+
}
|
|
786
|
+
this.summariesDisabled = isSummariesDisabled(summaryConfiguration);
|
|
787
|
+
const { maxOpsSinceLastSummary = 0, initialSummarizerDelayMs = 0 } = isSummariesDisabled(summaryConfiguration)
|
|
788
|
+
? {}
|
|
789
|
+
: {
|
|
790
|
+
...summaryConfiguration,
|
|
791
|
+
initialSummarizerDelayMs:
|
|
792
|
+
// back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
|
|
793
|
+
// to ISummaryConfiguration in 0.60.
|
|
794
|
+
runtimeOptions.summaryOptions.initialSummarizerDelayMs ??
|
|
795
|
+
summaryConfiguration.initialSummarizerDelayMs,
|
|
796
|
+
};
|
|
764
797
|
this.maxConsecutiveReconnects =
|
|
765
|
-
this.mc.config.getNumber(maxConsecutiveReconnectsKey) ??
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
supportedFeatures?.get("referenceSequenceNumbers")
|
|
798
|
+
this.mc.config.getNumber(maxConsecutiveReconnectsKey) ?? defaultMaxConsecutiveReconnects;
|
|
799
|
+
// If the context has ILayerCompatDetails, it supports referenceSequenceNumbers since that features
|
|
800
|
+
// predates ILayerCompatDetails.
|
|
801
|
+
const referenceSequenceNumbersSupported = maybeLoaderCompatDetails.ILayerCompatDetails === undefined
|
|
802
|
+
? supportedFeatures?.get("referenceSequenceNumbers") === true
|
|
803
|
+
: true;
|
|
804
|
+
if (runtimeOptions.flushMode === FlushModeExperimental.Async &&
|
|
805
|
+
!referenceSequenceNumbersSupported) {
|
|
770
806
|
// The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
|
|
771
807
|
this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
|
|
772
808
|
this._flushMode = FlushMode.TurnBased;
|
|
773
809
|
}
|
|
774
810
|
else {
|
|
775
|
-
this._flushMode =
|
|
811
|
+
this._flushMode = runtimeOptions.flushMode;
|
|
776
812
|
}
|
|
777
813
|
this.offlineEnabled =
|
|
778
814
|
this.mc.config.getBoolean("Fluid.Container.enableOfflineLoad") ?? false;
|
|
@@ -787,6 +823,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
787
823
|
if (this.offlineEnabled) {
|
|
788
824
|
this.duplicateBatchDetector = new DuplicateBatchDetector(recentBatchInfo);
|
|
789
825
|
}
|
|
826
|
+
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
790
827
|
if (context.attachState === AttachState.Attached) {
|
|
791
828
|
const maxSnapshotCacheDurationMs = this._storage?.policies?.maximumCacheDurationMs;
|
|
792
829
|
if (maxSnapshotCacheDurationMs !== undefined &&
|
|
@@ -799,13 +836,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
799
836
|
}
|
|
800
837
|
this.garbageCollector = GarbageCollector.create({
|
|
801
838
|
runtime: this,
|
|
802
|
-
gcOptions:
|
|
839
|
+
gcOptions: runtimeOptions.gcOptions,
|
|
803
840
|
baseSnapshot,
|
|
804
841
|
baseLogger: this.mc.logger,
|
|
805
842
|
existing,
|
|
806
843
|
metadata,
|
|
807
844
|
createContainerMetadata: this.createContainerMetadata,
|
|
808
|
-
isSummarizerClient
|
|
845
|
+
isSummarizerClient,
|
|
809
846
|
getNodePackagePath: async (nodePath) => this.getGCNodePackagePath(nodePath),
|
|
810
847
|
getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
|
|
811
848
|
readAndParseBlob: async (id) => readAndParse(this.storage, id),
|
|
@@ -819,7 +856,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
819
856
|
const summaryReferenceSequenceNumber = baseSnapshot === undefined || metadata?.disableIsolatedChannels === true
|
|
820
857
|
? undefined
|
|
821
858
|
: loadedFromSequenceNumber;
|
|
822
|
-
this.summarizerNode = createRootSummarizerNodeWithGC(createChildLogger({ logger: this.
|
|
859
|
+
this.summarizerNode = createRootSummarizerNodeWithGC(createChildLogger({ logger: this.baseLogger, namespace: "SummarizerNode" }),
|
|
823
860
|
// Summarize function to call when summarize is called. Summarizer node always tracks summary state.
|
|
824
861
|
async (fullTree, trackState, telemetryContext) => this.summarizeInternal(fullTree, trackState, telemetryContext),
|
|
825
862
|
// Latest change sequence number, no changes since summary applied yet
|
|
@@ -879,13 +916,14 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
879
916
|
stashedBlobs: pendingRuntimeState?.pendingAttachmentBlobs,
|
|
880
917
|
closeContainer: (error) => this.closeFn(error),
|
|
881
918
|
});
|
|
882
|
-
this.
|
|
919
|
+
this.deltaScheduler = new DeltaScheduler(this.innerDeltaManager, this, createChildLogger({ logger: this.baseLogger, namespace: "DeltaScheduler" }));
|
|
920
|
+
this.inboundBatchAggregator = new InboundBatchAggregator(this.innerDeltaManager, () => this.clientId, createChildLogger({ logger: this.baseLogger, namespace: "InboundBatchAggregator" }));
|
|
883
921
|
const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
|
|
884
|
-
const legacySendBatchFn = makeLegacySendBatchFn(
|
|
922
|
+
const legacySendBatchFn = makeLegacySendBatchFn(submitFn, this.innerDeltaManager);
|
|
885
923
|
this.outbox = new Outbox({
|
|
886
924
|
shouldSend: () => this.canSendOps(),
|
|
887
925
|
pendingStateManager: this.pendingStateManager,
|
|
888
|
-
submitBatchFn
|
|
926
|
+
submitBatchFn,
|
|
889
927
|
legacySendBatchFn,
|
|
890
928
|
compressor: new OpCompressor(this.mc.logger),
|
|
891
929
|
splitter: opSplitter,
|
|
@@ -932,7 +970,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
932
970
|
const closeSummarizerDelayOverride = this.mc.config.getNumber("Fluid.ContainerRuntime.Test.CloseSummarizerDelayOverrideMs");
|
|
933
971
|
this.closeSummarizerDelayMs =
|
|
934
972
|
closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
|
|
935
|
-
|
|
973
|
+
const summaryCollection = new SummaryCollection(this.deltaManager, this.baseLogger);
|
|
936
974
|
this.dirtyContainer =
|
|
937
975
|
this.attachState !== AttachState.Attached || this.hasPendingMessages();
|
|
938
976
|
context.updateDirtyContainerState(this.dirtyContainer);
|
|
@@ -941,14 +979,17 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
941
979
|
}
|
|
942
980
|
else {
|
|
943
981
|
const orderedClientLogger = createChildLogger({
|
|
944
|
-
logger: this.
|
|
982
|
+
logger: this.baseLogger,
|
|
945
983
|
namespace: "OrderedClientElection",
|
|
946
984
|
});
|
|
947
985
|
const orderedClientCollection = new OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
|
|
948
986
|
const orderedClientElectionForSummarizer = new OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, SummarizerClientElection.isClientEligible, this.mc.config.getBoolean("Fluid.ContainerRuntime.OrderedClientElection.EnablePerformanceEvents"));
|
|
949
|
-
this.summarizerClientElection = new SummarizerClientElection(orderedClientLogger,
|
|
950
|
-
if (
|
|
951
|
-
|
|
987
|
+
this.summarizerClientElection = new SummarizerClientElection(orderedClientLogger, summaryCollection, orderedClientElectionForSummarizer, maxOpsSinceLastSummary);
|
|
988
|
+
if (isSummarizerClient) {
|
|
989
|
+
// eslint-disable-next-line import/no-deprecated
|
|
990
|
+
this._summarizer = new Summarizer(this /* ISummarizerRuntime */, () => summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, summaryCollection,
|
|
991
|
+
// eslint-disable-next-line import/no-deprecated
|
|
992
|
+
async (runtime) => RunWhileConnectedCoordinator.create(runtime,
|
|
952
993
|
// Summarization runs in summarizer client and needs access to the real (non-proxy) active
|
|
953
994
|
// information. The proxy delta manager would always return false for summarizer client.
|
|
954
995
|
() => this.innerDeltaManager.active));
|
|
@@ -957,48 +998,49 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
957
998
|
// Only create a SummaryManager and SummarizerClientElection
|
|
958
999
|
// if summaries are enabled and we are not the summarizer client.
|
|
959
1000
|
const defaultAction = () => {
|
|
960
|
-
if (
|
|
1001
|
+
if (summaryCollection.opsSinceLastAck > maxOpsSinceLastSummary) {
|
|
961
1002
|
this.mc.logger.sendTelemetryEvent({ eventName: "SummaryStatus:Behind" });
|
|
962
1003
|
// unregister default to no log on every op after falling behind
|
|
963
1004
|
// and register summary ack handler to re-register this handler
|
|
964
1005
|
// after successful summary
|
|
965
|
-
|
|
1006
|
+
summaryCollection.once(MessageType.SummaryAck, () => {
|
|
966
1007
|
this.mc.logger.sendTelemetryEvent({
|
|
967
1008
|
eventName: "SummaryStatus:CaughtUp",
|
|
968
1009
|
});
|
|
969
1010
|
// we've caught up, so re-register the default action to monitor for
|
|
970
1011
|
// falling behind, and unregister ourself
|
|
971
|
-
|
|
1012
|
+
summaryCollection.on("default", defaultAction);
|
|
972
1013
|
});
|
|
973
|
-
|
|
1014
|
+
summaryCollection.off("default", defaultAction);
|
|
974
1015
|
}
|
|
975
1016
|
};
|
|
976
|
-
|
|
1017
|
+
summaryCollection.on("default", defaultAction);
|
|
977
1018
|
// Create the SummaryManager and mark the initial state
|
|
978
1019
|
this.summaryManager = new SummaryManager(this.summarizerClientElection, this, // IConnectedState
|
|
979
|
-
|
|
1020
|
+
summaryCollection, this.baseLogger, this.formCreateSummarizerFn(loader), new Throttler(60 * 1000, // 60 sec delay window
|
|
980
1021
|
30 * 1000, // 30 sec max delay
|
|
981
1022
|
// throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
|
|
982
1023
|
formExponentialFn({ coefficient: 20, initialDelay: 0 })), {
|
|
983
|
-
initialDelayMs:
|
|
1024
|
+
initialDelayMs: initialSummarizerDelayMs,
|
|
984
1025
|
});
|
|
985
1026
|
// Forward events from SummaryManager
|
|
986
|
-
[
|
|
1027
|
+
for (const eventName of [
|
|
987
1028
|
"summarize",
|
|
988
1029
|
"summarizeAllAttemptsFailed",
|
|
989
1030
|
"summarizerStop",
|
|
990
1031
|
"summarizerStart",
|
|
991
1032
|
"summarizerStartupFailed",
|
|
992
|
-
]
|
|
1033
|
+
]) {
|
|
993
1034
|
this.summaryManager?.on(eventName, (...args) => {
|
|
994
1035
|
this.emit(eventName, ...args);
|
|
995
1036
|
});
|
|
996
|
-
}
|
|
1037
|
+
}
|
|
997
1038
|
this.summaryManager.start();
|
|
998
1039
|
}
|
|
999
1040
|
}
|
|
1000
1041
|
// logging hardware telemetry
|
|
1001
|
-
this.
|
|
1042
|
+
this.baseLogger.send({
|
|
1043
|
+
category: "generic",
|
|
1002
1044
|
eventName: "DeviceSpec",
|
|
1003
1045
|
...getDeviceSpec(),
|
|
1004
1046
|
});
|
|
@@ -1010,13 +1052,12 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1010
1052
|
summaryFormatVersion: metadata?.summaryFormatVersion,
|
|
1011
1053
|
disableIsolatedChannels: metadata?.disableIsolatedChannels,
|
|
1012
1054
|
gcVersion: metadata?.gcFeature,
|
|
1013
|
-
options: JSON.stringify(
|
|
1055
|
+
options: JSON.stringify(baseRuntimeOptions),
|
|
1014
1056
|
idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
|
|
1015
|
-
idCompressorMode: this.idCompressorMode,
|
|
1057
|
+
idCompressorMode: this.sessionSchema.idCompressorMode,
|
|
1016
1058
|
sessionRuntimeSchema: JSON.stringify(this.sessionSchema),
|
|
1017
1059
|
featureGates: JSON.stringify({
|
|
1018
1060
|
...featureGatesForTelemetry,
|
|
1019
|
-
disableAttachReorder: this.disableAttachReorder,
|
|
1020
1061
|
disablePartialFlush,
|
|
1021
1062
|
closeSummarizerDelayOverride,
|
|
1022
1063
|
}),
|
|
@@ -1024,11 +1065,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1024
1065
|
groupedBatchingEnabled: this.groupedBatchingEnabled,
|
|
1025
1066
|
initialSequenceNumber: this.deltaManager.initialSequenceNumber,
|
|
1026
1067
|
});
|
|
1027
|
-
ReportOpPerfTelemetry(this.clientId, this._deltaManager, this, this.
|
|
1028
|
-
BindBatchTracker(this, this.
|
|
1068
|
+
ReportOpPerfTelemetry(this.clientId, this._deltaManager, this, this.baseLogger);
|
|
1069
|
+
BindBatchTracker(this, this.baseLogger);
|
|
1029
1070
|
this.entryPoint = new LazyPromise(async () => {
|
|
1030
|
-
if (this.
|
|
1031
|
-
assert(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
|
|
1071
|
+
if (this._summarizer !== undefined) {
|
|
1032
1072
|
return this._summarizer;
|
|
1033
1073
|
}
|
|
1034
1074
|
return provideEntryPoint(this);
|
|
@@ -1037,8 +1077,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1037
1077
|
// saved state, i.e. all the ops marked by Loader layer sa savedOp === true.
|
|
1038
1078
|
this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
|
|
1039
1079
|
}
|
|
1080
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1040
1081
|
onSchemaChange(schema) {
|
|
1041
|
-
this.logger.sendTelemetryEvent({
|
|
1082
|
+
this.mc.logger.sendTelemetryEvent({
|
|
1042
1083
|
eventName: "SchemaChangeAccept",
|
|
1043
1084
|
sessionRuntimeSchema: JSON.stringify(schema),
|
|
1044
1085
|
});
|
|
@@ -1061,19 +1102,20 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1061
1102
|
deleteChildSummarizerNode(id) {
|
|
1062
1103
|
return this.summarizerNode.deleteChild(id);
|
|
1063
1104
|
}
|
|
1064
|
-
|
|
1105
|
+
// #region `IFluidParentContext` APIs that should not be called on Root
|
|
1065
1106
|
makeLocallyVisible() {
|
|
1066
1107
|
assert(false, 0x8eb /* should not be called */);
|
|
1067
1108
|
}
|
|
1068
1109
|
setChannelDirty(address) {
|
|
1069
1110
|
assert(false, 0x909 /* should not be called */);
|
|
1070
1111
|
}
|
|
1112
|
+
// #endregion
|
|
1071
1113
|
/**
|
|
1072
1114
|
* Initializes the state from the base snapshot this container runtime loaded from.
|
|
1073
1115
|
*/
|
|
1074
1116
|
async initializeBaseState() {
|
|
1075
|
-
if (this.idCompressorMode === "on" ||
|
|
1076
|
-
(this.idCompressorMode === "delayed" && this.connected)) {
|
|
1117
|
+
if (this.sessionSchema.idCompressorMode === "on" ||
|
|
1118
|
+
(this.sessionSchema.idCompressorMode === "delayed" && this.connected)) {
|
|
1077
1119
|
this._idCompressor = await this.createIdCompressor();
|
|
1078
1120
|
// This is called from loadRuntime(), long before we process any ops, so there should be no ops accumulated yet.
|
|
1079
1121
|
assert(this.pendingIdCompressorOps.length === 0, 0x8ec /* no pending ops */);
|
|
@@ -1098,6 +1140,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1098
1140
|
this._summarizer?.dispose();
|
|
1099
1141
|
this.channelCollection.dispose();
|
|
1100
1142
|
this.pendingStateManager.dispose();
|
|
1143
|
+
this.inboundBatchAggregator.dispose();
|
|
1144
|
+
this.deltaScheduler.dispose();
|
|
1101
1145
|
this.emit("dispose");
|
|
1102
1146
|
this.removeAllListeners();
|
|
1103
1147
|
}
|
|
@@ -1114,7 +1158,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1114
1158
|
// Lookup up in the cache, if not present then make the network call as multiple datastores could
|
|
1115
1159
|
// be in same loading group. So, once we have fetched the snapshot for that loading group on
|
|
1116
1160
|
// any request, then cache that as same group could be requested in future too.
|
|
1117
|
-
const snapshot = await this.snapshotCacheForLoadingGroupIds.addOrGet(sortedLoadingGroupIds.join(), async () => {
|
|
1161
|
+
const snapshot = await this.snapshotCacheForLoadingGroupIds.addOrGet(sortedLoadingGroupIds.join(","), async () => {
|
|
1118
1162
|
assert(this.storage.getSnapshot !== undefined, 0x8ee /* getSnapshot api should be defined if used */);
|
|
1119
1163
|
loadedFromCache = false;
|
|
1120
1164
|
return this.storage.getSnapshot({
|
|
@@ -1123,7 +1167,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1123
1167
|
loadingGroupIds: sortedLoadingGroupIds,
|
|
1124
1168
|
});
|
|
1125
1169
|
});
|
|
1126
|
-
this.logger.sendTelemetryEvent({
|
|
1170
|
+
this.mc.logger.sendTelemetryEvent({
|
|
1127
1171
|
eventName: "GroupIdSnapshotFetched",
|
|
1128
1172
|
details: JSON.stringify({
|
|
1129
1173
|
fromCache: loadedFromCache,
|
|
@@ -1153,7 +1197,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1153
1197
|
// another snapshot from which the summarizer loaded and it is behind, then just give up as
|
|
1154
1198
|
// the summarizer state is not up to date.
|
|
1155
1199
|
// This should be a recoverable scenario and shouldn't happen as we should process the ack first.
|
|
1156
|
-
if (this.
|
|
1200
|
+
if (this._summarizer !== undefined) {
|
|
1157
1201
|
throw new Error("Summarizer client behind, loaded newer snapshot with loadingGroupId");
|
|
1158
1202
|
}
|
|
1159
1203
|
// We want to catchup from sequenceNumber to targetSequenceNumber
|
|
@@ -1215,7 +1259,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1215
1259
|
return {
|
|
1216
1260
|
status: 200,
|
|
1217
1261
|
mimeType: "fluid/object",
|
|
1218
|
-
value: this.
|
|
1262
|
+
value: this._summarizer,
|
|
1219
1263
|
};
|
|
1220
1264
|
}
|
|
1221
1265
|
return create404Response(request);
|
|
@@ -1270,7 +1314,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1270
1314
|
internalId(maybeAlias) {
|
|
1271
1315
|
return this.channelCollection.internalId(maybeAlias);
|
|
1272
1316
|
}
|
|
1273
|
-
/**
|
|
1317
|
+
/**
|
|
1318
|
+
* Adds the container's metadata to the given summary tree.
|
|
1319
|
+
*/
|
|
1274
1320
|
addMetadataToSummary(summaryTree) {
|
|
1275
1321
|
// The last message processed at the time of summary. If there are no new messages, use the message from the
|
|
1276
1322
|
// last summary.
|
|
@@ -1279,6 +1325,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1279
1325
|
const documentSchema = this.documentsSchemaController.summarizeDocumentSchema(this.deltaManager.lastSequenceNumber);
|
|
1280
1326
|
// Is document schema explicit control on?
|
|
1281
1327
|
const explicitSchemaControl = documentSchema?.runtime.explicitSchemaControl;
|
|
1328
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1282
1329
|
const metadata = {
|
|
1283
1330
|
...this.createContainerMetadata,
|
|
1284
1331
|
// Increment the summary number for the next summary that will be generated.
|
|
@@ -1292,7 +1339,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1292
1339
|
// last message's sequence number.
|
|
1293
1340
|
// See also lastMessageFromMetadata()
|
|
1294
1341
|
message: explicitSchemaControl
|
|
1295
|
-
?
|
|
1342
|
+
? // eslint-disable-next-line import/no-deprecated
|
|
1343
|
+
{ sequenceNumber: -1 }
|
|
1296
1344
|
: message,
|
|
1297
1345
|
lastMessage: explicitSchemaControl ? message : undefined,
|
|
1298
1346
|
documentSchema,
|
|
@@ -1408,9 +1456,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1408
1456
|
switch (opContents.type) {
|
|
1409
1457
|
case ContainerMessageType.FluidDataStoreOp:
|
|
1410
1458
|
case ContainerMessageType.Attach:
|
|
1411
|
-
case ContainerMessageType.Alias:
|
|
1459
|
+
case ContainerMessageType.Alias: {
|
|
1412
1460
|
return this.channelCollection.applyStashedOp(opContents);
|
|
1413
|
-
|
|
1461
|
+
}
|
|
1462
|
+
case ContainerMessageType.IdAllocation: {
|
|
1414
1463
|
// IDs allocation ops in stashed state are ignored because the tip state of the compressor
|
|
1415
1464
|
// is serialized into the pending state. This is done because generation of new IDs during
|
|
1416
1465
|
// stashed op application (or, later, resubmit) must generate new IDs and if the compressor
|
|
@@ -1420,17 +1469,22 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1420
1469
|
// and the runtime could filter out all ID allocation ops from the stashed state and apply them
|
|
1421
1470
|
// before applying the rest of the stashed ops. This would accomplish the same thing but with
|
|
1422
1471
|
// better performance in future incremental stashed state creation.
|
|
1423
|
-
assert(this.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
|
|
1472
|
+
assert(this.sessionSchema.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
|
|
1424
1473
|
return;
|
|
1425
|
-
|
|
1474
|
+
}
|
|
1475
|
+
case ContainerMessageType.DocumentSchemaChange: {
|
|
1426
1476
|
return;
|
|
1427
|
-
|
|
1477
|
+
}
|
|
1478
|
+
case ContainerMessageType.BlobAttach: {
|
|
1428
1479
|
return;
|
|
1429
|
-
|
|
1480
|
+
}
|
|
1481
|
+
case ContainerMessageType.Rejoin: {
|
|
1430
1482
|
throw new Error("rejoin not expected here");
|
|
1431
|
-
|
|
1483
|
+
}
|
|
1484
|
+
case ContainerMessageType.GC: {
|
|
1432
1485
|
// GC op is only sent in summarizer which should never have stashed ops.
|
|
1433
1486
|
throw new LoggingError("GC op not expected to be stashed in summarizer");
|
|
1487
|
+
}
|
|
1434
1488
|
default: {
|
|
1435
1489
|
const error = getUnknownMessageTypeError(opContents.type, "applyStashedOp" /* codePath */);
|
|
1436
1490
|
this.closeFn(error);
|
|
@@ -1440,7 +1494,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1440
1494
|
}
|
|
1441
1495
|
async loadIdCompressor() {
|
|
1442
1496
|
if (this._idCompressor === undefined &&
|
|
1443
|
-
this.idCompressorMode !== undefined &&
|
|
1497
|
+
this.sessionSchema.idCompressorMode !== undefined &&
|
|
1444
1498
|
this._loadIdCompressor === undefined) {
|
|
1445
1499
|
this._loadIdCompressor = this.createIdCompressor()
|
|
1446
1500
|
.then((compressor) => {
|
|
@@ -1454,7 +1508,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1454
1508
|
this._idCompressor = compressor;
|
|
1455
1509
|
})
|
|
1456
1510
|
.catch((error) => {
|
|
1457
|
-
this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
|
|
1511
|
+
this.mc.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
|
|
1458
1512
|
throw error;
|
|
1459
1513
|
});
|
|
1460
1514
|
}
|
|
@@ -1465,7 +1519,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1465
1519
|
const currentClientId = this._audience.getSelf()?.clientId;
|
|
1466
1520
|
assert(clientId === currentClientId, 0x977 /* input clientId does not match Audience */);
|
|
1467
1521
|
assert(this.clientId === currentClientId, 0x978 /* this.clientId does not match Audience */);
|
|
1468
|
-
if (connected && this.idCompressorMode === "delayed") {
|
|
1522
|
+
if (connected && this.sessionSchema.idCompressorMode === "delayed") {
|
|
1469
1523
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1470
1524
|
this.loadIdCompressor();
|
|
1471
1525
|
}
|
|
@@ -1554,7 +1608,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1554
1608
|
// or something different, like a system message.
|
|
1555
1609
|
const hasModernRuntimeMessageEnvelope = messageCopy.type === MessageType.Operation;
|
|
1556
1610
|
const savedOp = messageCopy.metadata?.savedOp;
|
|
1557
|
-
const logLegacyCase = getSingleUseLegacyLogCallback(this.logger, messageCopy.type);
|
|
1611
|
+
const logLegacyCase = getSingleUseLegacyLogCallback(this.mc.logger, messageCopy.type);
|
|
1558
1612
|
let runtimeBatch = hasModernRuntimeMessageEnvelope || isUnpackedRuntimeMessage(messageCopy);
|
|
1559
1613
|
if (runtimeBatch) {
|
|
1560
1614
|
// We expect runtime messages to have JSON contents - deserialize it in place.
|
|
@@ -1639,7 +1693,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1639
1693
|
}
|
|
1640
1694
|
}
|
|
1641
1695
|
/**
|
|
1642
|
-
* Processes inbound message(s). It calls
|
|
1696
|
+
* Processes inbound message(s). It calls delta scheduler according to the messages' location in the batch.
|
|
1643
1697
|
* @param messagesWithMetadata - messages to process along with their metadata.
|
|
1644
1698
|
* @param locationInBatch - Are we processing the start and/or end of a batch?
|
|
1645
1699
|
* @param local - true if the messages were originally generated by the client receiving it.
|
|
@@ -1651,19 +1705,19 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1651
1705
|
if (locationInBatch.batchStart) {
|
|
1652
1706
|
const firstMessage = messagesWithMetadata[0]?.message;
|
|
1653
1707
|
assert(firstMessage !== undefined, 0xa31 /* Batch must have at least one message */);
|
|
1654
|
-
this.
|
|
1708
|
+
this.emit("batchBegin", firstMessage);
|
|
1655
1709
|
}
|
|
1656
1710
|
let error;
|
|
1657
1711
|
try {
|
|
1658
1712
|
if (!runtimeBatch) {
|
|
1659
|
-
|
|
1713
|
+
for (const { message } of messagesWithMetadata) {
|
|
1660
1714
|
this.ensureNoDataModelChanges(() => {
|
|
1661
1715
|
this.observeNonRuntimeMessage(message);
|
|
1662
1716
|
});
|
|
1663
|
-
}
|
|
1717
|
+
}
|
|
1664
1718
|
return;
|
|
1665
1719
|
}
|
|
1666
|
-
//
|
|
1720
|
+
// Updates a message's minimum sequence number to the minimum sequence number that container
|
|
1667
1721
|
// runtime is tracking and sets _processedClientSequenceNumber. It returns the updated message.
|
|
1668
1722
|
const updateSequenceNumbers = (message) => {
|
|
1669
1723
|
// Set the minimum sequence number to the containerRuntime's understanding of minimum sequence number.
|
|
@@ -1694,7 +1748,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1694
1748
|
}
|
|
1695
1749
|
let bunchedMessagesContent = [];
|
|
1696
1750
|
let previousMessage;
|
|
1697
|
-
//
|
|
1751
|
+
// Process the previous bunch of messages.
|
|
1698
1752
|
const sendBunchedMessages = () => {
|
|
1699
1753
|
assert(previousMessage !== undefined, 0xa67 /* previous message must exist */);
|
|
1700
1754
|
this.ensureNoDataModelChanges(() => {
|
|
@@ -1728,15 +1782,15 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1728
1782
|
this.emit("op", message, true /* runtimeMessage */);
|
|
1729
1783
|
}
|
|
1730
1784
|
}
|
|
1731
|
-
catch (
|
|
1732
|
-
error =
|
|
1785
|
+
catch (error_) {
|
|
1786
|
+
error = error_;
|
|
1733
1787
|
throw error;
|
|
1734
1788
|
}
|
|
1735
1789
|
finally {
|
|
1736
1790
|
if (locationInBatch.batchEnd) {
|
|
1737
1791
|
const lastMessage = messagesWithMetadata[messagesWithMetadata.length - 1]?.message;
|
|
1738
1792
|
assert(lastMessage !== undefined, 0xa32 /* Batch must have at least one message */);
|
|
1739
|
-
this.
|
|
1793
|
+
this.emit("batchEnd", error, lastMessage);
|
|
1740
1794
|
}
|
|
1741
1795
|
}
|
|
1742
1796
|
}
|
|
@@ -1786,30 +1840,39 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1786
1840
|
switch (message.type) {
|
|
1787
1841
|
case ContainerMessageType.FluidDataStoreOp:
|
|
1788
1842
|
case ContainerMessageType.Attach:
|
|
1789
|
-
case ContainerMessageType.Alias:
|
|
1843
|
+
case ContainerMessageType.Alias: {
|
|
1790
1844
|
// Remove the metadata from the message before sending it to the channel collection. The metadata
|
|
1791
1845
|
// is added by the container runtime and is not part of the message that the channel collection and
|
|
1792
1846
|
// layers below it expect.
|
|
1793
1847
|
this.channelCollection.processMessages({ envelope: message, messagesContent, local });
|
|
1794
1848
|
break;
|
|
1795
|
-
|
|
1849
|
+
}
|
|
1850
|
+
case ContainerMessageType.BlobAttach: {
|
|
1796
1851
|
this.blobManager.processBlobAttachMessage(message, local);
|
|
1797
1852
|
break;
|
|
1798
|
-
|
|
1853
|
+
}
|
|
1854
|
+
case ContainerMessageType.IdAllocation: {
|
|
1799
1855
|
this.processIdCompressorMessages(contents, savedOp);
|
|
1800
1856
|
break;
|
|
1801
|
-
|
|
1857
|
+
}
|
|
1858
|
+
case ContainerMessageType.GC: {
|
|
1802
1859
|
this.garbageCollector.processMessages(contents, message.timestamp, local);
|
|
1803
1860
|
break;
|
|
1804
|
-
|
|
1861
|
+
}
|
|
1862
|
+
case ContainerMessageType.ChunkedOp: {
|
|
1805
1863
|
// From observability POV, we should not expose the rest of the system (including "op" events on object) to these messages.
|
|
1806
1864
|
// Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
|
|
1807
1865
|
assert(false, 0x93d /* should not even get here */);
|
|
1808
|
-
|
|
1866
|
+
}
|
|
1867
|
+
case ContainerMessageType.Rejoin: {
|
|
1809
1868
|
break;
|
|
1810
|
-
|
|
1811
|
-
|
|
1869
|
+
}
|
|
1870
|
+
case ContainerMessageType.DocumentSchemaChange: {
|
|
1871
|
+
this.documentsSchemaController.processDocumentSchemaMessages(
|
|
1872
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1873
|
+
contents, local, message.sequenceNumber);
|
|
1812
1874
|
break;
|
|
1875
|
+
}
|
|
1813
1876
|
default: {
|
|
1814
1877
|
const error = getUnknownMessageTypeError(message.type, "validateAndProcessRuntimeMessage" /* codePath */, message);
|
|
1815
1878
|
this.closeFn(error);
|
|
@@ -1827,7 +1890,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1827
1890
|
// Some other client turned on the id compressor. If we have not turned it on,
|
|
1828
1891
|
// put it in a pending queue and delay finalization.
|
|
1829
1892
|
if (this._idCompressor === undefined) {
|
|
1830
|
-
assert(this.idCompressorMode !== undefined, 0x93c /* id compressor should be enabled */);
|
|
1893
|
+
assert(this.sessionSchema.idCompressorMode !== undefined, 0x93c /* id compressor should be enabled */);
|
|
1831
1894
|
this.pendingIdCompressorOps.push(range);
|
|
1832
1895
|
}
|
|
1833
1896
|
else {
|
|
@@ -1861,7 +1924,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1861
1924
|
* Updates signal telemetry including emitting telemetry events.
|
|
1862
1925
|
*/
|
|
1863
1926
|
processSignalForTelemetry(envelope) {
|
|
1864
|
-
const { clientBroadcastSignalSequenceNumber } = envelope;
|
|
1927
|
+
const { clientBroadcastSignalSequenceNumber, contents: envelopeContents, address: envelopeAddress, } = envelope;
|
|
1865
1928
|
if (clientBroadcastSignalSequenceNumber === undefined) {
|
|
1866
1929
|
return;
|
|
1867
1930
|
}
|
|
@@ -1899,8 +1962,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1899
1962
|
};
|
|
1900
1963
|
// Only log `contents.type` when address is for container to avoid
|
|
1901
1964
|
// chance that contents type is customer data.
|
|
1902
|
-
if (
|
|
1903
|
-
details.contentsType =
|
|
1965
|
+
if (envelopeAddress === undefined) {
|
|
1966
|
+
details.contentsType = envelopeContents.type; // Type of signal that was received out of order.
|
|
1904
1967
|
}
|
|
1905
1968
|
this.mc.logger.sendTelemetryEvent({
|
|
1906
1969
|
eventName: "SignalOutOfOrder",
|
|
@@ -1981,8 +2044,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1981
2044
|
try {
|
|
1982
2045
|
checkpoint.rollback((message) => this.rollback(message.contents, message.localOpMetadata));
|
|
1983
2046
|
}
|
|
1984
|
-
catch (
|
|
1985
|
-
const error2 = wrapError(
|
|
2047
|
+
catch (error_) {
|
|
2048
|
+
const error2 = wrapError(error_, (message) => {
|
|
1986
2049
|
return DataProcessingError.create(`RollbackError: ${message}`, "checkpointRollback", undefined);
|
|
1987
2050
|
});
|
|
1988
2051
|
this.closeFn(error2);
|
|
@@ -2043,15 +2106,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2043
2106
|
return this.channelCollection.createDetachedDataStore(pkg, loadingGroupId);
|
|
2044
2107
|
}
|
|
2045
2108
|
async createDataStore(pkg, loadingGroupId) {
|
|
2046
|
-
const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg],
|
|
2047
|
-
loadingGroupId);
|
|
2048
|
-
return channelToDataStore(await context.realize(), context.id, this.channelCollection, this.mc.logger);
|
|
2049
|
-
}
|
|
2050
|
-
/**
|
|
2051
|
-
* @deprecated 0.16 Issue #1537, #3631
|
|
2052
|
-
*/
|
|
2053
|
-
async _createDataStoreWithProps(pkg, props) {
|
|
2054
|
-
const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], props);
|
|
2109
|
+
const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], loadingGroupId);
|
|
2055
2110
|
return channelToDataStore(await context.realize(), context.id, this.channelCollection, this.mc.logger);
|
|
2056
2111
|
}
|
|
2057
2112
|
canSendOps() {
|
|
@@ -2078,7 +2133,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2078
2133
|
get isDirty() {
|
|
2079
2134
|
return this.dirtyContainer;
|
|
2080
2135
|
}
|
|
2081
|
-
isContainerMessageDirtyable({ type, contents }) {
|
|
2136
|
+
isContainerMessageDirtyable({ type, contents, }) {
|
|
2082
2137
|
// Certain container runtime messages should not mark the container dirty such as the old built-in
|
|
2083
2138
|
// AgentScheduler and Garbage collector messages.
|
|
2084
2139
|
switch (type) {
|
|
@@ -2101,8 +2156,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2101
2156
|
case ContainerMessageType.GC: {
|
|
2102
2157
|
return false;
|
|
2103
2158
|
}
|
|
2104
|
-
default:
|
|
2159
|
+
default: {
|
|
2105
2160
|
break;
|
|
2161
|
+
}
|
|
2106
2162
|
}
|
|
2107
2163
|
return true;
|
|
2108
2164
|
}
|
|
@@ -2131,7 +2187,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2131
2187
|
clientBroadcastSignalSequenceNumber;
|
|
2132
2188
|
}
|
|
2133
2189
|
// We should not track the round trip of a new signal in the case we are already tracking one.
|
|
2134
|
-
if (clientBroadcastSignalSequenceNumber %
|
|
2190
|
+
if (clientBroadcastSignalSequenceNumber % defaultTelemetrySignalSampleCount === 1 &&
|
|
2135
2191
|
this._signalTracking.roundTripSignalSequenceNumber === undefined) {
|
|
2136
2192
|
this._signalTracking.signalTimestamp = Date.now();
|
|
2137
2193
|
this._signalTracking.roundTripSignalSequenceNumber =
|
|
@@ -2197,6 +2253,12 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2197
2253
|
this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
|
|
2198
2254
|
return summarizeResult.summary;
|
|
2199
2255
|
}
|
|
2256
|
+
/**
|
|
2257
|
+
* Builds the Summary tree including all the channels and the container state.
|
|
2258
|
+
*
|
|
2259
|
+
* @remarks - Unfortunately, this function is accessed in a non-typesafe way by a legacy first-party partner,
|
|
2260
|
+
* so until we can provide a proper API for their scenario, we need to ensure this function doesn't change.
|
|
2261
|
+
*/
|
|
2200
2262
|
async summarizeInternal(fullTree, trackState, telemetryContext) {
|
|
2201
2263
|
const summarizeResult = await this.channelCollection.summarize(fullTree, trackState, telemetryContext);
|
|
2202
2264
|
// Wrap data store summaries in .channels subtree.
|
|
@@ -2277,8 +2339,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2277
2339
|
*/
|
|
2278
2340
|
deleteSweepReadyNodes(sweepReadyRoutes) {
|
|
2279
2341
|
const { dataStoreRoutes, blobManagerRoutes } = this.getDataStoreAndBlobManagerRoutes(sweepReadyRoutes);
|
|
2280
|
-
|
|
2281
|
-
|
|
2342
|
+
return [
|
|
2343
|
+
...this.channelCollection.deleteSweepReadyNodes(dataStoreRoutes),
|
|
2344
|
+
...this.blobManager.deleteSweepReadyNodes(blobManagerRoutes),
|
|
2345
|
+
];
|
|
2282
2346
|
}
|
|
2283
2347
|
/**
|
|
2284
2348
|
* This is called to update objects that are tombstones.
|
|
@@ -2304,10 +2368,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2304
2368
|
* Returns the type of the GC node. Currently, there are nodes that belong to the root ("/"), data stores or
|
|
2305
2369
|
* blob manager.
|
|
2306
2370
|
*/
|
|
2371
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2307
2372
|
getNodeType(nodePath) {
|
|
2308
2373
|
if (isBlobPath(nodePath)) {
|
|
2374
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2309
2375
|
return GCNodeType.Blob;
|
|
2310
2376
|
}
|
|
2377
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2311
2378
|
return this.channelCollection.getGCNodeType(nodePath) ?? GCNodeType.Other;
|
|
2312
2379
|
}
|
|
2313
2380
|
/**
|
|
@@ -2321,13 +2388,19 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2321
2388
|
return ["_gcRoot"];
|
|
2322
2389
|
}
|
|
2323
2390
|
switch (this.getNodeType(nodePath)) {
|
|
2324
|
-
|
|
2391
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2392
|
+
case GCNodeType.Blob: {
|
|
2325
2393
|
return [blobManagerBasePath];
|
|
2394
|
+
}
|
|
2395
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2326
2396
|
case GCNodeType.DataStore:
|
|
2327
|
-
|
|
2397
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2398
|
+
case GCNodeType.SubDataStore: {
|
|
2328
2399
|
return this.channelCollection.getDataStorePackagePath(nodePath);
|
|
2329
|
-
|
|
2400
|
+
}
|
|
2401
|
+
default: {
|
|
2330
2402
|
assert(false, 0x2de /* "Package path requested for unsupported node type." */);
|
|
2403
|
+
}
|
|
2331
2404
|
}
|
|
2332
2405
|
}
|
|
2333
2406
|
/**
|
|
@@ -2389,8 +2462,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2389
2462
|
* op processing, updating SummarizerNode state tracking, and garbage collection.
|
|
2390
2463
|
* @param options - options controlling how the summary is generated or submitted
|
|
2391
2464
|
*/
|
|
2465
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2392
2466
|
async submitSummary(options) {
|
|
2393
|
-
const { fullTree = false, finalAttempt = false, summaryLogger, latestSummaryRefSeqNum, } = options;
|
|
2467
|
+
const { cancellationToken, fullTree = false, finalAttempt = false, summaryLogger, latestSummaryRefSeqNum, } = options;
|
|
2394
2468
|
// The summary number for this summary. This will be updated during the summary process, so get it now and
|
|
2395
2469
|
// use it for all events logged during this summary.
|
|
2396
2470
|
const summaryNumber = this.nextSummaryNumber;
|
|
@@ -2474,7 +2548,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2474
2548
|
eventName: "LatestSummaryRefSeqNumMismatch",
|
|
2475
2549
|
details: {
|
|
2476
2550
|
...startSummaryResult,
|
|
2477
|
-
mismatchNumbers:
|
|
2551
|
+
mismatchNumbers: [...startSummaryResult.mismatchNumbers],
|
|
2478
2552
|
},
|
|
2479
2553
|
});
|
|
2480
2554
|
if (shouldValidatePreSummaryState && !finalAttempt) {
|
|
@@ -2494,7 +2568,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2494
2568
|
// summarizer to reconnect in the future.
|
|
2495
2569
|
// Also checking for cancellation is a must as summary process may be abandoned for other reasons,
|
|
2496
2570
|
// like loss of connectivity for main (interactive) client.
|
|
2497
|
-
if (
|
|
2571
|
+
if (cancellationToken.cancelled) {
|
|
2498
2572
|
return { continue: false, error: "disconnected" };
|
|
2499
2573
|
}
|
|
2500
2574
|
// That said, we rely on submitSystemMessage() that today only works in connected state.
|
|
@@ -2607,7 +2681,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2607
2681
|
};
|
|
2608
2682
|
let handle;
|
|
2609
2683
|
try {
|
|
2610
|
-
handle = await this.storage.uploadSummaryWithContext(
|
|
2684
|
+
handle = await this.storage.uploadSummaryWithContext(summaryTree, summaryContext);
|
|
2611
2685
|
}
|
|
2612
2686
|
catch (error) {
|
|
2613
2687
|
return {
|
|
@@ -2729,13 +2803,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2729
2803
|
return this.pendingMessagesCount !== 0;
|
|
2730
2804
|
}
|
|
2731
2805
|
updateDocumentDirtyState(dirty) {
|
|
2732
|
-
if (this.attachState
|
|
2733
|
-
assert(dirty, 0x3d2 /* Non-attached container is dirty */);
|
|
2734
|
-
}
|
|
2735
|
-
else {
|
|
2806
|
+
if (this.attachState === AttachState.Attached) {
|
|
2736
2807
|
// Other way is not true = see this.isContainerMessageDirtyable()
|
|
2737
2808
|
assert(!dirty || this.hasPendingMessages(), 0x3d3 /* if doc is dirty, there has to be pending ops */);
|
|
2738
2809
|
}
|
|
2810
|
+
else {
|
|
2811
|
+
assert(dirty, 0x3d2 /* Non-attached container is dirty */);
|
|
2812
|
+
}
|
|
2739
2813
|
if (this.dirtyContainer === dirty) {
|
|
2740
2814
|
return;
|
|
2741
2815
|
}
|
|
@@ -2744,7 +2818,11 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2744
2818
|
this.emit(dirty ? "dirty" : "saved");
|
|
2745
2819
|
}
|
|
2746
2820
|
}
|
|
2747
|
-
submitMessage(type,
|
|
2821
|
+
submitMessage(type,
|
|
2822
|
+
// TODO: better typing
|
|
2823
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
|
|
2824
|
+
contents, localOpMetadata = undefined) {
|
|
2825
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
2748
2826
|
this.submit({ type, contents }, localOpMetadata);
|
|
2749
2827
|
}
|
|
2750
2828
|
async uploadBlob(blob, signal) {
|
|
@@ -2793,7 +2871,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2793
2871
|
// on this callback to do actual sending.
|
|
2794
2872
|
const schemaChangeMessage = this.documentsSchemaController.maybeSendSchemaMessage();
|
|
2795
2873
|
if (schemaChangeMessage) {
|
|
2796
|
-
this.logger.sendTelemetryEvent({
|
|
2874
|
+
this.mc.logger.sendTelemetryEvent({
|
|
2797
2875
|
eventName: "SchemaChangeProposal",
|
|
2798
2876
|
refSeq: schemaChangeMessage.refSeq,
|
|
2799
2877
|
version: schemaChangeMessage.version,
|
|
@@ -2845,6 +2923,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2845
2923
|
return;
|
|
2846
2924
|
}
|
|
2847
2925
|
this.flushTaskExists = true;
|
|
2926
|
+
// TODO: hoist this out of the function scope to save unnecessary allocations
|
|
2927
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping -- Separate `flush` method already exists in outer scope
|
|
2848
2928
|
const flush = () => {
|
|
2849
2929
|
this.flushTaskExists = false;
|
|
2850
2930
|
try {
|
|
@@ -2855,22 +2935,25 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2855
2935
|
}
|
|
2856
2936
|
};
|
|
2857
2937
|
switch (this.flushMode) {
|
|
2858
|
-
case FlushMode.TurnBased:
|
|
2938
|
+
case FlushMode.TurnBased: {
|
|
2859
2939
|
// When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
|
|
2860
2940
|
// batch at the end of the turn
|
|
2861
2941
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
2862
2942
|
Promise.resolve().then(flush);
|
|
2863
2943
|
break;
|
|
2944
|
+
}
|
|
2864
2945
|
// FlushModeExperimental is experimental and not exposed directly in the runtime APIs
|
|
2865
|
-
case FlushModeExperimental.Async:
|
|
2946
|
+
case FlushModeExperimental.Async: {
|
|
2866
2947
|
// When in Async flush mode, the runtime will accumulate all operations across JS turns and send them as a single
|
|
2867
2948
|
// batch when all micro-tasks are complete.
|
|
2868
2949
|
// Compared to TurnBased, this flush mode will capture more ops into the same batch.
|
|
2869
2950
|
setTimeout(flush, 0);
|
|
2870
2951
|
break;
|
|
2871
|
-
|
|
2952
|
+
}
|
|
2953
|
+
default: {
|
|
2872
2954
|
assert(this._orderSequentiallyCalls > 0, 0x587 /* Unreachable unless running under orderSequentially */);
|
|
2873
2955
|
break;
|
|
2956
|
+
}
|
|
2874
2957
|
}
|
|
2875
2958
|
}
|
|
2876
2959
|
submitSummaryMessage(contents, referenceSequenceNumber) {
|
|
@@ -2878,10 +2961,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2878
2961
|
assert(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
|
|
2879
2962
|
// System message should not be sent in the middle of the batch.
|
|
2880
2963
|
assert(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
|
|
2881
|
-
|
|
2882
|
-
return this.submitSummaryFn !== undefined
|
|
2883
|
-
? this.submitSummaryFn(contents, referenceSequenceNumber)
|
|
2884
|
-
: this.submitFn(MessageType.Summarize, contents, false);
|
|
2964
|
+
return this.submitSummaryFn(contents, referenceSequenceNumber);
|
|
2885
2965
|
}
|
|
2886
2966
|
/**
|
|
2887
2967
|
* Throw an error if the runtime is closed. Methods that are expected to potentially
|
|
@@ -2921,15 +3001,16 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2921
3001
|
* @param localOpMetadata - The local metadata associated with the original message.
|
|
2922
3002
|
*/
|
|
2923
3003
|
reSubmitCore(message, localOpMetadata, opMetadata) {
|
|
2924
|
-
assert(
|
|
3004
|
+
assert(this._summarizer === undefined, 0x8f2 /* Summarizer never reconnects so should never resubmit */);
|
|
2925
3005
|
switch (message.type) {
|
|
2926
3006
|
case ContainerMessageType.FluidDataStoreOp:
|
|
2927
3007
|
case ContainerMessageType.Attach:
|
|
2928
|
-
case ContainerMessageType.Alias:
|
|
3008
|
+
case ContainerMessageType.Alias: {
|
|
2929
3009
|
// For Operations, call resubmitDataStoreOp which will find the right store
|
|
2930
3010
|
// and trigger resubmission on it.
|
|
2931
3011
|
this.channelCollection.reSubmit(message.type, message.contents, localOpMetadata);
|
|
2932
3012
|
break;
|
|
3013
|
+
}
|
|
2933
3014
|
case ContainerMessageType.IdAllocation: {
|
|
2934
3015
|
// Allocation ops are never resubmitted/rebased. This is because they require special handling to
|
|
2935
3016
|
// avoid being submitted out of order. For example, if the pending state manager contained
|
|
@@ -2940,20 +3021,24 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2940
3021
|
// all pending IDs. The resubmitted allocation ops are then ignored here.
|
|
2941
3022
|
break;
|
|
2942
3023
|
}
|
|
2943
|
-
case ContainerMessageType.BlobAttach:
|
|
3024
|
+
case ContainerMessageType.BlobAttach: {
|
|
2944
3025
|
this.blobManager.reSubmit(opMetadata);
|
|
2945
3026
|
break;
|
|
2946
|
-
|
|
3027
|
+
}
|
|
3028
|
+
case ContainerMessageType.Rejoin: {
|
|
2947
3029
|
this.submit(message);
|
|
2948
3030
|
break;
|
|
2949
|
-
|
|
3031
|
+
}
|
|
3032
|
+
case ContainerMessageType.GC: {
|
|
2950
3033
|
this.submit(message);
|
|
2951
3034
|
break;
|
|
2952
|
-
|
|
3035
|
+
}
|
|
3036
|
+
case ContainerMessageType.DocumentSchemaChange: {
|
|
2953
3037
|
// There is no need to resend this message. Document schema controller will properly resend it again (if needed)
|
|
2954
3038
|
// on a first occasion (any ops sent after reconnect). There is a good chance, though, that it will not want to
|
|
2955
3039
|
// send any ops, as some other client already changed schema.
|
|
2956
3040
|
break;
|
|
3041
|
+
}
|
|
2957
3042
|
default: {
|
|
2958
3043
|
const error = getUnknownMessageTypeError(message.type, "reSubmitCore" /* codePath */);
|
|
2959
3044
|
this.closeFn(error);
|
|
@@ -2965,16 +3050,21 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2965
3050
|
// Need to parse from string for back-compat
|
|
2966
3051
|
const { type, contents } = this.parseLocalOpContent(content);
|
|
2967
3052
|
switch (type) {
|
|
2968
|
-
case ContainerMessageType.FluidDataStoreOp:
|
|
3053
|
+
case ContainerMessageType.FluidDataStoreOp: {
|
|
2969
3054
|
// For operations, call rollbackDataStoreOp which will find the right store
|
|
2970
3055
|
// and trigger rollback on it.
|
|
2971
3056
|
this.channelCollection.rollback(type, contents, localOpMetadata);
|
|
2972
3057
|
break;
|
|
2973
|
-
|
|
3058
|
+
}
|
|
3059
|
+
default: {
|
|
2974
3060
|
throw new Error(`Can't rollback ${type}`);
|
|
3061
|
+
}
|
|
2975
3062
|
}
|
|
2976
3063
|
}
|
|
2977
|
-
/**
|
|
3064
|
+
/**
|
|
3065
|
+
* Implementation of ISummarizerInternalsProvider.refreshLatestSummaryAck
|
|
3066
|
+
*/
|
|
3067
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2978
3068
|
async refreshLatestSummaryAck(options) {
|
|
2979
3069
|
const { proposalHandle, ackHandle, summaryRefSeq, summaryLogger } = options;
|
|
2980
3070
|
// proposalHandle is always passed from RunningSummarizer.
|
|
@@ -3044,15 +3134,16 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
3044
3134
|
snapshotTree = snapshot.snapshotTree;
|
|
3045
3135
|
}
|
|
3046
3136
|
else {
|
|
3047
|
-
const versions = await this.storage.getVersions(
|
|
3137
|
+
const versions = await this.storage.getVersions(
|
|
3138
|
+
// eslint-disable-next-line unicorn/no-null
|
|
3139
|
+
null, 1, scenarioName, FetchSource.noCache);
|
|
3048
3140
|
assert(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
|
|
3049
3141
|
snapshotTree = await this.storage.getSnapshotTree(versions[0]);
|
|
3050
3142
|
assert(!!snapshotTree, 0x138 /* "Failed to get snapshot from storage" */);
|
|
3051
3143
|
props.snapshotVersion = versions[0].id;
|
|
3052
3144
|
}
|
|
3053
3145
|
props.getSnapshotDuration = trace.trace().duration;
|
|
3054
|
-
const
|
|
3055
|
-
const snapshotRefSeq = await seqFromTree(snapshotTree, readAndParseBlob);
|
|
3146
|
+
const snapshotRefSeq = await seqFromTree(snapshotTree, this.readAndParseBlob);
|
|
3056
3147
|
props.snapshotRefSeq = snapshotRefSeq;
|
|
3057
3148
|
props.newerSnapshotPresent = snapshotRefSeq >= targetRefSeq;
|
|
3058
3149
|
perfEvent.end({ details: props });
|
|
@@ -3105,32 +3196,32 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
3105
3196
|
: PerformanceEvent.timedExec(this.mc.logger, perfEvent, (event) => logAndReturnPendingState(event, getSyncState()));
|
|
3106
3197
|
}
|
|
3107
3198
|
summarizeOnDemand(options) {
|
|
3108
|
-
if (this.
|
|
3109
|
-
return this.
|
|
3199
|
+
if (this._summarizer !== undefined) {
|
|
3200
|
+
return this._summarizer.summarizeOnDemand(options);
|
|
3110
3201
|
}
|
|
3111
|
-
else if (this.summaryManager
|
|
3112
|
-
return this.summaryManager.summarizeOnDemand(options);
|
|
3113
|
-
}
|
|
3114
|
-
else {
|
|
3202
|
+
else if (this.summaryManager === undefined) {
|
|
3115
3203
|
// If we're not the summarizer, and we don't have a summaryManager, we expect that
|
|
3116
3204
|
// disableSummaries is turned on. We are throwing instead of returning a failure here,
|
|
3117
3205
|
// because it is a misuse of the API rather than an expected failure.
|
|
3118
3206
|
throw new UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
|
|
3119
3207
|
}
|
|
3208
|
+
else {
|
|
3209
|
+
return this.summaryManager.summarizeOnDemand(options);
|
|
3210
|
+
}
|
|
3120
3211
|
}
|
|
3121
3212
|
enqueueSummarize(options) {
|
|
3122
|
-
if (this.
|
|
3123
|
-
return this.
|
|
3124
|
-
}
|
|
3125
|
-
else if (this.summaryManager !== undefined) {
|
|
3126
|
-
return this.summaryManager.enqueueSummarize(options);
|
|
3213
|
+
if (this._summarizer !== undefined) {
|
|
3214
|
+
return this._summarizer.enqueueSummarize(options);
|
|
3127
3215
|
}
|
|
3128
|
-
else {
|
|
3216
|
+
else if (this.summaryManager === undefined) {
|
|
3129
3217
|
// If we're not the summarizer, and we don't have a summaryManager, we expect that
|
|
3130
3218
|
// generateSummaries is turned off. We are throwing instead of returning a failure here,
|
|
3131
3219
|
// because it is a misuse of the API rather than an expected failure.
|
|
3132
3220
|
throw new UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
|
|
3133
3221
|
}
|
|
3222
|
+
else {
|
|
3223
|
+
return this.summaryManager.enqueueSummarize(options);
|
|
3224
|
+
}
|
|
3134
3225
|
}
|
|
3135
3226
|
/**
|
|
3136
3227
|
* Forms a function that will create and retrieve a Summarizer.
|