@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/src/blobManager.ts
CHANGED
|
@@ -17,21 +17,17 @@ import {
|
|
|
17
17
|
responseToException,
|
|
18
18
|
SummaryTreeBuilder,
|
|
19
19
|
} from "@fluidframework/runtime-utils";
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
bufferToString,
|
|
23
|
-
Deferred,
|
|
24
|
-
stringToBuffer,
|
|
25
|
-
TypedEventEmitter,
|
|
26
|
-
} from "@fluidframework/common-utils";
|
|
20
|
+
import { assert, Deferred } from "@fluidframework/core-utils";
|
|
21
|
+
import { bufferToString, stringToBuffer, TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
27
22
|
import {
|
|
28
23
|
IContainerRuntime,
|
|
29
24
|
IContainerRuntimeEvents,
|
|
30
25
|
} from "@fluidframework/container-runtime-definitions";
|
|
31
26
|
import { AttachState, ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
32
27
|
import {
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
createChildMonitoringContext,
|
|
29
|
+
GenericError,
|
|
30
|
+
LoggingError,
|
|
35
31
|
MonitoringContext,
|
|
36
32
|
PerformanceEvent,
|
|
37
33
|
} from "@fluidframework/telemetry-utils";
|
|
@@ -40,9 +36,13 @@ import {
|
|
|
40
36
|
ISummaryTreeWithStats,
|
|
41
37
|
ITelemetryContext,
|
|
42
38
|
} from "@fluidframework/runtime-definitions";
|
|
43
|
-
|
|
39
|
+
|
|
44
40
|
import { ContainerRuntime, TombstoneResponseHeaderKey } from "./containerRuntime";
|
|
45
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
sendGCUnexpectedUsageEvent,
|
|
43
|
+
disableAttachmentBlobSweepKey,
|
|
44
|
+
throwOnTombstoneLoadKey,
|
|
45
|
+
} from "./gc";
|
|
46
46
|
import { Throttler, formExponentialFn, IThrottler } from "./throttler";
|
|
47
47
|
import { summarizerClientType } from "./summary";
|
|
48
48
|
import { IBlobMetadata } from "./metadata";
|
|
@@ -122,32 +122,26 @@ export type IBlobManagerRuntime = Pick<
|
|
|
122
122
|
Pick<ContainerRuntime, "gcTombstoneEnforcementAllowed"> &
|
|
123
123
|
TypedEventEmitter<IContainerRuntimeEvents>;
|
|
124
124
|
|
|
125
|
-
// Note that while offline we "submit" an op before uploading the blob, but we always
|
|
126
|
-
// expect blobs to be uploaded before we actually see the op round-trip
|
|
127
|
-
enum PendingBlobStatus {
|
|
128
|
-
OnlinePendingUpload,
|
|
129
|
-
OnlinePendingOp,
|
|
130
|
-
OfflinePendingUpload,
|
|
131
|
-
OfflinePendingOp,
|
|
132
|
-
}
|
|
133
|
-
|
|
134
125
|
type ICreateBlobResponseWithTTL = ICreateBlobResponse & Partial<Record<"minTTLInSeconds", number>>;
|
|
135
126
|
|
|
136
127
|
interface PendingBlob {
|
|
137
128
|
blob: ArrayBufferLike;
|
|
138
|
-
|
|
129
|
+
uploading?: boolean;
|
|
130
|
+
opsent?: boolean;
|
|
139
131
|
storageId?: string;
|
|
140
132
|
handleP: Deferred<BlobHandle>;
|
|
141
|
-
uploadP?: Promise<ICreateBlobResponse>;
|
|
133
|
+
uploadP?: Promise<ICreateBlobResponse | void>;
|
|
142
134
|
uploadTime?: number;
|
|
143
135
|
minTTLInSeconds?: number;
|
|
144
136
|
attached?: boolean;
|
|
145
137
|
acked?: boolean;
|
|
138
|
+
abortSignal?: AbortSignal;
|
|
146
139
|
}
|
|
147
140
|
|
|
148
141
|
export interface IPendingBlobs {
|
|
149
142
|
[id: string]: {
|
|
150
143
|
blob: string;
|
|
144
|
+
storageId?: string;
|
|
151
145
|
uploadTime?: number;
|
|
152
146
|
minTTLInSeconds?: number;
|
|
153
147
|
attached?: boolean;
|
|
@@ -174,9 +168,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
174
168
|
private readonly redirectTable: Map<string, string | undefined>;
|
|
175
169
|
|
|
176
170
|
/**
|
|
177
|
-
* Blobs which
|
|
178
|
-
* Until we see the op round-trip, there is a possibility we may need to re-upload the blob, so
|
|
179
|
-
* we must save it. This is true for both the online and offline flow.
|
|
171
|
+
* Blobs which we have not yet seen a BlobAttach op round-trip and not yet attached to a DDS.
|
|
180
172
|
*/
|
|
181
173
|
private readonly pendingBlobs: Map<string, PendingBlob> = new Map();
|
|
182
174
|
|
|
@@ -232,15 +224,16 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
232
224
|
private readonly closeContainer: (error?: ICriticalContainerError) => void,
|
|
233
225
|
) {
|
|
234
226
|
super();
|
|
235
|
-
this.mc =
|
|
227
|
+
this.mc = createChildMonitoringContext({
|
|
228
|
+
logger: this.runtime.logger,
|
|
229
|
+
namespace: "BlobManager",
|
|
230
|
+
});
|
|
236
231
|
// Read the feature flag that tells whether to throw when a tombstone blob is requested.
|
|
237
232
|
this.throwOnTombstoneLoad =
|
|
238
233
|
this.mc.config.getBoolean(throwOnTombstoneLoadKey) === true &&
|
|
239
234
|
this.runtime.gcTombstoneEnforcementAllowed &&
|
|
240
235
|
this.runtime.clientDetails.type !== summarizerClientType;
|
|
241
236
|
|
|
242
|
-
this.runtime.on("disconnected", () => this.onDisconnected());
|
|
243
|
-
|
|
244
237
|
this.redirectTable = this.load(snapshot);
|
|
245
238
|
|
|
246
239
|
// Begin uploading stashed blobs from previous container instance
|
|
@@ -248,14 +241,17 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
248
241
|
const blob = stringToBuffer(entry.blob, "base64");
|
|
249
242
|
const attached = entry.attached;
|
|
250
243
|
const acked = entry.acked;
|
|
244
|
+
const storageId = entry.storageId; // entry.storageId = response.id
|
|
251
245
|
if (entry.minTTLInSeconds && entry.uploadTime) {
|
|
252
246
|
const timeLapseSinceLocalUpload = (Date.now() - entry.uploadTime) / 1000;
|
|
253
247
|
// stashed entries with more than half-life in storage will not be reuploaded
|
|
254
248
|
if (entry.minTTLInSeconds - timeLapseSinceLocalUpload > entry.minTTLInSeconds / 2) {
|
|
255
249
|
this.pendingBlobs.set(localId, {
|
|
256
250
|
blob,
|
|
257
|
-
|
|
251
|
+
uploading: false,
|
|
252
|
+
opsent: true,
|
|
258
253
|
handleP: new Deferred(),
|
|
254
|
+
storageId,
|
|
259
255
|
uploadP: undefined,
|
|
260
256
|
uploadTime: entry.uploadTime,
|
|
261
257
|
minTTLInSeconds: entry.minTTLInSeconds,
|
|
@@ -267,22 +263,26 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
267
263
|
}
|
|
268
264
|
this.pendingBlobs.set(localId, {
|
|
269
265
|
blob,
|
|
270
|
-
|
|
266
|
+
uploading: true,
|
|
271
267
|
handleP: new Deferred(),
|
|
272
268
|
uploadP: this.uploadBlob(localId, blob),
|
|
273
269
|
attached,
|
|
274
270
|
acked,
|
|
271
|
+
opsent: true,
|
|
275
272
|
});
|
|
276
273
|
});
|
|
277
274
|
|
|
278
275
|
this.sendBlobAttachOp = (localId: string, blobId?: string) => {
|
|
279
276
|
const pendingEntry = this.pendingBlobs.get(localId);
|
|
277
|
+
assert(
|
|
278
|
+
pendingEntry !== undefined,
|
|
279
|
+
0x725 /* Must have pending blob entry for upcoming op */,
|
|
280
|
+
);
|
|
280
281
|
if (pendingEntry?.uploadTime && pendingEntry?.minTTLInSeconds) {
|
|
281
282
|
const secondsSinceUpload = (Date.now() - pendingEntry.uploadTime) / 1000;
|
|
282
283
|
const expired = pendingEntry.minTTLInSeconds - secondsSinceUpload < 0;
|
|
283
284
|
this.mc.logger.sendTelemetryEvent({
|
|
284
285
|
eventName: "sendBlobAttach",
|
|
285
|
-
entryStatus: pendingEntry.status,
|
|
286
286
|
secondsSinceUpload,
|
|
287
287
|
minTTLInSeconds: pendingEntry.minTTLInSeconds,
|
|
288
288
|
expired,
|
|
@@ -296,25 +296,24 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
296
296
|
{
|
|
297
297
|
localId,
|
|
298
298
|
blobId,
|
|
299
|
-
entryStatus: pendingEntry.status,
|
|
300
299
|
secondsSinceUpload,
|
|
301
300
|
},
|
|
302
301
|
),
|
|
303
302
|
);
|
|
304
303
|
}
|
|
305
304
|
}
|
|
305
|
+
pendingEntry.opsent = true;
|
|
306
306
|
return sendBlobAttachOp(localId, blobId);
|
|
307
307
|
};
|
|
308
308
|
}
|
|
309
309
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
(
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
return this.pendingOfflineUploads.length > 0;
|
|
310
|
+
public get allBlobsAttached(): boolean {
|
|
311
|
+
for (const [, entry] of this.pendingBlobs) {
|
|
312
|
+
if (entry.attached === false) {
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return true;
|
|
318
317
|
}
|
|
319
318
|
|
|
320
319
|
public get hasPendingBlobs(): boolean {
|
|
@@ -324,16 +323,24 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
324
323
|
);
|
|
325
324
|
}
|
|
326
325
|
|
|
326
|
+
private createAbortError(pending?: PendingBlob) {
|
|
327
|
+
return new LoggingError("uploadBlob aborted", {
|
|
328
|
+
acked: pending?.acked,
|
|
329
|
+
uploadTime: pending?.uploadTime,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
327
332
|
/**
|
|
328
333
|
* Upload blobs added while offline. This must be completed before connecting and resubmitting ops.
|
|
329
334
|
*/
|
|
330
|
-
public async
|
|
335
|
+
public async processStashedChanges() {
|
|
331
336
|
this.retryThrottler.cancel();
|
|
332
|
-
const pendingUploads = this.
|
|
337
|
+
const pendingUploads = Array.from(this.pendingBlobs.values())
|
|
338
|
+
.filter((e) => e.uploading === true)
|
|
339
|
+
.map(async (e) => e.uploadP);
|
|
333
340
|
await PerformanceEvent.timedExecAsync(
|
|
334
341
|
this.mc.logger,
|
|
335
342
|
{
|
|
336
|
-
eventName: "
|
|
343
|
+
eventName: "BlobUploadProcessStashedChanges",
|
|
337
344
|
count: pendingUploads.length,
|
|
338
345
|
},
|
|
339
346
|
async () => Promise.all(pendingUploads),
|
|
@@ -341,20 +348,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
341
348
|
);
|
|
342
349
|
}
|
|
343
350
|
|
|
344
|
-
/**
|
|
345
|
-
* Transition online blobs waiting for BlobAttach op round-trip since we will not see the op until we are connected
|
|
346
|
-
* again
|
|
347
|
-
*/
|
|
348
|
-
private onDisconnected() {
|
|
349
|
-
for (const [localId, entry] of this.pendingBlobs) {
|
|
350
|
-
if (entry.status === PendingBlobStatus.OnlinePendingOp) {
|
|
351
|
-
// This will submit another BlobAttach op for this blob. This is necessary because the one we sent
|
|
352
|
-
// already didn't have the local ID.
|
|
353
|
-
this.transitionToOffline(localId);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
351
|
/**
|
|
359
352
|
* Set of actual storage IDs (i.e., IDs that can be requested from storage). This will be empty if the container is
|
|
360
353
|
* detached or there are no (non-pending) attachment blobs in the document
|
|
@@ -420,6 +413,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
420
413
|
const callback = pending
|
|
421
414
|
? () => {
|
|
422
415
|
pending.attached = true;
|
|
416
|
+
this.emit("blobAttached", pending);
|
|
423
417
|
this.deletePendingBlobMaybe(id);
|
|
424
418
|
}
|
|
425
419
|
: undefined;
|
|
@@ -441,7 +435,10 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
441
435
|
return this.getBlobHandle(response.id);
|
|
442
436
|
}
|
|
443
437
|
|
|
444
|
-
public async createBlob(
|
|
438
|
+
public async createBlob(
|
|
439
|
+
blob: ArrayBufferLike,
|
|
440
|
+
signal?: AbortSignal,
|
|
441
|
+
): Promise<IFluidHandle<ArrayBufferLike>> {
|
|
445
442
|
if (this.runtime.attachState === AttachState.Detached) {
|
|
446
443
|
return this.createBlobDetached(blob);
|
|
447
444
|
}
|
|
@@ -455,23 +452,41 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
455
452
|
0x385 /* For clarity and paranoid defense against adding future attachment states */,
|
|
456
453
|
);
|
|
457
454
|
|
|
455
|
+
if (signal?.aborted) {
|
|
456
|
+
throw this.createAbortError();
|
|
457
|
+
}
|
|
458
|
+
|
|
458
459
|
// Create a local ID for the blob. After uploading it to storage and before returning it, a local ID to
|
|
459
460
|
// storage ID mapping is created.
|
|
460
461
|
const localId = uuid();
|
|
461
462
|
const pendingEntry: PendingBlob = {
|
|
462
463
|
blob,
|
|
463
|
-
|
|
464
|
+
uploading: true,
|
|
464
465
|
handleP: new Deferred(),
|
|
465
466
|
uploadP: this.uploadBlob(localId, blob),
|
|
466
467
|
attached: false,
|
|
467
468
|
acked: false,
|
|
469
|
+
abortSignal: signal,
|
|
470
|
+
opsent: false,
|
|
468
471
|
};
|
|
469
472
|
this.pendingBlobs.set(localId, pendingEntry);
|
|
470
473
|
|
|
471
|
-
|
|
474
|
+
const abortListener = () => {
|
|
475
|
+
if (!pendingEntry.acked) {
|
|
476
|
+
pendingEntry.handleP.reject(this.createAbortError(pendingEntry));
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
signal?.addEventListener("abort", abortListener, { once: true });
|
|
480
|
+
|
|
481
|
+
return pendingEntry.handleP.promise.finally(() => {
|
|
482
|
+
signal?.removeEventListener("abort", abortListener);
|
|
483
|
+
});
|
|
472
484
|
}
|
|
473
485
|
|
|
474
|
-
private async uploadBlob(
|
|
486
|
+
private async uploadBlob(
|
|
487
|
+
localId: string,
|
|
488
|
+
blob: ArrayBufferLike,
|
|
489
|
+
): Promise<ICreateBlobResponse | void> {
|
|
475
490
|
return PerformanceEvent.timedExecAsync(
|
|
476
491
|
this.mc.logger,
|
|
477
492
|
{ eventName: "createBlob" },
|
|
@@ -495,72 +510,67 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
495
510
|
if (this.pendingBlobs.has(id)) {
|
|
496
511
|
const entry = this.pendingBlobs.get(id);
|
|
497
512
|
if (entry?.attached && entry?.acked) {
|
|
498
|
-
this.
|
|
499
|
-
if (!this.hasPendingBlobs) {
|
|
500
|
-
this.emit("noPendingBlobs");
|
|
501
|
-
}
|
|
513
|
+
this.deletePendingBlob(id);
|
|
502
514
|
}
|
|
503
515
|
}
|
|
504
516
|
}
|
|
505
517
|
|
|
518
|
+
private deletePendingBlob(id: string) {
|
|
519
|
+
if (this.pendingBlobs.delete(id) && !this.hasPendingBlobs) {
|
|
520
|
+
this.emit("noPendingBlobs");
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
506
524
|
private onUploadResolve(localId: string, response: ICreateBlobResponseWithTTL) {
|
|
507
525
|
const entry = this.pendingBlobs.get(localId);
|
|
508
526
|
assert(entry !== undefined, 0x6c8 /* pending blob entry not found for uploaded blob */);
|
|
527
|
+
if (entry.abortSignal?.aborted === true && !entry.opsent) {
|
|
528
|
+
this.deletePendingBlob(localId);
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
509
531
|
assert(
|
|
510
|
-
entry.
|
|
511
|
-
entry.status === PendingBlobStatus.OfflinePendingUpload,
|
|
532
|
+
entry.uploading === true,
|
|
512
533
|
0x386 /* Must have pending blob entry for uploaded blob */,
|
|
513
534
|
);
|
|
514
535
|
entry.storageId = response.id;
|
|
515
536
|
entry.uploadTime = Date.now();
|
|
516
537
|
entry.minTTLInSeconds = response.minTTLInSeconds;
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
} else {
|
|
533
|
-
// If there is already an op for this storage ID, append the local ID to the list. Once any op for
|
|
534
|
-
// this storage ID is ack'd, all pending blobs for it can be resolved since the op will keep the
|
|
535
|
-
// blob alive in storage.
|
|
536
|
-
this.opsInFlight.set(
|
|
537
|
-
response.id,
|
|
538
|
-
(this.opsInFlight.get(response.id) ?? []).concat(localId),
|
|
539
|
-
);
|
|
540
|
-
entry.status = PendingBlobStatus.OnlinePendingOp;
|
|
541
|
-
}
|
|
542
|
-
} else if (entry.status === PendingBlobStatus.OfflinePendingUpload) {
|
|
543
|
-
// We already submitted a BlobAttach op for this blob when it was transitioned to offline flow
|
|
544
|
-
entry.status = PendingBlobStatus.OfflinePendingOp;
|
|
545
|
-
}
|
|
538
|
+
// Send a blob attach op. This serves two purposes:
|
|
539
|
+
// 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
|
|
540
|
+
// until its storage ID is added to the next summary.
|
|
541
|
+
// 2. It will create a local ID to storage ID mapping in all clients which is needed to retrieve the
|
|
542
|
+
// blob from the server via the storage ID.
|
|
543
|
+
if (!entry.opsent) {
|
|
544
|
+
this.sendBlobAttachOp(localId, response.id);
|
|
545
|
+
}
|
|
546
|
+
if (this.storageIds.has(response.id)) {
|
|
547
|
+
// The blob is de-duped. Set up a local ID to storage ID mapping and return the blob. Since this is
|
|
548
|
+
// an existing blob, we don't have to wait for the op to be ack'd since this step has already
|
|
549
|
+
// happened before and so, the server won't delete it.
|
|
550
|
+
this.setRedirection(localId, response.id);
|
|
551
|
+
entry.handleP.resolve(this.getBlobHandle(localId));
|
|
552
|
+
this.deletePendingBlobMaybe(localId);
|
|
546
553
|
} else {
|
|
547
|
-
//
|
|
548
|
-
this
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
554
|
+
// If there is already an op for this storage ID, append the local ID to the list. Once any op for
|
|
555
|
+
// this storage ID is ack'd, all pending blobs for it can be resolved since the op will keep the
|
|
556
|
+
// blob alive in storage.
|
|
557
|
+
this.opsInFlight.set(
|
|
558
|
+
response.id,
|
|
559
|
+
(this.opsInFlight.get(response.id) ?? []).concat(localId),
|
|
560
|
+
);
|
|
553
561
|
}
|
|
562
|
+
|
|
554
563
|
return response;
|
|
555
564
|
}
|
|
556
565
|
|
|
557
|
-
private async onUploadReject(localId: string, error) {
|
|
566
|
+
private async onUploadReject(localId: string, error: any) {
|
|
558
567
|
const entry = this.pendingBlobs.get(localId);
|
|
559
568
|
assert(!!entry, 0x387 /* Must have pending blob entry for blob which failed to upload */);
|
|
569
|
+
if (entry.abortSignal?.aborted === true && !entry.opsent) {
|
|
570
|
+
this.deletePendingBlob(localId);
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
560
573
|
if (!this.runtime.connected) {
|
|
561
|
-
if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
|
|
562
|
-
this.transitionToOffline(localId);
|
|
563
|
-
}
|
|
564
574
|
// we are probably not connected to storage but start another upload request in case we are
|
|
565
575
|
entry.uploadP = this.retryThrottler
|
|
566
576
|
.getDelay()
|
|
@@ -572,39 +582,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
572
582
|
}
|
|
573
583
|
}
|
|
574
584
|
|
|
575
|
-
private transitionToOffline(localId: string) {
|
|
576
|
-
assert(
|
|
577
|
-
!this.runtime.connected,
|
|
578
|
-
0x388 /* Must only transition to offline flow while runtime is disconnected */,
|
|
579
|
-
);
|
|
580
|
-
const entry = this.pendingBlobs.get(localId);
|
|
581
|
-
assert(!!entry, 0x389 /* No pending blob entry */);
|
|
582
|
-
assert(
|
|
583
|
-
[PendingBlobStatus.OnlinePendingUpload, PendingBlobStatus.OnlinePendingOp].includes(
|
|
584
|
-
entry.status,
|
|
585
|
-
),
|
|
586
|
-
0x38a /* Blob must be in online flow to transition to offline flow */,
|
|
587
|
-
);
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* If we haven't already submitted a BlobAttach op for this entry, send it before returning the blob handle.
|
|
591
|
-
* This will make sure that the BlobAttach op is sequenced prior to any ops referencing the handle. Otherwise,
|
|
592
|
-
* an invalid handle could be added to the document.
|
|
593
|
-
* storageId may be undefined but since we are not connected we will have a chance to add it when reSubmit()
|
|
594
|
-
* is called on reconnection.
|
|
595
|
-
*/
|
|
596
|
-
if (entry.status !== PendingBlobStatus.OnlinePendingOp) {
|
|
597
|
-
this.sendBlobAttachOp(localId, entry.storageId);
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
entry.status =
|
|
601
|
-
entry.status === PendingBlobStatus.OnlinePendingUpload
|
|
602
|
-
? PendingBlobStatus.OfflinePendingUpload
|
|
603
|
-
: PendingBlobStatus.OfflinePendingOp;
|
|
604
|
-
|
|
605
|
-
entry.handleP.resolve(this.getBlobHandle(localId));
|
|
606
|
-
}
|
|
607
|
-
|
|
608
585
|
/**
|
|
609
586
|
* Resubmit a BlobAttach op. Used to add storage IDs to ops that were
|
|
610
587
|
* submitted to runtime while disconnected.
|
|
@@ -619,11 +596,10 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
619
596
|
if (!blobId) {
|
|
620
597
|
// We submitted this op while offline. The blob should have been uploaded by now.
|
|
621
598
|
assert(
|
|
622
|
-
pendingEntry?.
|
|
623
|
-
!!pendingEntry?.storageId,
|
|
599
|
+
pendingEntry?.opsent === true && !!pendingEntry?.storageId,
|
|
624
600
|
0x38d /* blob must be uploaded before resubmitting BlobAttach op */,
|
|
625
601
|
);
|
|
626
|
-
return this.sendBlobAttachOp(localId, pendingEntry
|
|
602
|
+
return this.sendBlobAttachOp(localId, pendingEntry?.storageId);
|
|
627
603
|
}
|
|
628
604
|
return this.sendBlobAttachOp(localId, blobId);
|
|
629
605
|
}
|
|
@@ -631,6 +607,14 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
631
607
|
public processBlobAttachOp(message: ISequencedDocumentMessage, local: boolean) {
|
|
632
608
|
const localId = (message.metadata as IBlobMetadata | undefined)?.localId;
|
|
633
609
|
const blobId = (message.metadata as IBlobMetadata | undefined)?.blobId;
|
|
610
|
+
|
|
611
|
+
if (localId) {
|
|
612
|
+
const pendingEntry = this.pendingBlobs.get(localId);
|
|
613
|
+
if (pendingEntry?.abortSignal?.aborted) {
|
|
614
|
+
this.deletePendingBlob(localId);
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
634
618
|
assert(blobId !== undefined, 0x12a /* "Missing blob id on metadata" */);
|
|
635
619
|
|
|
636
620
|
// Set up a mapping from local ID to storage ID. This is crucial since without this the blob cannot be
|
|
@@ -656,22 +640,17 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
656
640
|
entry !== undefined,
|
|
657
641
|
0x38f /* local online BlobAttach op with no pending blob entry */,
|
|
658
642
|
);
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
entry.acked = true;
|
|
664
|
-
entry.handleP.resolve(this.getBlobHandle(pendingLocalId));
|
|
665
|
-
this.deletePendingBlobMaybe(pendingLocalId);
|
|
666
|
-
}
|
|
643
|
+
this.setRedirection(pendingLocalId, blobId);
|
|
644
|
+
entry.acked = true;
|
|
645
|
+
entry.handleP.resolve(this.getBlobHandle(pendingLocalId));
|
|
646
|
+
this.deletePendingBlobMaybe(pendingLocalId);
|
|
667
647
|
});
|
|
668
648
|
this.opsInFlight.delete(blobId);
|
|
669
649
|
}
|
|
670
|
-
// offline flow does not resolve the handle (since it was already resolved)
|
|
671
|
-
// but we still need to delete the entry in case is acked and attached.
|
|
672
650
|
const localEntry = this.pendingBlobs.get(localId);
|
|
673
651
|
if (localEntry) {
|
|
674
652
|
localEntry.acked = true;
|
|
653
|
+
localEntry.handleP.resolve(this.getBlobHandle(localId));
|
|
675
654
|
this.deletePendingBlobMaybe(localId);
|
|
676
655
|
}
|
|
677
656
|
}
|
|
@@ -780,11 +759,11 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
780
759
|
* Delete attachment blobs that are sweep ready.
|
|
781
760
|
* @param sweepReadyBlobRoutes - The routes of blobs that are sweep ready and should be deleted. These routes will
|
|
782
761
|
* be based off of local ids.
|
|
783
|
-
* @returns
|
|
762
|
+
* @returns The routes of blobs that were deleted.
|
|
784
763
|
*/
|
|
785
764
|
public deleteSweepReadyNodes(sweepReadyBlobRoutes: string[]): string[] {
|
|
786
765
|
// If sweep for attachment blobs is not enabled, return empty list indicating nothing is deleted.
|
|
787
|
-
if (this.mc.config.getBoolean(
|
|
766
|
+
if (this.mc.config.getBoolean(disableAttachmentBlobSweepKey) === true) {
|
|
788
767
|
return [];
|
|
789
768
|
}
|
|
790
769
|
|
|
@@ -943,18 +922,61 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
943
922
|
}
|
|
944
923
|
}
|
|
945
924
|
|
|
946
|
-
public getPendingBlobs(): IPendingBlobs {
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
925
|
+
public async getPendingBlobs(waitBlobsToAttach?: boolean): Promise<IPendingBlobs | undefined> {
|
|
926
|
+
return PerformanceEvent.timedExecAsync(
|
|
927
|
+
this.mc.logger,
|
|
928
|
+
{ eventName: "GetPendingBlobs" },
|
|
929
|
+
async () => {
|
|
930
|
+
if (this.pendingBlobs.size === 0) {
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
933
|
+
const blobs = {};
|
|
934
|
+
const localBlobs = new Set<PendingBlob>();
|
|
935
|
+
while (localBlobs.size < this.pendingBlobs.size) {
|
|
936
|
+
const attachBlobsP: Promise<void>[] = [];
|
|
937
|
+
for (const [id, entry] of this.pendingBlobs) {
|
|
938
|
+
if (!localBlobs.has(entry)) {
|
|
939
|
+
localBlobs.add(entry);
|
|
940
|
+
if (waitBlobsToAttach) {
|
|
941
|
+
if (!entry.opsent) {
|
|
942
|
+
this.sendBlobAttachOp(id, entry.storageId);
|
|
943
|
+
}
|
|
944
|
+
entry.handleP.resolve(this.getBlobHandle(id));
|
|
945
|
+
attachBlobsP.push(
|
|
946
|
+
new Promise<void>((resolve) => {
|
|
947
|
+
const onBlobAttached = (attachedEntry) => {
|
|
948
|
+
if (attachedEntry === entry) {
|
|
949
|
+
this.off("blobAttached", onBlobAttached);
|
|
950
|
+
resolve();
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
if (!entry.attached) {
|
|
954
|
+
this.on("blobAttached", onBlobAttached);
|
|
955
|
+
} else {
|
|
956
|
+
resolve();
|
|
957
|
+
}
|
|
958
|
+
}),
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
await Promise.all(attachBlobsP);
|
|
964
|
+
}
|
|
965
|
+
// another for is needed to correctly mark attach state
|
|
966
|
+
// future optimization won't add unattached blobs to the list
|
|
967
|
+
for (const [id, entry] of this.pendingBlobs) {
|
|
968
|
+
blobs[id] = {
|
|
969
|
+
blob: bufferToString(entry.blob, "base64"),
|
|
970
|
+
storageId: entry.storageId,
|
|
971
|
+
attached: entry.attached,
|
|
972
|
+
acked: entry.acked,
|
|
973
|
+
minTTLInSeconds: entry.minTTLInSeconds,
|
|
974
|
+
uploadTime: entry.uploadTime,
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
return blobs;
|
|
978
|
+
},
|
|
979
|
+
);
|
|
958
980
|
}
|
|
959
981
|
}
|
|
960
982
|
|
|
@@ -3,14 +3,19 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
ITelemetryLoggerExt,
|
|
8
|
+
createChildLogger,
|
|
9
|
+
formatTick,
|
|
10
|
+
} from "@fluidframework/telemetry-utils";
|
|
7
11
|
import { IDeltaManager } from "@fluidframework/container-definitions";
|
|
8
12
|
import {
|
|
9
13
|
IDocumentMessage,
|
|
10
14
|
ISequencedDocumentMessage,
|
|
11
15
|
MessageType,
|
|
12
16
|
} from "@fluidframework/protocol-definitions";
|
|
13
|
-
import { assert
|
|
17
|
+
import { assert } from "@fluidframework/core-utils";
|
|
18
|
+
import { performance } from "@fluid-internal/client-utils";
|
|
14
19
|
|
|
15
20
|
/**
|
|
16
21
|
* We report various latency-related errors when waiting for op roundtrip takes longer than that amout of time.
|
|
@@ -75,7 +80,7 @@ class OpPerfTelemetry {
|
|
|
75
80
|
private readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
|
|
76
81
|
logger: ITelemetryLoggerExt,
|
|
77
82
|
) {
|
|
78
|
-
this.logger =
|
|
83
|
+
this.logger = createChildLogger({ logger, namespace: "OpPerf" });
|
|
79
84
|
|
|
80
85
|
this.deltaManager.on("pong", (latency) => this.recordPingTime(latency));
|
|
81
86
|
this.deltaManager.on("submitOp", (message) => this.beforeOpSubmit(message));
|
|
@@ -179,7 +184,7 @@ class OpPerfTelemetry {
|
|
|
179
184
|
ops: this.gap,
|
|
180
185
|
// track time to connect only for first connection.
|
|
181
186
|
timeToConnect: this.firstConnection
|
|
182
|
-
?
|
|
187
|
+
? formatTick(this.connectionStartTime - this.bootTime)
|
|
183
188
|
: undefined,
|
|
184
189
|
firstConnection: this.firstConnection,
|
|
185
190
|
});
|