@fluidframework/container-runtime 2.0.0-dev.5.2.0.169897 → 2.0.0-dev.6.4.0.191258
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +147 -0
- package/README.md +4 -3
- package/dist/batchTracker.d.ts +3 -2
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +6 -5
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +15 -18
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +212 -171
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +33 -17
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +172 -35
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +722 -425
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +15 -7
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +4 -4
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +87 -90
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +10 -10
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.js +2 -2
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/dataStores.d.ts +23 -7
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +125 -82
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaManagerProxyBase.d.ts +35 -0
- package/dist/deltaManagerProxyBase.d.ts.map +1 -0
- package/dist/deltaManagerProxyBase.js +77 -0
- package/dist/deltaManagerProxyBase.js.map +1 -0
- package/dist/deltaManagerSummarizerProxy.d.ts +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -1
- package/dist/deltaManagerSummarizerProxy.js +4 -2
- package/dist/deltaManagerSummarizerProxy.js.map +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +10 -10
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/error.d.ts +14 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +21 -0
- package/dist/error.js.map +1 -0
- package/dist/gc/garbageCollection.d.ts +10 -9
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +65 -56
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +18 -14
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +17 -5
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +14 -15
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +0 -8
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +11 -24
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +4 -7
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +19 -58
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +45 -35
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.js +4 -4
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/dist/gc/index.d.ts +2 -2
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +3 -5
- package/dist/gc/index.js.map +1 -1
- package/dist/id-compressor/appendOnlySortedMap.d.ts +8 -30
- package/dist/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
- package/dist/id-compressor/appendOnlySortedMap.js +26 -68
- package/dist/id-compressor/appendOnlySortedMap.js.map +1 -1
- package/dist/id-compressor/finalSpace.d.ts +29 -0
- package/dist/id-compressor/finalSpace.d.ts.map +1 -0
- package/dist/id-compressor/finalSpace.js +62 -0
- package/dist/id-compressor/finalSpace.js.map +1 -0
- package/dist/id-compressor/idCompressor.d.ts +25 -250
- package/dist/id-compressor/idCompressor.d.ts.map +1 -1
- package/dist/id-compressor/idCompressor.js +390 -1153
- package/dist/id-compressor/idCompressor.js.map +1 -1
- package/dist/id-compressor/identifiers.d.ts +32 -0
- package/dist/id-compressor/identifiers.d.ts.map +1 -0
- package/dist/id-compressor/identifiers.js +15 -0
- package/dist/id-compressor/identifiers.js.map +1 -0
- package/dist/id-compressor/index.d.ts +5 -6
- package/dist/id-compressor/index.d.ts.map +1 -1
- package/dist/id-compressor/index.js +20 -26
- package/dist/id-compressor/index.js.map +1 -1
- package/dist/id-compressor/persistanceUtilities.d.ts +22 -0
- package/dist/id-compressor/persistanceUtilities.d.ts.map +1 -0
- package/dist/id-compressor/persistanceUtilities.js +43 -0
- package/dist/id-compressor/persistanceUtilities.js.map +1 -0
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
- package/dist/id-compressor/sessionSpaceNormalizer.js +80 -0
- package/dist/id-compressor/sessionSpaceNormalizer.js.map +1 -0
- package/dist/id-compressor/sessions.d.ts +115 -0
- package/dist/id-compressor/sessions.d.ts.map +1 -0
- package/dist/id-compressor/sessions.js +305 -0
- package/dist/id-compressor/sessions.js.map +1 -0
- package/dist/id-compressor/utilities.d.ts +49 -0
- package/dist/id-compressor/utilities.d.ts.map +1 -0
- package/dist/id-compressor/utilities.js +166 -0
- package/dist/id-compressor/utilities.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +18 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +7 -0
- package/dist/metadata.js.map +1 -0
- package/dist/opLifecycle/batchManager.d.ts +2 -1
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +15 -7
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +11 -0
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +2 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts +2 -2
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +12 -7
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +2 -2
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +30 -21
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +19 -13
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +2 -2
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +24 -19
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +39 -6
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +138 -61
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +6 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +22 -8
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/opProperties.js +1 -2
- package/dist/opProperties.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +25 -10
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +101 -64
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +43 -33
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/index.d.ts +4 -4
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +3 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +3 -3
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +26 -27
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js +3 -3
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +31 -10
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +271 -139
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +8 -7
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +79 -78
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +2 -2
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js +7 -11
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.js +10 -14
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/index.d.ts +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 +40 -23
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +144 -149
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +25 -29
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js +2 -4
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +21 -16
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +74 -123
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +44 -24
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +2 -2
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +16 -13
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +4 -0
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +8 -5
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +21 -6
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +117 -54
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +8 -7
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +38 -28
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/batchTracker.d.ts +3 -2
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +5 -4
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +15 -18
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +187 -146
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +23 -7
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +172 -35
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +678 -380
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +13 -5
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +4 -4
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +49 -52
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +3 -3
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.js +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/dataStores.d.ts +23 -7
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +107 -64
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaManagerProxyBase.d.ts +35 -0
- package/lib/deltaManagerProxyBase.d.ts.map +1 -0
- package/lib/deltaManagerProxyBase.js +73 -0
- package/lib/deltaManagerProxyBase.js.map +1 -0
- package/lib/deltaManagerSummarizerProxy.d.ts +1 -1
- package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -1
- package/lib/deltaManagerSummarizerProxy.js +3 -1
- package/lib/deltaManagerSummarizerProxy.js.map +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +7 -7
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/error.d.ts +14 -0
- package/lib/error.d.ts.map +1 -0
- package/lib/error.js +17 -0
- package/lib/error.js.map +1 -0
- package/lib/gc/garbageCollection.d.ts +10 -9
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +61 -52
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +16 -12
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +17 -5
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +13 -14
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +0 -8
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +5 -17
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +4 -7
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +20 -59
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +46 -36
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/lib/gc/index.d.ts +2 -2
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +2 -2
- package/lib/gc/index.js.map +1 -1
- package/lib/id-compressor/appendOnlySortedMap.d.ts +8 -30
- package/lib/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
- package/lib/id-compressor/appendOnlySortedMap.js +25 -66
- package/lib/id-compressor/appendOnlySortedMap.js.map +1 -1
- package/lib/id-compressor/finalSpace.d.ts +29 -0
- package/lib/id-compressor/finalSpace.d.ts.map +1 -0
- package/lib/id-compressor/finalSpace.js +58 -0
- package/lib/id-compressor/finalSpace.js.map +1 -0
- package/lib/id-compressor/idCompressor.d.ts +25 -250
- package/lib/id-compressor/idCompressor.d.ts.map +1 -1
- package/lib/id-compressor/idCompressor.js +385 -1142
- package/lib/id-compressor/idCompressor.js.map +1 -1
- package/lib/id-compressor/identifiers.d.ts +32 -0
- package/lib/id-compressor/identifiers.d.ts.map +1 -0
- package/lib/id-compressor/identifiers.js +11 -0
- package/lib/id-compressor/identifiers.js.map +1 -0
- package/lib/id-compressor/index.d.ts +5 -6
- package/lib/id-compressor/index.d.ts.map +1 -1
- package/lib/id-compressor/index.js +5 -6
- package/lib/id-compressor/index.js.map +1 -1
- package/lib/id-compressor/persistanceUtilities.d.ts +22 -0
- package/lib/id-compressor/persistanceUtilities.d.ts.map +1 -0
- package/lib/id-compressor/persistanceUtilities.js +34 -0
- package/lib/id-compressor/persistanceUtilities.js.map +1 -0
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
- package/lib/id-compressor/sessionSpaceNormalizer.js +76 -0
- package/lib/id-compressor/sessionSpaceNormalizer.js.map +1 -0
- package/lib/id-compressor/sessions.d.ts +115 -0
- package/lib/id-compressor/sessions.d.ts.map +1 -0
- package/lib/id-compressor/sessions.js +290 -0
- package/lib/id-compressor/sessions.js.map +1 -0
- package/lib/id-compressor/utilities.d.ts +49 -0
- package/lib/id-compressor/utilities.d.ts.map +1 -0
- package/lib/id-compressor/utilities.js +148 -0
- package/lib/id-compressor/utilities.js.map +1 -0
- package/lib/index.d.ts +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/metadata.d.ts +18 -0
- package/lib/metadata.d.ts.map +1 -0
- package/lib/metadata.js +6 -0
- package/lib/metadata.js.map +1 -0
- package/lib/opLifecycle/batchManager.d.ts +2 -1
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +15 -7
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +11 -0
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts +2 -2
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +10 -5
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +2 -2
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +22 -13
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +17 -11
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +2 -2
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +15 -10
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +39 -6
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +132 -56
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +6 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +23 -9
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/opProperties.js +1 -2
- package/lib/opProperties.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 +25 -10
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +90 -53
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +25 -15
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/index.d.ts +4 -4
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +2 -2
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +3 -3
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +21 -22
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +31 -10
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +265 -133
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +8 -7
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +75 -74
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +2 -2
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js +6 -10
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.js +9 -13
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/index.d.ts +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 +40 -23
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +132 -137
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +25 -29
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js +2 -4
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +21 -16
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +70 -119
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +44 -24
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +2 -2
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +9 -6
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +4 -0
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +7 -4
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +21 -6
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +109 -47
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +8 -7
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +35 -25
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +30 -32
- package/src/batchTracker.ts +7 -5
- package/src/blobManager.ts +235 -172
- package/src/connectionTelemetry.ts +19 -5
- package/src/containerRuntime.ts +853 -431
- package/src/dataStore.ts +12 -4
- package/src/dataStoreContext.ts +49 -46
- package/src/dataStoreContexts.ts +4 -4
- package/src/dataStoreRegistry.ts +1 -1
- package/src/dataStores.ts +119 -80
- package/src/deltaManagerProxyBase.ts +111 -0
- package/src/deltaManagerSummarizerProxy.ts +4 -1
- package/src/deltaScheduler.ts +7 -11
- package/src/error.ts +18 -0
- package/src/gc/garbageCollection.md +53 -5
- package/src/gc/garbageCollection.ts +58 -51
- package/src/gc/gcConfigs.ts +4 -2
- package/src/gc/gcDefinitions.ts +17 -21
- package/src/gc/gcEarlyAdoption.md +145 -0
- package/src/gc/gcHelpers.ts +1 -12
- package/src/gc/gcSummaryStateTracker.ts +19 -65
- package/src/gc/gcTelemetry.ts +15 -13
- package/src/gc/gcUnreferencedStateTracker.ts +1 -1
- package/src/gc/index.ts +2 -4
- package/src/id-compressor/appendOnlySortedMap.ts +26 -87
- package/src/id-compressor/finalSpace.ts +67 -0
- package/src/id-compressor/idCompressor.ts +458 -1682
- package/src/id-compressor/identifiers.ts +42 -0
- package/src/id-compressor/index.ts +11 -20
- package/src/id-compressor/persistanceUtilities.ts +58 -0
- package/src/id-compressor/sessionSpaceNormalizer.ts +83 -0
- package/src/id-compressor/sessions.ts +405 -0
- package/src/id-compressor/utilities.ts +187 -0
- package/src/index.ts +9 -2
- package/src/metadata.ts +19 -0
- package/src/opLifecycle/README.md +20 -0
- package/src/opLifecycle/batchManager.ts +9 -1
- package/src/opLifecycle/definitions.ts +11 -0
- package/src/opLifecycle/index.ts +1 -1
- package/src/opLifecycle/opCompressor.ts +6 -5
- package/src/opLifecycle/opDecompressor.ts +47 -17
- package/src/opLifecycle/opGroupingManager.ts +18 -8
- package/src/opLifecycle/opSplitter.ts +10 -7
- package/src/opLifecycle/outbox.ts +177 -72
- package/src/opLifecycle/remoteMessageProcessor.ts +32 -9
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +123 -78
- package/src/scheduleManager.ts +22 -11
- package/src/summary/index.ts +7 -4
- package/src/summary/orderedClientElection.ts +10 -6
- package/src/summary/runWhileConnectedCoordinator.ts +1 -1
- package/src/summary/runningSummarizer.ts +291 -163
- package/src/summary/summarizer.ts +27 -16
- package/src/summary/summarizerClientElection.ts +2 -2
- package/src/summary/summarizerHeuristics.ts +1 -1
- package/src/summary/summarizerNode/index.ts +2 -2
- package/src/summary/summarizerNode/summarizerNode.ts +142 -184
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +27 -35
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +72 -148
- package/src/summary/summarizerTypes.ts +49 -24
- package/src/summary/summaryCollection.ts +9 -4
- package/src/summary/summaryFormat.ts +9 -2
- package/src/summary/summaryGenerator.ts +72 -49
- package/src/summary/summaryManager.ts +44 -16
- package/dist/id-compressor/idRange.d.ts +0 -11
- package/dist/id-compressor/idRange.d.ts.map +0 -1
- package/dist/id-compressor/idRange.js +0 -29
- package/dist/id-compressor/idRange.js.map +0 -1
- package/dist/id-compressor/numericUuid.d.ts +0 -59
- package/dist/id-compressor/numericUuid.d.ts.map +0 -1
- package/dist/id-compressor/numericUuid.js +0 -325
- package/dist/id-compressor/numericUuid.js.map +0 -1
- package/dist/id-compressor/sessionIdNormalizer.d.ts +0 -138
- package/dist/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
- package/dist/id-compressor/sessionIdNormalizer.js +0 -488
- package/dist/id-compressor/sessionIdNormalizer.js.map +0 -1
- package/dist/id-compressor/utils.d.ts +0 -57
- package/dist/id-compressor/utils.d.ts.map +0 -1
- package/dist/id-compressor/utils.js +0 -90
- package/dist/id-compressor/utils.js.map +0 -1
- package/dist/id-compressor/uuidUtilities.d.ts +0 -30
- package/dist/id-compressor/uuidUtilities.d.ts.map +0 -1
- package/dist/id-compressor/uuidUtilities.js +0 -106
- package/dist/id-compressor/uuidUtilities.js.map +0 -1
- package/lib/id-compressor/idRange.d.ts +0 -11
- package/lib/id-compressor/idRange.d.ts.map +0 -1
- package/lib/id-compressor/idRange.js +0 -25
- package/lib/id-compressor/idRange.js.map +0 -1
- package/lib/id-compressor/numericUuid.d.ts +0 -59
- package/lib/id-compressor/numericUuid.d.ts.map +0 -1
- package/lib/id-compressor/numericUuid.js +0 -315
- package/lib/id-compressor/numericUuid.js.map +0 -1
- package/lib/id-compressor/sessionIdNormalizer.d.ts +0 -138
- package/lib/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
- package/lib/id-compressor/sessionIdNormalizer.js +0 -484
- package/lib/id-compressor/sessionIdNormalizer.js.map +0 -1
- package/lib/id-compressor/utils.d.ts +0 -57
- package/lib/id-compressor/utils.d.ts.map +0 -1
- package/lib/id-compressor/utils.js +0 -79
- package/lib/id-compressor/utils.js.map +0 -1
- package/lib/id-compressor/uuidUtilities.d.ts +0 -30
- package/lib/id-compressor/uuidUtilities.d.ts.map +0 -1
- package/lib/id-compressor/uuidUtilities.js +0 -98
- package/lib/id-compressor/uuidUtilities.js.map +0 -1
- package/src/id-compressor/idRange.ts +0 -35
- package/src/id-compressor/numericUuid.ts +0 -383
- package/src/id-compressor/sessionIdNormalizer.ts +0 -609
- package/src/id-compressor/utils.ts +0 -114
- package/src/id-compressor/uuidUtilities.ts +0 -123
|
@@ -2,28 +2,41 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import { assert } from "@fluidframework/
|
|
7
|
-
import { GenericError, UsageError } from "@fluidframework/container-utils";
|
|
8
|
-
import { MessageType } from "@fluidframework/protocol-definitions";
|
|
5
|
+
import { createChildMonitoringContext, GenericError, UsageError, } from "@fluidframework/telemetry-utils";
|
|
6
|
+
import { assert } from "@fluidframework/core-utils";
|
|
9
7
|
import { BatchManager, estimateSocketSize, sequenceNumbersMatch, } from "./batchManager";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Temporarily increase the stack limit while executing the provided action.
|
|
10
|
+
* If a negative value is provided for `length`, no stack frames will be collected.
|
|
11
|
+
* If Infinity is provided, all frames will be collected.
|
|
12
|
+
*
|
|
13
|
+
* ADO:4663 - add this to the common packages.
|
|
14
|
+
*
|
|
15
|
+
* @param action - action which returns an error
|
|
16
|
+
* @param length - number of stack frames to collect, 50 if unspecified.
|
|
17
|
+
* @returns the result of the action provided
|
|
18
|
+
*/
|
|
19
|
+
export function getLongStack(action, length = 50) {
|
|
20
|
+
const errorObj = Error;
|
|
21
|
+
if ((Object.getOwnPropertyDescriptor(errorObj, "stackTraceLimit") ||
|
|
22
|
+
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(errorObj), "stackTraceLimit"))?.writable !== true) {
|
|
23
|
+
return action();
|
|
18
24
|
}
|
|
19
|
-
|
|
25
|
+
const originalStackTraceLimit = errorObj.stackTraceLimit;
|
|
26
|
+
try {
|
|
27
|
+
errorObj.stackTraceLimit = length;
|
|
20
28
|
return action();
|
|
21
29
|
}
|
|
30
|
+
finally {
|
|
31
|
+
errorObj.stackTraceLimit = originalStackTraceLimit;
|
|
32
|
+
}
|
|
22
33
|
}
|
|
23
34
|
export class Outbox {
|
|
24
35
|
constructor(params) {
|
|
25
36
|
this.params = params;
|
|
26
37
|
this.defaultAttachFlowSoftLimitInBytes = 320 * 1024;
|
|
38
|
+
this.batchRebasesToReport = 5;
|
|
39
|
+
this.rebasing = false;
|
|
27
40
|
/**
|
|
28
41
|
* Track the number of ops which were detected to have a mismatched
|
|
29
42
|
* reference sequence number, in order to self-throttle the telemetry events.
|
|
@@ -32,7 +45,7 @@ export class Outbox {
|
|
|
32
45
|
*/
|
|
33
46
|
this.maxMismatchedOpsToReport = 3;
|
|
34
47
|
this.mismatchedOpsReported = 0;
|
|
35
|
-
this.mc =
|
|
48
|
+
this.mc = createChildMonitoringContext({ logger: params.logger, namespace: "Outbox" });
|
|
36
49
|
const isCompressionEnabled = this.params.config.compressionOptions.minimumBatchSizeInBytes !==
|
|
37
50
|
Number.POSITIVE_INFINITY;
|
|
38
51
|
// We need to allow infinite size batches if we enable compression
|
|
@@ -40,9 +53,13 @@ export class Outbox {
|
|
|
40
53
|
const softLimit = isCompressionEnabled ? Infinity : this.defaultAttachFlowSoftLimitInBytes;
|
|
41
54
|
this.attachFlowBatch = new BatchManager({ hardLimit, softLimit });
|
|
42
55
|
this.mainBatch = new BatchManager({ hardLimit });
|
|
56
|
+
this.blobAttachBatch = new BatchManager({ hardLimit });
|
|
57
|
+
}
|
|
58
|
+
get messageCount() {
|
|
59
|
+
return this.attachFlowBatch.length + this.mainBatch.length + this.blobAttachBatch.length;
|
|
43
60
|
}
|
|
44
61
|
get isEmpty() {
|
|
45
|
-
return this.
|
|
62
|
+
return this.messageCount === 0;
|
|
46
63
|
}
|
|
47
64
|
/**
|
|
48
65
|
* If we detect that the reference sequence number of the incoming message does not match
|
|
@@ -53,11 +70,14 @@ export class Outbox {
|
|
|
53
70
|
maybeFlushPartialBatch() {
|
|
54
71
|
const mainBatchSeqNums = this.mainBatch.sequenceNumbers;
|
|
55
72
|
const attachFlowBatchSeqNums = this.attachFlowBatch.sequenceNumbers;
|
|
73
|
+
const blobAttachSeqNums = this.blobAttachBatch.sequenceNumbers;
|
|
56
74
|
assert(this.params.config.disablePartialFlush ||
|
|
57
|
-
sequenceNumbersMatch(mainBatchSeqNums, attachFlowBatchSeqNums)
|
|
75
|
+
(sequenceNumbersMatch(mainBatchSeqNums, attachFlowBatchSeqNums) &&
|
|
76
|
+
sequenceNumbersMatch(mainBatchSeqNums, blobAttachSeqNums)), 0x58d /* Reference sequence numbers from both batches must be in sync */);
|
|
58
77
|
const currentSequenceNumbers = this.params.getCurrentSequenceNumbers();
|
|
59
78
|
if (sequenceNumbersMatch(mainBatchSeqNums, currentSequenceNumbers) &&
|
|
60
|
-
sequenceNumbersMatch(attachFlowBatchSeqNums, currentSequenceNumbers)
|
|
79
|
+
sequenceNumbersMatch(attachFlowBatchSeqNums, currentSequenceNumbers) &&
|
|
80
|
+
sequenceNumbersMatch(blobAttachSeqNums, currentSequenceNumbers)) {
|
|
61
81
|
// The reference sequence numbers are stable, there is nothing to do
|
|
62
82
|
return;
|
|
63
83
|
}
|
|
@@ -69,42 +89,28 @@ export class Outbox {
|
|
|
69
89
|
mainClientSequenceNumber: mainBatchSeqNums.clientSequenceNumber,
|
|
70
90
|
attachReferenceSequenceNumber: attachFlowBatchSeqNums.referenceSequenceNumber,
|
|
71
91
|
attachClientSequenceNumber: attachFlowBatchSeqNums.clientSequenceNumber,
|
|
92
|
+
blobAttachReferenceSequenceNumber: blobAttachSeqNums.referenceSequenceNumber,
|
|
93
|
+
blobAttachClientSequenceNumber: blobAttachSeqNums.clientSequenceNumber,
|
|
72
94
|
currentReferenceSequenceNumber: currentSequenceNumbers.referenceSequenceNumber,
|
|
73
95
|
currentClientSequenceNumber: currentSequenceNumbers.clientSequenceNumber,
|
|
74
96
|
}, getLongStack(() => new UsageError("Submission of an out of order message")));
|
|
75
97
|
}
|
|
76
98
|
if (!this.params.config.disablePartialFlush) {
|
|
77
|
-
this.
|
|
99
|
+
this.flushAll();
|
|
78
100
|
}
|
|
79
101
|
}
|
|
80
102
|
submit(message) {
|
|
81
|
-
var _a, _b;
|
|
82
103
|
this.maybeFlushPartialBatch();
|
|
83
|
-
|
|
84
|
-
throw new GenericError("BatchTooLarge", /* error */ undefined, {
|
|
85
|
-
opSize: (_b = (_a = message.contents) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0,
|
|
86
|
-
batchSize: this.mainBatch.contentSizeInBytes,
|
|
87
|
-
count: this.mainBatch.length,
|
|
88
|
-
limit: this.mainBatch.options.hardLimit,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
104
|
+
this.addMessageToBatchManager(this.mainBatch, message);
|
|
91
105
|
}
|
|
92
106
|
submitAttach(message) {
|
|
93
|
-
var _a, _b;
|
|
94
107
|
this.maybeFlushPartialBatch();
|
|
95
|
-
if (!this.attachFlowBatch.push(message, this.params.getCurrentSequenceNumbers().clientSequenceNumber)) {
|
|
108
|
+
if (!this.attachFlowBatch.push(message, this.isContextReentrant(), this.params.getCurrentSequenceNumbers().clientSequenceNumber)) {
|
|
96
109
|
// BatchManager has two limits - soft limit & hard limit. Soft limit is only engaged
|
|
97
110
|
// when queue is not empty.
|
|
98
111
|
// Flush queue & retry. Failure on retry would mean - single message is bigger than hard limit
|
|
99
|
-
this.flushInternal(this.attachFlowBatch
|
|
100
|
-
|
|
101
|
-
throw new GenericError("BatchTooLarge", /* error */ undefined, {
|
|
102
|
-
opSize: (_b = (_a = message.contents) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0,
|
|
103
|
-
batchSize: this.attachFlowBatch.contentSizeInBytes,
|
|
104
|
-
count: this.attachFlowBatch.length,
|
|
105
|
-
limit: this.attachFlowBatch.options.hardLimit,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
112
|
+
this.flushInternal(this.attachFlowBatch);
|
|
113
|
+
this.addMessageToBatchManager(this.attachFlowBatch, message);
|
|
108
114
|
}
|
|
109
115
|
// If compression is enabled, we will always successfully receive
|
|
110
116
|
// attach ops and compress then send them at the next JS turn, regardless
|
|
@@ -113,28 +119,103 @@ export class Outbox {
|
|
|
113
119
|
// after they reach a size which would benefit from compression.
|
|
114
120
|
if (this.attachFlowBatch.contentSizeInBytes >=
|
|
115
121
|
this.params.config.compressionOptions.minimumBatchSizeInBytes) {
|
|
116
|
-
this.flushInternal(this.attachFlowBatch
|
|
122
|
+
this.flushInternal(this.attachFlowBatch);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
submitBlobAttach(message) {
|
|
126
|
+
this.maybeFlushPartialBatch();
|
|
127
|
+
this.addMessageToBatchManager(this.blobAttachBatch, message);
|
|
128
|
+
// If compression is enabled, we will always successfully receive
|
|
129
|
+
// blobAttach ops and compress then send them at the next JS turn, regardless
|
|
130
|
+
// of the overall size of the accumulated ops in the batch.
|
|
131
|
+
// However, it is more efficient to flush these ops faster, preferably
|
|
132
|
+
// after they reach a size which would benefit from compression.
|
|
133
|
+
if (this.blobAttachBatch.contentSizeInBytes >=
|
|
134
|
+
this.params.config.compressionOptions.minimumBatchSizeInBytes) {
|
|
135
|
+
this.flushInternal(this.blobAttachBatch);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
addMessageToBatchManager(batchManager, message) {
|
|
139
|
+
if (!batchManager.push(message, this.isContextReentrant(), this.params.getCurrentSequenceNumbers().clientSequenceNumber)) {
|
|
140
|
+
throw new GenericError("BatchTooLarge", /* error */ undefined, {
|
|
141
|
+
opSize: message.contents?.length ?? 0,
|
|
142
|
+
batchSize: batchManager.contentSizeInBytes,
|
|
143
|
+
count: batchManager.length,
|
|
144
|
+
limit: batchManager.options.hardLimit,
|
|
145
|
+
});
|
|
117
146
|
}
|
|
118
147
|
}
|
|
119
148
|
flush() {
|
|
120
|
-
|
|
121
|
-
|
|
149
|
+
if (this.isContextReentrant()) {
|
|
150
|
+
const error = new UsageError("Flushing is not supported inside DDS event handlers");
|
|
151
|
+
this.params.closeContainer(error);
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
this.flushAll();
|
|
155
|
+
}
|
|
156
|
+
flushAll() {
|
|
157
|
+
this.flushInternal(this.attachFlowBatch);
|
|
158
|
+
this.flushInternal(this.blobAttachBatch, true /* disableGroupedBatching */);
|
|
159
|
+
this.flushInternal(this.mainBatch);
|
|
122
160
|
}
|
|
123
|
-
flushInternal(
|
|
124
|
-
|
|
161
|
+
flushInternal(batchManager, disableGroupedBatching = false) {
|
|
162
|
+
if (batchManager.empty) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const rawBatch = batchManager.popBatch();
|
|
166
|
+
if (rawBatch.hasReentrantOps === true && this.params.config.enableGroupedBatching) {
|
|
167
|
+
assert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);
|
|
168
|
+
// If a batch contains reentrant ops (ops created as a result from processing another op)
|
|
169
|
+
// it needs to be rebased so that we can ensure consistent reference sequence numbers
|
|
170
|
+
// and eventual consistency at the DDS level.
|
|
171
|
+
this.rebase(rawBatch, batchManager);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const processedBatch = this.compressBatch(rawBatch, disableGroupedBatching);
|
|
125
175
|
this.sendBatch(processedBatch);
|
|
126
176
|
this.persistBatch(rawBatch.content);
|
|
127
177
|
}
|
|
128
|
-
|
|
178
|
+
/**
|
|
179
|
+
* Rebases a batch. All the ops in the batch are resubmitted to the runtime and
|
|
180
|
+
* they will end up back in the same batch manager they were flushed from and subsequently flushed.
|
|
181
|
+
*
|
|
182
|
+
* @param rawBatch - the batch to be rebased
|
|
183
|
+
*/
|
|
184
|
+
rebase(rawBatch, batchManager) {
|
|
185
|
+
assert(!this.rebasing, 0x6fb /* Reentrancy */);
|
|
186
|
+
this.rebasing = true;
|
|
187
|
+
for (const message of rawBatch.content) {
|
|
188
|
+
this.params.reSubmit({
|
|
189
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
190
|
+
content: message.contents,
|
|
191
|
+
localOpMetadata: message.localOpMetadata,
|
|
192
|
+
opMetadata: message.metadata,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
if (this.batchRebasesToReport > 0) {
|
|
196
|
+
this.mc.logger.sendTelemetryEvent({
|
|
197
|
+
eventName: "BatchRebase",
|
|
198
|
+
length: rawBatch.content.length,
|
|
199
|
+
referenceSequenceNumber: rawBatch.referenceSequenceNumber,
|
|
200
|
+
}, new UsageError("BatchRebase"));
|
|
201
|
+
this.batchRebasesToReport--;
|
|
202
|
+
}
|
|
203
|
+
this.flushInternal(batchManager);
|
|
204
|
+
this.rebasing = false;
|
|
205
|
+
}
|
|
206
|
+
isContextReentrant() {
|
|
207
|
+
return this.params.opReentrancy() && !this.rebasing;
|
|
208
|
+
}
|
|
209
|
+
compressBatch(batch, disableGroupedBatching) {
|
|
129
210
|
if (batch.content.length === 0 ||
|
|
130
211
|
this.params.config.compressionOptions === undefined ||
|
|
131
212
|
this.params.config.compressionOptions.minimumBatchSizeInBytes >
|
|
132
213
|
batch.contentSizeInBytes ||
|
|
133
|
-
this.params.
|
|
214
|
+
this.params.submitBatchFn === undefined) {
|
|
134
215
|
// Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress
|
|
135
|
-
return this.params.groupingManager.groupBatch(batch);
|
|
216
|
+
return disableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch);
|
|
136
217
|
}
|
|
137
|
-
const compressedBatch = this.params.compressor.compressBatch(this.params.groupingManager.groupBatch(batch));
|
|
218
|
+
const compressedBatch = this.params.compressor.compressBatch(disableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch));
|
|
138
219
|
if (this.params.splitter.isBatchChunkingEnabled) {
|
|
139
220
|
return compressedBatch.contentSizeInBytes <= this.params.splitter.chunkSizeInBytes
|
|
140
221
|
? compressedBatch
|
|
@@ -174,21 +255,15 @@ export class Outbox {
|
|
|
174
255
|
socketSize,
|
|
175
256
|
});
|
|
176
257
|
}
|
|
177
|
-
if (this.params.
|
|
258
|
+
if (this.params.submitBatchFn === undefined) {
|
|
178
259
|
// Legacy path - supporting old loader versions. Can be removed only when LTS moves above
|
|
179
260
|
// version that has support for batches (submitBatchFn)
|
|
180
261
|
assert(batch.content[0].compression === undefined, 0x5a6 /* Compression should not have happened if the loader does not support it */);
|
|
181
|
-
|
|
182
|
-
this.params.containerContext.submitFn(MessageType.Operation,
|
|
183
|
-
// For back-compat (submitFn only works on deserialized content)
|
|
184
|
-
message.contents === undefined ? undefined : JSON.parse(message.contents), true, // batch
|
|
185
|
-
message.metadata);
|
|
186
|
-
}
|
|
187
|
-
this.params.containerContext.deltaManager.flush();
|
|
262
|
+
this.params.legacySendBatchFn(batch);
|
|
188
263
|
}
|
|
189
264
|
else {
|
|
190
265
|
assert(batch.referenceSequenceNumber !== undefined, 0x58e /* Batch must not be empty */);
|
|
191
|
-
this.params.
|
|
266
|
+
this.params.submitBatchFn(batch.content.map((message) => ({
|
|
192
267
|
contents: message.contents,
|
|
193
268
|
metadata: message.metadata,
|
|
194
269
|
compression: message.compression,
|
|
@@ -209,6 +284,7 @@ export class Outbox {
|
|
|
209
284
|
return {
|
|
210
285
|
mainBatch: this.mainBatch.checkpoint(),
|
|
211
286
|
attachFlowBatch: this.attachFlowBatch.checkpoint(),
|
|
287
|
+
blobAttachBatch: this.blobAttachBatch.checkpoint(),
|
|
212
288
|
};
|
|
213
289
|
}
|
|
214
290
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outbox.js","sourceRoot":"","sources":["../../src/opLifecycle/outbox.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tITelemetryLoggerExt,\n\tChildLogger,\n\tloggerToMonitoringContext,\n\tMonitoringContext,\n} from \"@fluidframework/telemetry-utils\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IContainerContext } from \"@fluidframework/container-definitions\";\nimport { GenericError, UsageError } from \"@fluidframework/container-utils\";\nimport { MessageType } from \"@fluidframework/protocol-definitions\";\nimport { ICompressionRuntimeOptions } from \"../containerRuntime\";\nimport { PendingStateManager } from \"../pendingStateManager\";\nimport {\n\tBatchManager,\n\tBatchSequenceNumbers,\n\testimateSocketSize,\n\tsequenceNumbersMatch,\n} from \"./batchManager\";\nimport { BatchMessage, IBatch } from \"./definitions\";\nimport { OpCompressor } from \"./opCompressor\";\nimport { OpGroupingManager } from \"./opGroupingManager\";\nimport { OpSplitter } from \"./opSplitter\";\n\nexport interface IOutboxConfig {\n\treadonly compressionOptions: ICompressionRuntimeOptions;\n\t// The maximum size of a batch that we can send over the wire.\n\treadonly maxBatchSizeInBytes: number;\n\treadonly disablePartialFlush: boolean;\n}\n\nexport interface IOutboxParameters {\n\treadonly shouldSend: () => boolean;\n\treadonly pendingStateManager: PendingStateManager;\n\treadonly containerContext: IContainerContext;\n\treadonly config: IOutboxConfig;\n\treadonly compressor: OpCompressor;\n\treadonly splitter: OpSplitter;\n\treadonly logger: ITelemetryLoggerExt;\n\treadonly groupingManager: OpGroupingManager;\n\treadonly getCurrentSequenceNumbers: () => BatchSequenceNumbers;\n}\n\nfunction getLongStack(action: () => Error): Error {\n\t// Increase the stack trace limit temporarily, so as to debug better in case it occurs.\n\ttry {\n\t\tconst originalStackTraceLimit = (Error as any).stackTraceLimit;\n\t\t(Error as any).stackTraceLimit = 50;\n\t\tconst result = action();\n\t\t(Error as any).stackTraceLimit = originalStackTraceLimit;\n\t\treturn result;\n\t} catch (error) {\n\t\treturn action();\n\t}\n}\n\nexport class Outbox {\n\tprivate readonly mc: MonitoringContext;\n\tprivate readonly attachFlowBatch: BatchManager;\n\tprivate readonly mainBatch: BatchManager;\n\tprivate readonly defaultAttachFlowSoftLimitInBytes = 320 * 1024;\n\n\t/**\n\t * Track the number of ops which were detected to have a mismatched\n\t * reference sequence number, in order to self-throttle the telemetry events.\n\t *\n\t * This should be removed as part of ADO:2322\n\t */\n\tprivate readonly maxMismatchedOpsToReport = 3;\n\tprivate mismatchedOpsReported = 0;\n\n\tconstructor(private readonly params: IOutboxParameters) {\n\t\tthis.mc = loggerToMonitoringContext(ChildLogger.create(params.logger, \"Outbox\"));\n\t\tconst isCompressionEnabled =\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes !==\n\t\t\tNumber.POSITIVE_INFINITY;\n\t\t// We need to allow infinite size batches if we enable compression\n\t\tconst hardLimit = isCompressionEnabled ? Infinity : this.params.config.maxBatchSizeInBytes;\n\t\tconst softLimit = isCompressionEnabled ? Infinity : this.defaultAttachFlowSoftLimitInBytes;\n\n\t\tthis.attachFlowBatch = new BatchManager({ hardLimit, softLimit });\n\t\tthis.mainBatch = new BatchManager({ hardLimit });\n\t}\n\n\tpublic get isEmpty(): boolean {\n\t\treturn this.attachFlowBatch.length === 0 && this.mainBatch.length === 0;\n\t}\n\n\t/**\n\t * If we detect that the reference sequence number of the incoming message does not match\n\t * what was already in the batch managers, this means that batching has been interrupted so\n\t * we will flush the accumulated messages to account for that and create a new batch with the new\n\t * message as the first message.\n\t */\n\tprivate maybeFlushPartialBatch() {\n\t\tconst mainBatchSeqNums = this.mainBatch.sequenceNumbers;\n\t\tconst attachFlowBatchSeqNums = this.attachFlowBatch.sequenceNumbers;\n\t\tassert(\n\t\t\tthis.params.config.disablePartialFlush ||\n\t\t\t\tsequenceNumbersMatch(mainBatchSeqNums, attachFlowBatchSeqNums),\n\t\t\t0x58d /* Reference sequence numbers from both batches must be in sync */,\n\t\t);\n\n\t\tconst currentSequenceNumbers = this.params.getCurrentSequenceNumbers();\n\n\t\tif (\n\t\t\tsequenceNumbersMatch(mainBatchSeqNums, currentSequenceNumbers) &&\n\t\t\tsequenceNumbersMatch(attachFlowBatchSeqNums, currentSequenceNumbers)\n\t\t) {\n\t\t\t// The reference sequence numbers are stable, there is nothing to do\n\t\t\treturn;\n\t\t}\n\n\t\tif (++this.mismatchedOpsReported <= this.maxMismatchedOpsToReport) {\n\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\tcategory: this.params.config.disablePartialFlush ? \"error\" : \"generic\",\n\t\t\t\t\teventName: \"ReferenceSequenceNumberMismatch\",\n\t\t\t\t\tmainReferenceSequenceNumber: mainBatchSeqNums.referenceSequenceNumber,\n\t\t\t\t\tmainClientSequenceNumber: mainBatchSeqNums.clientSequenceNumber,\n\t\t\t\t\tattachReferenceSequenceNumber: attachFlowBatchSeqNums.referenceSequenceNumber,\n\t\t\t\t\tattachClientSequenceNumber: attachFlowBatchSeqNums.clientSequenceNumber,\n\t\t\t\t\tcurrentReferenceSequenceNumber: currentSequenceNumbers.referenceSequenceNumber,\n\t\t\t\t\tcurrentClientSequenceNumber: currentSequenceNumbers.clientSequenceNumber,\n\t\t\t\t},\n\t\t\t\tgetLongStack(() => new UsageError(\"Submission of an out of order message\")),\n\t\t\t);\n\t\t}\n\n\t\tif (!this.params.config.disablePartialFlush) {\n\t\t\tthis.flush();\n\t\t}\n\t}\n\n\tpublic submit(message: BatchMessage) {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tif (\n\t\t\t!this.mainBatch.push(\n\t\t\t\tmessage,\n\t\t\t\tthis.params.getCurrentSequenceNumbers().clientSequenceNumber,\n\t\t\t)\n\t\t) {\n\t\t\tthrow new GenericError(\"BatchTooLarge\", /* error */ undefined, {\n\t\t\t\topSize: message.contents?.length ?? 0,\n\t\t\t\tbatchSize: this.mainBatch.contentSizeInBytes,\n\t\t\t\tcount: this.mainBatch.length,\n\t\t\t\tlimit: this.mainBatch.options.hardLimit,\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic submitAttach(message: BatchMessage) {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tif (\n\t\t\t!this.attachFlowBatch.push(\n\t\t\t\tmessage,\n\t\t\t\tthis.params.getCurrentSequenceNumbers().clientSequenceNumber,\n\t\t\t)\n\t\t) {\n\t\t\t// BatchManager has two limits - soft limit & hard limit. Soft limit is only engaged\n\t\t\t// when queue is not empty.\n\t\t\t// Flush queue & retry. Failure on retry would mean - single message is bigger than hard limit\n\t\t\tthis.flushInternal(this.attachFlowBatch.popBatch());\n\t\t\tif (\n\t\t\t\t!this.attachFlowBatch.push(\n\t\t\t\t\tmessage,\n\t\t\t\t\tthis.params.getCurrentSequenceNumbers().clientSequenceNumber,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tthrow new GenericError(\"BatchTooLarge\", /* error */ undefined, {\n\t\t\t\t\topSize: message.contents?.length ?? 0,\n\t\t\t\t\tbatchSize: this.attachFlowBatch.contentSizeInBytes,\n\t\t\t\t\tcount: this.attachFlowBatch.length,\n\t\t\t\t\tlimit: this.attachFlowBatch.options.hardLimit,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// If compression is enabled, we will always successfully receive\n\t\t// attach ops and compress then send them at the next JS turn, regardless\n\t\t// of the overall size of the accumulated ops in the batch.\n\t\t// However, it is more efficient to flush these ops faster, preferably\n\t\t// after they reach a size which would benefit from compression.\n\t\tif (\n\t\t\tthis.attachFlowBatch.contentSizeInBytes >=\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes\n\t\t) {\n\t\t\tthis.flushInternal(this.attachFlowBatch.popBatch());\n\t\t}\n\t}\n\n\tpublic flush() {\n\t\tthis.flushInternal(this.attachFlowBatch.popBatch());\n\t\tthis.flushInternal(this.mainBatch.popBatch());\n\t}\n\n\tprivate flushInternal(rawBatch: IBatch) {\n\t\tconst processedBatch = this.compressBatch(rawBatch);\n\t\tthis.sendBatch(processedBatch);\n\n\t\tthis.persistBatch(rawBatch.content);\n\t}\n\n\tprivate compressBatch(batch: IBatch): IBatch {\n\t\tif (\n\t\t\tbatch.content.length === 0 ||\n\t\t\tthis.params.config.compressionOptions === undefined ||\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes >\n\t\t\t\tbatch.contentSizeInBytes ||\n\t\t\tthis.params.containerContext.submitBatchFn === undefined\n\t\t) {\n\t\t\t// Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress\n\t\t\treturn this.params.groupingManager.groupBatch(batch);\n\t\t}\n\n\t\tconst compressedBatch = this.params.compressor.compressBatch(\n\t\t\tthis.params.groupingManager.groupBatch(batch),\n\t\t);\n\n\t\tif (this.params.splitter.isBatchChunkingEnabled) {\n\t\t\treturn compressedBatch.contentSizeInBytes <= this.params.splitter.chunkSizeInBytes\n\t\t\t\t? compressedBatch\n\t\t\t\t: this.params.splitter.splitFirstBatchMessage(compressedBatch);\n\t\t}\n\n\t\tif (compressedBatch.contentSizeInBytes >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthrow new GenericError(\"BatchTooLarge\", /* error */ undefined, {\n\t\t\t\tbatchSize: batch.contentSizeInBytes,\n\t\t\t\tcompressedBatchSize: compressedBatch.contentSizeInBytes,\n\t\t\t\tcount: compressedBatch.content.length,\n\t\t\t\tlimit: this.params.config.maxBatchSizeInBytes,\n\t\t\t\tchunkingEnabled: this.params.splitter.isBatchChunkingEnabled,\n\t\t\t\tcompressionOptions: JSON.stringify(this.params.config.compressionOptions),\n\t\t\t\tsocketSize: estimateSocketSize(batch),\n\t\t\t});\n\t\t}\n\n\t\treturn compressedBatch;\n\t}\n\n\t/**\n\t * Sends the batch object to the container context to be sent over the wire.\n\t *\n\t * @param batch - batch to be sent\n\t */\n\tprivate sendBatch(batch: IBatch) {\n\t\tconst length = batch.content.length;\n\n\t\t// Did we disconnect in the middle of turn-based batch?\n\t\t// If so, do nothing, as pending state manager will resubmit it correctly on reconnect.\n\t\tif (length === 0 || !this.params.shouldSend()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst socketSize = estimateSocketSize(batch);\n\t\tif (socketSize >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthis.mc.logger.sendPerformanceEvent({\n\t\t\t\teventName: \"LargeBatch\",\n\t\t\t\tlength: batch.content.length,\n\t\t\t\tsizeInBytes: batch.contentSizeInBytes,\n\t\t\t\tsocketSize,\n\t\t\t});\n\t\t}\n\n\t\tif (this.params.containerContext.submitBatchFn === undefined) {\n\t\t\t// Legacy path - supporting old loader versions. Can be removed only when LTS moves above\n\t\t\t// version that has support for batches (submitBatchFn)\n\t\t\tassert(\n\t\t\t\tbatch.content[0].compression === undefined,\n\t\t\t\t0x5a6 /* Compression should not have happened if the loader does not support it */,\n\t\t\t);\n\n\t\t\tfor (const message of batch.content) {\n\t\t\t\tthis.params.containerContext.submitFn(\n\t\t\t\t\tMessageType.Operation,\n\t\t\t\t\t// For back-compat (submitFn only works on deserialized content)\n\t\t\t\t\tmessage.contents === undefined ? undefined : JSON.parse(message.contents),\n\t\t\t\t\ttrue, // batch\n\t\t\t\t\tmessage.metadata,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.params.containerContext.deltaManager.flush();\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tbatch.referenceSequenceNumber !== undefined,\n\t\t\t\t0x58e /* Batch must not be empty */,\n\t\t\t);\n\t\t\tthis.params.containerContext.submitBatchFn(\n\t\t\t\tbatch.content.map((message) => ({\n\t\t\t\t\tcontents: message.contents,\n\t\t\t\t\tmetadata: message.metadata,\n\t\t\t\t\tcompression: message.compression,\n\t\t\t\t\treferenceSequenceNumber: message.referenceSequenceNumber,\n\t\t\t\t})),\n\t\t\t\tbatch.referenceSequenceNumber,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate persistBatch(batch: BatchMessage[]) {\n\t\t// Let the PendingStateManager know that a message was submitted.\n\t\t// In future, need to shift toward keeping batch as a whole!\n\t\tfor (const message of batch) {\n\t\t\tthis.params.pendingStateManager.onSubmitMessage(\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tmessage.contents!,\n\t\t\t\tmessage.referenceSequenceNumber,\n\t\t\t\tmessage.localOpMetadata,\n\t\t\t\tmessage.metadata,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic checkpoint() {\n\t\treturn {\n\t\t\tmainBatch: this.mainBatch.checkpoint(),\n\t\t\tattachFlowBatch: this.attachFlowBatch.checkpoint(),\n\t\t};\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"outbox.js","sourceRoot":"","sources":["../../src/opLifecycle/outbox.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tcreateChildMonitoringContext,\n\tGenericError,\n\tMonitoringContext,\n\tUsageError,\n} from \"@fluidframework/telemetry-utils\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IBatchMessage, ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { ICompressionRuntimeOptions } from \"../containerRuntime\";\nimport { IPendingBatchMessage, PendingStateManager } from \"../pendingStateManager\";\nimport {\n\tBatchManager,\n\tBatchSequenceNumbers,\n\testimateSocketSize,\n\tsequenceNumbersMatch,\n} from \"./batchManager\";\nimport { BatchMessage, IBatch } from \"./definitions\";\nimport { OpCompressor } from \"./opCompressor\";\nimport { OpGroupingManager } from \"./opGroupingManager\";\nimport { OpSplitter } from \"./opSplitter\";\n\nexport interface IOutboxConfig {\n\treadonly compressionOptions: ICompressionRuntimeOptions;\n\t// The maximum size of a batch that we can send over the wire.\n\treadonly maxBatchSizeInBytes: number;\n\treadonly disablePartialFlush: boolean;\n\treadonly enableGroupedBatching: boolean;\n}\n\nexport interface IOutboxParameters {\n\treadonly shouldSend: () => boolean;\n\treadonly pendingStateManager: PendingStateManager;\n\treadonly submitBatchFn:\n\t\t| ((batch: IBatchMessage[], referenceSequenceNumber?: number) => number)\n\t\t| undefined;\n\treadonly legacySendBatchFn: (batch: IBatch) => void;\n\treadonly config: IOutboxConfig;\n\treadonly compressor: OpCompressor;\n\treadonly splitter: OpSplitter;\n\treadonly logger: ITelemetryBaseLogger;\n\treadonly groupingManager: OpGroupingManager;\n\treadonly getCurrentSequenceNumbers: () => BatchSequenceNumbers;\n\treadonly reSubmit: (message: IPendingBatchMessage) => void;\n\treadonly opReentrancy: () => boolean;\n\treadonly closeContainer: (error?: ICriticalContainerError) => void;\n}\n\n/**\n * Temporarily increase the stack limit while executing the provided action.\n * If a negative value is provided for `length`, no stack frames will be collected.\n * If Infinity is provided, all frames will be collected.\n *\n * ADO:4663 - add this to the common packages.\n *\n * @param action - action which returns an error\n * @param length - number of stack frames to collect, 50 if unspecified.\n * @returns the result of the action provided\n */\nexport function getLongStack<T>(action: () => T, length: number = 50): T {\n\tconst errorObj = Error as any;\n\tif (\n\t\t(\n\t\t\tObject.getOwnPropertyDescriptor(errorObj, \"stackTraceLimit\") ||\n\t\t\tObject.getOwnPropertyDescriptor(Object.getPrototypeOf(errorObj), \"stackTraceLimit\")\n\t\t)?.writable !== true\n\t) {\n\t\treturn action();\n\t}\n\n\tconst originalStackTraceLimit = errorObj.stackTraceLimit;\n\ttry {\n\t\terrorObj.stackTraceLimit = length;\n\t\treturn action();\n\t} finally {\n\t\terrorObj.stackTraceLimit = originalStackTraceLimit;\n\t}\n}\n\nexport class Outbox {\n\tprivate readonly mc: MonitoringContext;\n\tprivate readonly attachFlowBatch: BatchManager;\n\tprivate readonly mainBatch: BatchManager;\n\tprivate readonly blobAttachBatch: BatchManager;\n\tprivate readonly defaultAttachFlowSoftLimitInBytes = 320 * 1024;\n\tprivate batchRebasesToReport = 5;\n\tprivate rebasing = false;\n\n\t/**\n\t * Track the number of ops which were detected to have a mismatched\n\t * reference sequence number, in order to self-throttle the telemetry events.\n\t *\n\t * This should be removed as part of ADO:2322\n\t */\n\tprivate readonly maxMismatchedOpsToReport = 3;\n\tprivate mismatchedOpsReported = 0;\n\n\tconstructor(private readonly params: IOutboxParameters) {\n\t\tthis.mc = createChildMonitoringContext({ logger: params.logger, namespace: \"Outbox\" });\n\t\tconst isCompressionEnabled =\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes !==\n\t\t\tNumber.POSITIVE_INFINITY;\n\t\t// We need to allow infinite size batches if we enable compression\n\t\tconst hardLimit = isCompressionEnabled ? Infinity : this.params.config.maxBatchSizeInBytes;\n\t\tconst softLimit = isCompressionEnabled ? Infinity : this.defaultAttachFlowSoftLimitInBytes;\n\n\t\tthis.attachFlowBatch = new BatchManager({ hardLimit, softLimit });\n\t\tthis.mainBatch = new BatchManager({ hardLimit });\n\t\tthis.blobAttachBatch = new BatchManager({ hardLimit });\n\t}\n\n\tpublic get messageCount(): number {\n\t\treturn this.attachFlowBatch.length + this.mainBatch.length + this.blobAttachBatch.length;\n\t}\n\n\tpublic get isEmpty(): boolean {\n\t\treturn this.messageCount === 0;\n\t}\n\n\t/**\n\t * If we detect that the reference sequence number of the incoming message does not match\n\t * what was already in the batch managers, this means that batching has been interrupted so\n\t * we will flush the accumulated messages to account for that and create a new batch with the new\n\t * message as the first message.\n\t */\n\tprivate maybeFlushPartialBatch() {\n\t\tconst mainBatchSeqNums = this.mainBatch.sequenceNumbers;\n\t\tconst attachFlowBatchSeqNums = this.attachFlowBatch.sequenceNumbers;\n\t\tconst blobAttachSeqNums = this.blobAttachBatch.sequenceNumbers;\n\t\tassert(\n\t\t\tthis.params.config.disablePartialFlush ||\n\t\t\t\t(sequenceNumbersMatch(mainBatchSeqNums, attachFlowBatchSeqNums) &&\n\t\t\t\t\tsequenceNumbersMatch(mainBatchSeqNums, blobAttachSeqNums)),\n\t\t\t0x58d /* Reference sequence numbers from both batches must be in sync */,\n\t\t);\n\n\t\tconst currentSequenceNumbers = this.params.getCurrentSequenceNumbers();\n\n\t\tif (\n\t\t\tsequenceNumbersMatch(mainBatchSeqNums, currentSequenceNumbers) &&\n\t\t\tsequenceNumbersMatch(attachFlowBatchSeqNums, currentSequenceNumbers) &&\n\t\t\tsequenceNumbersMatch(blobAttachSeqNums, currentSequenceNumbers)\n\t\t) {\n\t\t\t// The reference sequence numbers are stable, there is nothing to do\n\t\t\treturn;\n\t\t}\n\n\t\tif (++this.mismatchedOpsReported <= this.maxMismatchedOpsToReport) {\n\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\tcategory: this.params.config.disablePartialFlush ? \"error\" : \"generic\",\n\t\t\t\t\teventName: \"ReferenceSequenceNumberMismatch\",\n\t\t\t\t\tmainReferenceSequenceNumber: mainBatchSeqNums.referenceSequenceNumber,\n\t\t\t\t\tmainClientSequenceNumber: mainBatchSeqNums.clientSequenceNumber,\n\t\t\t\t\tattachReferenceSequenceNumber: attachFlowBatchSeqNums.referenceSequenceNumber,\n\t\t\t\t\tattachClientSequenceNumber: attachFlowBatchSeqNums.clientSequenceNumber,\n\t\t\t\t\tblobAttachReferenceSequenceNumber: blobAttachSeqNums.referenceSequenceNumber,\n\t\t\t\t\tblobAttachClientSequenceNumber: blobAttachSeqNums.clientSequenceNumber,\n\t\t\t\t\tcurrentReferenceSequenceNumber: currentSequenceNumbers.referenceSequenceNumber,\n\t\t\t\t\tcurrentClientSequenceNumber: currentSequenceNumbers.clientSequenceNumber,\n\t\t\t\t},\n\t\t\t\tgetLongStack(() => new UsageError(\"Submission of an out of order message\")),\n\t\t\t);\n\t\t}\n\n\t\tif (!this.params.config.disablePartialFlush) {\n\t\t\tthis.flushAll();\n\t\t}\n\t}\n\n\tpublic submit(message: BatchMessage) {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tthis.addMessageToBatchManager(this.mainBatch, message);\n\t}\n\n\tpublic submitAttach(message: BatchMessage) {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tif (\n\t\t\t!this.attachFlowBatch.push(\n\t\t\t\tmessage,\n\t\t\t\tthis.isContextReentrant(),\n\t\t\t\tthis.params.getCurrentSequenceNumbers().clientSequenceNumber,\n\t\t\t)\n\t\t) {\n\t\t\t// BatchManager has two limits - soft limit & hard limit. Soft limit is only engaged\n\t\t\t// when queue is not empty.\n\t\t\t// Flush queue & retry. Failure on retry would mean - single message is bigger than hard limit\n\t\t\tthis.flushInternal(this.attachFlowBatch);\n\n\t\t\tthis.addMessageToBatchManager(this.attachFlowBatch, message);\n\t\t}\n\n\t\t// If compression is enabled, we will always successfully receive\n\t\t// attach ops and compress then send them at the next JS turn, regardless\n\t\t// of the overall size of the accumulated ops in the batch.\n\t\t// However, it is more efficient to flush these ops faster, preferably\n\t\t// after they reach a size which would benefit from compression.\n\t\tif (\n\t\t\tthis.attachFlowBatch.contentSizeInBytes >=\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes\n\t\t) {\n\t\t\tthis.flushInternal(this.attachFlowBatch);\n\t\t}\n\t}\n\n\tpublic submitBlobAttach(message: BatchMessage) {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tthis.addMessageToBatchManager(this.blobAttachBatch, message);\n\n\t\t// If compression is enabled, we will always successfully receive\n\t\t// blobAttach ops and compress then send them at the next JS turn, regardless\n\t\t// of the overall size of the accumulated ops in the batch.\n\t\t// However, it is more efficient to flush these ops faster, preferably\n\t\t// after they reach a size which would benefit from compression.\n\t\tif (\n\t\t\tthis.blobAttachBatch.contentSizeInBytes >=\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes\n\t\t) {\n\t\t\tthis.flushInternal(this.blobAttachBatch);\n\t\t}\n\t}\n\n\tprivate addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage) {\n\t\tif (\n\t\t\t!batchManager.push(\n\t\t\t\tmessage,\n\t\t\t\tthis.isContextReentrant(),\n\t\t\t\tthis.params.getCurrentSequenceNumbers().clientSequenceNumber,\n\t\t\t)\n\t\t) {\n\t\t\tthrow new GenericError(\"BatchTooLarge\", /* error */ undefined, {\n\t\t\t\topSize: message.contents?.length ?? 0,\n\t\t\t\tbatchSize: batchManager.contentSizeInBytes,\n\t\t\t\tcount: batchManager.length,\n\t\t\t\tlimit: batchManager.options.hardLimit,\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic flush() {\n\t\tif (this.isContextReentrant()) {\n\t\t\tconst error = new UsageError(\"Flushing is not supported inside DDS event handlers\");\n\t\t\tthis.params.closeContainer(error);\n\t\t\tthrow error;\n\t\t}\n\n\t\tthis.flushAll();\n\t}\n\n\tprivate flushAll() {\n\t\tthis.flushInternal(this.attachFlowBatch);\n\t\tthis.flushInternal(this.blobAttachBatch, true /* disableGroupedBatching */);\n\t\tthis.flushInternal(this.mainBatch);\n\t}\n\n\tprivate flushInternal(batchManager: BatchManager, disableGroupedBatching: boolean = false) {\n\t\tif (batchManager.empty) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst rawBatch = batchManager.popBatch();\n\t\tif (rawBatch.hasReentrantOps === true && this.params.config.enableGroupedBatching) {\n\t\t\tassert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);\n\t\t\t// If a batch contains reentrant ops (ops created as a result from processing another op)\n\t\t\t// it needs to be rebased so that we can ensure consistent reference sequence numbers\n\t\t\t// and eventual consistency at the DDS level.\n\t\t\tthis.rebase(rawBatch, batchManager);\n\t\t\treturn;\n\t\t}\n\n\t\tconst processedBatch = this.compressBatch(rawBatch, disableGroupedBatching);\n\t\tthis.sendBatch(processedBatch);\n\n\t\tthis.persistBatch(rawBatch.content);\n\t}\n\n\t/**\n\t * Rebases a batch. All the ops in the batch are resubmitted to the runtime and\n\t * they will end up back in the same batch manager they were flushed from and subsequently flushed.\n\t *\n\t * @param rawBatch - the batch to be rebased\n\t */\n\tprivate rebase(rawBatch: IBatch, batchManager: BatchManager) {\n\t\tassert(!this.rebasing, 0x6fb /* Reentrancy */);\n\n\t\tthis.rebasing = true;\n\t\tfor (const message of rawBatch.content) {\n\t\t\tthis.params.reSubmit({\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tcontent: message.contents!,\n\t\t\t\tlocalOpMetadata: message.localOpMetadata,\n\t\t\t\topMetadata: message.metadata,\n\t\t\t});\n\t\t}\n\n\t\tif (this.batchRebasesToReport > 0) {\n\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"BatchRebase\",\n\t\t\t\t\tlength: rawBatch.content.length,\n\t\t\t\t\treferenceSequenceNumber: rawBatch.referenceSequenceNumber,\n\t\t\t\t},\n\t\t\t\tnew UsageError(\"BatchRebase\"),\n\t\t\t);\n\t\t\tthis.batchRebasesToReport--;\n\t\t}\n\n\t\tthis.flushInternal(batchManager);\n\t\tthis.rebasing = false;\n\t}\n\n\tprivate isContextReentrant(): boolean {\n\t\treturn this.params.opReentrancy() && !this.rebasing;\n\t}\n\n\tprivate compressBatch(batch: IBatch, disableGroupedBatching: boolean): IBatch {\n\t\tif (\n\t\t\tbatch.content.length === 0 ||\n\t\t\tthis.params.config.compressionOptions === undefined ||\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes >\n\t\t\t\tbatch.contentSizeInBytes ||\n\t\t\tthis.params.submitBatchFn === undefined\n\t\t) {\n\t\t\t// Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress\n\t\t\treturn disableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch);\n\t\t}\n\n\t\tconst compressedBatch = this.params.compressor.compressBatch(\n\t\t\tdisableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch),\n\t\t);\n\n\t\tif (this.params.splitter.isBatchChunkingEnabled) {\n\t\t\treturn compressedBatch.contentSizeInBytes <= this.params.splitter.chunkSizeInBytes\n\t\t\t\t? compressedBatch\n\t\t\t\t: this.params.splitter.splitFirstBatchMessage(compressedBatch);\n\t\t}\n\n\t\tif (compressedBatch.contentSizeInBytes >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthrow new GenericError(\"BatchTooLarge\", /* error */ undefined, {\n\t\t\t\tbatchSize: batch.contentSizeInBytes,\n\t\t\t\tcompressedBatchSize: compressedBatch.contentSizeInBytes,\n\t\t\t\tcount: compressedBatch.content.length,\n\t\t\t\tlimit: this.params.config.maxBatchSizeInBytes,\n\t\t\t\tchunkingEnabled: this.params.splitter.isBatchChunkingEnabled,\n\t\t\t\tcompressionOptions: JSON.stringify(this.params.config.compressionOptions),\n\t\t\t\tsocketSize: estimateSocketSize(batch),\n\t\t\t});\n\t\t}\n\n\t\treturn compressedBatch;\n\t}\n\n\t/**\n\t * Sends the batch object to the container context to be sent over the wire.\n\t *\n\t * @param batch - batch to be sent\n\t */\n\tprivate sendBatch(batch: IBatch) {\n\t\tconst length = batch.content.length;\n\n\t\t// Did we disconnect in the middle of turn-based batch?\n\t\t// If so, do nothing, as pending state manager will resubmit it correctly on reconnect.\n\t\tif (length === 0 || !this.params.shouldSend()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst socketSize = estimateSocketSize(batch);\n\t\tif (socketSize >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthis.mc.logger.sendPerformanceEvent({\n\t\t\t\teventName: \"LargeBatch\",\n\t\t\t\tlength: batch.content.length,\n\t\t\t\tsizeInBytes: batch.contentSizeInBytes,\n\t\t\t\tsocketSize,\n\t\t\t});\n\t\t}\n\n\t\tif (this.params.submitBatchFn === undefined) {\n\t\t\t// Legacy path - supporting old loader versions. Can be removed only when LTS moves above\n\t\t\t// version that has support for batches (submitBatchFn)\n\t\t\tassert(\n\t\t\t\tbatch.content[0].compression === undefined,\n\t\t\t\t0x5a6 /* Compression should not have happened if the loader does not support it */,\n\t\t\t);\n\n\t\t\tthis.params.legacySendBatchFn(batch);\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tbatch.referenceSequenceNumber !== undefined,\n\t\t\t\t0x58e /* Batch must not be empty */,\n\t\t\t);\n\t\t\tthis.params.submitBatchFn(\n\t\t\t\tbatch.content.map((message) => ({\n\t\t\t\t\tcontents: message.contents,\n\t\t\t\t\tmetadata: message.metadata,\n\t\t\t\t\tcompression: message.compression,\n\t\t\t\t\treferenceSequenceNumber: message.referenceSequenceNumber,\n\t\t\t\t})),\n\t\t\t\tbatch.referenceSequenceNumber,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate persistBatch(batch: BatchMessage[]) {\n\t\t// Let the PendingStateManager know that a message was submitted.\n\t\t// In future, need to shift toward keeping batch as a whole!\n\t\tfor (const message of batch) {\n\t\t\tthis.params.pendingStateManager.onSubmitMessage(\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tmessage.contents!,\n\t\t\t\tmessage.referenceSequenceNumber,\n\t\t\t\tmessage.localOpMetadata,\n\t\t\t\tmessage.metadata,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic checkpoint() {\n\t\treturn {\n\t\t\tmainBatch: this.mainBatch.checkpoint(),\n\t\t\tattachFlowBatch: this.attachFlowBatch.checkpoint(),\n\t\t\tblobAttachBatch: this.blobAttachBatch.checkpoint(),\n\t\t};\n\t}\n}\n"]}
|
|
@@ -13,6 +13,11 @@ export declare class RemoteMessageProcessor {
|
|
|
13
13
|
constructor(opSplitter: OpSplitter, opDecompressor: OpDecompressor, opGroupingManager: OpGroupingManager);
|
|
14
14
|
get partialMessages(): ReadonlyMap<string, string[]>;
|
|
15
15
|
clearPartialMessagesFor(clientId: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Ungroups and Unchunks the runtime ops encapsulated by the single remoteMessage received over the wire
|
|
18
|
+
* @param remoteMessage - A message from another client, likely a chunked/grouped op
|
|
19
|
+
* @returns the ungrouped, unchunked, unpacked SequencedContainerRuntimeMessage encapsulated in the remote message
|
|
20
|
+
*/
|
|
16
21
|
process(remoteMessage: ISequencedDocumentMessage): ISequencedDocumentMessage[];
|
|
17
22
|
}
|
|
18
23
|
/**
|
|
@@ -20,7 +25,7 @@ export declare class RemoteMessageProcessor {
|
|
|
20
25
|
*
|
|
21
26
|
* @remarks This API makes no promises regarding backward-compatibility. This is internal API.
|
|
22
27
|
* @param message - message (as it observed in storage / service)
|
|
23
|
-
* @returns
|
|
28
|
+
* @returns whether the given message was unpacked
|
|
24
29
|
*
|
|
25
30
|
* @internal
|
|
26
31
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteMessageProcessor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/remoteMessageProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAe,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"remoteMessageProcessor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/remoteMessageProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAe,MAAM,sCAAsC,CAAC;AAM9F,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,qBAAa,sBAAsB;IAEjC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAFjB,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,EAC9B,iBAAiB,EAAE,iBAAiB;IAGtD,IAAW,eAAe,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAE1D;IAEM,uBAAuB,CAAC,QAAQ,EAAE,MAAM;IAI/C;;;;OAIG;IACI,OAAO,CAAC,aAAa,EAAE,yBAAyB,GAAG,yBAAyB,EAAE;CAiDrF;AAsCD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAsBhF"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { MessageType } from "@fluidframework/protocol-definitions";
|
|
6
|
-
import { ContainerMessageType } from "../containerRuntime";
|
|
6
|
+
import { ContainerMessageType, } from "../containerRuntime";
|
|
7
7
|
export class RemoteMessageProcessor {
|
|
8
8
|
constructor(opSplitter, opDecompressor, opGroupingManager) {
|
|
9
9
|
this.opSplitter = opSplitter;
|
|
@@ -16,12 +16,18 @@ export class RemoteMessageProcessor {
|
|
|
16
16
|
clearPartialMessagesFor(clientId) {
|
|
17
17
|
this.opSplitter.clearPartialChunks(clientId);
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Ungroups and Unchunks the runtime ops encapsulated by the single remoteMessage received over the wire
|
|
21
|
+
* @param remoteMessage - A message from another client, likely a chunked/grouped op
|
|
22
|
+
* @returns the ungrouped, unchunked, unpacked SequencedContainerRuntimeMessage encapsulated in the remote message
|
|
23
|
+
*/
|
|
19
24
|
process(remoteMessage) {
|
|
20
25
|
const result = [];
|
|
21
26
|
// Ungroup before and after decompression for back-compat (cleanup tracked by AB#4371)
|
|
22
27
|
for (const ungroupedMessage of this.opGroupingManager.ungroupOp(copy(remoteMessage))) {
|
|
23
28
|
const message = this.opDecompressor.processMessage(ungroupedMessage).message;
|
|
24
29
|
for (let ungroupedMessage2 of this.opGroupingManager.ungroupOp(message)) {
|
|
30
|
+
// unpack and unchunk the ungrouped message in place
|
|
25
31
|
unpackRuntimeMessage(ungroupedMessage2);
|
|
26
32
|
const chunkProcessingResult = this.opSplitter.processRemoteMessage(ungroupedMessage2);
|
|
27
33
|
ungroupedMessage2 = chunkProcessingResult.message;
|
|
@@ -56,7 +62,7 @@ const copy = (remoteMessage) => {
|
|
|
56
62
|
// There might be multiple container instances receiving same message
|
|
57
63
|
// We do not need to make deep copy, as each layer will just replace message.content itself,
|
|
58
64
|
// but would not modify contents details
|
|
59
|
-
const message =
|
|
65
|
+
const message = { ...remoteMessage };
|
|
60
66
|
// back-compat: ADO #1385: eventually should become unconditional, but only for runtime messages!
|
|
61
67
|
// System message may have no contents, or in some cases (mostly for back-compat) they may have actual objects.
|
|
62
68
|
// Old ops may contain empty string (I assume noops).
|
|
@@ -66,20 +72,26 @@ const copy = (remoteMessage) => {
|
|
|
66
72
|
return message;
|
|
67
73
|
};
|
|
68
74
|
/**
|
|
69
|
-
* For a given message, it moves the nested
|
|
75
|
+
* For a given message, it moves the nested ContainerRuntimeMessage props one level up.
|
|
70
76
|
*
|
|
77
|
+
* The return type illustrates the assumption that the message param
|
|
78
|
+
* becomes a ContainerRuntimeMessage by the time the function returns
|
|
79
|
+
* (but there is no runtime validation of the 'type' or 'compatDetails' values)
|
|
71
80
|
*/
|
|
72
|
-
|
|
81
|
+
function unpack(message) {
|
|
73
82
|
const innerContents = message.contents;
|
|
74
|
-
message
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
// We're going to turn message into a SequencedContainerRuntimeMessage in-place
|
|
84
|
+
const sequencedContainerRuntimeMessage = message;
|
|
85
|
+
sequencedContainerRuntimeMessage.type = innerContents.type;
|
|
86
|
+
sequencedContainerRuntimeMessage.contents = innerContents.contents;
|
|
87
|
+
sequencedContainerRuntimeMessage.compatDetails = innerContents.compatDetails;
|
|
88
|
+
}
|
|
77
89
|
/**
|
|
78
90
|
* Unpacks runtime messages.
|
|
79
91
|
*
|
|
80
92
|
* @remarks This API makes no promises regarding backward-compatibility. This is internal API.
|
|
81
93
|
* @param message - message (as it observed in storage / service)
|
|
82
|
-
* @returns
|
|
94
|
+
* @returns whether the given message was unpacked
|
|
83
95
|
*
|
|
84
96
|
* @internal
|
|
85
97
|
*/
|
|
@@ -92,7 +104,9 @@ export function unpackRuntimeMessage(message) {
|
|
|
92
104
|
return false;
|
|
93
105
|
}
|
|
94
106
|
// legacy op format?
|
|
95
|
-
if
|
|
107
|
+
// TODO: Unsure if this is a real format we should be concerned with. There doesn't appear to be anything prepared to handle the address member.
|
|
108
|
+
if (message.contents.address !== undefined &&
|
|
109
|
+
message.contents.type === undefined) {
|
|
96
110
|
message.type = ContainerMessageType.FluidDataStoreOp;
|
|
97
111
|
}
|
|
98
112
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteMessageProcessor.js","sourceRoot":"","sources":["../../src/opLifecycle/remoteMessageProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAA6B,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAC9F,OAAO,
|
|
1
|
+
{"version":3,"file":"remoteMessageProcessor.js","sourceRoot":"","sources":["../../src/opLifecycle/remoteMessageProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAA6B,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAC9F,OAAO,EACN,oBAAoB,GAGpB,MAAM,qBAAqB,CAAC;AAK7B,MAAM,OAAO,sBAAsB;IAClC,YACkB,UAAsB,EACtB,cAA8B,EAC9B,iBAAoC;QAFpC,eAAU,GAAV,UAAU,CAAY;QACtB,mBAAc,GAAd,cAAc,CAAgB;QAC9B,sBAAiB,GAAjB,iBAAiB,CAAmB;IACnD,CAAC;IAEJ,IAAW,eAAe;QACzB,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;IAC/B,CAAC;IAEM,uBAAuB,CAAC,QAAgB;QAC9C,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;;;OAIG;IACI,OAAO,CAAC,aAAwC;QACtD,MAAM,MAAM,GAAgC,EAAE,CAAC;QAE/C,sFAAsF;QACtF,KAAK,MAAM,gBAAgB,IAAI,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE;YACrF,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC;YAE7E,KAAK,IAAI,iBAAiB,IAAI,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;gBACxE,oDAAoD;gBACpD,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;gBACxC,MAAM,qBAAqB,GAC1B,IAAI,CAAC,UAAU,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;gBACzD,iBAAiB,GAAG,qBAAqB,CAAC,OAAO,CAAC;gBAElD,IAAI,qBAAqB,CAAC,KAAK,KAAK,WAAW,EAAE;oBAChD,6FAA6F;oBAC7F,0CAA0C;oBAC1C,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;oBAC/B,SAAS;iBACT;gBAED,sFAAsF;gBACtF,KAAK,MAAM,6BAA6B,IAAI,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAC3E,iBAAiB,CACjB,EAAE;oBACF,MAAM,0BAA0B,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CACpE,6BAA6B,CAC7B,CAAC;oBAEF,KAAK,MAAM,8BAA8B,IAAI,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAC5E,0BAA0B,CAAC,OAAO,CAClC,EAAE;wBACF,IAAI,0BAA0B,CAAC,KAAK,KAAK,SAAS,EAAE;4BACnD,8DAA8D;4BAC9D,0CAA0C;4BAC1C,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;4BAC5C,SAAS;yBACT;wBAED,kEAAkE;wBAClE,MAAM,CAAC,8BAA8B,CAAC,CAAC;wBACvC,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;qBAC5C;iBACD;aACD;SACD;QAED,OAAO,MAAM,CAAC;IACf,CAAC;CACD;AAED,MAAM,IAAI,GAAG,CAAC,aAAwC,EAA6B,EAAE;IACpF,qEAAqE;IACrE,qEAAqE;IACrE,4FAA4F;IAC5F,wCAAwC;IACxC,MAAM,OAAO,GAAG,EAAE,GAAG,aAAa,EAAE,CAAC;IAErC,iGAAiG;IACjG,+GAA+G;IAC/G,qDAAqD;IACrD,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,QAAQ,KAAK,EAAE,EAAE;QACpE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;KAChD;IAED,OAAO,OAAO,CAAC;AAChB,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,SAAS,MAAM,CACd,OAAkC;IAElC,MAAM,aAAa,GAAG,OAAO,CAAC,QAAmC,CAAC;IAElE,+EAA+E;IAC/E,MAAM,gCAAgC,GAAG,OAA2C,CAAC;IACrF,gCAAgC,CAAC,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC;IAC3D,gCAAgC,CAAC,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;IACnE,gCAAgC,CAAC,aAAa,GAAG,aAAa,CAAC,aAAa,CAAC;AAC9E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAkC;IACtE,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,SAAS,EAAE;QAC3C,8CAA8C;QAC9C,sDAAsD;QACtD,+BAA+B;QAC/B,8BAA8B;QAC9B,OAAO,KAAK,CAAC;KACb;IAED,oBAAoB;IACpB,gJAAgJ;IAChJ,IACE,OAAO,CAAC,QAAkC,CAAC,OAAO,KAAK,SAAS;QAChE,OAAO,CAAC,QAA+B,CAAC,IAAI,KAAK,SAAS,EAC1D;QACD,OAAO,CAAC,IAAI,GAAG,oBAAoB,CAAC,gBAAgB,CAAC;KACrD;SAAM;QACN,aAAa;QACb,MAAM,CAAC,OAAO,CAAC,CAAC;KAChB;IAED,OAAO,IAAI,CAAC;AACb,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport {\n\tContainerMessageType,\n\tContainerRuntimeMessage,\n\tSequencedContainerRuntimeMessage,\n} from \"../containerRuntime\";\nimport { OpDecompressor } from \"./opDecompressor\";\nimport { OpGroupingManager } from \"./opGroupingManager\";\nimport { OpSplitter } from \"./opSplitter\";\n\nexport class RemoteMessageProcessor {\n\tconstructor(\n\t\tprivate readonly opSplitter: OpSplitter,\n\t\tprivate readonly opDecompressor: OpDecompressor,\n\t\tprivate readonly opGroupingManager: OpGroupingManager,\n\t) {}\n\n\tpublic get partialMessages(): ReadonlyMap<string, string[]> {\n\t\treturn this.opSplitter.chunks;\n\t}\n\n\tpublic clearPartialMessagesFor(clientId: string) {\n\t\tthis.opSplitter.clearPartialChunks(clientId);\n\t}\n\n\t/**\n\t * Ungroups and Unchunks the runtime ops encapsulated by the single remoteMessage received over the wire\n\t * @param remoteMessage - A message from another client, likely a chunked/grouped op\n\t * @returns the ungrouped, unchunked, unpacked SequencedContainerRuntimeMessage encapsulated in the remote message\n\t */\n\tpublic process(remoteMessage: ISequencedDocumentMessage): ISequencedDocumentMessage[] {\n\t\tconst result: ISequencedDocumentMessage[] = [];\n\n\t\t// Ungroup before and after decompression for back-compat (cleanup tracked by AB#4371)\n\t\tfor (const ungroupedMessage of this.opGroupingManager.ungroupOp(copy(remoteMessage))) {\n\t\t\tconst message = this.opDecompressor.processMessage(ungroupedMessage).message;\n\n\t\t\tfor (let ungroupedMessage2 of this.opGroupingManager.ungroupOp(message)) {\n\t\t\t\t// unpack and unchunk the ungrouped message in place\n\t\t\t\tunpackRuntimeMessage(ungroupedMessage2);\n\t\t\t\tconst chunkProcessingResult =\n\t\t\t\t\tthis.opSplitter.processRemoteMessage(ungroupedMessage2);\n\t\t\t\tungroupedMessage2 = chunkProcessingResult.message;\n\n\t\t\t\tif (chunkProcessingResult.state !== \"Processed\") {\n\t\t\t\t\t// If the message is not chunked or if the splitter is still rebuilding the original message,\n\t\t\t\t\t// there is no need to continue processing\n\t\t\t\t\tresult.push(ungroupedMessage2);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Ungroup before and after decompression for back-compat (cleanup tracked by AB#4371)\n\t\t\t\tfor (const ungroupedMessageAfterChunking of this.opGroupingManager.ungroupOp(\n\t\t\t\t\tungroupedMessage2,\n\t\t\t\t)) {\n\t\t\t\t\tconst decompressionAfterChunking = this.opDecompressor.processMessage(\n\t\t\t\t\t\tungroupedMessageAfterChunking,\n\t\t\t\t\t);\n\n\t\t\t\t\tfor (const ungroupedMessageAfterChunking2 of this.opGroupingManager.ungroupOp(\n\t\t\t\t\t\tdecompressionAfterChunking.message,\n\t\t\t\t\t)) {\n\t\t\t\t\t\tif (decompressionAfterChunking.state === \"Skipped\") {\n\t\t\t\t\t\t\t// After chunking, if the original message was not compressed,\n\t\t\t\t\t\t\t// there is no need to continue processing\n\t\t\t\t\t\t\tresult.push(ungroupedMessageAfterChunking2);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// The message needs to be unpacked after chunking + decompression\n\t\t\t\t\t\tunpack(ungroupedMessageAfterChunking2);\n\t\t\t\t\t\tresult.push(ungroupedMessageAfterChunking2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n}\n\nconst copy = (remoteMessage: ISequencedDocumentMessage): ISequencedDocumentMessage => {\n\t// Do shallow copy of message, as the processing flow will modify it.\n\t// There might be multiple container instances receiving same message\n\t// We do not need to make deep copy, as each layer will just replace message.content itself,\n\t// but would not modify contents details\n\tconst message = { ...remoteMessage };\n\n\t// back-compat: ADO #1385: eventually should become unconditional, but only for runtime messages!\n\t// System message may have no contents, or in some cases (mostly for back-compat) they may have actual objects.\n\t// Old ops may contain empty string (I assume noops).\n\tif (typeof message.contents === \"string\" && message.contents !== \"\") {\n\t\tmessage.contents = JSON.parse(message.contents);\n\t}\n\n\treturn message;\n};\n\n/**\n * For a given message, it moves the nested ContainerRuntimeMessage props one level up.\n *\n * The return type illustrates the assumption that the message param\n * becomes a ContainerRuntimeMessage by the time the function returns\n * (but there is no runtime validation of the 'type' or 'compatDetails' values)\n */\nfunction unpack(\n\tmessage: ISequencedDocumentMessage,\n): asserts message is SequencedContainerRuntimeMessage {\n\tconst innerContents = message.contents as ContainerRuntimeMessage;\n\n\t// We're going to turn message into a SequencedContainerRuntimeMessage in-place\n\tconst sequencedContainerRuntimeMessage = message as SequencedContainerRuntimeMessage;\n\tsequencedContainerRuntimeMessage.type = innerContents.type;\n\tsequencedContainerRuntimeMessage.contents = innerContents.contents;\n\tsequencedContainerRuntimeMessage.compatDetails = innerContents.compatDetails;\n}\n\n/**\n * Unpacks runtime messages.\n *\n * @remarks This API makes no promises regarding backward-compatibility. This is internal API.\n * @param message - message (as it observed in storage / service)\n * @returns whether the given message was unpacked\n *\n * @internal\n */\nexport function unpackRuntimeMessage(message: ISequencedDocumentMessage): boolean {\n\tif (message.type !== MessageType.Operation) {\n\t\t// Legacy format, but it's already \"unpacked\",\n\t\t// i.e. message.type is actually ContainerMessageType.\n\t\t// Or it's non-runtime message.\n\t\t// Nothing to do in such case.\n\t\treturn false;\n\t}\n\n\t// legacy op format?\n\t// TODO: Unsure if this is a real format we should be concerned with. There doesn't appear to be anything prepared to handle the address member.\n\tif (\n\t\t(message.contents as { address?: unknown }).address !== undefined &&\n\t\t(message.contents as { type?: unknown }).type === undefined\n\t) {\n\t\tmessage.type = ContainerMessageType.FluidDataStoreOp;\n\t} else {\n\t\t// new format\n\t\tunpack(message);\n\t}\n\n\treturn true;\n}\n"]}
|
package/lib/opProperties.js
CHANGED
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
export const opSize = (op) => {
|
|
6
|
-
var _a;
|
|
7
6
|
// Some messages may already have string contents,
|
|
8
7
|
// so stringifying them again will add inaccurate overhead.
|
|
9
|
-
const content = typeof op.contents === "string" ? op.contents :
|
|
8
|
+
const content = typeof op.contents === "string" ? op.contents : JSON.stringify(op.contents) ?? "";
|
|
10
9
|
const data = opHasData(op) ? op.data : "";
|
|
11
10
|
return content.length + data.length;
|
|
12
11
|
};
|
package/lib/opProperties.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opProperties.js","sourceRoot":"","sources":["../src/opProperties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EAA6B,EAAU,EAAE
|
|
1
|
+
{"version":3,"file":"opProperties.js","sourceRoot":"","sources":["../src/opProperties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EAA6B,EAAU,EAAE;IAC/D,kDAAkD;IAClD,2DAA2D;IAC3D,MAAM,OAAO,GACZ,OAAO,EAAE,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnF,MAAM,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1C,OAAO,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,EAA6B,EAAyC,EAAE,CACzF,EAAsC,CAAC,IAAI,KAAK,SAAS,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tISequencedDocumentMessage,\n\tISequencedDocumentSystemMessage,\n} from \"@fluidframework/protocol-definitions\";\n\nexport const opSize = (op: ISequencedDocumentMessage): number => {\n\t// Some messages may already have string contents,\n\t// so stringifying them again will add inaccurate overhead.\n\tconst content =\n\t\ttypeof op.contents === \"string\" ? op.contents : JSON.stringify(op.contents) ?? \"\";\n\tconst data = opHasData(op) ? op.data : \"\";\n\treturn content.length + data.length;\n};\n\nconst opHasData = (op: ISequencedDocumentMessage): op is ISequencedDocumentSystemMessage =>\n\t(op as ISequencedDocumentSystemMessage).data !== undefined;\n"]}
|
package/lib/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/container-runtime";
|
|
8
|
-
export declare const pkgVersion = "2.0.0-dev.
|
|
8
|
+
export declare const pkgVersion = "2.0.0-dev.6.4.0.191258";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
package/lib/packageVersion.js
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export const pkgName = "@fluidframework/container-runtime";
|
|
8
|
-
export const pkgVersion = "2.0.0-dev.
|
|
8
|
+
export const pkgVersion = "2.0.0-dev.6.4.0.191258";
|
|
9
9
|
//# sourceMappingURL=packageVersion.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,mCAAmC,CAAC;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,wBAAwB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-dev.
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,mCAAmC,CAAC;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,wBAAwB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-dev.6.4.0.191258\";\n"]}
|