@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
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
import { IsoBuffer } from "@fluid-internal/client-utils";
|
|
7
7
|
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
8
8
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
UsageError,
|
|
11
|
+
createChildLogger,
|
|
12
|
+
type ITelemetryLoggerExt,
|
|
13
|
+
} from "@fluidframework/telemetry-utils/internal";
|
|
10
14
|
import { compress } from "lz4js";
|
|
11
15
|
|
|
12
16
|
import { CompressionAlgorithms } from "../containerRuntime.js";
|
|
@@ -20,7 +24,7 @@ import { BatchMessage, IBatch } from "./definitions.js";
|
|
|
20
24
|
* op to reserve sequence numbers.
|
|
21
25
|
*/
|
|
22
26
|
export class OpCompressor {
|
|
23
|
-
private readonly logger;
|
|
27
|
+
private readonly logger: ITelemetryLoggerExt;
|
|
24
28
|
|
|
25
29
|
constructor(logger: ITelemetryBaseLogger) {
|
|
26
30
|
this.logger = createChildLogger({ logger, namespace: "OpCompressor" });
|
|
@@ -30,13 +34,14 @@ export class OpCompressor {
|
|
|
30
34
|
* Combines the contents of the batch into a single JSON string and compresses it, putting
|
|
31
35
|
* the resulting string as the first message of the batch. The rest of the messages are
|
|
32
36
|
* empty placeholders to reserve sequence numbers.
|
|
37
|
+
* This should only take a single message batch and compress it.
|
|
33
38
|
* @param batch - The batch to compress
|
|
34
39
|
* @returns A batch of the same length as the input batch, containing a single compressed message followed by empty placeholders
|
|
35
40
|
*/
|
|
36
|
-
public compressBatch(batch: IBatch): IBatch {
|
|
41
|
+
public compressBatch(batch: IBatch): IBatch<[BatchMessage]> {
|
|
37
42
|
assert(
|
|
38
|
-
batch.contentSizeInBytes > 0 && batch.messages.length
|
|
39
|
-
0x5a4 /* Batch should not be empty */,
|
|
43
|
+
batch.contentSizeInBytes > 0 && batch.messages.length === 1,
|
|
44
|
+
0x5a4 /* Batch should not be empty and should contain a single message */,
|
|
40
45
|
);
|
|
41
46
|
|
|
42
47
|
const compressionStart = Date.now();
|
|
@@ -45,24 +50,16 @@ export class OpCompressor {
|
|
|
45
50
|
const compressedContent = IsoBuffer.from(compressedContents).toString("base64");
|
|
46
51
|
const duration = Date.now() - compressionStart;
|
|
47
52
|
|
|
48
|
-
const messages: BatchMessage
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
const messages: [BatchMessage] = [
|
|
54
|
+
{
|
|
55
|
+
...batch.messages[0],
|
|
56
|
+
contents: JSON.stringify({ packedContents: compressedContent }),
|
|
57
|
+
metadata: batch.messages[0].metadata,
|
|
58
|
+
compression: CompressionAlgorithms.lz4,
|
|
59
|
+
},
|
|
60
|
+
];
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
for (const message of batch.messages.slice(1)) {
|
|
58
|
-
messages.push({
|
|
59
|
-
localOpMetadata: message.localOpMetadata,
|
|
60
|
-
metadata: message.metadata,
|
|
61
|
-
referenceSequenceNumber: message.referenceSequenceNumber,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const compressedBatch: IBatch = {
|
|
62
|
+
const compressedBatch = {
|
|
66
63
|
contentSizeInBytes: compressedContent.length,
|
|
67
64
|
messages,
|
|
68
65
|
referenceSequenceNumber: batch.referenceSequenceNumber,
|
|
@@ -89,8 +86,8 @@ export class OpCompressor {
|
|
|
89
86
|
try {
|
|
90
87
|
// Yields a valid JSON array, since each message.contents is already serialized to JSON
|
|
91
88
|
return `[${batch.messages.map(({ contents }) => contents).join(",")}]`;
|
|
92
|
-
} catch (
|
|
93
|
-
if (
|
|
89
|
+
} catch (newError: unknown) {
|
|
90
|
+
if ((newError as Partial<Error>).message === "Invalid string length") {
|
|
94
91
|
// This is how JSON.stringify signals that
|
|
95
92
|
// the content size exceeds its capacity
|
|
96
93
|
const error = new UsageError("Payload too large");
|
|
@@ -105,7 +102,7 @@ export class OpCompressor {
|
|
|
105
102
|
throw error;
|
|
106
103
|
}
|
|
107
104
|
|
|
108
|
-
throw
|
|
105
|
+
throw newError;
|
|
109
106
|
}
|
|
110
107
|
}
|
|
111
108
|
}
|
|
@@ -7,7 +7,10 @@ import { IsoBuffer, Uint8ArrayToString } from "@fluid-internal/client-utils";
|
|
|
7
7
|
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
8
8
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
9
9
|
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
createChildLogger,
|
|
12
|
+
type ITelemetryLoggerExt,
|
|
13
|
+
} from "@fluidframework/telemetry-utils/internal";
|
|
11
14
|
import { decompress } from "lz4js";
|
|
12
15
|
|
|
13
16
|
import { CompressionAlgorithms } from "../containerRuntime.js";
|
|
@@ -27,12 +30,17 @@ interface IPackedContentsContents {
|
|
|
27
30
|
* 2. Messages in the middle of a compressed batch will have neither batch metadata nor the compression property set
|
|
28
31
|
* 3. The final message of a batch will have batch metadata set to false
|
|
29
32
|
* 4. An individually compressed op will have undefined batch metadata and compression set to true
|
|
33
|
+
*
|
|
34
|
+
* Compressed batches from current code are always a single message but this class needs to handle a legacy compressed batch with multiple messages
|
|
35
|
+
* because we need that functionality for back compat.
|
|
30
36
|
*/
|
|
31
37
|
export class OpDecompressor {
|
|
32
38
|
private activeBatch = false;
|
|
39
|
+
// TODO: better typing
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
41
|
private rootMessageContents: any | undefined;
|
|
34
42
|
private processedCount = 0;
|
|
35
|
-
private readonly logger;
|
|
43
|
+
private readonly logger: ITelemetryLoggerExt;
|
|
36
44
|
|
|
37
45
|
constructor(logger: ITelemetryBaseLogger) {
|
|
38
46
|
this.logger = createChildLogger({ logger, namespace: "OpDecompressor" });
|
|
@@ -74,18 +82,20 @@ export class OpDecompressor {
|
|
|
74
82
|
});
|
|
75
83
|
return true;
|
|
76
84
|
}
|
|
77
|
-
} catch
|
|
85
|
+
} catch {
|
|
78
86
|
return false;
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
return false;
|
|
82
90
|
}
|
|
83
91
|
|
|
84
|
-
public get currentlyUnrolling() {
|
|
92
|
+
public get currentlyUnrolling(): boolean {
|
|
85
93
|
return this.activeBatch;
|
|
86
94
|
}
|
|
87
95
|
|
|
88
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* Is the decompressed and stored batch only comprised of a single message
|
|
98
|
+
*/
|
|
89
99
|
private isSingleMessageBatch = false;
|
|
90
100
|
|
|
91
101
|
/**
|
|
@@ -118,8 +128,8 @@ export class OpDecompressor {
|
|
|
118
128
|
);
|
|
119
129
|
const decompressedMessage = decompress(contents);
|
|
120
130
|
const intoString = Uint8ArrayToString(decompressedMessage);
|
|
121
|
-
|
|
122
|
-
this.rootMessageContents =
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
132
|
+
this.rootMessageContents = JSON.parse(intoString);
|
|
123
133
|
}
|
|
124
134
|
|
|
125
135
|
/**
|
|
@@ -130,6 +140,7 @@ export class OpDecompressor {
|
|
|
130
140
|
assert(this.currentlyUnrolling, 0x942 /* not currently unrolling */);
|
|
131
141
|
assert(this.rootMessageContents !== undefined, 0x943 /* missing rootMessageContents */);
|
|
132
142
|
assert(
|
|
143
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
133
144
|
this.rootMessageContents.length > this.processedCount,
|
|
134
145
|
0x944 /* no more content to unroll */,
|
|
135
146
|
);
|
|
@@ -138,6 +149,7 @@ export class OpDecompressor {
|
|
|
138
149
|
|
|
139
150
|
if (batchMetadata === false || this.isSingleMessageBatch) {
|
|
140
151
|
// End of compressed batch
|
|
152
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
141
153
|
const returnMessage = newMessage(message, this.rootMessageContents[this.processedCount]);
|
|
142
154
|
|
|
143
155
|
this.activeBatch = false;
|
|
@@ -148,6 +160,7 @@ export class OpDecompressor {
|
|
|
148
160
|
return returnMessage;
|
|
149
161
|
} else if (batchMetadata === true) {
|
|
150
162
|
// Start of compressed batch
|
|
163
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
151
164
|
return newMessage(message, this.rootMessageContents[this.processedCount++]);
|
|
152
165
|
}
|
|
153
166
|
|
|
@@ -155,6 +168,7 @@ export class OpDecompressor {
|
|
|
155
168
|
assert(message.contents === undefined, 0x512 /* Expecting empty message */);
|
|
156
169
|
|
|
157
170
|
// Continuation of compressed batch
|
|
171
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
158
172
|
return newMessage(message, this.rootMessageContents[this.processedCount++]);
|
|
159
173
|
}
|
|
160
174
|
}
|
|
@@ -162,7 +176,7 @@ export class OpDecompressor {
|
|
|
162
176
|
// We should not be mutating the input message nor its metadata
|
|
163
177
|
const newMessage = (
|
|
164
178
|
originalMessage: ISequencedDocumentMessage,
|
|
165
|
-
contents:
|
|
179
|
+
contents: unknown,
|
|
166
180
|
): ISequencedDocumentMessage => ({
|
|
167
181
|
...originalMessage,
|
|
168
182
|
contents,
|
|
@@ -170,7 +184,5 @@ const newMessage = (
|
|
|
170
184
|
// TODO: It should already be the case that we're not modifying any metadata, not clear if/why this shallow clone should be required.
|
|
171
185
|
|
|
172
186
|
metadata:
|
|
173
|
-
originalMessage.metadata === undefined
|
|
174
|
-
? undefined
|
|
175
|
-
: { ...(originalMessage.metadata as any) },
|
|
187
|
+
originalMessage.metadata === undefined ? undefined : { ...originalMessage.metadata },
|
|
176
188
|
});
|
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
7
7
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
8
8
|
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
createChildLogger,
|
|
11
|
+
type ITelemetryLoggerExt,
|
|
12
|
+
} from "@fluidframework/telemetry-utils/internal";
|
|
10
13
|
|
|
11
14
|
import { IBatch, type BatchMessage } from "./definitions.js";
|
|
12
15
|
|
|
@@ -24,8 +27,11 @@ interface IGroupedMessage {
|
|
|
24
27
|
compression?: string;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
function isGroupContents(opContents:
|
|
28
|
-
return
|
|
30
|
+
function isGroupContents(opContents: unknown): opContents is IGroupedBatchMessageContents {
|
|
31
|
+
return (
|
|
32
|
+
(opContents as Partial<IGroupedBatchMessageContents>)?.type ===
|
|
33
|
+
OpGroupingManager.groupedBatchOp
|
|
34
|
+
);
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
export function isGroupedBatch(op: ISequencedDocumentMessage): boolean {
|
|
@@ -34,13 +40,11 @@ export function isGroupedBatch(op: ISequencedDocumentMessage): boolean {
|
|
|
34
40
|
|
|
35
41
|
export interface OpGroupingManagerConfig {
|
|
36
42
|
readonly groupedBatchingEnabled: boolean;
|
|
37
|
-
readonly opCountThreshold: number;
|
|
38
|
-
readonly reentrantBatchGroupingEnabled: boolean;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
export class OpGroupingManager {
|
|
42
46
|
static readonly groupedBatchOp = "groupedBatch";
|
|
43
|
-
private readonly logger;
|
|
47
|
+
private readonly logger: ITelemetryLoggerExt;
|
|
44
48
|
|
|
45
49
|
constructor(
|
|
46
50
|
private readonly config: OpGroupingManagerConfig,
|
|
@@ -97,7 +101,6 @@ export class OpGroupingManager {
|
|
|
97
101
|
this.logger.sendTelemetryEvent({
|
|
98
102
|
eventName: "GroupLargeBatch",
|
|
99
103
|
length: batch.messages.length,
|
|
100
|
-
threshold: this.config.opCountThreshold,
|
|
101
104
|
reentrant: batch.hasReentrantOps,
|
|
102
105
|
referenceSequenceNumber: batch.messages[0].referenceSequenceNumber,
|
|
103
106
|
});
|
|
@@ -154,11 +157,13 @@ export class OpGroupingManager {
|
|
|
154
157
|
return (
|
|
155
158
|
// Grouped batching must be enabled
|
|
156
159
|
this.config.groupedBatchingEnabled &&
|
|
157
|
-
// The number of ops in the batch must
|
|
160
|
+
// The number of ops in the batch must be 2 or more
|
|
158
161
|
// or be empty (to allow for empty batches to be grouped)
|
|
159
|
-
|
|
160
|
-
// Support for reentrant batches
|
|
161
|
-
(this.config.reentrantBatchGroupingEnabled || batch.hasReentrantOps !== true)
|
|
162
|
+
batch.messages.length !== 1
|
|
163
|
+
// Support for reentrant batches will be on by default
|
|
162
164
|
);
|
|
163
165
|
}
|
|
166
|
+
public groupedBatchingEnabled(): boolean {
|
|
167
|
+
return this.config.groupedBatchingEnabled;
|
|
168
|
+
}
|
|
164
169
|
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
DataCorruptionError,
|
|
12
12
|
createChildLogger,
|
|
13
13
|
extractSafePropertiesFromMessage,
|
|
14
|
+
type ITelemetryLoggerExt,
|
|
14
15
|
} from "@fluidframework/telemetry-utils/internal";
|
|
15
16
|
|
|
16
17
|
import { ContainerMessageType, ContainerRuntimeChunkedOpMessage } from "../messageTypes.js";
|
|
@@ -23,12 +24,12 @@ export function isChunkedMessage(message: ISequencedDocumentMessage): boolean {
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
interface IChunkedContents {
|
|
26
|
-
type: typeof ContainerMessageType.ChunkedOp;
|
|
27
|
-
contents: IChunkedOp;
|
|
27
|
+
readonly type: typeof ContainerMessageType.ChunkedOp;
|
|
28
|
+
readonly contents: IChunkedOp;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
function isChunkedContents(contents:
|
|
31
|
-
return contents?.type === ContainerMessageType.ChunkedOp;
|
|
31
|
+
function isChunkedContents(contents: unknown): contents is IChunkedContents {
|
|
32
|
+
return (contents as Partial<IChunkedContents>)?.type === ContainerMessageType.ChunkedOp;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
/**
|
|
@@ -37,7 +38,7 @@ function isChunkedContents(contents: any): contents is IChunkedContents {
|
|
|
37
38
|
export class OpSplitter {
|
|
38
39
|
// Local copy of incomplete received chunks.
|
|
39
40
|
private readonly chunkMap: Map<string, string[]>;
|
|
40
|
-
private readonly logger;
|
|
41
|
+
private readonly logger: ITelemetryLoggerExt;
|
|
41
42
|
|
|
42
43
|
constructor(
|
|
43
44
|
chunks: [string, string[]][],
|
|
@@ -62,7 +63,7 @@ export class OpSplitter {
|
|
|
62
63
|
return this.chunkMap;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
public clearPartialChunks(clientId: string) {
|
|
66
|
+
public clearPartialChunks(clientId: string): void {
|
|
66
67
|
if (this.chunkMap.has(clientId)) {
|
|
67
68
|
this.chunkMap.delete(clientId);
|
|
68
69
|
}
|
|
@@ -72,7 +73,7 @@ export class OpSplitter {
|
|
|
72
73
|
clientId: string,
|
|
73
74
|
chunkedContent: IChunkedOp,
|
|
74
75
|
originalMessage: ISequencedDocumentMessage,
|
|
75
|
-
) {
|
|
76
|
+
): void {
|
|
76
77
|
let map = this.chunkMap.get(clientId);
|
|
77
78
|
if (map === undefined) {
|
|
78
79
|
map = [];
|
|
@@ -98,25 +99,28 @@ export class OpSplitter {
|
|
|
98
99
|
* Splits the first op of a compressed batch in chunks, sends the chunks separately and
|
|
99
100
|
* returns a new batch composed of the last chunk and the rest of the ops in the original batch.
|
|
100
101
|
*
|
|
101
|
-
* A compressed batch is formed by one large op at the first position
|
|
102
|
-
* which are used in order to reserve the sequence numbers for when the first op gets unrolled into the original
|
|
103
|
-
* uncompressed ops at ingestion in the runtime.
|
|
102
|
+
* A compressed batch is formed by one large op at the first position.
|
|
104
103
|
*
|
|
105
|
-
* If the
|
|
104
|
+
* If the op is too large, it can be chunked (split into smaller op) which can be sent individually over the wire
|
|
106
105
|
* and accumulate at ingestion, until the last op in the chunk is processed, when the original op is unrolled.
|
|
107
106
|
*
|
|
108
|
-
* This method will send the first N - 1 chunks separately and use the last chunk as the first message in the result batch
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
107
|
+
* This method will send the first N - 1 chunks separately and use the last chunk as the first message in the result batch.
|
|
108
|
+
* This will ensure that the batch semantics of the original (non-compressed) batch are preserved, as the original chunked op
|
|
109
|
+
* will be unrolled by the runtime when the first message in the batch is processed (as it is the last chunk).
|
|
110
|
+
*
|
|
111
|
+
* To handle legacy compressed batches with empty placeholders this method can attach the empty placeholder ops at the end
|
|
112
|
+
* of the result batch, ensuring that the batch semantics are preserved.
|
|
113
|
+
*
|
|
114
|
+
* To illustrate the current functionality, if the input is `[largeOp]`, `largeOp` will be split into `[chunk1, chunk2, chunk3, chunk4]`.
|
|
115
|
+
* `chunk1`, `chunk2` and `chunk3` will be sent individually and `[chunk4]` will be returned.
|
|
112
116
|
*
|
|
113
|
-
*
|
|
117
|
+
* With the legacy code, if the input is `[largeOp, emptyOp, emptyOp]`, `largeOp` will be split into `[chunk1, chunk2, chunk3, chunk4]`.
|
|
114
118
|
* `chunk1`, `chunk2` and `chunk3` will be sent individually and `[chunk4, emptyOp, emptyOp]` will be returned.
|
|
115
119
|
*
|
|
116
120
|
* @remarks - A side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.
|
|
117
121
|
*
|
|
118
122
|
* @param batch - the compressed batch which needs to be processed
|
|
119
|
-
* @returns A
|
|
123
|
+
* @returns A batch with the last chunk of the original message
|
|
120
124
|
*/
|
|
121
125
|
public splitFirstBatchMessage(batch: IBatch): IBatch {
|
|
122
126
|
assert(this.isBatchChunkingEnabled, 0x513 /* Chunking needs to be enabled */);
|
|
@@ -215,6 +219,7 @@ export class OpSplitter {
|
|
|
215
219
|
// back-compat with 1.x builds
|
|
216
220
|
// This is only required / present for non-compressed, chunked ops
|
|
217
221
|
// For compressed ops, we have op grouping enabled, and type of each op is preserved within compressed content.
|
|
222
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
|
218
223
|
completeMessage.type = (chunkedContent as any).originalType;
|
|
219
224
|
completeMessage.metadata = chunkedContent.originalMetadata;
|
|
220
225
|
completeMessage.compression = chunkedContent.originalCompression;
|
|
@@ -280,7 +285,7 @@ export const splitOp = (
|
|
|
280
285
|
for (let chunkId = 1; chunkId <= chunkCount; chunkId++) {
|
|
281
286
|
const chunk: IChunkedOp = {
|
|
282
287
|
chunkId,
|
|
283
|
-
contents: op.contents.
|
|
288
|
+
contents: op.contents.slice(offset, offset + chunkSizeInBytes),
|
|
284
289
|
totalChunks: chunkCount,
|
|
285
290
|
};
|
|
286
291
|
|
|
@@ -298,6 +303,7 @@ export const splitOp = (
|
|
|
298
303
|
// This is really bad, as we will crash on later ops and it's very hard to debug these cases.
|
|
299
304
|
// If we put some known type here, then we will crash on it (as 1.x does not understand compression, and thus will not
|
|
300
305
|
// find info on the op like address of the channel to deliver the op)
|
|
306
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
301
307
|
(chunk as any).originalType = "component";
|
|
302
308
|
}
|
|
303
309
|
|
|
@@ -77,6 +77,8 @@ export function serializeOpContents(contents: OutboundContainerRuntimeMessage):
|
|
|
77
77
|
* @returns the result of the action provided
|
|
78
78
|
*/
|
|
79
79
|
export function getLongStack<T>(action: () => T, length: number = 50): T {
|
|
80
|
+
// TODO: better typing here
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment
|
|
80
82
|
const errorObj = Error as any;
|
|
81
83
|
if (
|
|
82
84
|
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
|
|
@@ -90,11 +92,14 @@ export function getLongStack<T>(action: () => T, length: number = 50): T {
|
|
|
90
92
|
return action();
|
|
91
93
|
}
|
|
92
94
|
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
|
93
96
|
const originalStackTraceLimit = errorObj.stackTraceLimit;
|
|
94
97
|
try {
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
95
99
|
errorObj.stackTraceLimit = length;
|
|
96
100
|
return action();
|
|
97
101
|
} finally {
|
|
102
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
|
98
103
|
errorObj.stackTraceLimit = originalStackTraceLimit;
|
|
99
104
|
}
|
|
100
105
|
}
|
|
@@ -130,7 +135,9 @@ export class Outbox {
|
|
|
130
135
|
this.params.config.compressionOptions.minimumBatchSizeInBytes !==
|
|
131
136
|
Number.POSITIVE_INFINITY;
|
|
132
137
|
// We need to allow infinite size batches if we enable compression
|
|
133
|
-
const hardLimit = isCompressionEnabled
|
|
138
|
+
const hardLimit = isCompressionEnabled
|
|
139
|
+
? Number.POSITIVE_INFINITY
|
|
140
|
+
: this.params.config.maxBatchSizeInBytes;
|
|
134
141
|
|
|
135
142
|
this.mainBatch = new BatchManager({ hardLimit, canRebase: true });
|
|
136
143
|
this.blobAttachBatch = new BatchManager({ hardLimit, canRebase: true });
|
|
@@ -171,7 +178,7 @@ export class Outbox {
|
|
|
171
178
|
* last message processed by the ContainerRuntime. In the absence of op reentrancy, this
|
|
172
179
|
* pair will remain stable during a single JS turn during which the batch is being built up.
|
|
173
180
|
*/
|
|
174
|
-
private maybeFlushPartialBatch() {
|
|
181
|
+
private maybeFlushPartialBatch(): void {
|
|
175
182
|
const mainBatchSeqNums = this.mainBatch.sequenceNumbers;
|
|
176
183
|
const blobAttachSeqNums = this.blobAttachBatch.sequenceNumbers;
|
|
177
184
|
const idAllocSeqNums = this.idAllocationBatch.sequenceNumbers;
|
|
@@ -214,37 +221,25 @@ export class Outbox {
|
|
|
214
221
|
}
|
|
215
222
|
}
|
|
216
223
|
|
|
217
|
-
public submit(message: BatchMessage) {
|
|
224
|
+
public submit(message: BatchMessage): void {
|
|
218
225
|
this.maybeFlushPartialBatch();
|
|
219
226
|
|
|
220
227
|
this.addMessageToBatchManager(this.mainBatch, message);
|
|
221
228
|
}
|
|
222
229
|
|
|
223
|
-
public submitBlobAttach(message: BatchMessage) {
|
|
230
|
+
public submitBlobAttach(message: BatchMessage): void {
|
|
224
231
|
this.maybeFlushPartialBatch();
|
|
225
232
|
|
|
226
233
|
this.addMessageToBatchManager(this.blobAttachBatch, message);
|
|
227
|
-
|
|
228
|
-
// If compression is enabled, we will always successfully receive
|
|
229
|
-
// blobAttach ops and compress then send them at the next JS turn, regardless
|
|
230
|
-
// of the overall size of the accumulated ops in the batch.
|
|
231
|
-
// However, it is more efficient to flush these ops faster, preferably
|
|
232
|
-
// after they reach a size which would benefit from compression.
|
|
233
|
-
if (
|
|
234
|
-
this.blobAttachBatch.contentSizeInBytes >=
|
|
235
|
-
this.params.config.compressionOptions.minimumBatchSizeInBytes
|
|
236
|
-
) {
|
|
237
|
-
this.flushInternal(this.blobAttachBatch);
|
|
238
|
-
}
|
|
239
234
|
}
|
|
240
235
|
|
|
241
|
-
public submitIdAllocation(message: BatchMessage) {
|
|
236
|
+
public submitIdAllocation(message: BatchMessage): void {
|
|
242
237
|
this.maybeFlushPartialBatch();
|
|
243
238
|
|
|
244
239
|
this.addMessageToBatchManager(this.idAllocationBatch, message);
|
|
245
240
|
}
|
|
246
241
|
|
|
247
|
-
private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage) {
|
|
242
|
+
private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage): void {
|
|
248
243
|
if (
|
|
249
244
|
!batchManager.push(
|
|
250
245
|
message,
|
|
@@ -267,7 +262,7 @@ export class Outbox {
|
|
|
267
262
|
* @param resubmittingBatchId - If defined, indicates this is a resubmission of a batch
|
|
268
263
|
* with the given Batch ID, which must be preserved
|
|
269
264
|
*/
|
|
270
|
-
public flush(resubmittingBatchId?: BatchId) {
|
|
265
|
+
public flush(resubmittingBatchId?: BatchId): void {
|
|
271
266
|
if (this.isContextReentrant()) {
|
|
272
267
|
const error = new UsageError("Flushing is not supported inside DDS event handlers");
|
|
273
268
|
this.params.closeContainer(error);
|
|
@@ -277,7 +272,7 @@ export class Outbox {
|
|
|
277
272
|
this.flushAll(resubmittingBatchId);
|
|
278
273
|
}
|
|
279
274
|
|
|
280
|
-
private flushAll(resubmittingBatchId?: BatchId) {
|
|
275
|
+
private flushAll(resubmittingBatchId?: BatchId): void {
|
|
281
276
|
// If we're resubmitting and all batches are empty, we need to flush an empty batch.
|
|
282
277
|
// Note that we currently resubmit one batch at a time, so on resubmit, 2 of the 3 batches will *always* be empty.
|
|
283
278
|
// It's theoretically possible that we don't *need* to resubmit this empty batch, and in those cases, it'll safely be ignored
|
|
@@ -304,7 +299,7 @@ export class Outbox {
|
|
|
304
299
|
);
|
|
305
300
|
}
|
|
306
301
|
|
|
307
|
-
private flushEmptyBatch(resubmittingBatchId: BatchId) {
|
|
302
|
+
private flushEmptyBatch(resubmittingBatchId: BatchId): void {
|
|
308
303
|
const referenceSequenceNumber =
|
|
309
304
|
this.params.getCurrentSequenceNumbers().referenceSequenceNumber;
|
|
310
305
|
assert(
|
|
@@ -330,7 +325,7 @@ export class Outbox {
|
|
|
330
325
|
batchManager: BatchManager,
|
|
331
326
|
disableGroupedBatching: boolean = false,
|
|
332
327
|
resubmittingBatchId?: BatchId,
|
|
333
|
-
) {
|
|
328
|
+
): void {
|
|
334
329
|
if (batchManager.empty) {
|
|
335
330
|
return;
|
|
336
331
|
}
|
|
@@ -352,9 +347,11 @@ export class Outbox {
|
|
|
352
347
|
// If so, do nothing, as pending state manager will resubmit it correctly on reconnect.
|
|
353
348
|
// Because flush() is a task that executes async (on clean stack), we can get here in disconnected state.
|
|
354
349
|
if (this.params.shouldSend()) {
|
|
355
|
-
const processedBatch =
|
|
356
|
-
|
|
357
|
-
|
|
350
|
+
const processedBatch = disableGroupedBatching
|
|
351
|
+
? rawBatch
|
|
352
|
+
: this.compressAndChunkBatch(
|
|
353
|
+
shouldGroup ? this.params.groupingManager.groupBatch(rawBatch) : rawBatch,
|
|
354
|
+
);
|
|
358
355
|
clientSequenceNumber = this.sendBatch(processedBatch);
|
|
359
356
|
assert(
|
|
360
357
|
clientSequenceNumber === undefined || clientSequenceNumber >= 0,
|
|
@@ -375,7 +372,7 @@ export class Outbox {
|
|
|
375
372
|
*
|
|
376
373
|
* @param rawBatch - the batch to be rebased
|
|
377
374
|
*/
|
|
378
|
-
private rebase(rawBatch: IBatch, batchManager: BatchManager) {
|
|
375
|
+
private rebase(rawBatch: IBatch, batchManager: BatchManager): void {
|
|
379
376
|
assert(!this.rebasing, 0x6fb /* Reentrancy */);
|
|
380
377
|
assert(batchManager.options.canRebase, 0x9a7 /* BatchManager does not support rebase */);
|
|
381
378
|
|
|
@@ -415,16 +412,17 @@ export class Outbox {
|
|
|
415
412
|
* @remarks - If chunking happens, a side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.
|
|
416
413
|
*
|
|
417
414
|
* @param batch - Raw or Grouped batch to consider for compression/chunking
|
|
418
|
-
* @returns Either (A) the original batch, (B) a compressed batch (same length as original)
|
|
419
|
-
* or (C) a batch containing the last chunk
|
|
415
|
+
* @returns Either (A) the original batch, (B) a compressed batch (same length as original)
|
|
416
|
+
* or (C) a batch containing the last chunk.
|
|
420
417
|
*/
|
|
421
|
-
private
|
|
418
|
+
private compressAndChunkBatch(batch: IBatch): IBatch {
|
|
422
419
|
if (
|
|
423
420
|
batch.messages.length === 0 ||
|
|
424
421
|
this.params.config.compressionOptions === undefined ||
|
|
425
422
|
this.params.config.compressionOptions.minimumBatchSizeInBytes >
|
|
426
423
|
batch.contentSizeInBytes ||
|
|
427
|
-
this.params.submitBatchFn === undefined
|
|
424
|
+
this.params.submitBatchFn === undefined ||
|
|
425
|
+
!this.params.groupingManager.groupedBatchingEnabled()
|
|
428
426
|
) {
|
|
429
427
|
// Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress
|
|
430
428
|
return batch;
|
|
@@ -459,7 +457,7 @@ export class Outbox {
|
|
|
459
457
|
* @param batch - batch to be sent
|
|
460
458
|
* @returns the clientSequenceNumber of the start of the batch, or undefined if nothing was sent
|
|
461
459
|
*/
|
|
462
|
-
private sendBatch(batch: IBatch) {
|
|
460
|
+
private sendBatch(batch: IBatch): number | undefined {
|
|
463
461
|
const length = batch.messages.length;
|
|
464
462
|
if (length === 0) {
|
|
465
463
|
return undefined; // Nothing submitted
|
|
@@ -505,9 +503,13 @@ export class Outbox {
|
|
|
505
503
|
}
|
|
506
504
|
|
|
507
505
|
/**
|
|
508
|
-
*
|
|
506
|
+
* Gets a checkpoint object per batch that facilitates iterating over the batch messages when rolling back.
|
|
509
507
|
*/
|
|
510
|
-
public getBatchCheckpoints() {
|
|
508
|
+
public getBatchCheckpoints(): {
|
|
509
|
+
mainBatch: IBatchCheckpoint;
|
|
510
|
+
idAllocationBatch: IBatchCheckpoint;
|
|
511
|
+
blobAttachBatch: IBatchCheckpoint;
|
|
512
|
+
} {
|
|
511
513
|
// This variable is declared with a specific type so that we have a standard import of the IBatchCheckpoint type.
|
|
512
514
|
// When the type is inferred, the generated .d.ts uses a dynamic import which doesn't resolve.
|
|
513
515
|
const mainBatch: IBatchCheckpoint = this.mainBatch.checkpoint();
|
|
@@ -22,11 +22,17 @@ import { OpSplitter, isChunkedMessage } from "./opSplitter.js";
|
|
|
22
22
|
// eslint-disable-next-line unused-imports/no-unused-imports -- Used by "@link" comment annotation below
|
|
23
23
|
import { serializeOpContents } from "./outbox.js";
|
|
24
24
|
|
|
25
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Info about the batch we learn when we process the first message
|
|
27
|
+
*/
|
|
26
28
|
export interface BatchStartInfo {
|
|
27
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Batch ID, if present
|
|
31
|
+
*/
|
|
28
32
|
readonly batchId: string | undefined;
|
|
29
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* clientId that sent this batch. Used to compute Batch ID if needed
|
|
35
|
+
*/
|
|
30
36
|
readonly clientId: string;
|
|
31
37
|
/**
|
|
32
38
|
* Client Sequence Number of the Grouped Batch message, or the first message in the ungrouped batch.
|
|
@@ -101,7 +107,7 @@ export class RemoteMessageProcessor {
|
|
|
101
107
|
return this.opSplitter.chunks;
|
|
102
108
|
}
|
|
103
109
|
|
|
104
|
-
public clearPartialMessagesFor(clientId: string) {
|
|
110
|
+
public clearPartialMessagesFor(clientId: string): void {
|
|
105
111
|
this.opSplitter.clearPartialChunks(clientId);
|
|
106
112
|
}
|
|
107
113
|
|
|
@@ -159,7 +165,9 @@ export class RemoteMessageProcessor {
|
|
|
159
165
|
// We should be awaiting a new batch (batchInProgress false)
|
|
160
166
|
assert(!this.batchInProgress, 0x9d3 /* Grouped batch interrupting another batch */);
|
|
161
167
|
const batchId = asBatchMetadata(message.metadata)?.batchId;
|
|
162
|
-
const groupedMessages = this.opGroupingManager
|
|
168
|
+
const groupedMessages = this.opGroupingManager
|
|
169
|
+
.ungroupOp(message)
|
|
170
|
+
.map((innerMessage) => unpack(innerMessage));
|
|
163
171
|
|
|
164
172
|
return {
|
|
165
173
|
type: "fullBatch",
|
package/src/packageVersion.ts
CHANGED