@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/dist/containerRuntime.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.ContainerRuntime = exports.loadContainerRuntime = exports.getSingleUseLegacyLogCallback = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isUnpackedRuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.disabledCompressionConfig = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DeletedResponseHeaderKey = exports.DefaultSummaryConfiguration = void 0;
|
|
7
|
+
exports.ContainerRuntime = exports.loadContainerRuntime = exports.getSingleUseLegacyLogCallback = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isUnpackedRuntimeMessage = exports.defaultPendingOpsRetryDelayMs = exports.defaultPendingOpsWaitTimeoutMs = exports.disabledCompressionConfig = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.DeletedResponseHeaderKey = exports.DefaultSummaryConfiguration = exports.isSummariesDisabled = void 0;
|
|
8
8
|
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
9
|
const container_definitions_1 = require("@fluidframework/container-definitions");
|
|
10
10
|
const internal_1 = require("@fluidframework/container-definitions/internal");
|
|
@@ -24,12 +24,14 @@ const containerHandleContext_js_1 = require("./containerHandleContext.js");
|
|
|
24
24
|
const dataStore_js_1 = require("./dataStore.js");
|
|
25
25
|
const dataStoreRegistry_js_1 = require("./dataStoreRegistry.js");
|
|
26
26
|
const deltaManagerProxies_js_1 = require("./deltaManagerProxies.js");
|
|
27
|
+
const deltaScheduler_js_1 = require("./deltaScheduler.js");
|
|
27
28
|
const index_js_2 = require("./gc/index.js");
|
|
29
|
+
const inboundBatchAggregator_js_1 = require("./inboundBatchAggregator.js");
|
|
30
|
+
const layerCompatState_js_1 = require("./layerCompatState.js");
|
|
28
31
|
const messageTypes_js_1 = require("./messageTypes.js");
|
|
29
32
|
const index_js_3 = require("./opLifecycle/index.js");
|
|
30
33
|
const packageVersion_js_1 = require("./packageVersion.js");
|
|
31
34
|
const pendingStateManager_js_1 = require("./pendingStateManager.js");
|
|
32
|
-
const scheduleManager_js_1 = require("./scheduleManager.js");
|
|
33
35
|
const index_js_4 = require("./summary/index.js");
|
|
34
36
|
const throttler_js_1 = require("./throttler.js");
|
|
35
37
|
/**
|
|
@@ -51,6 +53,10 @@ function getUnknownMessageTypeError(unknownContainerRuntimeMessageType, codePath
|
|
|
51
53
|
},
|
|
52
54
|
});
|
|
53
55
|
}
|
|
56
|
+
function isSummariesDisabled(config) {
|
|
57
|
+
return config.state === "disabled";
|
|
58
|
+
}
|
|
59
|
+
exports.isSummariesDisabled = isSummariesDisabled;
|
|
54
60
|
/**
|
|
55
61
|
* @legacy
|
|
56
62
|
* @alpha
|
|
@@ -66,13 +72,14 @@ exports.DefaultSummaryConfiguration = {
|
|
|
66
72
|
maxOpsSinceLastSummary: 7000,
|
|
67
73
|
initialSummarizerDelayMs: 5 * 1000, // 5 secs.
|
|
68
74
|
nonRuntimeOpWeight: 0.1,
|
|
69
|
-
runtimeOpWeight: 1
|
|
75
|
+
runtimeOpWeight: 1,
|
|
70
76
|
nonRuntimeHeuristicThreshold: 20,
|
|
71
77
|
};
|
|
72
78
|
/**
|
|
73
79
|
* Error responses when requesting a deleted object will have this header set to true
|
|
74
80
|
* @legacy
|
|
75
81
|
* @alpha
|
|
82
|
+
* @deprecated This type will be moved to internal in 2.30. External usage is not necessary or supported.
|
|
76
83
|
*/
|
|
77
84
|
exports.DeletedResponseHeaderKey = "wasDeleted";
|
|
78
85
|
/**
|
|
@@ -90,7 +97,9 @@ exports.TombstoneResponseHeaderKey = "isTombstoned";
|
|
|
90
97
|
* to this was experimental and is no longer supported.
|
|
91
98
|
*/
|
|
92
99
|
exports.InactiveResponseHeaderKey = "isInactive";
|
|
93
|
-
/**
|
|
100
|
+
/**
|
|
101
|
+
* Default values for Runtime Headers
|
|
102
|
+
*/
|
|
94
103
|
exports.defaultRuntimeHeaderData = {
|
|
95
104
|
wait: true,
|
|
96
105
|
viaHandle: false,
|
|
@@ -110,7 +119,7 @@ var CompressionAlgorithms;
|
|
|
110
119
|
* @alpha
|
|
111
120
|
*/
|
|
112
121
|
exports.disabledCompressionConfig = {
|
|
113
|
-
minimumBatchSizeInBytes:
|
|
122
|
+
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
|
|
114
123
|
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
115
124
|
};
|
|
116
125
|
const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
|
|
@@ -126,9 +135,13 @@ const defaultCompressionConfig = {
|
|
|
126
135
|
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
127
136
|
};
|
|
128
137
|
const defaultChunkSizeInBytes = 204800;
|
|
129
|
-
/**
|
|
138
|
+
/**
|
|
139
|
+
* The default time to wait for pending ops to be processed during summarization
|
|
140
|
+
*/
|
|
130
141
|
exports.defaultPendingOpsWaitTimeoutMs = 1000;
|
|
131
|
-
/**
|
|
142
|
+
/**
|
|
143
|
+
* The default time to delay a summarization retry attempt when there are pending ops
|
|
144
|
+
*/
|
|
132
145
|
exports.defaultPendingOpsRetryDelayMs = 1000;
|
|
133
146
|
/**
|
|
134
147
|
* Instead of refreshing from latest because we do not have 100% confidence in the state
|
|
@@ -155,12 +168,15 @@ function getDeviceSpec() {
|
|
|
155
168
|
try {
|
|
156
169
|
if (typeof navigator === "object" && navigator !== null) {
|
|
157
170
|
return {
|
|
171
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
|
158
172
|
deviceMemory: navigator.deviceMemory,
|
|
159
173
|
hardwareConcurrency: navigator.hardwareConcurrency,
|
|
160
174
|
};
|
|
161
175
|
}
|
|
162
176
|
}
|
|
163
|
-
catch {
|
|
177
|
+
catch {
|
|
178
|
+
// Eat the error
|
|
179
|
+
}
|
|
164
180
|
return {};
|
|
165
181
|
}
|
|
166
182
|
exports.getDeviceSpec = getDeviceSpec;
|
|
@@ -203,18 +219,20 @@ async function createSummarizer(loader, url) {
|
|
|
203
219
|
let fluidObject;
|
|
204
220
|
// Older containers may not have the "getEntryPoint" API
|
|
205
221
|
// ! This check will need to stay until LTS of loader moves past 2.0.0-internal.7.0.0
|
|
206
|
-
if (resolvedContainer.getEntryPoint
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
else {
|
|
210
|
-
const response = await resolvedContainer.request({
|
|
222
|
+
if (resolvedContainer.getEntryPoint === undefined) {
|
|
223
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any
|
|
224
|
+
const response = (await resolvedContainer.request({
|
|
211
225
|
url: `/${summarizerRequestUrl}`,
|
|
212
|
-
});
|
|
226
|
+
}));
|
|
213
227
|
if (response.status !== 200 || response.mimeType !== "fluid/object") {
|
|
214
228
|
throw (0, internal_6.responseToException)(response, request);
|
|
215
229
|
}
|
|
230
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
216
231
|
fluidObject = response.value;
|
|
217
232
|
}
|
|
233
|
+
else {
|
|
234
|
+
fluidObject = await resolvedContainer.getEntryPoint();
|
|
235
|
+
}
|
|
218
236
|
if (fluidObject?.ISummarizer === undefined) {
|
|
219
237
|
throw new internal_7.UsageError("Fluid object does not implement ISummarizer");
|
|
220
238
|
}
|
|
@@ -226,7 +244,9 @@ async function createSummarizer(loader, url) {
|
|
|
226
244
|
* This allows new runtime to make documents not openable for old runtimes, one explicit document schema control is enabled.
|
|
227
245
|
* Please see addMetadataToSummary() as well
|
|
228
246
|
*/
|
|
229
|
-
function lastMessageFromMetadata(
|
|
247
|
+
function lastMessageFromMetadata(
|
|
248
|
+
// eslint-disable-next-line import/no-deprecated
|
|
249
|
+
metadata) {
|
|
230
250
|
return metadata?.documentSchema?.runtime?.explicitSchemaControl
|
|
231
251
|
? metadata?.lastMessage
|
|
232
252
|
: metadata?.message;
|
|
@@ -243,6 +263,7 @@ let getSingleUseLegacyLogCallback = (logger, type) => {
|
|
|
243
263
|
details: { codePath, type },
|
|
244
264
|
});
|
|
245
265
|
// Now that we've logged, prevent future logging (globally).
|
|
266
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
246
267
|
exports.getSingleUseLegacyLogCallback = () => () => { };
|
|
247
268
|
};
|
|
248
269
|
};
|
|
@@ -258,15 +279,13 @@ async function loadContainerRuntime(params) {
|
|
|
258
279
|
return ContainerRuntime.loadRuntime(params);
|
|
259
280
|
}
|
|
260
281
|
exports.loadContainerRuntime = loadContainerRuntime;
|
|
282
|
+
const defaultMaxConsecutiveReconnects = 7;
|
|
283
|
+
const defaultTelemetrySignalSampleCount = 100;
|
|
261
284
|
/**
|
|
262
285
|
* Represents the runtime of the container. Contains helper functions/state of the container.
|
|
263
286
|
* It will define the store level mappings.
|
|
264
287
|
*
|
|
265
|
-
* @
|
|
266
|
-
* Use the loadContainerRuntime function and interfaces IContainerRuntime / IRuntime instead.
|
|
267
|
-
*
|
|
268
|
-
* @legacy
|
|
269
|
-
* @alpha
|
|
288
|
+
* @internal
|
|
270
289
|
*/
|
|
271
290
|
class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
272
291
|
/**
|
|
@@ -301,7 +320,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
301
320
|
},
|
|
302
321
|
});
|
|
303
322
|
const mc = (0, internal_7.loggerToMonitoringContext)(logger);
|
|
304
|
-
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions =
|
|
323
|
+
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = runtimeOptions.enableGroupedBatching === false
|
|
324
|
+
? exports.disabledCompressionConfig // Compression must be disabled if Grouping is disabled
|
|
325
|
+
: defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor, chunkSizeInBytes = defaultChunkSizeInBytes, enableGroupedBatching = true, explicitSchemaControl = false, } = runtimeOptions;
|
|
305
326
|
const registry = new dataStoreRegistry_js_1.FluidDataStoreRegistry(registryEntries);
|
|
306
327
|
const tryFetchBlob = async (blobName) => {
|
|
307
328
|
const blobId = context.baseSnapshot?.blobs[blobName];
|
|
@@ -315,7 +336,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
315
336
|
const [chunks, recentBatchInfo, metadata, electedSummarizerData, aliases, serializedIdCompressor,] = await Promise.all([
|
|
316
337
|
tryFetchBlob(index_js_4.chunksBlobName),
|
|
317
338
|
tryFetchBlob(index_js_4.recentBatchInfoBlobName),
|
|
339
|
+
// eslint-disable-next-line import/no-deprecated
|
|
318
340
|
tryFetchBlob(index_js_4.metadataBlobName),
|
|
341
|
+
// eslint-disable-next-line import/no-deprecated
|
|
319
342
|
tryFetchBlob(index_js_4.electedSummarizerBlobName),
|
|
320
343
|
tryFetchBlob(index_js_4.aliasBlobName),
|
|
321
344
|
tryFetchBlob(index_js_4.idCompressorBlobName),
|
|
@@ -329,6 +352,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
329
352
|
// When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
|
|
330
353
|
if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
|
|
331
354
|
// Unless bypass is explicitly set, then take action when sequence numbers mismatch.
|
|
355
|
+
// eslint-disable-next-line unicorn/no-lonely-if -- Separate if statements make flow easier to parse
|
|
332
356
|
if (loadSequenceNumberVerification !== "bypass" &&
|
|
333
357
|
runtimeSequenceNumber !== protocolSequenceNumber) {
|
|
334
358
|
// Message to OCEs:
|
|
@@ -351,15 +375,18 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
351
375
|
}
|
|
352
376
|
let desiredIdCompressorMode;
|
|
353
377
|
switch (mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) {
|
|
354
|
-
case true:
|
|
378
|
+
case true: {
|
|
355
379
|
desiredIdCompressorMode = "on";
|
|
356
380
|
break;
|
|
357
|
-
|
|
381
|
+
}
|
|
382
|
+
case false: {
|
|
358
383
|
desiredIdCompressorMode = undefined;
|
|
359
384
|
break;
|
|
360
|
-
|
|
385
|
+
}
|
|
386
|
+
default: {
|
|
361
387
|
desiredIdCompressorMode = enableRuntimeIdCompressor;
|
|
362
388
|
break;
|
|
389
|
+
}
|
|
363
390
|
}
|
|
364
391
|
// Enabling the IdCompressor is a one-way operation and we only want to
|
|
365
392
|
// allow new containers to turn it on.
|
|
@@ -412,15 +439,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
412
439
|
if (pendingLocalState?.pendingIdCompressorState !== undefined) {
|
|
413
440
|
return deserializeIdCompressor(pendingLocalState.pendingIdCompressorState, compressorLogger);
|
|
414
441
|
}
|
|
415
|
-
else if (serializedIdCompressor
|
|
416
|
-
return
|
|
442
|
+
else if (serializedIdCompressor === undefined) {
|
|
443
|
+
return createIdCompressor(compressorLogger);
|
|
417
444
|
}
|
|
418
445
|
else {
|
|
419
|
-
return
|
|
446
|
+
return deserializeIdCompressor(serializedIdCompressor, createSessionId(), compressorLogger);
|
|
420
447
|
}
|
|
421
448
|
};
|
|
422
|
-
const compressionLz4 = compressionOptions.minimumBatchSizeInBytes !==
|
|
449
|
+
const compressionLz4 = compressionOptions.minimumBatchSizeInBytes !== Number.POSITIVE_INFINITY &&
|
|
423
450
|
compressionOptions.compressionAlgorithm === "lz4";
|
|
451
|
+
// eslint-disable-next-line import/no-deprecated
|
|
424
452
|
const documentSchemaController = new index_js_4.DocumentsSchemaController(existing, protocolSequenceNumber, metadata?.documentSchema, {
|
|
425
453
|
explicitSchemaControl,
|
|
426
454
|
compressionLz4,
|
|
@@ -430,6 +458,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
430
458
|
}, (schema) => {
|
|
431
459
|
runtime.onSchemaChange(schema);
|
|
432
460
|
});
|
|
461
|
+
if (compressionLz4 && !enableGroupedBatching) {
|
|
462
|
+
throw new internal_7.UsageError("If compression is enabled, op grouping must be enabled too");
|
|
463
|
+
}
|
|
433
464
|
const featureGatesForTelemetry = {};
|
|
434
465
|
// Make sure we've got all the options including internal ones
|
|
435
466
|
const internalRuntimeOptions = {
|
|
@@ -490,29 +521,26 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
490
521
|
* has to deal with compressed ops as other clients might send them.
|
|
491
522
|
* And in reverse, session schema can have compression Off, but feature gates / runtime options want it On.
|
|
492
523
|
* In such case it will be off in session schema, however this client will propose change to schema, and once / if
|
|
493
|
-
* this op
|
|
524
|
+
* this op roundtrips, compression will be On. Client can't send compressed ops until it's change in schema.
|
|
494
525
|
*/
|
|
495
526
|
get sessionSchema() {
|
|
496
527
|
return this.documentsSchemaController.sessionSchema.runtime;
|
|
497
528
|
}
|
|
498
|
-
get idCompressorMode() {
|
|
499
|
-
return this.sessionSchema.idCompressorMode;
|
|
500
|
-
}
|
|
501
529
|
/**
|
|
502
|
-
*
|
|
530
|
+
* {@inheritDoc @fluidframework/runtime-definitions#IContainerRuntimeBase.idCompressor}
|
|
503
531
|
*/
|
|
504
532
|
get idCompressor() {
|
|
505
533
|
// Expose ID Compressor only if it's On from the start.
|
|
506
534
|
// If container uses delayed mode, then we can only expose generateDocumentUniqueId() and nothing else.
|
|
507
535
|
// That's because any other usage will require immidiate loading of ID Compressor in next sessions in order
|
|
508
536
|
// to reason over such things as session ID space.
|
|
509
|
-
if (this.idCompressorMode === "on") {
|
|
537
|
+
if (this.sessionSchema.idCompressorMode === "on") {
|
|
510
538
|
(0, internal_2.assert)(this._idCompressor !== undefined, 0x8ea /* compressor should have been loaded */);
|
|
511
539
|
return this._idCompressor;
|
|
512
540
|
}
|
|
513
541
|
}
|
|
514
542
|
/**
|
|
515
|
-
*
|
|
543
|
+
* {@inheritDoc @fluidframework/runtime-definitions#IContainerRuntimeBase.generateDocumentUniqueId}
|
|
516
544
|
*/
|
|
517
545
|
generateDocumentUniqueId() {
|
|
518
546
|
return this._idCompressor?.generateDocumentUniqueId() ?? (0, uuid_1.v4)();
|
|
@@ -548,35 +576,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
548
576
|
get connected() {
|
|
549
577
|
return this._connected;
|
|
550
578
|
}
|
|
551
|
-
/**
|
|
579
|
+
/**
|
|
580
|
+
* clientId of parent (non-summarizing) container that owns summarizer container
|
|
581
|
+
*/
|
|
552
582
|
get summarizerClientId() {
|
|
553
583
|
return this.summarizerClientElection?.electedClientId;
|
|
554
584
|
}
|
|
555
585
|
get disposed() {
|
|
556
586
|
return this._disposed;
|
|
557
587
|
}
|
|
558
|
-
get summarizer() {
|
|
559
|
-
(0, internal_2.assert)(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
|
|
560
|
-
return this._summarizer;
|
|
561
|
-
}
|
|
562
|
-
isSummariesDisabled() {
|
|
563
|
-
return this.summaryConfiguration.state === "disabled";
|
|
564
|
-
}
|
|
565
|
-
getMaxOpsSinceLastSummary() {
|
|
566
|
-
return this.summaryConfiguration.state !== "disabled"
|
|
567
|
-
? this.summaryConfiguration.maxOpsSinceLastSummary
|
|
568
|
-
: 0;
|
|
569
|
-
}
|
|
570
|
-
getInitialSummarizerDelayMs() {
|
|
571
|
-
// back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
|
|
572
|
-
// to ISummaryConfiguration in 0.60.
|
|
573
|
-
if (this.runtimeOptions.summaryOptions.initialSummarizerDelayMs !== undefined) {
|
|
574
|
-
return this.runtimeOptions.summaryOptions.initialSummarizerDelayMs;
|
|
575
|
-
}
|
|
576
|
-
return this.summaryConfiguration.state !== "disabled"
|
|
577
|
-
? this.summaryConfiguration.initialSummarizerDelayMs
|
|
578
|
-
: 0;
|
|
579
|
-
}
|
|
580
588
|
/**
|
|
581
589
|
* If false, loading or using a Tombstoned object should merely log, not fail.
|
|
582
590
|
* @deprecated NOT SUPPORTED - hardcoded to return false since it's deprecated.
|
|
@@ -593,14 +601,27 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
593
601
|
get gcThrowOnTombstoneUsage() {
|
|
594
602
|
return false;
|
|
595
603
|
}
|
|
604
|
+
get ILayerCompatDetails() {
|
|
605
|
+
return layerCompatState_js_1.RuntimeCompatDetails;
|
|
606
|
+
}
|
|
596
607
|
/***/
|
|
597
|
-
constructor(context, registry,
|
|
608
|
+
constructor(context, registry,
|
|
609
|
+
// eslint-disable-next-line import/no-deprecated
|
|
610
|
+
metadata,
|
|
611
|
+
// eslint-disable-next-line import/no-deprecated
|
|
612
|
+
electedSummarizerData, chunks, dataStoreAliasMap, baseRuntimeOptions, containerScope,
|
|
598
613
|
// Create a custom ITelemetryBaseLogger to output telemetry events.
|
|
599
|
-
baseLogger, existing,
|
|
614
|
+
baseLogger, existing,
|
|
615
|
+
// eslint-disable-next-line import/no-deprecated
|
|
616
|
+
blobManagerSnapshot, _storage, createIdCompressor,
|
|
617
|
+
// eslint-disable-next-line import/no-deprecated
|
|
618
|
+
documentsSchemaController, featureGatesForTelemetry, provideEntryPoint, requestHandler,
|
|
619
|
+
// eslint-disable-next-line unicorn/no-object-as-default-parameter
|
|
620
|
+
summaryConfiguration = {
|
|
600
621
|
// the defaults
|
|
601
622
|
...exports.DefaultSummaryConfiguration,
|
|
602
623
|
// the runtime configuration overrides
|
|
603
|
-
...
|
|
624
|
+
...baseRuntimeOptions.summaryOptions?.summaryConfigOverrides,
|
|
604
625
|
}, recentBatchInfo) {
|
|
605
626
|
super();
|
|
606
627
|
this.registry = registry;
|
|
@@ -611,19 +632,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
611
632
|
this.createIdCompressor = createIdCompressor;
|
|
612
633
|
this.documentsSchemaController = documentsSchemaController;
|
|
613
634
|
this.requestHandler = requestHandler;
|
|
614
|
-
this.summaryConfiguration = summaryConfiguration;
|
|
615
635
|
this.imminentClosure = false;
|
|
616
636
|
// We accumulate Id compressor Ops while Id compressor is not loaded yet (only for "delayed" mode)
|
|
617
637
|
// Once it loads, it will process all such ops and we will stop accumulating further ops - ops will be processes as they come in.
|
|
618
638
|
this.pendingIdCompressorOps = [];
|
|
619
|
-
this.defaultMaxConsecutiveReconnects = 7;
|
|
620
639
|
this._orderSequentiallyCalls = 0;
|
|
621
640
|
this.flushTaskExists = false;
|
|
622
641
|
this.consecutiveReconnects = 0;
|
|
623
642
|
this.ensureNoDataModelChangesCalls = 0;
|
|
624
643
|
this._disposed = false;
|
|
625
644
|
this.emitDirtyDocumentEvent = true;
|
|
626
|
-
this.defaultTelemetrySignalSampleCount = 100;
|
|
627
645
|
this._signalTracking = {
|
|
628
646
|
totalSignalsSentInLatencyWindow: 0,
|
|
629
647
|
signalsLost: 0,
|
|
@@ -642,16 +660,19 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
642
660
|
this.snapshotCacheForLoadingGroupIds = new internal_2.PromiseCache({
|
|
643
661
|
expiry: { policy: "absolute", durationMs: 60000 },
|
|
644
662
|
});
|
|
663
|
+
this.readAndParseBlob = async (id) => (0, internal_4.readAndParse)(this.storage, id);
|
|
645
664
|
const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, snapshotWithContents, } = context;
|
|
665
|
+
// In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
|
|
666
|
+
this.disposeFn = disposeFn ?? closeFn;
|
|
667
|
+
const maybeLoaderCompatDetails = context;
|
|
668
|
+
(0, layerCompatState_js_1.validateLoaderCompatibility)(maybeLoaderCompatDetails.ILayerCompatDetails, this.disposeFn);
|
|
646
669
|
// Backfill in defaults for the internal runtimeOptions, since they may not be present on the provided runtimeOptions object
|
|
647
|
-
|
|
670
|
+
const runtimeOptions = {
|
|
648
671
|
flushMode: defaultFlushMode,
|
|
649
|
-
|
|
650
|
-
...runtimeOptions,
|
|
672
|
+
...baseRuntimeOptions,
|
|
651
673
|
};
|
|
652
|
-
this.logger = (0, internal_7.createChildLogger)({ logger: this.baseLogger });
|
|
653
674
|
this.mc = (0, internal_7.createChildMonitoringContext)({
|
|
654
|
-
logger: this.
|
|
675
|
+
logger: this.baseLogger,
|
|
655
676
|
namespace: "ContainerRuntime",
|
|
656
677
|
});
|
|
657
678
|
// If we support multiple algorithms in the future, then we would need to manage it here carefully.
|
|
@@ -668,19 +689,23 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
668
689
|
this.innerDeltaManager = deltaManager;
|
|
669
690
|
// Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
|
|
670
691
|
// This makes ContainerRuntime the final gatekeeper for outgoing messages.
|
|
671
|
-
this
|
|
672
|
-
this.
|
|
673
|
-
|
|
692
|
+
// back-compat: ADO #1385: Make this call unconditional in the future
|
|
693
|
+
this.submitSummaryFn =
|
|
694
|
+
submitSummaryFn ??
|
|
695
|
+
((summaryOp, refseq) => submitFn(internal_3.MessageType.Summarize, summaryOp, false));
|
|
674
696
|
this.submitSignalFn = submitSignalFn;
|
|
675
697
|
// TODO: After IContainerContext.options is removed, we'll just create a new blank object {} here.
|
|
676
698
|
// Values are generally expected to be set from the runtime side.
|
|
677
699
|
this.options = options ?? {};
|
|
678
700
|
this.clientDetails = clientDetails;
|
|
679
|
-
|
|
701
|
+
const isSummarizerClient = this.clientDetails.type === index_js_4.summarizerClientType;
|
|
680
702
|
this.loadedFromVersionId = context.getLoadedFromVersion()?.id;
|
|
703
|
+
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
681
704
|
this._getClientId = () => context.clientId;
|
|
705
|
+
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
682
706
|
this._getAttachState = () => context.attachState;
|
|
683
707
|
this.getAbsoluteUrl = async (relativeUrl) => {
|
|
708
|
+
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
684
709
|
if (context.getAbsoluteUrl === undefined) {
|
|
685
710
|
throw new Error("Driver does not implement getAbsoluteUrl");
|
|
686
711
|
}
|
|
@@ -693,10 +718,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
693
718
|
// customer should observe dirty state on the runtime (the owner of dirty state) directly, rather than on the IContainer.
|
|
694
719
|
this.on("dirty", () => context.updateDirtyContainerState(true));
|
|
695
720
|
this.on("saved", () => context.updateDirtyContainerState(false));
|
|
696
|
-
// In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
|
|
697
|
-
this.disposeFn = disposeFn ?? closeFn;
|
|
698
721
|
// In cases of summarizer, we want to dispose instead since consumer doesn't interact with this container
|
|
699
|
-
this.closeFn =
|
|
722
|
+
this.closeFn = isSummarizerClient ? this.disposeFn : closeFn;
|
|
700
723
|
let loadSummaryNumber;
|
|
701
724
|
// Get the container creation metadata. For new container, we initialize these. For existing containers,
|
|
702
725
|
// get the values from the metadata blob.
|
|
@@ -725,18 +748,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
725
748
|
eventName: "GCFeatureMatrix",
|
|
726
749
|
metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
|
|
727
750
|
inputs: JSON.stringify({
|
|
728
|
-
|
|
751
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
752
|
+
gcOptions_gcGeneration: runtimeOptions.gcOptions[index_js_2.gcGenerationOptionName],
|
|
729
753
|
}),
|
|
730
754
|
});
|
|
731
755
|
this.telemetryDocumentId = metadata?.telemetryDocumentId ?? (0, uuid_1.v4)();
|
|
732
|
-
this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
|
|
733
756
|
const opGroupingManager = new index_js_3.OpGroupingManager({
|
|
734
757
|
groupedBatchingEnabled: this.groupedBatchingEnabled,
|
|
735
|
-
opCountThreshold: this.mc.config.getNumber("Fluid.ContainerRuntime.GroupedBatchingOpCount") ?? 2,
|
|
736
|
-
reentrantBatchGroupingEnabled: this.mc.config.getBoolean("Fluid.ContainerRuntime.GroupedBatchingReentrancy") ??
|
|
737
|
-
true,
|
|
738
758
|
}, this.mc.logger);
|
|
739
|
-
const opSplitter = new index_js_3.OpSplitter(chunks,
|
|
759
|
+
const opSplitter = new index_js_3.OpSplitter(chunks, submitBatchFn, runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
|
|
740
760
|
this.remoteMessageProcessor = new index_js_3.RemoteMessageProcessor(opSplitter, new index_js_3.OpDecompressor(this.mc.logger), opGroupingManager);
|
|
741
761
|
const pendingRuntimeState = pendingLocalState;
|
|
742
762
|
this.pendingStateManager = new pendingStateManager_js_1.PendingStateManager({
|
|
@@ -746,7 +766,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
746
766
|
reSubmitBatch: this.reSubmitBatch.bind(this),
|
|
747
767
|
isActiveConnection: () => this.innerDeltaManager.active,
|
|
748
768
|
isAttached: () => this.attachState !== container_definitions_1.AttachState.Detached,
|
|
749
|
-
}, pendingRuntimeState?.pending, this.
|
|
769
|
+
}, pendingRuntimeState?.pending, this.baseLogger);
|
|
750
770
|
let outerDeltaManager;
|
|
751
771
|
this.useDeltaManagerOpsProxy =
|
|
752
772
|
this.mc.config.getBoolean("Fluid.ContainerRuntime.DeltaManagerOpsProxy") === true;
|
|
@@ -761,24 +781,35 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
761
781
|
}
|
|
762
782
|
this._deltaManager = outerDeltaManager;
|
|
763
783
|
this.handleContext = new containerHandleContext_js_1.ContainerFluidHandleContext("", this);
|
|
764
|
-
if (
|
|
765
|
-
this.validateSummaryHeuristicConfiguration(
|
|
766
|
-
}
|
|
767
|
-
this.summariesDisabled =
|
|
768
|
-
|
|
769
|
-
|
|
784
|
+
if (summaryConfiguration.state === "enabled") {
|
|
785
|
+
this.validateSummaryHeuristicConfiguration(summaryConfiguration);
|
|
786
|
+
}
|
|
787
|
+
this.summariesDisabled = isSummariesDisabled(summaryConfiguration);
|
|
788
|
+
const { maxOpsSinceLastSummary = 0, initialSummarizerDelayMs = 0 } = isSummariesDisabled(summaryConfiguration)
|
|
789
|
+
? {}
|
|
790
|
+
: {
|
|
791
|
+
...summaryConfiguration,
|
|
792
|
+
initialSummarizerDelayMs:
|
|
793
|
+
// back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
|
|
794
|
+
// to ISummaryConfiguration in 0.60.
|
|
795
|
+
runtimeOptions.summaryOptions.initialSummarizerDelayMs ??
|
|
796
|
+
summaryConfiguration.initialSummarizerDelayMs,
|
|
797
|
+
};
|
|
770
798
|
this.maxConsecutiveReconnects =
|
|
771
|
-
this.mc.config.getNumber(maxConsecutiveReconnectsKey) ??
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
supportedFeatures?.get("referenceSequenceNumbers")
|
|
799
|
+
this.mc.config.getNumber(maxConsecutiveReconnectsKey) ?? defaultMaxConsecutiveReconnects;
|
|
800
|
+
// If the context has ILayerCompatDetails, it supports referenceSequenceNumbers since that features
|
|
801
|
+
// predates ILayerCompatDetails.
|
|
802
|
+
const referenceSequenceNumbersSupported = maybeLoaderCompatDetails.ILayerCompatDetails === undefined
|
|
803
|
+
? supportedFeatures?.get("referenceSequenceNumbers") === true
|
|
804
|
+
: true;
|
|
805
|
+
if (runtimeOptions.flushMode === internal_5.FlushModeExperimental.Async &&
|
|
806
|
+
!referenceSequenceNumbersSupported) {
|
|
776
807
|
// The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
|
|
777
808
|
this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
|
|
778
809
|
this._flushMode = internal_5.FlushMode.TurnBased;
|
|
779
810
|
}
|
|
780
811
|
else {
|
|
781
|
-
this._flushMode =
|
|
812
|
+
this._flushMode = runtimeOptions.flushMode;
|
|
782
813
|
}
|
|
783
814
|
this.offlineEnabled =
|
|
784
815
|
this.mc.config.getBoolean("Fluid.Container.enableOfflineLoad") ?? false;
|
|
@@ -793,6 +824,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
793
824
|
if (this.offlineEnabled) {
|
|
794
825
|
this.duplicateBatchDetector = new index_js_3.DuplicateBatchDetector(recentBatchInfo);
|
|
795
826
|
}
|
|
827
|
+
// eslint-disable-next-line unicorn/consistent-destructuring
|
|
796
828
|
if (context.attachState === container_definitions_1.AttachState.Attached) {
|
|
797
829
|
const maxSnapshotCacheDurationMs = this._storage?.policies?.maximumCacheDurationMs;
|
|
798
830
|
if (maxSnapshotCacheDurationMs !== undefined &&
|
|
@@ -805,13 +837,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
805
837
|
}
|
|
806
838
|
this.garbageCollector = index_js_2.GarbageCollector.create({
|
|
807
839
|
runtime: this,
|
|
808
|
-
gcOptions:
|
|
840
|
+
gcOptions: runtimeOptions.gcOptions,
|
|
809
841
|
baseSnapshot,
|
|
810
842
|
baseLogger: this.mc.logger,
|
|
811
843
|
existing,
|
|
812
844
|
metadata,
|
|
813
845
|
createContainerMetadata: this.createContainerMetadata,
|
|
814
|
-
isSummarizerClient
|
|
846
|
+
isSummarizerClient,
|
|
815
847
|
getNodePackagePath: async (nodePath) => this.getGCNodePackagePath(nodePath),
|
|
816
848
|
getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
|
|
817
849
|
readAndParseBlob: async (id) => (0, internal_4.readAndParse)(this.storage, id),
|
|
@@ -825,7 +857,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
825
857
|
const summaryReferenceSequenceNumber = baseSnapshot === undefined || metadata?.disableIsolatedChannels === true
|
|
826
858
|
? undefined
|
|
827
859
|
: loadedFromSequenceNumber;
|
|
828
|
-
this.summarizerNode = (0, index_js_4.createRootSummarizerNodeWithGC)((0, internal_7.createChildLogger)({ logger: this.
|
|
860
|
+
this.summarizerNode = (0, index_js_4.createRootSummarizerNodeWithGC)((0, internal_7.createChildLogger)({ logger: this.baseLogger, namespace: "SummarizerNode" }),
|
|
829
861
|
// Summarize function to call when summarize is called. Summarizer node always tracks summary state.
|
|
830
862
|
async (fullTree, trackState, telemetryContext) => this.summarizeInternal(fullTree, trackState, telemetryContext),
|
|
831
863
|
// Latest change sequence number, no changes since summary applied yet
|
|
@@ -885,13 +917,14 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
885
917
|
stashedBlobs: pendingRuntimeState?.pendingAttachmentBlobs,
|
|
886
918
|
closeContainer: (error) => this.closeFn(error),
|
|
887
919
|
});
|
|
888
|
-
this.
|
|
920
|
+
this.deltaScheduler = new deltaScheduler_js_1.DeltaScheduler(this.innerDeltaManager, this, (0, internal_7.createChildLogger)({ logger: this.baseLogger, namespace: "DeltaScheduler" }));
|
|
921
|
+
this.inboundBatchAggregator = new inboundBatchAggregator_js_1.InboundBatchAggregator(this.innerDeltaManager, () => this.clientId, (0, internal_7.createChildLogger)({ logger: this.baseLogger, namespace: "InboundBatchAggregator" }));
|
|
889
922
|
const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
|
|
890
|
-
const legacySendBatchFn = (0, exports.makeLegacySendBatchFn)(
|
|
923
|
+
const legacySendBatchFn = (0, exports.makeLegacySendBatchFn)(submitFn, this.innerDeltaManager);
|
|
891
924
|
this.outbox = new index_js_3.Outbox({
|
|
892
925
|
shouldSend: () => this.canSendOps(),
|
|
893
926
|
pendingStateManager: this.pendingStateManager,
|
|
894
|
-
submitBatchFn
|
|
927
|
+
submitBatchFn,
|
|
895
928
|
legacySendBatchFn,
|
|
896
929
|
compressor: new index_js_3.OpCompressor(this.mc.logger),
|
|
897
930
|
splitter: opSplitter,
|
|
@@ -938,7 +971,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
938
971
|
const closeSummarizerDelayOverride = this.mc.config.getNumber("Fluid.ContainerRuntime.Test.CloseSummarizerDelayOverrideMs");
|
|
939
972
|
this.closeSummarizerDelayMs =
|
|
940
973
|
closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
|
|
941
|
-
|
|
974
|
+
const summaryCollection = new index_js_4.SummaryCollection(this.deltaManager, this.baseLogger);
|
|
942
975
|
this.dirtyContainer =
|
|
943
976
|
this.attachState !== container_definitions_1.AttachState.Attached || this.hasPendingMessages();
|
|
944
977
|
context.updateDirtyContainerState(this.dirtyContainer);
|
|
@@ -947,14 +980,17 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
947
980
|
}
|
|
948
981
|
else {
|
|
949
982
|
const orderedClientLogger = (0, internal_7.createChildLogger)({
|
|
950
|
-
logger: this.
|
|
983
|
+
logger: this.baseLogger,
|
|
951
984
|
namespace: "OrderedClientElection",
|
|
952
985
|
});
|
|
953
986
|
const orderedClientCollection = new index_js_4.OrderedClientCollection(orderedClientLogger, this.innerDeltaManager, this._quorum);
|
|
954
987
|
const orderedClientElectionForSummarizer = new index_js_4.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber, index_js_4.SummarizerClientElection.isClientEligible, this.mc.config.getBoolean("Fluid.ContainerRuntime.OrderedClientElection.EnablePerformanceEvents"));
|
|
955
|
-
this.summarizerClientElection = new index_js_4.SummarizerClientElection(orderedClientLogger,
|
|
956
|
-
if (
|
|
957
|
-
|
|
988
|
+
this.summarizerClientElection = new index_js_4.SummarizerClientElection(orderedClientLogger, summaryCollection, orderedClientElectionForSummarizer, maxOpsSinceLastSummary);
|
|
989
|
+
if (isSummarizerClient) {
|
|
990
|
+
// eslint-disable-next-line import/no-deprecated
|
|
991
|
+
this._summarizer = new index_js_4.Summarizer(this /* ISummarizerRuntime */, () => summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, summaryCollection,
|
|
992
|
+
// eslint-disable-next-line import/no-deprecated
|
|
993
|
+
async (runtime) => index_js_4.RunWhileConnectedCoordinator.create(runtime,
|
|
958
994
|
// Summarization runs in summarizer client and needs access to the real (non-proxy) active
|
|
959
995
|
// information. The proxy delta manager would always return false for summarizer client.
|
|
960
996
|
() => this.innerDeltaManager.active));
|
|
@@ -963,48 +999,49 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
963
999
|
// Only create a SummaryManager and SummarizerClientElection
|
|
964
1000
|
// if summaries are enabled and we are not the summarizer client.
|
|
965
1001
|
const defaultAction = () => {
|
|
966
|
-
if (
|
|
1002
|
+
if (summaryCollection.opsSinceLastAck > maxOpsSinceLastSummary) {
|
|
967
1003
|
this.mc.logger.sendTelemetryEvent({ eventName: "SummaryStatus:Behind" });
|
|
968
1004
|
// unregister default to no log on every op after falling behind
|
|
969
1005
|
// and register summary ack handler to re-register this handler
|
|
970
1006
|
// after successful summary
|
|
971
|
-
|
|
1007
|
+
summaryCollection.once(internal_3.MessageType.SummaryAck, () => {
|
|
972
1008
|
this.mc.logger.sendTelemetryEvent({
|
|
973
1009
|
eventName: "SummaryStatus:CaughtUp",
|
|
974
1010
|
});
|
|
975
1011
|
// we've caught up, so re-register the default action to monitor for
|
|
976
1012
|
// falling behind, and unregister ourself
|
|
977
|
-
|
|
1013
|
+
summaryCollection.on("default", defaultAction);
|
|
978
1014
|
});
|
|
979
|
-
|
|
1015
|
+
summaryCollection.off("default", defaultAction);
|
|
980
1016
|
}
|
|
981
1017
|
};
|
|
982
|
-
|
|
1018
|
+
summaryCollection.on("default", defaultAction);
|
|
983
1019
|
// Create the SummaryManager and mark the initial state
|
|
984
1020
|
this.summaryManager = new index_js_4.SummaryManager(this.summarizerClientElection, this, // IConnectedState
|
|
985
|
-
|
|
1021
|
+
summaryCollection, this.baseLogger, this.formCreateSummarizerFn(loader), new throttler_js_1.Throttler(60 * 1000, // 60 sec delay window
|
|
986
1022
|
30 * 1000, // 30 sec max delay
|
|
987
1023
|
// throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
|
|
988
1024
|
(0, throttler_js_1.formExponentialFn)({ coefficient: 20, initialDelay: 0 })), {
|
|
989
|
-
initialDelayMs:
|
|
1025
|
+
initialDelayMs: initialSummarizerDelayMs,
|
|
990
1026
|
});
|
|
991
1027
|
// Forward events from SummaryManager
|
|
992
|
-
[
|
|
1028
|
+
for (const eventName of [
|
|
993
1029
|
"summarize",
|
|
994
1030
|
"summarizeAllAttemptsFailed",
|
|
995
1031
|
"summarizerStop",
|
|
996
1032
|
"summarizerStart",
|
|
997
1033
|
"summarizerStartupFailed",
|
|
998
|
-
]
|
|
1034
|
+
]) {
|
|
999
1035
|
this.summaryManager?.on(eventName, (...args) => {
|
|
1000
1036
|
this.emit(eventName, ...args);
|
|
1001
1037
|
});
|
|
1002
|
-
}
|
|
1038
|
+
}
|
|
1003
1039
|
this.summaryManager.start();
|
|
1004
1040
|
}
|
|
1005
1041
|
}
|
|
1006
1042
|
// logging hardware telemetry
|
|
1007
|
-
this.
|
|
1043
|
+
this.baseLogger.send({
|
|
1044
|
+
category: "generic",
|
|
1008
1045
|
eventName: "DeviceSpec",
|
|
1009
1046
|
...getDeviceSpec(),
|
|
1010
1047
|
});
|
|
@@ -1016,13 +1053,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1016
1053
|
summaryFormatVersion: metadata?.summaryFormatVersion,
|
|
1017
1054
|
disableIsolatedChannels: metadata?.disableIsolatedChannels,
|
|
1018
1055
|
gcVersion: metadata?.gcFeature,
|
|
1019
|
-
options: JSON.stringify(
|
|
1056
|
+
options: JSON.stringify(baseRuntimeOptions),
|
|
1020
1057
|
idCompressorModeMetadata: metadata?.documentSchema?.runtime?.idCompressorMode,
|
|
1021
|
-
idCompressorMode: this.idCompressorMode,
|
|
1058
|
+
idCompressorMode: this.sessionSchema.idCompressorMode,
|
|
1022
1059
|
sessionRuntimeSchema: JSON.stringify(this.sessionSchema),
|
|
1023
1060
|
featureGates: JSON.stringify({
|
|
1024
1061
|
...featureGatesForTelemetry,
|
|
1025
|
-
disableAttachReorder: this.disableAttachReorder,
|
|
1026
1062
|
disablePartialFlush,
|
|
1027
1063
|
closeSummarizerDelayOverride,
|
|
1028
1064
|
}),
|
|
@@ -1030,11 +1066,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1030
1066
|
groupedBatchingEnabled: this.groupedBatchingEnabled,
|
|
1031
1067
|
initialSequenceNumber: this.deltaManager.initialSequenceNumber,
|
|
1032
1068
|
});
|
|
1033
|
-
(0, connectionTelemetry_js_1.ReportOpPerfTelemetry)(this.clientId, this._deltaManager, this, this.
|
|
1034
|
-
(0, batchTracker_js_1.BindBatchTracker)(this, this.
|
|
1069
|
+
(0, connectionTelemetry_js_1.ReportOpPerfTelemetry)(this.clientId, this._deltaManager, this, this.baseLogger);
|
|
1070
|
+
(0, batchTracker_js_1.BindBatchTracker)(this, this.baseLogger);
|
|
1035
1071
|
this.entryPoint = new internal_2.LazyPromise(async () => {
|
|
1036
|
-
if (this.
|
|
1037
|
-
(0, internal_2.assert)(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
|
|
1072
|
+
if (this._summarizer !== undefined) {
|
|
1038
1073
|
return this._summarizer;
|
|
1039
1074
|
}
|
|
1040
1075
|
return provideEntryPoint(this);
|
|
@@ -1043,8 +1078,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1043
1078
|
// saved state, i.e. all the ops marked by Loader layer sa savedOp === true.
|
|
1044
1079
|
this.skipSavedCompressorOps = pendingRuntimeState?.pendingIdCompressorState !== undefined;
|
|
1045
1080
|
}
|
|
1081
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1046
1082
|
onSchemaChange(schema) {
|
|
1047
|
-
this.logger.sendTelemetryEvent({
|
|
1083
|
+
this.mc.logger.sendTelemetryEvent({
|
|
1048
1084
|
eventName: "SchemaChangeAccept",
|
|
1049
1085
|
sessionRuntimeSchema: JSON.stringify(schema),
|
|
1050
1086
|
});
|
|
@@ -1067,19 +1103,20 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1067
1103
|
deleteChildSummarizerNode(id) {
|
|
1068
1104
|
return this.summarizerNode.deleteChild(id);
|
|
1069
1105
|
}
|
|
1070
|
-
|
|
1106
|
+
// #region `IFluidParentContext` APIs that should not be called on Root
|
|
1071
1107
|
makeLocallyVisible() {
|
|
1072
1108
|
(0, internal_2.assert)(false, 0x8eb /* should not be called */);
|
|
1073
1109
|
}
|
|
1074
1110
|
setChannelDirty(address) {
|
|
1075
1111
|
(0, internal_2.assert)(false, 0x909 /* should not be called */);
|
|
1076
1112
|
}
|
|
1113
|
+
// #endregion
|
|
1077
1114
|
/**
|
|
1078
1115
|
* Initializes the state from the base snapshot this container runtime loaded from.
|
|
1079
1116
|
*/
|
|
1080
1117
|
async initializeBaseState() {
|
|
1081
|
-
if (this.idCompressorMode === "on" ||
|
|
1082
|
-
(this.idCompressorMode === "delayed" && this.connected)) {
|
|
1118
|
+
if (this.sessionSchema.idCompressorMode === "on" ||
|
|
1119
|
+
(this.sessionSchema.idCompressorMode === "delayed" && this.connected)) {
|
|
1083
1120
|
this._idCompressor = await this.createIdCompressor();
|
|
1084
1121
|
// This is called from loadRuntime(), long before we process any ops, so there should be no ops accumulated yet.
|
|
1085
1122
|
(0, internal_2.assert)(this.pendingIdCompressorOps.length === 0, 0x8ec /* no pending ops */);
|
|
@@ -1104,6 +1141,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1104
1141
|
this._summarizer?.dispose();
|
|
1105
1142
|
this.channelCollection.dispose();
|
|
1106
1143
|
this.pendingStateManager.dispose();
|
|
1144
|
+
this.inboundBatchAggregator.dispose();
|
|
1145
|
+
this.deltaScheduler.dispose();
|
|
1107
1146
|
this.emit("dispose");
|
|
1108
1147
|
this.removeAllListeners();
|
|
1109
1148
|
}
|
|
@@ -1120,7 +1159,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1120
1159
|
// Lookup up in the cache, if not present then make the network call as multiple datastores could
|
|
1121
1160
|
// be in same loading group. So, once we have fetched the snapshot for that loading group on
|
|
1122
1161
|
// any request, then cache that as same group could be requested in future too.
|
|
1123
|
-
const snapshot = await this.snapshotCacheForLoadingGroupIds.addOrGet(sortedLoadingGroupIds.join(), async () => {
|
|
1162
|
+
const snapshot = await this.snapshotCacheForLoadingGroupIds.addOrGet(sortedLoadingGroupIds.join(","), async () => {
|
|
1124
1163
|
(0, internal_2.assert)(this.storage.getSnapshot !== undefined, 0x8ee /* getSnapshot api should be defined if used */);
|
|
1125
1164
|
loadedFromCache = false;
|
|
1126
1165
|
return this.storage.getSnapshot({
|
|
@@ -1129,7 +1168,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1129
1168
|
loadingGroupIds: sortedLoadingGroupIds,
|
|
1130
1169
|
});
|
|
1131
1170
|
});
|
|
1132
|
-
this.logger.sendTelemetryEvent({
|
|
1171
|
+
this.mc.logger.sendTelemetryEvent({
|
|
1133
1172
|
eventName: "GroupIdSnapshotFetched",
|
|
1134
1173
|
details: JSON.stringify({
|
|
1135
1174
|
fromCache: loadedFromCache,
|
|
@@ -1159,7 +1198,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1159
1198
|
// another snapshot from which the summarizer loaded and it is behind, then just give up as
|
|
1160
1199
|
// the summarizer state is not up to date.
|
|
1161
1200
|
// This should be a recoverable scenario and shouldn't happen as we should process the ack first.
|
|
1162
|
-
if (this.
|
|
1201
|
+
if (this._summarizer !== undefined) {
|
|
1163
1202
|
throw new Error("Summarizer client behind, loaded newer snapshot with loadingGroupId");
|
|
1164
1203
|
}
|
|
1165
1204
|
// We want to catchup from sequenceNumber to targetSequenceNumber
|
|
@@ -1221,7 +1260,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1221
1260
|
return {
|
|
1222
1261
|
status: 200,
|
|
1223
1262
|
mimeType: "fluid/object",
|
|
1224
|
-
value: this.
|
|
1263
|
+
value: this._summarizer,
|
|
1225
1264
|
};
|
|
1226
1265
|
}
|
|
1227
1266
|
return (0, internal_6.create404Response)(request);
|
|
@@ -1276,7 +1315,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1276
1315
|
internalId(maybeAlias) {
|
|
1277
1316
|
return this.channelCollection.internalId(maybeAlias);
|
|
1278
1317
|
}
|
|
1279
|
-
/**
|
|
1318
|
+
/**
|
|
1319
|
+
* Adds the container's metadata to the given summary tree.
|
|
1320
|
+
*/
|
|
1280
1321
|
addMetadataToSummary(summaryTree) {
|
|
1281
1322
|
// The last message processed at the time of summary. If there are no new messages, use the message from the
|
|
1282
1323
|
// last summary.
|
|
@@ -1285,6 +1326,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1285
1326
|
const documentSchema = this.documentsSchemaController.summarizeDocumentSchema(this.deltaManager.lastSequenceNumber);
|
|
1286
1327
|
// Is document schema explicit control on?
|
|
1287
1328
|
const explicitSchemaControl = documentSchema?.runtime.explicitSchemaControl;
|
|
1329
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1288
1330
|
const metadata = {
|
|
1289
1331
|
...this.createContainerMetadata,
|
|
1290
1332
|
// Increment the summary number for the next summary that will be generated.
|
|
@@ -1298,7 +1340,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1298
1340
|
// last message's sequence number.
|
|
1299
1341
|
// See also lastMessageFromMetadata()
|
|
1300
1342
|
message: explicitSchemaControl
|
|
1301
|
-
?
|
|
1343
|
+
? // eslint-disable-next-line import/no-deprecated
|
|
1344
|
+
{ sequenceNumber: -1 }
|
|
1302
1345
|
: message,
|
|
1303
1346
|
lastMessage: explicitSchemaControl ? message : undefined,
|
|
1304
1347
|
documentSchema,
|
|
@@ -1414,9 +1457,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1414
1457
|
switch (opContents.type) {
|
|
1415
1458
|
case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
|
|
1416
1459
|
case messageTypes_js_1.ContainerMessageType.Attach:
|
|
1417
|
-
case messageTypes_js_1.ContainerMessageType.Alias:
|
|
1460
|
+
case messageTypes_js_1.ContainerMessageType.Alias: {
|
|
1418
1461
|
return this.channelCollection.applyStashedOp(opContents);
|
|
1419
|
-
|
|
1462
|
+
}
|
|
1463
|
+
case messageTypes_js_1.ContainerMessageType.IdAllocation: {
|
|
1420
1464
|
// IDs allocation ops in stashed state are ignored because the tip state of the compressor
|
|
1421
1465
|
// is serialized into the pending state. This is done because generation of new IDs during
|
|
1422
1466
|
// stashed op application (or, later, resubmit) must generate new IDs and if the compressor
|
|
@@ -1426,17 +1470,22 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1426
1470
|
// and the runtime could filter out all ID allocation ops from the stashed state and apply them
|
|
1427
1471
|
// before applying the rest of the stashed ops. This would accomplish the same thing but with
|
|
1428
1472
|
// better performance in future incremental stashed state creation.
|
|
1429
|
-
(0, internal_2.assert)(this.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
|
|
1473
|
+
(0, internal_2.assert)(this.sessionSchema.idCompressorMode !== undefined, 0x8f1 /* ID compressor should be in use */);
|
|
1430
1474
|
return;
|
|
1431
|
-
|
|
1475
|
+
}
|
|
1476
|
+
case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange: {
|
|
1432
1477
|
return;
|
|
1433
|
-
|
|
1478
|
+
}
|
|
1479
|
+
case messageTypes_js_1.ContainerMessageType.BlobAttach: {
|
|
1434
1480
|
return;
|
|
1435
|
-
|
|
1481
|
+
}
|
|
1482
|
+
case messageTypes_js_1.ContainerMessageType.Rejoin: {
|
|
1436
1483
|
throw new Error("rejoin not expected here");
|
|
1437
|
-
|
|
1484
|
+
}
|
|
1485
|
+
case messageTypes_js_1.ContainerMessageType.GC: {
|
|
1438
1486
|
// GC op is only sent in summarizer which should never have stashed ops.
|
|
1439
1487
|
throw new internal_7.LoggingError("GC op not expected to be stashed in summarizer");
|
|
1488
|
+
}
|
|
1440
1489
|
default: {
|
|
1441
1490
|
const error = getUnknownMessageTypeError(opContents.type, "applyStashedOp" /* codePath */);
|
|
1442
1491
|
this.closeFn(error);
|
|
@@ -1446,7 +1495,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1446
1495
|
}
|
|
1447
1496
|
async loadIdCompressor() {
|
|
1448
1497
|
if (this._idCompressor === undefined &&
|
|
1449
|
-
this.idCompressorMode !== undefined &&
|
|
1498
|
+
this.sessionSchema.idCompressorMode !== undefined &&
|
|
1450
1499
|
this._loadIdCompressor === undefined) {
|
|
1451
1500
|
this._loadIdCompressor = this.createIdCompressor()
|
|
1452
1501
|
.then((compressor) => {
|
|
@@ -1460,7 +1509,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1460
1509
|
this._idCompressor = compressor;
|
|
1461
1510
|
})
|
|
1462
1511
|
.catch((error) => {
|
|
1463
|
-
this.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
|
|
1512
|
+
this.mc.logger.sendErrorEvent({ eventName: "IdCompressorDelayedLoad" }, error);
|
|
1464
1513
|
throw error;
|
|
1465
1514
|
});
|
|
1466
1515
|
}
|
|
@@ -1471,7 +1520,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1471
1520
|
const currentClientId = this._audience.getSelf()?.clientId;
|
|
1472
1521
|
(0, internal_2.assert)(clientId === currentClientId, 0x977 /* input clientId does not match Audience */);
|
|
1473
1522
|
(0, internal_2.assert)(this.clientId === currentClientId, 0x978 /* this.clientId does not match Audience */);
|
|
1474
|
-
if (connected && this.idCompressorMode === "delayed") {
|
|
1523
|
+
if (connected && this.sessionSchema.idCompressorMode === "delayed") {
|
|
1475
1524
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1476
1525
|
this.loadIdCompressor();
|
|
1477
1526
|
}
|
|
@@ -1560,7 +1609,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1560
1609
|
// or something different, like a system message.
|
|
1561
1610
|
const hasModernRuntimeMessageEnvelope = messageCopy.type === internal_3.MessageType.Operation;
|
|
1562
1611
|
const savedOp = messageCopy.metadata?.savedOp;
|
|
1563
|
-
const logLegacyCase = (0, exports.getSingleUseLegacyLogCallback)(this.logger, messageCopy.type);
|
|
1612
|
+
const logLegacyCase = (0, exports.getSingleUseLegacyLogCallback)(this.mc.logger, messageCopy.type);
|
|
1564
1613
|
let runtimeBatch = hasModernRuntimeMessageEnvelope || isUnpackedRuntimeMessage(messageCopy);
|
|
1565
1614
|
if (runtimeBatch) {
|
|
1566
1615
|
// We expect runtime messages to have JSON contents - deserialize it in place.
|
|
@@ -1645,7 +1694,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1645
1694
|
}
|
|
1646
1695
|
}
|
|
1647
1696
|
/**
|
|
1648
|
-
* Processes inbound message(s). It calls
|
|
1697
|
+
* Processes inbound message(s). It calls delta scheduler according to the messages' location in the batch.
|
|
1649
1698
|
* @param messagesWithMetadata - messages to process along with their metadata.
|
|
1650
1699
|
* @param locationInBatch - Are we processing the start and/or end of a batch?
|
|
1651
1700
|
* @param local - true if the messages were originally generated by the client receiving it.
|
|
@@ -1657,19 +1706,19 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1657
1706
|
if (locationInBatch.batchStart) {
|
|
1658
1707
|
const firstMessage = messagesWithMetadata[0]?.message;
|
|
1659
1708
|
(0, internal_2.assert)(firstMessage !== undefined, 0xa31 /* Batch must have at least one message */);
|
|
1660
|
-
this.
|
|
1709
|
+
this.emit("batchBegin", firstMessage);
|
|
1661
1710
|
}
|
|
1662
1711
|
let error;
|
|
1663
1712
|
try {
|
|
1664
1713
|
if (!runtimeBatch) {
|
|
1665
|
-
|
|
1714
|
+
for (const { message } of messagesWithMetadata) {
|
|
1666
1715
|
this.ensureNoDataModelChanges(() => {
|
|
1667
1716
|
this.observeNonRuntimeMessage(message);
|
|
1668
1717
|
});
|
|
1669
|
-
}
|
|
1718
|
+
}
|
|
1670
1719
|
return;
|
|
1671
1720
|
}
|
|
1672
|
-
//
|
|
1721
|
+
// Updates a message's minimum sequence number to the minimum sequence number that container
|
|
1673
1722
|
// runtime is tracking and sets _processedClientSequenceNumber. It returns the updated message.
|
|
1674
1723
|
const updateSequenceNumbers = (message) => {
|
|
1675
1724
|
// Set the minimum sequence number to the containerRuntime's understanding of minimum sequence number.
|
|
@@ -1700,7 +1749,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1700
1749
|
}
|
|
1701
1750
|
let bunchedMessagesContent = [];
|
|
1702
1751
|
let previousMessage;
|
|
1703
|
-
//
|
|
1752
|
+
// Process the previous bunch of messages.
|
|
1704
1753
|
const sendBunchedMessages = () => {
|
|
1705
1754
|
(0, internal_2.assert)(previousMessage !== undefined, 0xa67 /* previous message must exist */);
|
|
1706
1755
|
this.ensureNoDataModelChanges(() => {
|
|
@@ -1734,15 +1783,15 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1734
1783
|
this.emit("op", message, true /* runtimeMessage */);
|
|
1735
1784
|
}
|
|
1736
1785
|
}
|
|
1737
|
-
catch (
|
|
1738
|
-
error =
|
|
1786
|
+
catch (error_) {
|
|
1787
|
+
error = error_;
|
|
1739
1788
|
throw error;
|
|
1740
1789
|
}
|
|
1741
1790
|
finally {
|
|
1742
1791
|
if (locationInBatch.batchEnd) {
|
|
1743
1792
|
const lastMessage = messagesWithMetadata[messagesWithMetadata.length - 1]?.message;
|
|
1744
1793
|
(0, internal_2.assert)(lastMessage !== undefined, 0xa32 /* Batch must have at least one message */);
|
|
1745
|
-
this.
|
|
1794
|
+
this.emit("batchEnd", error, lastMessage);
|
|
1746
1795
|
}
|
|
1747
1796
|
}
|
|
1748
1797
|
}
|
|
@@ -1792,30 +1841,39 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1792
1841
|
switch (message.type) {
|
|
1793
1842
|
case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
|
|
1794
1843
|
case messageTypes_js_1.ContainerMessageType.Attach:
|
|
1795
|
-
case messageTypes_js_1.ContainerMessageType.Alias:
|
|
1844
|
+
case messageTypes_js_1.ContainerMessageType.Alias: {
|
|
1796
1845
|
// Remove the metadata from the message before sending it to the channel collection. The metadata
|
|
1797
1846
|
// is added by the container runtime and is not part of the message that the channel collection and
|
|
1798
1847
|
// layers below it expect.
|
|
1799
1848
|
this.channelCollection.processMessages({ envelope: message, messagesContent, local });
|
|
1800
1849
|
break;
|
|
1801
|
-
|
|
1850
|
+
}
|
|
1851
|
+
case messageTypes_js_1.ContainerMessageType.BlobAttach: {
|
|
1802
1852
|
this.blobManager.processBlobAttachMessage(message, local);
|
|
1803
1853
|
break;
|
|
1804
|
-
|
|
1854
|
+
}
|
|
1855
|
+
case messageTypes_js_1.ContainerMessageType.IdAllocation: {
|
|
1805
1856
|
this.processIdCompressorMessages(contents, savedOp);
|
|
1806
1857
|
break;
|
|
1807
|
-
|
|
1858
|
+
}
|
|
1859
|
+
case messageTypes_js_1.ContainerMessageType.GC: {
|
|
1808
1860
|
this.garbageCollector.processMessages(contents, message.timestamp, local);
|
|
1809
1861
|
break;
|
|
1810
|
-
|
|
1862
|
+
}
|
|
1863
|
+
case messageTypes_js_1.ContainerMessageType.ChunkedOp: {
|
|
1811
1864
|
// From observability POV, we should not expose the rest of the system (including "op" events on object) to these messages.
|
|
1812
1865
|
// Also resetReconnectCount() would be wrong - see comment that was there before this change was made.
|
|
1813
1866
|
(0, internal_2.assert)(false, 0x93d /* should not even get here */);
|
|
1814
|
-
|
|
1867
|
+
}
|
|
1868
|
+
case messageTypes_js_1.ContainerMessageType.Rejoin: {
|
|
1815
1869
|
break;
|
|
1816
|
-
|
|
1817
|
-
|
|
1870
|
+
}
|
|
1871
|
+
case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange: {
|
|
1872
|
+
this.documentsSchemaController.processDocumentSchemaMessages(
|
|
1873
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1874
|
+
contents, local, message.sequenceNumber);
|
|
1818
1875
|
break;
|
|
1876
|
+
}
|
|
1819
1877
|
default: {
|
|
1820
1878
|
const error = getUnknownMessageTypeError(message.type, "validateAndProcessRuntimeMessage" /* codePath */, message);
|
|
1821
1879
|
this.closeFn(error);
|
|
@@ -1833,7 +1891,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1833
1891
|
// Some other client turned on the id compressor. If we have not turned it on,
|
|
1834
1892
|
// put it in a pending queue and delay finalization.
|
|
1835
1893
|
if (this._idCompressor === undefined) {
|
|
1836
|
-
(0, internal_2.assert)(this.idCompressorMode !== undefined, 0x93c /* id compressor should be enabled */);
|
|
1894
|
+
(0, internal_2.assert)(this.sessionSchema.idCompressorMode !== undefined, 0x93c /* id compressor should be enabled */);
|
|
1837
1895
|
this.pendingIdCompressorOps.push(range);
|
|
1838
1896
|
}
|
|
1839
1897
|
else {
|
|
@@ -1867,7 +1925,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1867
1925
|
* Updates signal telemetry including emitting telemetry events.
|
|
1868
1926
|
*/
|
|
1869
1927
|
processSignalForTelemetry(envelope) {
|
|
1870
|
-
const { clientBroadcastSignalSequenceNumber } = envelope;
|
|
1928
|
+
const { clientBroadcastSignalSequenceNumber, contents: envelopeContents, address: envelopeAddress, } = envelope;
|
|
1871
1929
|
if (clientBroadcastSignalSequenceNumber === undefined) {
|
|
1872
1930
|
return;
|
|
1873
1931
|
}
|
|
@@ -1905,8 +1963,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1905
1963
|
};
|
|
1906
1964
|
// Only log `contents.type` when address is for container to avoid
|
|
1907
1965
|
// chance that contents type is customer data.
|
|
1908
|
-
if (
|
|
1909
|
-
details.contentsType =
|
|
1966
|
+
if (envelopeAddress === undefined) {
|
|
1967
|
+
details.contentsType = envelopeContents.type; // Type of signal that was received out of order.
|
|
1910
1968
|
}
|
|
1911
1969
|
this.mc.logger.sendTelemetryEvent({
|
|
1912
1970
|
eventName: "SignalOutOfOrder",
|
|
@@ -1987,8 +2045,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
1987
2045
|
try {
|
|
1988
2046
|
checkpoint.rollback((message) => this.rollback(message.contents, message.localOpMetadata));
|
|
1989
2047
|
}
|
|
1990
|
-
catch (
|
|
1991
|
-
const error2 = (0, internal_7.wrapError)(
|
|
2048
|
+
catch (error_) {
|
|
2049
|
+
const error2 = (0, internal_7.wrapError)(error_, (message) => {
|
|
1992
2050
|
return internal_7.DataProcessingError.create(`RollbackError: ${message}`, "checkpointRollback", undefined);
|
|
1993
2051
|
});
|
|
1994
2052
|
this.closeFn(error2);
|
|
@@ -2049,15 +2107,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2049
2107
|
return this.channelCollection.createDetachedDataStore(pkg, loadingGroupId);
|
|
2050
2108
|
}
|
|
2051
2109
|
async createDataStore(pkg, loadingGroupId) {
|
|
2052
|
-
const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg],
|
|
2053
|
-
loadingGroupId);
|
|
2054
|
-
return (0, dataStore_js_1.channelToDataStore)(await context.realize(), context.id, this.channelCollection, this.mc.logger);
|
|
2055
|
-
}
|
|
2056
|
-
/**
|
|
2057
|
-
* @deprecated 0.16 Issue #1537, #3631
|
|
2058
|
-
*/
|
|
2059
|
-
async _createDataStoreWithProps(pkg, props) {
|
|
2060
|
-
const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], props);
|
|
2110
|
+
const context = this.channelCollection.createDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], loadingGroupId);
|
|
2061
2111
|
return (0, dataStore_js_1.channelToDataStore)(await context.realize(), context.id, this.channelCollection, this.mc.logger);
|
|
2062
2112
|
}
|
|
2063
2113
|
canSendOps() {
|
|
@@ -2084,7 +2134,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2084
2134
|
get isDirty() {
|
|
2085
2135
|
return this.dirtyContainer;
|
|
2086
2136
|
}
|
|
2087
|
-
isContainerMessageDirtyable({ type, contents }) {
|
|
2137
|
+
isContainerMessageDirtyable({ type, contents, }) {
|
|
2088
2138
|
// Certain container runtime messages should not mark the container dirty such as the old built-in
|
|
2089
2139
|
// AgentScheduler and Garbage collector messages.
|
|
2090
2140
|
switch (type) {
|
|
@@ -2107,8 +2157,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2107
2157
|
case messageTypes_js_1.ContainerMessageType.GC: {
|
|
2108
2158
|
return false;
|
|
2109
2159
|
}
|
|
2110
|
-
default:
|
|
2160
|
+
default: {
|
|
2111
2161
|
break;
|
|
2162
|
+
}
|
|
2112
2163
|
}
|
|
2113
2164
|
return true;
|
|
2114
2165
|
}
|
|
@@ -2137,7 +2188,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2137
2188
|
clientBroadcastSignalSequenceNumber;
|
|
2138
2189
|
}
|
|
2139
2190
|
// We should not track the round trip of a new signal in the case we are already tracking one.
|
|
2140
|
-
if (clientBroadcastSignalSequenceNumber %
|
|
2191
|
+
if (clientBroadcastSignalSequenceNumber % defaultTelemetrySignalSampleCount === 1 &&
|
|
2141
2192
|
this._signalTracking.roundTripSignalSequenceNumber === undefined) {
|
|
2142
2193
|
this._signalTracking.signalTimestamp = Date.now();
|
|
2143
2194
|
this._signalTracking.roundTripSignalSequenceNumber =
|
|
@@ -2203,6 +2254,12 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2203
2254
|
this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
|
|
2204
2255
|
return summarizeResult.summary;
|
|
2205
2256
|
}
|
|
2257
|
+
/**
|
|
2258
|
+
* Builds the Summary tree including all the channels and the container state.
|
|
2259
|
+
*
|
|
2260
|
+
* @remarks - Unfortunately, this function is accessed in a non-typesafe way by a legacy first-party partner,
|
|
2261
|
+
* so until we can provide a proper API for their scenario, we need to ensure this function doesn't change.
|
|
2262
|
+
*/
|
|
2206
2263
|
async summarizeInternal(fullTree, trackState, telemetryContext) {
|
|
2207
2264
|
const summarizeResult = await this.channelCollection.summarize(fullTree, trackState, telemetryContext);
|
|
2208
2265
|
// Wrap data store summaries in .channels subtree.
|
|
@@ -2283,8 +2340,10 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2283
2340
|
*/
|
|
2284
2341
|
deleteSweepReadyNodes(sweepReadyRoutes) {
|
|
2285
2342
|
const { dataStoreRoutes, blobManagerRoutes } = this.getDataStoreAndBlobManagerRoutes(sweepReadyRoutes);
|
|
2286
|
-
|
|
2287
|
-
|
|
2343
|
+
return [
|
|
2344
|
+
...this.channelCollection.deleteSweepReadyNodes(dataStoreRoutes),
|
|
2345
|
+
...this.blobManager.deleteSweepReadyNodes(blobManagerRoutes),
|
|
2346
|
+
];
|
|
2288
2347
|
}
|
|
2289
2348
|
/**
|
|
2290
2349
|
* This is called to update objects that are tombstones.
|
|
@@ -2310,10 +2369,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2310
2369
|
* Returns the type of the GC node. Currently, there are nodes that belong to the root ("/"), data stores or
|
|
2311
2370
|
* blob manager.
|
|
2312
2371
|
*/
|
|
2372
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2313
2373
|
getNodeType(nodePath) {
|
|
2314
2374
|
if ((0, index_js_1.isBlobPath)(nodePath)) {
|
|
2375
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2315
2376
|
return index_js_2.GCNodeType.Blob;
|
|
2316
2377
|
}
|
|
2378
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2317
2379
|
return this.channelCollection.getGCNodeType(nodePath) ?? index_js_2.GCNodeType.Other;
|
|
2318
2380
|
}
|
|
2319
2381
|
/**
|
|
@@ -2327,13 +2389,19 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2327
2389
|
return ["_gcRoot"];
|
|
2328
2390
|
}
|
|
2329
2391
|
switch (this.getNodeType(nodePath)) {
|
|
2330
|
-
|
|
2392
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2393
|
+
case index_js_2.GCNodeType.Blob: {
|
|
2331
2394
|
return [index_js_1.blobManagerBasePath];
|
|
2395
|
+
}
|
|
2396
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2332
2397
|
case index_js_2.GCNodeType.DataStore:
|
|
2333
|
-
|
|
2398
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2399
|
+
case index_js_2.GCNodeType.SubDataStore: {
|
|
2334
2400
|
return this.channelCollection.getDataStorePackagePath(nodePath);
|
|
2335
|
-
|
|
2401
|
+
}
|
|
2402
|
+
default: {
|
|
2336
2403
|
(0, internal_2.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
|
|
2404
|
+
}
|
|
2337
2405
|
}
|
|
2338
2406
|
}
|
|
2339
2407
|
/**
|
|
@@ -2395,8 +2463,9 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2395
2463
|
* op processing, updating SummarizerNode state tracking, and garbage collection.
|
|
2396
2464
|
* @param options - options controlling how the summary is generated or submitted
|
|
2397
2465
|
*/
|
|
2466
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2398
2467
|
async submitSummary(options) {
|
|
2399
|
-
const { fullTree = false, finalAttempt = false, summaryLogger, latestSummaryRefSeqNum, } = options;
|
|
2468
|
+
const { cancellationToken, fullTree = false, finalAttempt = false, summaryLogger, latestSummaryRefSeqNum, } = options;
|
|
2400
2469
|
// The summary number for this summary. This will be updated during the summary process, so get it now and
|
|
2401
2470
|
// use it for all events logged during this summary.
|
|
2402
2471
|
const summaryNumber = this.nextSummaryNumber;
|
|
@@ -2480,7 +2549,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2480
2549
|
eventName: "LatestSummaryRefSeqNumMismatch",
|
|
2481
2550
|
details: {
|
|
2482
2551
|
...startSummaryResult,
|
|
2483
|
-
mismatchNumbers:
|
|
2552
|
+
mismatchNumbers: [...startSummaryResult.mismatchNumbers],
|
|
2484
2553
|
},
|
|
2485
2554
|
});
|
|
2486
2555
|
if (shouldValidatePreSummaryState && !finalAttempt) {
|
|
@@ -2500,7 +2569,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2500
2569
|
// summarizer to reconnect in the future.
|
|
2501
2570
|
// Also checking for cancellation is a must as summary process may be abandoned for other reasons,
|
|
2502
2571
|
// like loss of connectivity for main (interactive) client.
|
|
2503
|
-
if (
|
|
2572
|
+
if (cancellationToken.cancelled) {
|
|
2504
2573
|
return { continue: false, error: "disconnected" };
|
|
2505
2574
|
}
|
|
2506
2575
|
// That said, we rely on submitSystemMessage() that today only works in connected state.
|
|
@@ -2613,7 +2682,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2613
2682
|
};
|
|
2614
2683
|
let handle;
|
|
2615
2684
|
try {
|
|
2616
|
-
handle = await this.storage.uploadSummaryWithContext(
|
|
2685
|
+
handle = await this.storage.uploadSummaryWithContext(summaryTree, summaryContext);
|
|
2617
2686
|
}
|
|
2618
2687
|
catch (error) {
|
|
2619
2688
|
return {
|
|
@@ -2735,13 +2804,13 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2735
2804
|
return this.pendingMessagesCount !== 0;
|
|
2736
2805
|
}
|
|
2737
2806
|
updateDocumentDirtyState(dirty) {
|
|
2738
|
-
if (this.attachState
|
|
2739
|
-
(0, internal_2.assert)(dirty, 0x3d2 /* Non-attached container is dirty */);
|
|
2740
|
-
}
|
|
2741
|
-
else {
|
|
2807
|
+
if (this.attachState === container_definitions_1.AttachState.Attached) {
|
|
2742
2808
|
// Other way is not true = see this.isContainerMessageDirtyable()
|
|
2743
2809
|
(0, internal_2.assert)(!dirty || this.hasPendingMessages(), 0x3d3 /* if doc is dirty, there has to be pending ops */);
|
|
2744
2810
|
}
|
|
2811
|
+
else {
|
|
2812
|
+
(0, internal_2.assert)(dirty, 0x3d2 /* Non-attached container is dirty */);
|
|
2813
|
+
}
|
|
2745
2814
|
if (this.dirtyContainer === dirty) {
|
|
2746
2815
|
return;
|
|
2747
2816
|
}
|
|
@@ -2750,7 +2819,11 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2750
2819
|
this.emit(dirty ? "dirty" : "saved");
|
|
2751
2820
|
}
|
|
2752
2821
|
}
|
|
2753
|
-
submitMessage(type,
|
|
2822
|
+
submitMessage(type,
|
|
2823
|
+
// TODO: better typing
|
|
2824
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
|
|
2825
|
+
contents, localOpMetadata = undefined) {
|
|
2826
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
2754
2827
|
this.submit({ type, contents }, localOpMetadata);
|
|
2755
2828
|
}
|
|
2756
2829
|
async uploadBlob(blob, signal) {
|
|
@@ -2799,7 +2872,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2799
2872
|
// on this callback to do actual sending.
|
|
2800
2873
|
const schemaChangeMessage = this.documentsSchemaController.maybeSendSchemaMessage();
|
|
2801
2874
|
if (schemaChangeMessage) {
|
|
2802
|
-
this.logger.sendTelemetryEvent({
|
|
2875
|
+
this.mc.logger.sendTelemetryEvent({
|
|
2803
2876
|
eventName: "SchemaChangeProposal",
|
|
2804
2877
|
refSeq: schemaChangeMessage.refSeq,
|
|
2805
2878
|
version: schemaChangeMessage.version,
|
|
@@ -2851,6 +2924,8 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2851
2924
|
return;
|
|
2852
2925
|
}
|
|
2853
2926
|
this.flushTaskExists = true;
|
|
2927
|
+
// TODO: hoist this out of the function scope to save unnecessary allocations
|
|
2928
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping -- Separate `flush` method already exists in outer scope
|
|
2854
2929
|
const flush = () => {
|
|
2855
2930
|
this.flushTaskExists = false;
|
|
2856
2931
|
try {
|
|
@@ -2861,22 +2936,25 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2861
2936
|
}
|
|
2862
2937
|
};
|
|
2863
2938
|
switch (this.flushMode) {
|
|
2864
|
-
case internal_5.FlushMode.TurnBased:
|
|
2939
|
+
case internal_5.FlushMode.TurnBased: {
|
|
2865
2940
|
// When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
|
|
2866
2941
|
// batch at the end of the turn
|
|
2867
2942
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
2868
2943
|
Promise.resolve().then(flush);
|
|
2869
2944
|
break;
|
|
2945
|
+
}
|
|
2870
2946
|
// FlushModeExperimental is experimental and not exposed directly in the runtime APIs
|
|
2871
|
-
case internal_5.FlushModeExperimental.Async:
|
|
2947
|
+
case internal_5.FlushModeExperimental.Async: {
|
|
2872
2948
|
// When in Async flush mode, the runtime will accumulate all operations across JS turns and send them as a single
|
|
2873
2949
|
// batch when all micro-tasks are complete.
|
|
2874
2950
|
// Compared to TurnBased, this flush mode will capture more ops into the same batch.
|
|
2875
2951
|
setTimeout(flush, 0);
|
|
2876
2952
|
break;
|
|
2877
|
-
|
|
2953
|
+
}
|
|
2954
|
+
default: {
|
|
2878
2955
|
(0, internal_2.assert)(this._orderSequentiallyCalls > 0, 0x587 /* Unreachable unless running under orderSequentially */);
|
|
2879
2956
|
break;
|
|
2957
|
+
}
|
|
2880
2958
|
}
|
|
2881
2959
|
}
|
|
2882
2960
|
submitSummaryMessage(contents, referenceSequenceNumber) {
|
|
@@ -2884,10 +2962,7 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2884
2962
|
(0, internal_2.assert)(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
|
|
2885
2963
|
// System message should not be sent in the middle of the batch.
|
|
2886
2964
|
(0, internal_2.assert)(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
|
|
2887
|
-
|
|
2888
|
-
return this.submitSummaryFn !== undefined
|
|
2889
|
-
? this.submitSummaryFn(contents, referenceSequenceNumber)
|
|
2890
|
-
: this.submitFn(internal_3.MessageType.Summarize, contents, false);
|
|
2965
|
+
return this.submitSummaryFn(contents, referenceSequenceNumber);
|
|
2891
2966
|
}
|
|
2892
2967
|
/**
|
|
2893
2968
|
* Throw an error if the runtime is closed. Methods that are expected to potentially
|
|
@@ -2927,15 +3002,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2927
3002
|
* @param localOpMetadata - The local metadata associated with the original message.
|
|
2928
3003
|
*/
|
|
2929
3004
|
reSubmitCore(message, localOpMetadata, opMetadata) {
|
|
2930
|
-
(0, internal_2.assert)(
|
|
3005
|
+
(0, internal_2.assert)(this._summarizer === undefined, 0x8f2 /* Summarizer never reconnects so should never resubmit */);
|
|
2931
3006
|
switch (message.type) {
|
|
2932
3007
|
case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
|
|
2933
3008
|
case messageTypes_js_1.ContainerMessageType.Attach:
|
|
2934
|
-
case messageTypes_js_1.ContainerMessageType.Alias:
|
|
3009
|
+
case messageTypes_js_1.ContainerMessageType.Alias: {
|
|
2935
3010
|
// For Operations, call resubmitDataStoreOp which will find the right store
|
|
2936
3011
|
// and trigger resubmission on it.
|
|
2937
3012
|
this.channelCollection.reSubmit(message.type, message.contents, localOpMetadata);
|
|
2938
3013
|
break;
|
|
3014
|
+
}
|
|
2939
3015
|
case messageTypes_js_1.ContainerMessageType.IdAllocation: {
|
|
2940
3016
|
// Allocation ops are never resubmitted/rebased. This is because they require special handling to
|
|
2941
3017
|
// avoid being submitted out of order. For example, if the pending state manager contained
|
|
@@ -2946,20 +3022,24 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2946
3022
|
// all pending IDs. The resubmitted allocation ops are then ignored here.
|
|
2947
3023
|
break;
|
|
2948
3024
|
}
|
|
2949
|
-
case messageTypes_js_1.ContainerMessageType.BlobAttach:
|
|
3025
|
+
case messageTypes_js_1.ContainerMessageType.BlobAttach: {
|
|
2950
3026
|
this.blobManager.reSubmit(opMetadata);
|
|
2951
3027
|
break;
|
|
2952
|
-
|
|
3028
|
+
}
|
|
3029
|
+
case messageTypes_js_1.ContainerMessageType.Rejoin: {
|
|
2953
3030
|
this.submit(message);
|
|
2954
3031
|
break;
|
|
2955
|
-
|
|
3032
|
+
}
|
|
3033
|
+
case messageTypes_js_1.ContainerMessageType.GC: {
|
|
2956
3034
|
this.submit(message);
|
|
2957
3035
|
break;
|
|
2958
|
-
|
|
3036
|
+
}
|
|
3037
|
+
case messageTypes_js_1.ContainerMessageType.DocumentSchemaChange: {
|
|
2959
3038
|
// There is no need to resend this message. Document schema controller will properly resend it again (if needed)
|
|
2960
3039
|
// on a first occasion (any ops sent after reconnect). There is a good chance, though, that it will not want to
|
|
2961
3040
|
// send any ops, as some other client already changed schema.
|
|
2962
3041
|
break;
|
|
3042
|
+
}
|
|
2963
3043
|
default: {
|
|
2964
3044
|
const error = getUnknownMessageTypeError(message.type, "reSubmitCore" /* codePath */);
|
|
2965
3045
|
this.closeFn(error);
|
|
@@ -2971,16 +3051,21 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
2971
3051
|
// Need to parse from string for back-compat
|
|
2972
3052
|
const { type, contents } = this.parseLocalOpContent(content);
|
|
2973
3053
|
switch (type) {
|
|
2974
|
-
case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp:
|
|
3054
|
+
case messageTypes_js_1.ContainerMessageType.FluidDataStoreOp: {
|
|
2975
3055
|
// For operations, call rollbackDataStoreOp which will find the right store
|
|
2976
3056
|
// and trigger rollback on it.
|
|
2977
3057
|
this.channelCollection.rollback(type, contents, localOpMetadata);
|
|
2978
3058
|
break;
|
|
2979
|
-
|
|
3059
|
+
}
|
|
3060
|
+
default: {
|
|
2980
3061
|
throw new Error(`Can't rollback ${type}`);
|
|
3062
|
+
}
|
|
2981
3063
|
}
|
|
2982
3064
|
}
|
|
2983
|
-
/**
|
|
3065
|
+
/**
|
|
3066
|
+
* Implementation of ISummarizerInternalsProvider.refreshLatestSummaryAck
|
|
3067
|
+
*/
|
|
3068
|
+
// eslint-disable-next-line import/no-deprecated
|
|
2984
3069
|
async refreshLatestSummaryAck(options) {
|
|
2985
3070
|
const { proposalHandle, ackHandle, summaryRefSeq, summaryLogger } = options;
|
|
2986
3071
|
// proposalHandle is always passed from RunningSummarizer.
|
|
@@ -3050,15 +3135,16 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
3050
3135
|
snapshotTree = snapshot.snapshotTree;
|
|
3051
3136
|
}
|
|
3052
3137
|
else {
|
|
3053
|
-
const versions = await this.storage.getVersions(
|
|
3138
|
+
const versions = await this.storage.getVersions(
|
|
3139
|
+
// eslint-disable-next-line unicorn/no-null
|
|
3140
|
+
null, 1, scenarioName, internal_3.FetchSource.noCache);
|
|
3054
3141
|
(0, internal_2.assert)(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
|
|
3055
3142
|
snapshotTree = await this.storage.getSnapshotTree(versions[0]);
|
|
3056
3143
|
(0, internal_2.assert)(!!snapshotTree, 0x138 /* "Failed to get snapshot from storage" */);
|
|
3057
3144
|
props.snapshotVersion = versions[0].id;
|
|
3058
3145
|
}
|
|
3059
3146
|
props.getSnapshotDuration = trace.trace().duration;
|
|
3060
|
-
const
|
|
3061
|
-
const snapshotRefSeq = await (0, internal_6.seqFromTree)(snapshotTree, readAndParseBlob);
|
|
3147
|
+
const snapshotRefSeq = await (0, internal_6.seqFromTree)(snapshotTree, this.readAndParseBlob);
|
|
3062
3148
|
props.snapshotRefSeq = snapshotRefSeq;
|
|
3063
3149
|
props.newerSnapshotPresent = snapshotRefSeq >= targetRefSeq;
|
|
3064
3150
|
perfEvent.end({ details: props });
|
|
@@ -3111,32 +3197,32 @@ class ContainerRuntime extends client_utils_1.TypedEventEmitter {
|
|
|
3111
3197
|
: internal_7.PerformanceEvent.timedExec(this.mc.logger, perfEvent, (event) => logAndReturnPendingState(event, getSyncState()));
|
|
3112
3198
|
}
|
|
3113
3199
|
summarizeOnDemand(options) {
|
|
3114
|
-
if (this.
|
|
3115
|
-
return this.
|
|
3200
|
+
if (this._summarizer !== undefined) {
|
|
3201
|
+
return this._summarizer.summarizeOnDemand(options);
|
|
3116
3202
|
}
|
|
3117
|
-
else if (this.summaryManager
|
|
3118
|
-
return this.summaryManager.summarizeOnDemand(options);
|
|
3119
|
-
}
|
|
3120
|
-
else {
|
|
3203
|
+
else if (this.summaryManager === undefined) {
|
|
3121
3204
|
// If we're not the summarizer, and we don't have a summaryManager, we expect that
|
|
3122
3205
|
// disableSummaries is turned on. We are throwing instead of returning a failure here,
|
|
3123
3206
|
// because it is a misuse of the API rather than an expected failure.
|
|
3124
3207
|
throw new internal_7.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
|
|
3125
3208
|
}
|
|
3209
|
+
else {
|
|
3210
|
+
return this.summaryManager.summarizeOnDemand(options);
|
|
3211
|
+
}
|
|
3126
3212
|
}
|
|
3127
3213
|
enqueueSummarize(options) {
|
|
3128
|
-
if (this.
|
|
3129
|
-
return this.
|
|
3130
|
-
}
|
|
3131
|
-
else if (this.summaryManager !== undefined) {
|
|
3132
|
-
return this.summaryManager.enqueueSummarize(options);
|
|
3214
|
+
if (this._summarizer !== undefined) {
|
|
3215
|
+
return this._summarizer.enqueueSummarize(options);
|
|
3133
3216
|
}
|
|
3134
|
-
else {
|
|
3217
|
+
else if (this.summaryManager === undefined) {
|
|
3135
3218
|
// If we're not the summarizer, and we don't have a summaryManager, we expect that
|
|
3136
3219
|
// generateSummaries is turned off. We are throwing instead of returning a failure here,
|
|
3137
3220
|
// because it is a misuse of the API rather than an expected failure.
|
|
3138
3221
|
throw new internal_7.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
|
|
3139
3222
|
}
|
|
3223
|
+
else {
|
|
3224
|
+
return this.summaryManager.enqueueSummarize(options);
|
|
3225
|
+
}
|
|
3140
3226
|
}
|
|
3141
3227
|
/**
|
|
3142
3228
|
* Forms a function that will create and retrieve a Summarizer.
|