@fluidframework/container-runtime 2.0.0-dev.5.3.2.178189 → 2.0.0-dev.6.4.0.191457
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 +123 -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 +10 -16
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +184 -172
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +25 -16
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +161 -35
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +697 -449
- 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 +3 -2
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +83 -87
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +1 -2
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +8 -9
- 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 +22 -6
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +123 -81
- 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 +61 -53
- 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 -4
- 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.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/opLifecycle/batchManager.js +10 -6
- package/dist/opLifecycle/batchManager.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 +23 -20
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +19 -9
- 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 +22 -19
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +7 -5
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +22 -31
- 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 +19 -7
- 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 +18 -8
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +73 -51
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +36 -32
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/index.d.ts +3 -3
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +2 -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 +10 -19
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +57 -130
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +6 -30
- 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 +4 -14
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +15 -101
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +38 -25
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +2 -3
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +12 -13
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +3 -0
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +6 -4
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +10 -4
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +106 -57
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +8 -8
- 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 +10 -16
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +159 -147
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +15 -6
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +161 -35
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +651 -402
- 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 +3 -2
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +47 -51
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +1 -2
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +3 -4
- 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 +22 -6
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +107 -65
- 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 -53
- 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 -4
- 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.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/opLifecycle/batchManager.js +10 -6
- package/lib/opLifecycle/batchManager.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 +15 -12
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +17 -7
- 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 +13 -10
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +7 -5
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +13 -22
- 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 +20 -8
- 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 +18 -8
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +62 -40
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +18 -14
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/index.d.ts +3 -3
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -1
- 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 +10 -19
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +42 -115
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +6 -30
- 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 +4 -14
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +14 -100
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +38 -25
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +2 -3
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +5 -6
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +3 -0
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +5 -3
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +10 -4
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +100 -51
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +8 -8
- 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 +28 -31
- package/src/batchTracker.ts +7 -5
- package/src/blobManager.ts +188 -166
- package/src/connectionTelemetry.ts +9 -4
- package/src/containerRuntime.ts +806 -441
- package/src/dataStore.ts +12 -4
- package/src/dataStoreContext.ts +39 -43
- package/src/dataStoreContexts.ts +4 -6
- package/src/dataStoreRegistry.ts +1 -1
- package/src/dataStores.ts +114 -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 -52
- package/src/gc/gcConfigs.ts +4 -2
- package/src/gc/gcDefinitions.ts +17 -20
- 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 +14 -12
- 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 +7 -2
- package/src/opLifecycle/opCompressor.ts +6 -5
- package/src/opLifecycle/opDecompressor.ts +6 -4
- package/src/opLifecycle/opGroupingManager.ts +9 -6
- package/src/opLifecycle/opSplitter.ts +7 -6
- package/src/opLifecycle/outbox.ts +23 -32
- package/src/opLifecycle/remoteMessageProcessor.ts +27 -8
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +72 -42
- package/src/scheduleManager.ts +7 -5
- package/src/summary/index.ts +4 -3
- 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 +1 -2
- package/src/summary/summarizerNode/summarizerNode.ts +36 -160
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +7 -38
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +11 -130
- package/src/summary/summarizerTypes.ts +40 -25
- package/src/summary/summaryCollection.ts +3 -3
- package/src/summary/summaryFormat.ts +4 -1
- package/src/summary/summaryGenerator.ts +52 -52
- package/src/summary/summaryManager.ts +44 -17
- 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 -28
- package/dist/id-compressor/uuidUtilities.d.ts.map +0 -1
- package/dist/id-compressor/uuidUtilities.js +0 -104
- 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 -28
- package/lib/id-compressor/uuidUtilities.d.ts.map +0 -1
- package/lib/id-compressor/uuidUtilities.js +0 -96
- 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 -120
package/lib/blobManager.js
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { v4 as uuid } from "uuid";
|
|
6
6
|
import { createResponseError, generateHandleContextPath, responseToException, SummaryTreeBuilder, } from "@fluidframework/runtime-utils";
|
|
7
|
-
import { assert,
|
|
7
|
+
import { assert, Deferred } from "@fluidframework/core-utils";
|
|
8
|
+
import { bufferToString, stringToBuffer, TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
8
9
|
import { AttachState } from "@fluidframework/container-definitions";
|
|
9
|
-
import {
|
|
10
|
-
import { GenericError } from "@fluidframework/container-utils";
|
|
10
|
+
import { createChildMonitoringContext, GenericError, LoggingError, PerformanceEvent, } from "@fluidframework/telemetry-utils";
|
|
11
11
|
import { TombstoneResponseHeaderKey } from "./containerRuntime";
|
|
12
|
-
import { sendGCUnexpectedUsageEvent,
|
|
12
|
+
import { sendGCUnexpectedUsageEvent, disableAttachmentBlobSweepKey, throwOnTombstoneLoadKey, } from "./gc";
|
|
13
13
|
import { Throttler, formExponentialFn } from "./throttler";
|
|
14
14
|
import { summarizerClientType } from "./summary";
|
|
15
15
|
/**
|
|
@@ -35,10 +35,9 @@ export class BlobHandle {
|
|
|
35
35
|
return this.routeContext.isAttached && this.attached;
|
|
36
36
|
}
|
|
37
37
|
attachGraph() {
|
|
38
|
-
var _a;
|
|
39
38
|
if (!this.attached) {
|
|
40
39
|
this.attached = true;
|
|
41
|
-
|
|
40
|
+
this.onAttachGraph?.();
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
43
|
bind(handle) {
|
|
@@ -61,15 +60,6 @@ class CancellableThrottler {
|
|
|
61
60
|
this.cancelP = new Deferred();
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
|
-
// Note that while offline we "submit" an op before uploading the blob, but we always
|
|
65
|
-
// expect blobs to be uploaded before we actually see the op round-trip
|
|
66
|
-
var PendingBlobStatus;
|
|
67
|
-
(function (PendingBlobStatus) {
|
|
68
|
-
PendingBlobStatus[PendingBlobStatus["OnlinePendingUpload"] = 0] = "OnlinePendingUpload";
|
|
69
|
-
PendingBlobStatus[PendingBlobStatus["OnlinePendingOp"] = 1] = "OnlinePendingOp";
|
|
70
|
-
PendingBlobStatus[PendingBlobStatus["OfflinePendingUpload"] = 2] = "OfflinePendingUpload";
|
|
71
|
-
PendingBlobStatus[PendingBlobStatus["OfflinePendingOp"] = 3] = "OfflinePendingOp";
|
|
72
|
-
})(PendingBlobStatus || (PendingBlobStatus = {}));
|
|
73
63
|
export class BlobManager extends TypedEventEmitter {
|
|
74
64
|
constructor(routeContext, snapshot, getStorage,
|
|
75
65
|
/**
|
|
@@ -97,9 +87,7 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
97
87
|
this.runtime = runtime;
|
|
98
88
|
this.closeContainer = closeContainer;
|
|
99
89
|
/**
|
|
100
|
-
* Blobs which
|
|
101
|
-
* Until we see the op round-trip, there is a possibility we may need to re-upload the blob, so
|
|
102
|
-
* we must save it. This is true for both the online and offline flow.
|
|
90
|
+
* Blobs which we have not yet seen a BlobAttach op round-trip and not yet attached to a DDS.
|
|
103
91
|
*/
|
|
104
92
|
this.pendingBlobs = new Map();
|
|
105
93
|
/**
|
|
@@ -117,27 +105,32 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
117
105
|
* Tombstone is a temporary feature that imitates a blob getting swept by garbage collection.
|
|
118
106
|
*/
|
|
119
107
|
this.tombstonedBlobs = new Set();
|
|
120
|
-
this.mc =
|
|
108
|
+
this.mc = createChildMonitoringContext({
|
|
109
|
+
logger: this.runtime.logger,
|
|
110
|
+
namespace: "BlobManager",
|
|
111
|
+
});
|
|
121
112
|
// Read the feature flag that tells whether to throw when a tombstone blob is requested.
|
|
122
113
|
this.throwOnTombstoneLoad =
|
|
123
114
|
this.mc.config.getBoolean(throwOnTombstoneLoadKey) === true &&
|
|
124
115
|
this.runtime.gcTombstoneEnforcementAllowed &&
|
|
125
116
|
this.runtime.clientDetails.type !== summarizerClientType;
|
|
126
|
-
this.runtime.on("disconnected", () => this.onDisconnected());
|
|
127
117
|
this.redirectTable = this.load(snapshot);
|
|
128
118
|
// Begin uploading stashed blobs from previous container instance
|
|
129
119
|
Object.entries(stashedBlobs).forEach(([localId, entry]) => {
|
|
130
120
|
const blob = stringToBuffer(entry.blob, "base64");
|
|
131
121
|
const attached = entry.attached;
|
|
132
122
|
const acked = entry.acked;
|
|
123
|
+
const storageId = entry.storageId; // entry.storageId = response.id
|
|
133
124
|
if (entry.minTTLInSeconds && entry.uploadTime) {
|
|
134
125
|
const timeLapseSinceLocalUpload = (Date.now() - entry.uploadTime) / 1000;
|
|
135
126
|
// stashed entries with more than half-life in storage will not be reuploaded
|
|
136
127
|
if (entry.minTTLInSeconds - timeLapseSinceLocalUpload > entry.minTTLInSeconds / 2) {
|
|
137
128
|
this.pendingBlobs.set(localId, {
|
|
138
129
|
blob,
|
|
139
|
-
|
|
130
|
+
uploading: false,
|
|
131
|
+
opsent: true,
|
|
140
132
|
handleP: new Deferred(),
|
|
133
|
+
storageId,
|
|
141
134
|
uploadP: undefined,
|
|
142
135
|
uploadTime: entry.uploadTime,
|
|
143
136
|
minTTLInSeconds: entry.minTTLInSeconds,
|
|
@@ -149,21 +142,22 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
149
142
|
}
|
|
150
143
|
this.pendingBlobs.set(localId, {
|
|
151
144
|
blob,
|
|
152
|
-
|
|
145
|
+
uploading: true,
|
|
153
146
|
handleP: new Deferred(),
|
|
154
147
|
uploadP: this.uploadBlob(localId, blob),
|
|
155
148
|
attached,
|
|
156
149
|
acked,
|
|
150
|
+
opsent: true,
|
|
157
151
|
});
|
|
158
152
|
});
|
|
159
153
|
this.sendBlobAttachOp = (localId, blobId) => {
|
|
160
154
|
const pendingEntry = this.pendingBlobs.get(localId);
|
|
161
|
-
|
|
155
|
+
assert(pendingEntry !== undefined, 0x725 /* Must have pending blob entry for upcoming op */);
|
|
156
|
+
if (pendingEntry?.uploadTime && pendingEntry?.minTTLInSeconds) {
|
|
162
157
|
const secondsSinceUpload = (Date.now() - pendingEntry.uploadTime) / 1000;
|
|
163
158
|
const expired = pendingEntry.minTTLInSeconds - secondsSinceUpload < 0;
|
|
164
159
|
this.mc.logger.sendTelemetryEvent({
|
|
165
160
|
eventName: "sendBlobAttach",
|
|
166
|
-
entryStatus: pendingEntry.status,
|
|
167
161
|
secondsSinceUpload,
|
|
168
162
|
minTTLInSeconds: pendingEntry.minTTLInSeconds,
|
|
169
163
|
expired,
|
|
@@ -173,48 +167,45 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
173
167
|
this.closeContainer(new GenericError("Trying to submit a BlobAttach for expired blob", undefined, {
|
|
174
168
|
localId,
|
|
175
169
|
blobId,
|
|
176
|
-
entryStatus: pendingEntry.status,
|
|
177
170
|
secondsSinceUpload,
|
|
178
171
|
}));
|
|
179
172
|
}
|
|
180
173
|
}
|
|
174
|
+
pendingEntry.opsent = true;
|
|
181
175
|
return sendBlobAttachOp(localId, blobId);
|
|
182
176
|
};
|
|
183
177
|
}
|
|
184
|
-
get
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
178
|
+
get allBlobsAttached() {
|
|
179
|
+
for (const [, entry] of this.pendingBlobs) {
|
|
180
|
+
if (entry.attached === false) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return true;
|
|
189
185
|
}
|
|
190
186
|
get hasPendingBlobs() {
|
|
191
187
|
return ((this.runtime.attachState !== AttachState.Attached && this.redirectTable.size > 0) ||
|
|
192
188
|
this.pendingBlobs.size > 0);
|
|
193
189
|
}
|
|
190
|
+
createAbortError(pending) {
|
|
191
|
+
return new LoggingError("uploadBlob aborted", {
|
|
192
|
+
acked: pending?.acked,
|
|
193
|
+
uploadTime: pending?.uploadTime,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
194
196
|
/**
|
|
195
197
|
* Upload blobs added while offline. This must be completed before connecting and resubmitting ops.
|
|
196
198
|
*/
|
|
197
|
-
async
|
|
199
|
+
async processStashedChanges() {
|
|
198
200
|
this.retryThrottler.cancel();
|
|
199
|
-
const pendingUploads = this.
|
|
201
|
+
const pendingUploads = Array.from(this.pendingBlobs.values())
|
|
202
|
+
.filter((e) => e.uploading === true)
|
|
203
|
+
.map(async (e) => e.uploadP);
|
|
200
204
|
await PerformanceEvent.timedExecAsync(this.mc.logger, {
|
|
201
|
-
eventName: "
|
|
205
|
+
eventName: "BlobUploadProcessStashedChanges",
|
|
202
206
|
count: pendingUploads.length,
|
|
203
207
|
}, async () => Promise.all(pendingUploads), { start: true, end: true });
|
|
204
208
|
}
|
|
205
|
-
/**
|
|
206
|
-
* Transition online blobs waiting for BlobAttach op round-trip since we will not see the op until we are connected
|
|
207
|
-
* again
|
|
208
|
-
*/
|
|
209
|
-
onDisconnected() {
|
|
210
|
-
for (const [localId, entry] of this.pendingBlobs) {
|
|
211
|
-
if (entry.status === PendingBlobStatus.OnlinePendingOp) {
|
|
212
|
-
// This will submit another BlobAttach op for this blob. This is necessary because the one we sent
|
|
213
|
-
// already didn't have the local ID.
|
|
214
|
-
this.transitionToOffline(localId);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
209
|
/**
|
|
219
210
|
* Set of actual storage IDs (i.e., IDs that can be requested from storage). This will be empty if the container is
|
|
220
211
|
* detached or there are no (non-pending) attachment blobs in the document
|
|
@@ -261,6 +252,7 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
261
252
|
const callback = pending
|
|
262
253
|
? () => {
|
|
263
254
|
pending.attached = true;
|
|
255
|
+
this.emit("blobAttached", pending);
|
|
264
256
|
this.deletePendingBlobMaybe(id);
|
|
265
257
|
}
|
|
266
258
|
: undefined;
|
|
@@ -273,7 +265,7 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
273
265
|
this.setRedirection(response.id, undefined);
|
|
274
266
|
return this.getBlobHandle(response.id);
|
|
275
267
|
}
|
|
276
|
-
async createBlob(blob) {
|
|
268
|
+
async createBlob(blob, signal) {
|
|
277
269
|
if (this.runtime.attachState === AttachState.Detached) {
|
|
278
270
|
return this.createBlobDetached(blob);
|
|
279
271
|
}
|
|
@@ -283,19 +275,32 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
283
275
|
await new Promise((resolve) => this.runtime.once("attached", resolve));
|
|
284
276
|
}
|
|
285
277
|
assert(this.runtime.attachState === AttachState.Attached, 0x385 /* For clarity and paranoid defense against adding future attachment states */);
|
|
278
|
+
if (signal?.aborted) {
|
|
279
|
+
throw this.createAbortError();
|
|
280
|
+
}
|
|
286
281
|
// Create a local ID for the blob. After uploading it to storage and before returning it, a local ID to
|
|
287
282
|
// storage ID mapping is created.
|
|
288
283
|
const localId = uuid();
|
|
289
284
|
const pendingEntry = {
|
|
290
285
|
blob,
|
|
291
|
-
|
|
286
|
+
uploading: true,
|
|
292
287
|
handleP: new Deferred(),
|
|
293
288
|
uploadP: this.uploadBlob(localId, blob),
|
|
294
289
|
attached: false,
|
|
295
290
|
acked: false,
|
|
291
|
+
abortSignal: signal,
|
|
292
|
+
opsent: false,
|
|
296
293
|
};
|
|
297
294
|
this.pendingBlobs.set(localId, pendingEntry);
|
|
298
|
-
|
|
295
|
+
const abortListener = () => {
|
|
296
|
+
if (!pendingEntry.acked) {
|
|
297
|
+
pendingEntry.handleP.reject(this.createAbortError(pendingEntry));
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
signal?.addEventListener("abort", abortListener, { once: true });
|
|
301
|
+
return pendingEntry.handleP.promise.finally(() => {
|
|
302
|
+
signal?.removeEventListener("abort", abortListener);
|
|
303
|
+
});
|
|
299
304
|
}
|
|
300
305
|
async uploadBlob(localId, blob) {
|
|
301
306
|
return PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "createBlob" }, async () => this.getStorage().createBlob(blob), { end: true, cancel: this.runtime.connected ? "error" : "generic" }).then((response) => this.onUploadResolve(localId, response), async (err) => this.onUploadReject(localId, err));
|
|
@@ -310,69 +315,59 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
310
315
|
deletePendingBlobMaybe(id) {
|
|
311
316
|
if (this.pendingBlobs.has(id)) {
|
|
312
317
|
const entry = this.pendingBlobs.get(id);
|
|
313
|
-
if (
|
|
314
|
-
this.
|
|
315
|
-
if (!this.hasPendingBlobs) {
|
|
316
|
-
this.emit("noPendingBlobs");
|
|
317
|
-
}
|
|
318
|
+
if (entry?.attached && entry?.acked) {
|
|
319
|
+
this.deletePendingBlob(id);
|
|
318
320
|
}
|
|
319
321
|
}
|
|
320
322
|
}
|
|
323
|
+
deletePendingBlob(id) {
|
|
324
|
+
if (this.pendingBlobs.delete(id) && !this.hasPendingBlobs) {
|
|
325
|
+
this.emit("noPendingBlobs");
|
|
326
|
+
}
|
|
327
|
+
}
|
|
321
328
|
onUploadResolve(localId, response) {
|
|
322
|
-
var _a;
|
|
323
329
|
const entry = this.pendingBlobs.get(localId);
|
|
324
330
|
assert(entry !== undefined, 0x6c8 /* pending blob entry not found for uploaded blob */);
|
|
325
|
-
|
|
326
|
-
|
|
331
|
+
if (entry.abortSignal?.aborted === true && !entry.opsent) {
|
|
332
|
+
this.deletePendingBlob(localId);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
assert(entry.uploading === true, 0x386 /* Must have pending blob entry for uploaded blob */);
|
|
327
336
|
entry.storageId = response.id;
|
|
328
337
|
entry.uploadTime = Date.now();
|
|
329
338
|
entry.minTTLInSeconds = response.minTTLInSeconds;
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
else {
|
|
347
|
-
// If there is already an op for this storage ID, append the local ID to the list. Once any op for
|
|
348
|
-
// this storage ID is ack'd, all pending blobs for it can be resolved since the op will keep the
|
|
349
|
-
// blob alive in storage.
|
|
350
|
-
this.opsInFlight.set(response.id, ((_a = this.opsInFlight.get(response.id)) !== null && _a !== void 0 ? _a : []).concat(localId));
|
|
351
|
-
entry.status = PendingBlobStatus.OnlinePendingOp;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
else if (entry.status === PendingBlobStatus.OfflinePendingUpload) {
|
|
355
|
-
// We already submitted a BlobAttach op for this blob when it was transitioned to offline flow
|
|
356
|
-
entry.status = PendingBlobStatus.OfflinePendingOp;
|
|
357
|
-
}
|
|
339
|
+
// Send a blob attach op. This serves two purposes:
|
|
340
|
+
// 1. If its a new blob, i.e., it isn't de-duped, the server will keep the blob alive if it sees this op
|
|
341
|
+
// until its storage ID is added to the next summary.
|
|
342
|
+
// 2. It will create a local ID to storage ID mapping in all clients which is needed to retrieve the
|
|
343
|
+
// blob from the server via the storage ID.
|
|
344
|
+
if (!entry.opsent) {
|
|
345
|
+
this.sendBlobAttachOp(localId, response.id);
|
|
346
|
+
}
|
|
347
|
+
if (this.storageIds.has(response.id)) {
|
|
348
|
+
// The blob is de-duped. Set up a local ID to storage ID mapping and return the blob. Since this is
|
|
349
|
+
// an existing blob, we don't have to wait for the op to be ack'd since this step has already
|
|
350
|
+
// happened before and so, the server won't delete it.
|
|
351
|
+
this.setRedirection(localId, response.id);
|
|
352
|
+
entry.handleP.resolve(this.getBlobHandle(localId));
|
|
353
|
+
this.deletePendingBlobMaybe(localId);
|
|
358
354
|
}
|
|
359
355
|
else {
|
|
360
|
-
//
|
|
361
|
-
this
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
}
|
|
365
|
-
entry.status = PendingBlobStatus.OfflinePendingOp;
|
|
356
|
+
// If there is already an op for this storage ID, append the local ID to the list. Once any op for
|
|
357
|
+
// this storage ID is ack'd, all pending blobs for it can be resolved since the op will keep the
|
|
358
|
+
// blob alive in storage.
|
|
359
|
+
this.opsInFlight.set(response.id, (this.opsInFlight.get(response.id) ?? []).concat(localId));
|
|
366
360
|
}
|
|
367
361
|
return response;
|
|
368
362
|
}
|
|
369
363
|
async onUploadReject(localId, error) {
|
|
370
364
|
const entry = this.pendingBlobs.get(localId);
|
|
371
365
|
assert(!!entry, 0x387 /* Must have pending blob entry for blob which failed to upload */);
|
|
366
|
+
if (entry.abortSignal?.aborted === true && !entry.opsent) {
|
|
367
|
+
this.deletePendingBlob(localId);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
372
370
|
if (!this.runtime.connected) {
|
|
373
|
-
if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
|
|
374
|
-
this.transitionToOffline(localId);
|
|
375
|
-
}
|
|
376
371
|
// we are probably not connected to storage but start another upload request in case we are
|
|
377
372
|
entry.uploadP = this.retryThrottler
|
|
378
373
|
.getDelay()
|
|
@@ -384,27 +379,6 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
384
379
|
throw error;
|
|
385
380
|
}
|
|
386
381
|
}
|
|
387
|
-
transitionToOffline(localId) {
|
|
388
|
-
assert(!this.runtime.connected, 0x388 /* Must only transition to offline flow while runtime is disconnected */);
|
|
389
|
-
const entry = this.pendingBlobs.get(localId);
|
|
390
|
-
assert(!!entry, 0x389 /* No pending blob entry */);
|
|
391
|
-
assert([PendingBlobStatus.OnlinePendingUpload, PendingBlobStatus.OnlinePendingOp].includes(entry.status), 0x38a /* Blob must be in online flow to transition to offline flow */);
|
|
392
|
-
/**
|
|
393
|
-
* If we haven't already submitted a BlobAttach op for this entry, send it before returning the blob handle.
|
|
394
|
-
* This will make sure that the BlobAttach op is sequenced prior to any ops referencing the handle. Otherwise,
|
|
395
|
-
* an invalid handle could be added to the document.
|
|
396
|
-
* storageId may be undefined but since we are not connected we will have a chance to add it when reSubmit()
|
|
397
|
-
* is called on reconnection.
|
|
398
|
-
*/
|
|
399
|
-
if (entry.status !== PendingBlobStatus.OnlinePendingOp) {
|
|
400
|
-
this.sendBlobAttachOp(localId, entry.storageId);
|
|
401
|
-
}
|
|
402
|
-
entry.status =
|
|
403
|
-
entry.status === PendingBlobStatus.OnlinePendingUpload
|
|
404
|
-
? PendingBlobStatus.OfflinePendingUpload
|
|
405
|
-
: PendingBlobStatus.OfflinePendingOp;
|
|
406
|
-
entry.handleP.resolve(this.getBlobHandle(localId));
|
|
407
|
-
}
|
|
408
382
|
/**
|
|
409
383
|
* Resubmit a BlobAttach op. Used to add storage IDs to ops that were
|
|
410
384
|
* submitted to runtime while disconnected.
|
|
@@ -417,16 +391,21 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
417
391
|
const pendingEntry = this.pendingBlobs.get(localId);
|
|
418
392
|
if (!blobId) {
|
|
419
393
|
// We submitted this op while offline. The blob should have been uploaded by now.
|
|
420
|
-
assert(
|
|
421
|
-
|
|
422
|
-
return this.sendBlobAttachOp(localId, pendingEntry.storageId);
|
|
394
|
+
assert(pendingEntry?.opsent === true && !!pendingEntry?.storageId, 0x38d /* blob must be uploaded before resubmitting BlobAttach op */);
|
|
395
|
+
return this.sendBlobAttachOp(localId, pendingEntry?.storageId);
|
|
423
396
|
}
|
|
424
397
|
return this.sendBlobAttachOp(localId, blobId);
|
|
425
398
|
}
|
|
426
399
|
processBlobAttachOp(message, local) {
|
|
427
|
-
|
|
428
|
-
const
|
|
429
|
-
|
|
400
|
+
const localId = message.metadata?.localId;
|
|
401
|
+
const blobId = message.metadata?.blobId;
|
|
402
|
+
if (localId) {
|
|
403
|
+
const pendingEntry = this.pendingBlobs.get(localId);
|
|
404
|
+
if (pendingEntry?.abortSignal?.aborted) {
|
|
405
|
+
this.deletePendingBlob(localId);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
430
409
|
assert(blobId !== undefined, 0x12a /* "Missing blob id on metadata" */);
|
|
431
410
|
// Set up a mapping from local ID to storage ID. This is crucial since without this the blob cannot be
|
|
432
411
|
// requested from the server.
|
|
@@ -447,21 +426,17 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
447
426
|
waitingBlobs.forEach((pendingLocalId) => {
|
|
448
427
|
const entry = this.pendingBlobs.get(pendingLocalId);
|
|
449
428
|
assert(entry !== undefined, 0x38f /* local online BlobAttach op with no pending blob entry */);
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
entry.handleP.resolve(this.getBlobHandle(pendingLocalId));
|
|
455
|
-
this.deletePendingBlobMaybe(pendingLocalId);
|
|
456
|
-
}
|
|
429
|
+
this.setRedirection(pendingLocalId, blobId);
|
|
430
|
+
entry.acked = true;
|
|
431
|
+
entry.handleP.resolve(this.getBlobHandle(pendingLocalId));
|
|
432
|
+
this.deletePendingBlobMaybe(pendingLocalId);
|
|
457
433
|
});
|
|
458
434
|
this.opsInFlight.delete(blobId);
|
|
459
435
|
}
|
|
460
|
-
// offline flow does not resolve the handle (since it was already resolved)
|
|
461
|
-
// but we still need to delete the entry in case is acked and attached.
|
|
462
436
|
const localEntry = this.pendingBlobs.get(localId);
|
|
463
437
|
if (localEntry) {
|
|
464
438
|
localEntry.acked = true;
|
|
439
|
+
localEntry.handleP.resolve(this.getBlobHandle(localId));
|
|
465
440
|
this.deletePendingBlobMaybe(localId);
|
|
466
441
|
}
|
|
467
442
|
}
|
|
@@ -490,11 +465,10 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
490
465
|
* Load a set of previously attached blob IDs and redirect table from a previous snapshot.
|
|
491
466
|
*/
|
|
492
467
|
load(snapshot) {
|
|
493
|
-
var _a, _b, _c;
|
|
494
468
|
this.mc.logger.sendTelemetryEvent({
|
|
495
469
|
eventName: "AttachmentBlobsLoaded",
|
|
496
|
-
count:
|
|
497
|
-
redirectTable:
|
|
470
|
+
count: snapshot.ids?.length ?? 0,
|
|
471
|
+
redirectTable: snapshot.redirectTable?.length,
|
|
498
472
|
});
|
|
499
473
|
const table = new Map(snapshot.redirectTable);
|
|
500
474
|
if (snapshot.ids) {
|
|
@@ -553,11 +527,11 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
553
527
|
* Delete attachment blobs that are sweep ready.
|
|
554
528
|
* @param sweepReadyBlobRoutes - The routes of blobs that are sweep ready and should be deleted. These routes will
|
|
555
529
|
* be based off of local ids.
|
|
556
|
-
* @returns
|
|
530
|
+
* @returns The routes of blobs that were deleted.
|
|
557
531
|
*/
|
|
558
532
|
deleteSweepReadyNodes(sweepReadyBlobRoutes) {
|
|
559
533
|
// If sweep for attachment blobs is not enabled, return empty list indicating nothing is deleted.
|
|
560
|
-
if (this.mc.config.getBoolean(
|
|
534
|
+
if (this.mc.config.getBoolean(disableAttachmentBlobSweepKey) === true) {
|
|
561
535
|
return [];
|
|
562
536
|
}
|
|
563
537
|
this.deleteBlobsFromRedirectTable(sweepReadyBlobRoutes);
|
|
@@ -681,18 +655,56 @@ export class BlobManager extends TypedEventEmitter {
|
|
|
681
655
|
this.setRedirection(storageId, storageId);
|
|
682
656
|
}
|
|
683
657
|
}
|
|
684
|
-
getPendingBlobs() {
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
658
|
+
async getPendingBlobs(waitBlobsToAttach) {
|
|
659
|
+
return PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "GetPendingBlobs" }, async () => {
|
|
660
|
+
if (this.pendingBlobs.size === 0) {
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
const blobs = {};
|
|
664
|
+
const localBlobs = new Set();
|
|
665
|
+
while (localBlobs.size < this.pendingBlobs.size) {
|
|
666
|
+
const attachBlobsP = [];
|
|
667
|
+
for (const [id, entry] of this.pendingBlobs) {
|
|
668
|
+
if (!localBlobs.has(entry)) {
|
|
669
|
+
localBlobs.add(entry);
|
|
670
|
+
if (waitBlobsToAttach) {
|
|
671
|
+
if (!entry.opsent) {
|
|
672
|
+
this.sendBlobAttachOp(id, entry.storageId);
|
|
673
|
+
}
|
|
674
|
+
entry.handleP.resolve(this.getBlobHandle(id));
|
|
675
|
+
attachBlobsP.push(new Promise((resolve) => {
|
|
676
|
+
const onBlobAttached = (attachedEntry) => {
|
|
677
|
+
if (attachedEntry === entry) {
|
|
678
|
+
this.off("blobAttached", onBlobAttached);
|
|
679
|
+
resolve();
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
if (!entry.attached) {
|
|
683
|
+
this.on("blobAttached", onBlobAttached);
|
|
684
|
+
}
|
|
685
|
+
else {
|
|
686
|
+
resolve();
|
|
687
|
+
}
|
|
688
|
+
}));
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
await Promise.all(attachBlobsP);
|
|
693
|
+
}
|
|
694
|
+
// another for is needed to correctly mark attach state
|
|
695
|
+
// future optimization won't add unattached blobs to the list
|
|
696
|
+
for (const [id, entry] of this.pendingBlobs) {
|
|
697
|
+
blobs[id] = {
|
|
698
|
+
blob: bufferToString(entry.blob, "base64"),
|
|
699
|
+
storageId: entry.storageId,
|
|
700
|
+
attached: entry.attached,
|
|
701
|
+
acked: entry.acked,
|
|
702
|
+
minTTLInSeconds: entry.minTTLInSeconds,
|
|
703
|
+
uploadTime: entry.uploadTime,
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
return blobs;
|
|
707
|
+
});
|
|
696
708
|
}
|
|
697
709
|
}
|
|
698
710
|
BlobManager.basePath = "_blobs";
|