@fluidframework/container-runtime 2.53.1 → 2.61.0-355054
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/.mocharc.cjs +1 -2
- package/CHANGELOG.md +4 -0
- package/api-report/{container-runtime.legacy.alpha.api.md → container-runtime.legacy.beta.api.md} +55 -55
- package/container-runtime.test-files.tar +0 -0
- package/dist/batchTracker.d.ts +1 -1
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager/blobManager.d.ts +29 -17
- package/dist/blobManager/blobManager.d.ts.map +1 -1
- package/dist/blobManager/blobManager.js +150 -135
- package/dist/blobManager/blobManager.js.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.d.ts +4 -4
- package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.js +30 -33
- package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
- package/dist/blobManager/index.d.ts +2 -2
- package/dist/blobManager/index.d.ts.map +1 -1
- package/dist/blobManager/index.js.map +1 -1
- package/dist/channelCollection.d.ts +9 -11
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +2 -3
- package/dist/channelCollection.js.map +1 -1
- package/dist/compressionDefinitions.d.ts +3 -6
- package/dist/compressionDefinitions.d.ts.map +1 -1
- package/dist/compressionDefinitions.js +2 -4
- package/dist/compressionDefinitions.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +3 -4
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerHandleContext.d.ts +2 -2
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +13 -20
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +4 -7
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts +3 -3
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +8 -8
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +2 -2
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.d.ts +1 -1
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/deltaManagerProxies.d.ts +2 -3
- package/dist/deltaManagerProxies.d.ts.map +1 -1
- package/dist/deltaManagerProxies.js.map +1 -1
- package/dist/deltaScheduler.d.ts +2 -2
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/error.d.ts +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +4 -4
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts +3 -3
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +10 -11
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +4 -4
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcReferenceGraphAlgorithm.d.ts +1 -1
- package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -1
- package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
- package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
- package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -1
- package/dist/gc/gcSummaryDefinitions.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +4 -4
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +6 -6
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/index.d.ts +3 -3
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js.map +1 -1
- package/dist/inboundBatchAggregator.d.ts +2 -2
- package/dist/inboundBatchAggregator.d.ts.map +1 -1
- package/dist/inboundBatchAggregator.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +2 -1
- package/dist/messageTypes.d.ts +7 -8
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js +1 -2
- package/dist/messageTypes.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +2 -2
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +1 -1
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/duplicateBatchDetector.d.ts +1 -1
- package/dist/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
- package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +5 -5
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts +2 -2
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js.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.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +3 -3
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +4 -4
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +9 -9
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +4 -4
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/opProperties.d.ts +1 -1
- package/dist/opProperties.d.ts.map +1 -1
- package/dist/opProperties.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +3 -3
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/storageServiceWithAttachBlobs.d.ts +1 -1
- package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -1
- package/dist/storageServiceWithAttachBlobs.js.map +1 -1
- package/dist/summary/documentSchema.d.ts +1 -2
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/index.d.ts +10 -10
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +4 -4
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +5 -5
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerNode/index.d.ts +3 -3
- 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 +5 -6
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +3 -3
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +3 -3
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +25 -44
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summarizerUtils.d.ts +3 -3
- package/dist/summary/summarizerUtils.d.ts.map +1 -1
- package/dist/summary/summarizerUtils.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +13 -23
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +1 -2
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/index.d.ts +2 -2
- package/dist/summary/summaryDelayLoadedModule/index.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/index.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts +1 -1
- package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts +3 -3
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts +5 -5
- package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts +3 -4
- package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +3 -3
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +5 -10
- package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +9 -14
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryHelpers.d.ts +1 -2
- package/dist/summary/summaryHelpers.d.ts.map +1 -1
- package/dist/summary/summaryHelpers.js +1 -2
- package/dist/summary/summaryHelpers.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +3 -3
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js.map +1 -1
- package/internal.d.ts +1 -1
- package/legacy.d.ts +1 -1
- package/lib/batchTracker.d.ts +1 -1
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager/blobManager.d.ts +29 -17
- package/lib/blobManager/blobManager.d.ts.map +1 -1
- package/lib/blobManager/blobManager.js +142 -127
- package/lib/blobManager/blobManager.js.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.d.ts +4 -4
- package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.js +26 -29
- package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
- package/lib/blobManager/index.d.ts +2 -2
- package/lib/blobManager/index.d.ts.map +1 -1
- package/lib/blobManager/index.js.map +1 -1
- package/lib/channelCollection.d.ts +9 -11
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +2 -3
- package/lib/channelCollection.js.map +1 -1
- package/lib/compressionDefinitions.d.ts +3 -6
- package/lib/compressionDefinitions.d.ts.map +1 -1
- package/lib/compressionDefinitions.js +2 -4
- package/lib/compressionDefinitions.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +3 -4
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerHandleContext.d.ts +2 -2
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +13 -20
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +4 -7
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts +3 -3
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +8 -8
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +2 -2
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.d.ts +1 -1
- package/lib/dataStoreRegistry.d.ts.map +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/deltaManagerProxies.d.ts +2 -3
- package/lib/deltaManagerProxies.d.ts.map +1 -1
- package/lib/deltaManagerProxies.js.map +1 -1
- package/lib/deltaScheduler.d.ts +2 -2
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +1 -1
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/error.d.ts +1 -1
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +4 -4
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts +3 -3
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +10 -11
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +4 -4
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcReferenceGraphAlgorithm.d.ts +1 -1
- package/lib/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -1
- package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -1
- package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
- package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -1
- package/lib/gc/gcSummaryDefinitions.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +4 -4
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +6 -6
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/index.d.ts +3 -3
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js.map +1 -1
- package/lib/inboundBatchAggregator.d.ts +2 -2
- package/lib/inboundBatchAggregator.d.ts.map +1 -1
- package/lib/inboundBatchAggregator.js.map +1 -1
- package/lib/index.d.ts +7 -7
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +2 -1
- package/lib/messageTypes.d.ts +7 -8
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js +1 -2
- package/lib/messageTypes.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +2 -2
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +1 -1
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/duplicateBatchDetector.d.ts +1 -1
- package/lib/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
- package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +5 -5
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts +2 -2
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js.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.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +3 -3
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +4 -4
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +1 -1
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +9 -9
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +4 -4
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/opProperties.d.ts +1 -1
- package/lib/opProperties.d.ts.map +1 -1
- package/lib/opProperties.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +3 -3
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/storageServiceWithAttachBlobs.d.ts +1 -1
- package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -1
- package/lib/storageServiceWithAttachBlobs.js.map +1 -1
- package/lib/summary/documentSchema.d.ts +1 -2
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/index.d.ts +10 -10
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +4 -4
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +5 -5
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerNode/index.d.ts +3 -3
- 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 +5 -6
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +3 -3
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +3 -3
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +25 -44
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summarizerUtils.d.ts +3 -3
- package/lib/summary/summarizerUtils.d.ts.map +1 -1
- package/lib/summary/summarizerUtils.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +13 -23
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +1 -2
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/index.d.ts +2 -2
- package/lib/summary/summaryDelayLoadedModule/index.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/index.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts +1 -1
- package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts +3 -3
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts +5 -5
- package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts +3 -4
- package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +3 -3
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +5 -10
- package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +9 -14
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryHelpers.d.ts +1 -2
- package/lib/summary/summaryHelpers.d.ts.map +1 -1
- package/lib/summary/summaryHelpers.js +1 -2
- package/lib/summary/summaryHelpers.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +3 -3
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/package.json +27 -27
- package/src/batchTracker.ts +3 -3
- package/src/blobManager/blobManager.ts +165 -174
- package/src/blobManager/blobManagerSnapSum.ts +31 -53
- package/src/blobManager/index.ts +4 -4
- package/src/channelCollection.ts +28 -29
- package/src/compressionDefinitions.ts +3 -6
- package/src/connectionTelemetry.ts +8 -9
- package/src/containerHandleContext.ts +2 -2
- package/src/containerRuntime.ts +43 -50
- package/src/dataStore.ts +6 -6
- package/src/dataStoreContext.ts +33 -33
- package/src/dataStoreContexts.ts +3 -3
- package/src/dataStoreRegistry.ts +1 -1
- package/src/deltaManagerProxies.ts +3 -3
- package/src/deltaScheduler.ts +6 -3
- package/src/error.ts +1 -1
- package/src/gc/garbageCollection.ts +18 -18
- package/src/gc/gcConfigs.ts +7 -7
- package/src/gc/gcDefinitions.ts +11 -12
- package/src/gc/gcHelpers.ts +7 -7
- package/src/gc/gcReferenceGraphAlgorithm.ts +1 -1
- package/src/gc/gcSummaryDefinitions.ts +1 -1
- package/src/gc/gcSummaryStateTracker.ts +5 -5
- package/src/gc/gcTelemetry.ts +8 -8
- package/src/gc/index.ts +18 -18
- package/src/inboundBatchAggregator.ts +4 -4
- package/src/index.ts +79 -79
- package/src/messageTypes.ts +9 -10
- package/src/opLifecycle/batchManager.ts +2 -2
- package/src/opLifecycle/definitions.ts +1 -1
- package/src/opLifecycle/duplicateBatchDetector.ts +1 -1
- package/src/opLifecycle/index.ts +9 -9
- package/src/opLifecycle/opCompressor.ts +2 -2
- package/src/opLifecycle/opDecompressor.ts +3 -3
- package/src/opLifecycle/opGroupingManager.ts +6 -6
- package/src/opLifecycle/opSplitter.ts +10 -7
- package/src/opLifecycle/outbox.ts +17 -14
- package/src/opLifecycle/remoteMessageProcessor.ts +4 -4
- package/src/opProperties.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +10 -10
- package/src/storageServiceWithAttachBlobs.ts +11 -11
- package/src/summary/documentSchema.ts +1 -2
- package/src/summary/index.ts +69 -69
- package/src/summary/orderedClientElection.ts +12 -4
- package/src/summary/summarizerClientElection.ts +5 -5
- package/src/summary/summarizerNode/index.ts +3 -3
- package/src/summary/summarizerNode/summarizerNode.ts +14 -12
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +3 -3
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +3 -3
- package/src/summary/summarizerTypes.ts +25 -44
- package/src/summary/summarizerUtils.ts +3 -3
- package/src/summary/summaryCollection.ts +19 -29
- package/src/summary/summaryDelayLoadedModule/index.ts +2 -2
- package/src/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.ts +1 -1
- package/src/summary/summaryDelayLoadedModule/runningSummarizer.ts +4 -4
- package/src/summary/summaryDelayLoadedModule/summarizer.ts +8 -8
- package/src/summary/summaryDelayLoadedModule/summarizerHeuristics.ts +4 -4
- package/src/summary/summaryDelayLoadedModule/summaryGenerator.ts +3 -3
- package/src/summary/summaryDelayLoadedModule/summaryResultBuilder.ts +3 -3
- package/src/summary/summaryDelayLoadedModule/summaryResultTypes.ts +5 -10
- package/src/summary/summaryFormat.ts +9 -14
- package/src/summary/summaryHelpers.ts +1 -2
- package/src/summary/summaryManager.ts +4 -4
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
AttachState,
|
|
9
9
|
type IContainerStorageService,
|
|
10
10
|
} from "@fluidframework/container-definitions/internal";
|
|
11
|
-
import {
|
|
11
|
+
import type {
|
|
12
12
|
IContainerRuntime,
|
|
13
13
|
IContainerRuntimeEvents,
|
|
14
14
|
} from "@fluidframework/container-runtime-definitions/internal";
|
|
@@ -23,13 +23,12 @@ import type {
|
|
|
23
23
|
PayloadState,
|
|
24
24
|
} from "@fluidframework/core-interfaces/internal";
|
|
25
25
|
import { assert, Deferred } from "@fluidframework/core-utils/internal";
|
|
26
|
-
import { ICreateBlobResponse } from "@fluidframework/driver-definitions/internal";
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
26
|
+
import type { ICreateBlobResponse } from "@fluidframework/driver-definitions/internal";
|
|
27
|
+
import type {
|
|
29
28
|
IGarbageCollectionData,
|
|
30
29
|
ISummaryTreeWithStats,
|
|
31
30
|
ITelemetryContext,
|
|
32
|
-
|
|
31
|
+
ISequencedMessageEnvelope,
|
|
33
32
|
} from "@fluidframework/runtime-definitions/internal";
|
|
34
33
|
import {
|
|
35
34
|
FluidHandleBase,
|
|
@@ -39,11 +38,10 @@ import {
|
|
|
39
38
|
} from "@fluidframework/runtime-utils/internal";
|
|
40
39
|
import {
|
|
41
40
|
LoggingError,
|
|
42
|
-
MonitoringContext,
|
|
41
|
+
type MonitoringContext,
|
|
43
42
|
PerformanceEvent,
|
|
44
43
|
UsageError,
|
|
45
44
|
createChildMonitoringContext,
|
|
46
|
-
wrapError,
|
|
47
45
|
} from "@fluidframework/telemetry-utils/internal";
|
|
48
46
|
import { v4 as uuid } from "uuid";
|
|
49
47
|
|
|
@@ -143,7 +141,7 @@ interface PendingBlob {
|
|
|
143
141
|
opsent?: boolean;
|
|
144
142
|
storageId?: string;
|
|
145
143
|
handleP: Deferred<BlobHandle>;
|
|
146
|
-
uploadP?: Promise<
|
|
144
|
+
uploadP?: Promise<void>;
|
|
147
145
|
uploadTime?: number;
|
|
148
146
|
minTTLInSeconds?: number;
|
|
149
147
|
attached?: boolean;
|
|
@@ -183,13 +181,12 @@ export class BlobManager {
|
|
|
183
181
|
private readonly internalEvents = createEmitter<IBlobManagerInternalEvents>();
|
|
184
182
|
|
|
185
183
|
/**
|
|
186
|
-
* Map of local IDs to storage IDs.
|
|
187
|
-
* be a key in this map. Blobs created while the container is detached are
|
|
188
|
-
* gives
|
|
189
|
-
*
|
|
190
|
-
* that uploaded the blob but its mapping to storage ID is needed in all clients in order to retrieve the blob.
|
|
184
|
+
* Map of local IDs to storage IDs. Also includes identity mappings of storage ID to storage ID for all known
|
|
185
|
+
* storage IDs. All requested IDs must be a key in this map. Blobs created while the container is detached are
|
|
186
|
+
* stored in IDetachedBlobStorage which gives pseudo storage IDs; the real storage IDs are filled in at attach
|
|
187
|
+
* time via setRedirectTable().
|
|
191
188
|
*/
|
|
192
|
-
private readonly redirectTable: Map<string, string
|
|
189
|
+
private readonly redirectTable: Map<string, string>;
|
|
193
190
|
|
|
194
191
|
/**
|
|
195
192
|
* Blobs which we have not yet seen a BlobAttach op round-trip and not yet attached to a DDS.
|
|
@@ -208,13 +205,13 @@ export class BlobManager {
|
|
|
208
205
|
private readonly routeContext: IFluidHandleContext;
|
|
209
206
|
private readonly storage: Pick<IContainerStorageService, "createBlob" | "readBlob">;
|
|
210
207
|
// Called when a blob node is requested. blobPath is the path of the blob's node in GC's graph.
|
|
211
|
-
// blobPath's format - `/<basePath>/<
|
|
208
|
+
// blobPath's format - `/<basePath>/<localId>`.
|
|
212
209
|
private readonly blobRequested: (blobPath: string) => void;
|
|
213
210
|
// Called to check if a blob has been deleted by GC.
|
|
214
|
-
// blobPath's format - `/<basePath>/<
|
|
211
|
+
// blobPath's format - `/<basePath>/<localId>`.
|
|
215
212
|
private readonly isBlobDeleted: (blobPath: string) => boolean;
|
|
216
213
|
private readonly runtime: IBlobManagerRuntime;
|
|
217
|
-
private readonly
|
|
214
|
+
private readonly localIdGenerator: () => string;
|
|
218
215
|
|
|
219
216
|
private readonly createBlobPayloadPending: boolean;
|
|
220
217
|
|
|
@@ -235,14 +232,14 @@ export class BlobManager {
|
|
|
235
232
|
*/
|
|
236
233
|
sendBlobAttachOp: (localId: string, storageId: string) => void;
|
|
237
234
|
// Called when a blob node is requested. blobPath is the path of the blob's node in GC's graph.
|
|
238
|
-
// blobPath's format - `/<basePath>/<
|
|
235
|
+
// blobPath's format - `/<basePath>/<localId>`.
|
|
239
236
|
readonly blobRequested: (blobPath: string) => void;
|
|
240
237
|
// Called to check if a blob has been deleted by GC.
|
|
241
|
-
// blobPath's format - `/<basePath>/<
|
|
238
|
+
// blobPath's format - `/<basePath>/<localId>`.
|
|
242
239
|
readonly isBlobDeleted: (blobPath: string) => boolean;
|
|
243
240
|
readonly runtime: IBlobManagerRuntime;
|
|
244
241
|
stashedBlobs: IPendingBlobs | undefined;
|
|
245
|
-
readonly
|
|
242
|
+
readonly localIdGenerator?: (() => string) | undefined;
|
|
246
243
|
readonly createBlobPayloadPending: boolean;
|
|
247
244
|
}) {
|
|
248
245
|
const {
|
|
@@ -253,7 +250,7 @@ export class BlobManager {
|
|
|
253
250
|
blobRequested,
|
|
254
251
|
isBlobDeleted,
|
|
255
252
|
runtime,
|
|
256
|
-
|
|
253
|
+
localIdGenerator,
|
|
257
254
|
createBlobPayloadPending,
|
|
258
255
|
} = props;
|
|
259
256
|
this.routeContext = routeContext;
|
|
@@ -261,7 +258,7 @@ export class BlobManager {
|
|
|
261
258
|
this.blobRequested = blobRequested;
|
|
262
259
|
this.isBlobDeleted = isBlobDeleted;
|
|
263
260
|
this.runtime = runtime;
|
|
264
|
-
this.
|
|
261
|
+
this.localIdGenerator = localIdGenerator ?? uuid;
|
|
265
262
|
this.createBlobPayloadPending = createBlobPayloadPending;
|
|
266
263
|
|
|
267
264
|
this.mc = createChildMonitoringContext({
|
|
@@ -269,13 +266,9 @@ export class BlobManager {
|
|
|
269
266
|
namespace: "BlobManager",
|
|
270
267
|
});
|
|
271
268
|
|
|
272
|
-
this.redirectTable = toRedirectTable(
|
|
273
|
-
blobManagerLoadInfo,
|
|
274
|
-
this.mc.logger,
|
|
275
|
-
this.runtime.attachState,
|
|
276
|
-
);
|
|
269
|
+
this.redirectTable = toRedirectTable(blobManagerLoadInfo, this.mc.logger);
|
|
277
270
|
|
|
278
|
-
this.sendBlobAttachOp = (localId: string,
|
|
271
|
+
this.sendBlobAttachOp = (localId: string, storageId: string) => {
|
|
279
272
|
const pendingEntry = this.pendingBlobs.get(localId);
|
|
280
273
|
assert(
|
|
281
274
|
pendingEntry !== undefined,
|
|
@@ -304,7 +297,7 @@ export class BlobManager {
|
|
|
304
297
|
}
|
|
305
298
|
}
|
|
306
299
|
pendingEntry.opsent = true;
|
|
307
|
-
sendBlobAttachOp(localId,
|
|
300
|
+
sendBlobAttachOp(localId, storageId);
|
|
308
301
|
};
|
|
309
302
|
}
|
|
310
303
|
|
|
@@ -331,59 +324,49 @@ export class BlobManager {
|
|
|
331
324
|
});
|
|
332
325
|
}
|
|
333
326
|
|
|
334
|
-
public hasBlob(
|
|
335
|
-
return this.redirectTable.get(
|
|
327
|
+
public hasBlob(localId: string): boolean {
|
|
328
|
+
return this.redirectTable.get(localId) !== undefined;
|
|
336
329
|
}
|
|
337
330
|
|
|
338
331
|
/**
|
|
339
332
|
* Retrieve the blob with the given local blob id.
|
|
340
|
-
* @param
|
|
333
|
+
* @param localId - The local blob id. Likely coming from a handle.
|
|
341
334
|
* @param payloadPending - Whether we suspect the payload may be pending and not available yet.
|
|
342
335
|
* @returns A promise which resolves to the blob contents
|
|
343
336
|
*/
|
|
344
|
-
public async getBlob(
|
|
337
|
+
public async getBlob(localId: string, payloadPending: boolean): Promise<ArrayBufferLike> {
|
|
345
338
|
// Verify that the blob is not deleted, i.e., it has not been garbage collected. If it is, this will throw
|
|
346
339
|
// an error, failing the call.
|
|
347
|
-
this.verifyBlobNotDeleted(
|
|
340
|
+
this.verifyBlobNotDeleted(localId);
|
|
348
341
|
// Let runtime know that the corresponding GC node was requested.
|
|
349
342
|
// Note that this will throw if the blob is inactive or tombstoned and throwing on incorrect usage
|
|
350
343
|
// is configured.
|
|
351
|
-
this.blobRequested(
|
|
344
|
+
this.blobRequested(getGCNodePathFromLocalId(localId));
|
|
352
345
|
|
|
353
|
-
const pending = this.pendingBlobs.get(
|
|
346
|
+
const pending = this.pendingBlobs.get(localId);
|
|
354
347
|
if (pending) {
|
|
355
348
|
return pending.blob;
|
|
356
349
|
}
|
|
357
350
|
|
|
358
|
-
let storageId
|
|
359
|
-
if (
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
//
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
attachedStorageId ??
|
|
378
|
-
(await new Promise<string>((resolve) => {
|
|
379
|
-
const onProcessBlobAttach = (localId: string, _storageId: string): void => {
|
|
380
|
-
if (localId === blobId) {
|
|
381
|
-
this.internalEvents.off("processedBlobAttach", onProcessBlobAttach);
|
|
382
|
-
resolve(_storageId);
|
|
383
|
-
}
|
|
384
|
-
};
|
|
385
|
-
this.internalEvents.on("processedBlobAttach", onProcessBlobAttach);
|
|
386
|
-
}));
|
|
351
|
+
let storageId = this.redirectTable.get(localId);
|
|
352
|
+
if (storageId === undefined) {
|
|
353
|
+
// Only blob handles explicitly marked with pending payload are permitted to exist without
|
|
354
|
+
// yet knowing their storage id. Otherwise they must already be associated with a storage id.
|
|
355
|
+
// Handles for detached blobs are not payload pending.
|
|
356
|
+
assert(payloadPending, 0x11f /* "requesting unknown blobs" */);
|
|
357
|
+
// If we didn't find it in the redirectTable and it's payloadPending, assume the attach op is coming
|
|
358
|
+
// eventually and wait. We do this even if the local client doesn't have the blob payloadPending flag
|
|
359
|
+
// enabled, in case a remote client does have it enabled. This wait may be infinite if the uploading
|
|
360
|
+
// client failed the upload and doesn't exist anymore.
|
|
361
|
+
storageId = await new Promise<string>((resolve) => {
|
|
362
|
+
const onProcessBlobAttach = (_localId: string, _storageId: string): void => {
|
|
363
|
+
if (_localId === localId) {
|
|
364
|
+
this.internalEvents.off("processedBlobAttach", onProcessBlobAttach);
|
|
365
|
+
resolve(_storageId);
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
this.internalEvents.on("processedBlobAttach", onProcessBlobAttach);
|
|
369
|
+
});
|
|
387
370
|
}
|
|
388
371
|
|
|
389
372
|
return PerformanceEvent.timedExecAsync(
|
|
@@ -419,7 +402,7 @@ export class BlobManager {
|
|
|
419
402
|
}
|
|
420
403
|
: undefined;
|
|
421
404
|
return new BlobHandle(
|
|
422
|
-
|
|
405
|
+
getGCNodePathFromLocalId(localId),
|
|
423
406
|
this.routeContext,
|
|
424
407
|
async () => this.getBlob(localId, false),
|
|
425
408
|
false, // payloadPending
|
|
@@ -430,11 +413,13 @@ export class BlobManager {
|
|
|
430
413
|
private async createBlobDetached(
|
|
431
414
|
blob: ArrayBufferLike,
|
|
432
415
|
): Promise<IFluidHandleInternalPayloadPending<ArrayBufferLike>> {
|
|
416
|
+
const localId = this.localIdGenerator();
|
|
433
417
|
// Blobs created while the container is detached are stored in IDetachedBlobStorage.
|
|
434
|
-
// The 'IContainerStorageService.createBlob()' call below will respond with a
|
|
435
|
-
|
|
436
|
-
this.
|
|
437
|
-
|
|
418
|
+
// The 'IContainerStorageService.createBlob()' call below will respond with a pseudo storage ID.
|
|
419
|
+
// That pseudo storage ID will be replaced with the real storage ID at attach time.
|
|
420
|
+
const { id: detachedStorageId } = await this.storage.createBlob(blob);
|
|
421
|
+
this.setRedirection(localId, detachedStorageId);
|
|
422
|
+
return this.getBlobHandle(localId);
|
|
438
423
|
}
|
|
439
424
|
|
|
440
425
|
public async createBlob(
|
|
@@ -469,7 +454,7 @@ export class BlobManager {
|
|
|
469
454
|
|
|
470
455
|
// Create a local ID for the blob. After uploading it to storage and before returning it, a local ID to
|
|
471
456
|
// storage ID mapping is created.
|
|
472
|
-
const localId = this.
|
|
457
|
+
const localId = this.localIdGenerator();
|
|
473
458
|
const pendingEntry: PendingBlob = {
|
|
474
459
|
blob,
|
|
475
460
|
handleP: new Deferred(),
|
|
@@ -496,10 +481,10 @@ export class BlobManager {
|
|
|
496
481
|
private createBlobWithPayloadPending(
|
|
497
482
|
blob: ArrayBufferLike,
|
|
498
483
|
): IFluidHandleInternalPayloadPending<ArrayBufferLike> {
|
|
499
|
-
const localId = this.
|
|
484
|
+
const localId = this.localIdGenerator();
|
|
500
485
|
|
|
501
486
|
const blobHandle = new BlobHandle(
|
|
502
|
-
|
|
487
|
+
getGCNodePathFromLocalId(localId),
|
|
503
488
|
this.routeContext,
|
|
504
489
|
async () => blob,
|
|
505
490
|
true, // payloadPending
|
|
@@ -535,59 +520,55 @@ export class BlobManager {
|
|
|
535
520
|
return blobHandle;
|
|
536
521
|
}
|
|
537
522
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
{
|
|
564
|
-
cancel: this.pendingBlobs.get(localId)?.abortSignal,
|
|
565
|
-
},
|
|
566
|
-
).then(
|
|
567
|
-
(response) => this.onUploadResolve(localId, response),
|
|
568
|
-
(error) => {
|
|
569
|
-
this.mc.logger.sendTelemetryEvent({
|
|
570
|
-
eventName: "UploadBlobReject",
|
|
571
|
-
// TODO: better typing
|
|
572
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
573
|
-
error,
|
|
574
|
-
localId,
|
|
575
|
-
});
|
|
576
|
-
// it will only reject if we haven't sent an op
|
|
577
|
-
// and is a non-retriable error. It will only reject
|
|
578
|
-
// the promise but not throw any error outside.
|
|
579
|
-
this.pendingBlobs.get(localId)?.handleP.reject(error);
|
|
523
|
+
/**
|
|
524
|
+
* Upload a blob to the storage service.
|
|
525
|
+
* @returns A promise that resolves when the upload is complete and a blob attach op has been sent (but not ack'd).
|
|
526
|
+
*
|
|
527
|
+
* @privateRemarks This method must not reject, as there is no error handling for it in current tracking.
|
|
528
|
+
*/
|
|
529
|
+
private async uploadBlob(localId: string, blob: ArrayBufferLike): Promise<void> {
|
|
530
|
+
let response: ICreateBlobResponseWithTTL;
|
|
531
|
+
try {
|
|
532
|
+
response = await this.storage.createBlob(blob);
|
|
533
|
+
} catch (error) {
|
|
534
|
+
const entry = this.pendingBlobs.get(localId);
|
|
535
|
+
this.mc.logger.sendTelemetryEvent({
|
|
536
|
+
eventName: "UploadBlobReject",
|
|
537
|
+
// TODO: better typing
|
|
538
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
|
|
539
|
+
error: error as any,
|
|
540
|
+
message: entry === undefined ? "Missing pendingBlob" : undefined,
|
|
541
|
+
localId,
|
|
542
|
+
});
|
|
543
|
+
// We probably should assert the pendingBlobs entry here, but we don't currently have any error handling
|
|
544
|
+
// for the uploadP - a promise rejection would be unhandled anyway. For now we can detect this with the
|
|
545
|
+
// message on the UploadBlobReject telemetry.
|
|
546
|
+
if (entry !== undefined) {
|
|
547
|
+
entry.handleP.reject(error);
|
|
580
548
|
this.deletePendingBlob(localId);
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
549
|
+
}
|
|
550
|
+
this.internalEvents.emit("uploadFailed", localId, error);
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
try {
|
|
555
|
+
this.onUploadResolve(localId, response);
|
|
556
|
+
} catch (error) {
|
|
557
|
+
this.mc.logger.sendTelemetryEvent({
|
|
558
|
+
eventName: "OnUploadResolveError",
|
|
559
|
+
// TODO: better typing
|
|
560
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
|
|
561
|
+
error: error as any,
|
|
562
|
+
localId,
|
|
563
|
+
});
|
|
564
|
+
}
|
|
584
565
|
}
|
|
585
566
|
|
|
586
567
|
/**
|
|
587
568
|
* Set up a mapping in the redirect table from fromId to toId. Also, notify the runtime that a reference is added
|
|
588
569
|
* which is required for GC.
|
|
589
570
|
*/
|
|
590
|
-
private setRedirection(fromId: string, toId: string
|
|
571
|
+
private setRedirection(fromId: string, toId: string): void {
|
|
591
572
|
this.redirectTable.set(fromId, toId);
|
|
592
573
|
}
|
|
593
574
|
|
|
@@ -636,7 +617,7 @@ export class BlobManager {
|
|
|
636
617
|
if (!entry.opsent) {
|
|
637
618
|
this.sendBlobAttachOp(localId, response.id);
|
|
638
619
|
}
|
|
639
|
-
const storageIds = getStorageIds(this.redirectTable
|
|
620
|
+
const storageIds = getStorageIds(this.redirectTable);
|
|
640
621
|
if (storageIds.has(response.id)) {
|
|
641
622
|
// The blob is de-duped. Set up a local ID to storage ID mapping and return the blob. Since this is
|
|
642
623
|
// an existing blob, we don't have to wait for the op to be ack'd since this step has already
|
|
@@ -669,7 +650,7 @@ export class BlobManager {
|
|
|
669
650
|
*/
|
|
670
651
|
public reSubmit(metadata: Record<string, unknown> | undefined): void {
|
|
671
652
|
assert(isBlobMetadata(metadata), 0xc01 /* Expected blob metadata for a BlobAttach op */);
|
|
672
|
-
const { localId, blobId } = metadata;
|
|
653
|
+
const { localId, blobId: storageId } = metadata;
|
|
673
654
|
// Any blob that we're actively trying to advance to attached state must have a
|
|
674
655
|
// pendingBlobs entry. Decline to resubmit for anything else.
|
|
675
656
|
// For example, we might be asked to resubmit stashed ops for blobs that never had
|
|
@@ -677,7 +658,7 @@ export class BlobManager {
|
|
|
677
658
|
// try to attach them since they won't be accessible to the customer and would just
|
|
678
659
|
// be considered garbage immediately.
|
|
679
660
|
if (this.pendingBlobs.has(localId)) {
|
|
680
|
-
this.sendBlobAttachOp(localId,
|
|
661
|
+
this.sendBlobAttachOp(localId, storageId);
|
|
681
662
|
}
|
|
682
663
|
}
|
|
683
664
|
|
|
@@ -686,19 +667,19 @@ export class BlobManager {
|
|
|
686
667
|
isBlobMetadata(message.metadata),
|
|
687
668
|
0xc02 /* Expected blob metadata for a BlobAttach op */,
|
|
688
669
|
);
|
|
689
|
-
const { localId, blobId } = message.metadata;
|
|
670
|
+
const { localId, blobId: storageId } = message.metadata;
|
|
690
671
|
const pendingEntry = this.pendingBlobs.get(localId);
|
|
691
672
|
if (pendingEntry?.abortSignal?.aborted) {
|
|
692
673
|
this.deletePendingBlob(localId);
|
|
693
674
|
return;
|
|
694
675
|
}
|
|
695
676
|
|
|
696
|
-
this.setRedirection(localId,
|
|
677
|
+
this.setRedirection(localId, storageId);
|
|
697
678
|
// set identity (id -> id) entry
|
|
698
|
-
this.setRedirection(
|
|
679
|
+
this.setRedirection(storageId, storageId);
|
|
699
680
|
|
|
700
681
|
if (local) {
|
|
701
|
-
const waitingBlobs = this.opsInFlight.get(
|
|
682
|
+
const waitingBlobs = this.opsInFlight.get(storageId);
|
|
702
683
|
if (waitingBlobs !== undefined) {
|
|
703
684
|
// For each op corresponding to this storage ID that we are waiting for, resolve the pending blob.
|
|
704
685
|
// This is safe because the server will keep the blob alive and the op containing the local ID to
|
|
@@ -709,14 +690,14 @@ export class BlobManager {
|
|
|
709
690
|
entry !== undefined,
|
|
710
691
|
0x38f /* local online BlobAttach op with no pending blob entry */,
|
|
711
692
|
);
|
|
712
|
-
this.setRedirection(pendingLocalId,
|
|
693
|
+
this.setRedirection(pendingLocalId, storageId);
|
|
713
694
|
entry.acked = true;
|
|
714
695
|
const blobHandle = this.getBlobHandle(pendingLocalId);
|
|
715
696
|
blobHandle.notifyShared();
|
|
716
697
|
entry.handleP.resolve(blobHandle);
|
|
717
698
|
this.deletePendingBlobMaybe(pendingLocalId);
|
|
718
699
|
}
|
|
719
|
-
this.opsInFlight.delete(
|
|
700
|
+
this.opsInFlight.delete(storageId);
|
|
720
701
|
}
|
|
721
702
|
const localEntry = this.pendingBlobs.get(localId);
|
|
722
703
|
if (localEntry) {
|
|
@@ -727,11 +708,11 @@ export class BlobManager {
|
|
|
727
708
|
this.deletePendingBlobMaybe(localId);
|
|
728
709
|
}
|
|
729
710
|
}
|
|
730
|
-
this.internalEvents.emit("processedBlobAttach", localId,
|
|
711
|
+
this.internalEvents.emit("processedBlobAttach", localId, storageId);
|
|
731
712
|
}
|
|
732
713
|
|
|
733
714
|
public summarize(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {
|
|
734
|
-
return summarizeBlobManagerState(this.redirectTable
|
|
715
|
+
return summarizeBlobManagerState(this.redirectTable);
|
|
735
716
|
}
|
|
736
717
|
|
|
737
718
|
/**
|
|
@@ -743,13 +724,12 @@ export class BlobManager {
|
|
|
743
724
|
public getGCData(fullGC: boolean = false): IGarbageCollectionData {
|
|
744
725
|
const gcData: IGarbageCollectionData = { gcNodes: {} };
|
|
745
726
|
for (const [localId, storageId] of this.redirectTable) {
|
|
746
|
-
|
|
747
|
-
//
|
|
748
|
-
// id entries have the same key and value, ignore them.
|
|
749
|
-
// The outbound routes are empty because a blob node cannot reference other nodes. It can only be referenced
|
|
750
|
-
// by adding its handle to a referenced DDS.
|
|
727
|
+
// Don't report the identity mappings to GC - these exist to service old handles that referenced the storage
|
|
728
|
+
// IDs directly. We'll implicitly clean them up if all of their localId references get GC'd first.
|
|
751
729
|
if (localId !== storageId) {
|
|
752
|
-
|
|
730
|
+
// The outbound routes are empty because a blob node cannot reference other nodes. It can only be referenced
|
|
731
|
+
// by adding its handle to a referenced DDS.
|
|
732
|
+
gcData.gcNodes[getGCNodePathFromLocalId(localId)] = [];
|
|
753
733
|
}
|
|
754
734
|
}
|
|
755
735
|
return gcData;
|
|
@@ -770,58 +750,55 @@ export class BlobManager {
|
|
|
770
750
|
* Delete blobs with the given routes from the redirect table.
|
|
771
751
|
*
|
|
772
752
|
* @remarks
|
|
773
|
-
* The routes are GC nodes paths of format -`/<blobManagerBasePath>/<
|
|
753
|
+
* The routes are GC nodes paths of format -`/<blobManagerBasePath>/<localId>`.
|
|
774
754
|
* Deleting the blobs involves 2 steps:
|
|
775
755
|
*
|
|
776
756
|
* 1. The redirect table entry for the local ids are deleted.
|
|
777
757
|
*
|
|
778
|
-
* 2. If the storage ids corresponding to the deleted local ids are not
|
|
779
|
-
*
|
|
758
|
+
* 2. If the storage ids corresponding to the deleted local ids are not referenced by any further local ids, the
|
|
759
|
+
* identity mappings in the redirect table are deleted as well.
|
|
780
760
|
*
|
|
781
761
|
* Note that this does not delete the blobs from storage service immediately. Deleting the blobs from redirect table
|
|
782
|
-
* will
|
|
762
|
+
* will ensure we don't create an attachment blob for them at the next summary. The service would then delete them
|
|
763
|
+
* some time in the future.
|
|
783
764
|
*/
|
|
784
765
|
private deleteBlobsFromRedirectTable(blobRoutes: readonly string[]): void {
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
// This tracks the storage ids of local ids that are deleted. After the local ids have been deleted, if any of
|
|
790
|
-
// these storage ids are unused, they will be deleted as well.
|
|
766
|
+
// maybeUnusedStorageIds is used to compute the set of storage IDs that *used to have a local ID*, but that
|
|
767
|
+
// local ID is being deleted.
|
|
791
768
|
const maybeUnusedStorageIds: Set<string> = new Set();
|
|
792
769
|
for (const route of blobRoutes) {
|
|
793
|
-
const
|
|
770
|
+
const localId = getLocalIdFromGCNodePath(route);
|
|
794
771
|
// If the blob hasn't already been deleted, log an error because this should never happen.
|
|
795
772
|
// If the blob has already been deleted, log a telemetry event. This can happen because multiple GC
|
|
796
773
|
// sweep ops can contain the same data store. It would be interesting to track how often this happens.
|
|
797
774
|
const alreadyDeleted = this.isBlobDeleted(route);
|
|
798
|
-
|
|
775
|
+
const storageId = this.redirectTable.get(localId);
|
|
776
|
+
if (storageId === undefined) {
|
|
799
777
|
this.mc.logger.sendTelemetryEvent({
|
|
800
778
|
eventName: "DeletedAttachmentBlobNotFound",
|
|
801
779
|
category: alreadyDeleted ? "generic" : "error",
|
|
802
|
-
blobId,
|
|
780
|
+
blobId: localId,
|
|
803
781
|
details: { alreadyDeleted },
|
|
804
782
|
});
|
|
805
783
|
continue;
|
|
806
784
|
}
|
|
807
|
-
const storageId = this.redirectTable.get(blobId);
|
|
808
|
-
assert(!!storageId, 0x5bb /* Must be attached to run GC */);
|
|
809
785
|
maybeUnusedStorageIds.add(storageId);
|
|
810
|
-
this.redirectTable.delete(
|
|
786
|
+
this.redirectTable.delete(localId);
|
|
811
787
|
}
|
|
812
788
|
|
|
813
|
-
//
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
assert(!!storageId, 0x5bc /* Must be attached to run GC */);
|
|
817
|
-
// For every storage id, the redirect table has a id -> id entry. These do not make the storage id in-use.
|
|
818
|
-
if (maybeUnusedStorageIds.has(storageId) && localId !== storageId) {
|
|
789
|
+
// Remove any storage IDs that still have local IDs referring to them (excluding the identity mapping).
|
|
790
|
+
for (const [localId, storageId] of this.redirectTable) {
|
|
791
|
+
if (localId !== storageId) {
|
|
819
792
|
maybeUnusedStorageIds.delete(storageId);
|
|
820
793
|
}
|
|
821
794
|
}
|
|
822
795
|
|
|
823
|
-
//
|
|
824
|
-
// This way they'll be absent from the next summary, and the service
|
|
796
|
+
// Now delete any identity mappings (storage ID -> storage ID) from the redirect table that used to be
|
|
797
|
+
// referenced by a distinct local ID. This way they'll be absent from the next summary, and the service
|
|
798
|
+
// is free to delete them from storage.
|
|
799
|
+
// WARNING: This can potentially delete identity mappings that are still referenced, if storage deduping
|
|
800
|
+
// has let us add a local ID -> storage ID mapping that is later deleted. AB#47337 tracks this issue
|
|
801
|
+
// and possible solutions.
|
|
825
802
|
for (const storageId of maybeUnusedStorageIds) {
|
|
826
803
|
this.redirectTable.delete(storageId);
|
|
827
804
|
}
|
|
@@ -831,12 +808,12 @@ export class BlobManager {
|
|
|
831
808
|
* Verifies that the blob with given id is not deleted, i.e., it has not been garbage collected. If the blob is GC'd,
|
|
832
809
|
* log an error and throw if necessary.
|
|
833
810
|
*/
|
|
834
|
-
private verifyBlobNotDeleted(
|
|
835
|
-
if (!this.isBlobDeleted(
|
|
811
|
+
private verifyBlobNotDeleted(localId: string): void {
|
|
812
|
+
if (!this.isBlobDeleted(getGCNodePathFromLocalId(localId))) {
|
|
836
813
|
return;
|
|
837
814
|
}
|
|
838
815
|
|
|
839
|
-
const request = { url:
|
|
816
|
+
const request = { url: localId };
|
|
840
817
|
const error = responseToException(
|
|
841
818
|
createResponseError(404, `Blob was deleted`, request),
|
|
842
819
|
request,
|
|
@@ -852,20 +829,34 @@ export class BlobManager {
|
|
|
852
829
|
throw error;
|
|
853
830
|
}
|
|
854
831
|
|
|
855
|
-
|
|
832
|
+
/**
|
|
833
|
+
* Called in detached state just prior to attaching, this will update the redirect table by
|
|
834
|
+
* converting the pseudo storage IDs into real storage IDs using the provided detachedStorageTable.
|
|
835
|
+
* The provided table must have exactly the same set of pseudo storage IDs as are found in the redirect table.
|
|
836
|
+
* @param detachedStorageTable - A map of pseudo storage IDs to real storage IDs.
|
|
837
|
+
*/
|
|
838
|
+
public patchRedirectTable(detachedStorageTable: Map<string, string>): void {
|
|
856
839
|
assert(
|
|
857
840
|
this.runtime.attachState === AttachState.Detached,
|
|
858
841
|
0x252 /* "redirect table can only be set in detached container" */,
|
|
859
842
|
);
|
|
843
|
+
// The values of the redirect table are the pseudo storage IDs, which are the keys of the
|
|
844
|
+
// detachedStorageTable. We expect to have a many:1 mapping from local IDs to pseudo
|
|
845
|
+
// storage IDs (many in the case that the storage dedupes the blob).
|
|
860
846
|
assert(
|
|
861
|
-
this.redirectTable.size ===
|
|
847
|
+
new Set(this.redirectTable.values()).size === detachedStorageTable.size,
|
|
862
848
|
0x391 /* Redirect table size must match BlobManager's local ID count */,
|
|
863
849
|
);
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
850
|
+
// Taking a snapshot of the redirect table entries before iterating, because
|
|
851
|
+
// we will be adding identity mappings to the the redirect table as we iterate
|
|
852
|
+
// and we don't want to include those in the iteration.
|
|
853
|
+
const redirectTableEntries = [...this.redirectTable.entries()];
|
|
854
|
+
for (const [localId, detachedStorageId] of redirectTableEntries) {
|
|
855
|
+
const newStorageId = detachedStorageTable.get(detachedStorageId);
|
|
856
|
+
assert(newStorageId !== undefined, "Couldn't find a matching storage ID");
|
|
857
|
+
this.setRedirection(localId, newStorageId);
|
|
867
858
|
// set identity (id -> id) entry
|
|
868
|
-
this.setRedirection(
|
|
859
|
+
this.setRedirection(newStorageId, newStorageId);
|
|
869
860
|
}
|
|
870
861
|
}
|
|
871
862
|
|
|
@@ -902,17 +893,17 @@ export class BlobManager {
|
|
|
902
893
|
}
|
|
903
894
|
|
|
904
895
|
/**
|
|
905
|
-
* For a
|
|
896
|
+
* For a localId, returns its path in GC's graph. The node path is of the format `/<blobManagerBasePath>/<localId>`.
|
|
906
897
|
* This path must match the path of the blob handle returned by the createBlob API because blobs are marked
|
|
907
898
|
* referenced by storing these handles in a referenced DDS.
|
|
908
899
|
*/
|
|
909
|
-
const
|
|
910
|
-
`/${blobManagerBasePath}/${
|
|
900
|
+
const getGCNodePathFromLocalId = (localId: string): string =>
|
|
901
|
+
`/${blobManagerBasePath}/${localId}`;
|
|
911
902
|
|
|
912
903
|
/**
|
|
913
|
-
* For a given GC node path, return the
|
|
904
|
+
* For a given GC node path, return the localId. The node path is of the format `/<basePath>/<localId>`.
|
|
914
905
|
*/
|
|
915
|
-
const
|
|
906
|
+
const getLocalIdFromGCNodePath = (nodePath: string): string => {
|
|
916
907
|
const pathParts = nodePath.split("/");
|
|
917
908
|
assert(areBlobPathParts(pathParts), 0x5bd /* Invalid blob node path */);
|
|
918
909
|
return pathParts[2];
|