@fluidframework/container-runtime 2.0.0-dev.5.2.0.169897 → 2.0.0-dev.6.4.0.191258
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +147 -0
- package/README.md +4 -3
- package/dist/batchTracker.d.ts +3 -2
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +6 -5
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +15 -18
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +212 -171
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +33 -17
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +172 -35
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +722 -425
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +15 -7
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +4 -4
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +87 -90
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +10 -10
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.js +2 -2
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/dataStores.d.ts +23 -7
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +125 -82
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaManagerProxyBase.d.ts +35 -0
- package/dist/deltaManagerProxyBase.d.ts.map +1 -0
- package/dist/deltaManagerProxyBase.js +77 -0
- package/dist/deltaManagerProxyBase.js.map +1 -0
- package/dist/deltaManagerSummarizerProxy.d.ts +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -1
- package/dist/deltaManagerSummarizerProxy.js +4 -2
- package/dist/deltaManagerSummarizerProxy.js.map +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +10 -10
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/error.d.ts +14 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +21 -0
- package/dist/error.js.map +1 -0
- package/dist/gc/garbageCollection.d.ts +10 -9
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +65 -56
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +18 -14
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +17 -5
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +14 -15
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +0 -8
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +11 -24
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +4 -7
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +19 -58
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +45 -35
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.js +4 -4
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/dist/gc/index.d.ts +2 -2
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +3 -5
- package/dist/gc/index.js.map +1 -1
- package/dist/id-compressor/appendOnlySortedMap.d.ts +8 -30
- package/dist/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
- package/dist/id-compressor/appendOnlySortedMap.js +26 -68
- package/dist/id-compressor/appendOnlySortedMap.js.map +1 -1
- package/dist/id-compressor/finalSpace.d.ts +29 -0
- package/dist/id-compressor/finalSpace.d.ts.map +1 -0
- package/dist/id-compressor/finalSpace.js +62 -0
- package/dist/id-compressor/finalSpace.js.map +1 -0
- package/dist/id-compressor/idCompressor.d.ts +25 -250
- package/dist/id-compressor/idCompressor.d.ts.map +1 -1
- package/dist/id-compressor/idCompressor.js +390 -1153
- package/dist/id-compressor/idCompressor.js.map +1 -1
- package/dist/id-compressor/identifiers.d.ts +32 -0
- package/dist/id-compressor/identifiers.d.ts.map +1 -0
- package/dist/id-compressor/identifiers.js +15 -0
- package/dist/id-compressor/identifiers.js.map +1 -0
- package/dist/id-compressor/index.d.ts +5 -6
- package/dist/id-compressor/index.d.ts.map +1 -1
- package/dist/id-compressor/index.js +20 -26
- package/dist/id-compressor/index.js.map +1 -1
- package/dist/id-compressor/persistanceUtilities.d.ts +22 -0
- package/dist/id-compressor/persistanceUtilities.d.ts.map +1 -0
- package/dist/id-compressor/persistanceUtilities.js +43 -0
- package/dist/id-compressor/persistanceUtilities.js.map +1 -0
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
- package/dist/id-compressor/sessionSpaceNormalizer.js +80 -0
- package/dist/id-compressor/sessionSpaceNormalizer.js.map +1 -0
- package/dist/id-compressor/sessions.d.ts +115 -0
- package/dist/id-compressor/sessions.d.ts.map +1 -0
- package/dist/id-compressor/sessions.js +305 -0
- package/dist/id-compressor/sessions.js.map +1 -0
- package/dist/id-compressor/utilities.d.ts +49 -0
- package/dist/id-compressor/utilities.d.ts.map +1 -0
- package/dist/id-compressor/utilities.js +166 -0
- package/dist/id-compressor/utilities.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +18 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +7 -0
- package/dist/metadata.js.map +1 -0
- package/dist/opLifecycle/batchManager.d.ts +2 -1
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +15 -7
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +11 -0
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +2 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts +2 -2
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +12 -7
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +2 -2
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +30 -21
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +19 -13
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +2 -2
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +24 -19
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +39 -6
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +138 -61
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +6 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +22 -8
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/opProperties.js +1 -2
- package/dist/opProperties.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +25 -10
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +101 -64
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +43 -33
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/index.d.ts +4 -4
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +3 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +3 -3
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +26 -27
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js +3 -3
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +31 -10
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +271 -139
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +8 -7
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +79 -78
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +2 -2
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js +7 -11
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.js +10 -14
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/index.d.ts +1 -1
- package/dist/summary/summarizerNode/index.d.ts.map +1 -1
- package/dist/summary/summarizerNode/index.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +40 -23
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +144 -149
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +25 -29
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js +2 -4
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +21 -16
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +74 -123
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +44 -24
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +2 -2
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +16 -13
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +4 -0
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +8 -5
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +21 -6
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +117 -54
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +8 -7
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +38 -28
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/batchTracker.d.ts +3 -2
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +5 -4
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +15 -18
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +187 -146
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +23 -7
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +172 -35
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +678 -380
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +13 -5
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +4 -4
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +49 -52
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +3 -3
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.js +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/dataStores.d.ts +23 -7
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +107 -64
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaManagerProxyBase.d.ts +35 -0
- package/lib/deltaManagerProxyBase.d.ts.map +1 -0
- package/lib/deltaManagerProxyBase.js +73 -0
- package/lib/deltaManagerProxyBase.js.map +1 -0
- package/lib/deltaManagerSummarizerProxy.d.ts +1 -1
- package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -1
- package/lib/deltaManagerSummarizerProxy.js +3 -1
- package/lib/deltaManagerSummarizerProxy.js.map +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +7 -7
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/error.d.ts +14 -0
- package/lib/error.d.ts.map +1 -0
- package/lib/error.js +17 -0
- package/lib/error.js.map +1 -0
- package/lib/gc/garbageCollection.d.ts +10 -9
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +61 -52
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +16 -12
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +17 -5
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +13 -14
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +0 -8
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +5 -17
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +4 -7
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +20 -59
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +46 -36
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/lib/gc/index.d.ts +2 -2
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +2 -2
- package/lib/gc/index.js.map +1 -1
- package/lib/id-compressor/appendOnlySortedMap.d.ts +8 -30
- package/lib/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
- package/lib/id-compressor/appendOnlySortedMap.js +25 -66
- package/lib/id-compressor/appendOnlySortedMap.js.map +1 -1
- package/lib/id-compressor/finalSpace.d.ts +29 -0
- package/lib/id-compressor/finalSpace.d.ts.map +1 -0
- package/lib/id-compressor/finalSpace.js +58 -0
- package/lib/id-compressor/finalSpace.js.map +1 -0
- package/lib/id-compressor/idCompressor.d.ts +25 -250
- package/lib/id-compressor/idCompressor.d.ts.map +1 -1
- package/lib/id-compressor/idCompressor.js +385 -1142
- package/lib/id-compressor/idCompressor.js.map +1 -1
- package/lib/id-compressor/identifiers.d.ts +32 -0
- package/lib/id-compressor/identifiers.d.ts.map +1 -0
- package/lib/id-compressor/identifiers.js +11 -0
- package/lib/id-compressor/identifiers.js.map +1 -0
- package/lib/id-compressor/index.d.ts +5 -6
- package/lib/id-compressor/index.d.ts.map +1 -1
- package/lib/id-compressor/index.js +5 -6
- package/lib/id-compressor/index.js.map +1 -1
- package/lib/id-compressor/persistanceUtilities.d.ts +22 -0
- package/lib/id-compressor/persistanceUtilities.d.ts.map +1 -0
- package/lib/id-compressor/persistanceUtilities.js +34 -0
- package/lib/id-compressor/persistanceUtilities.js.map +1 -0
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
- package/lib/id-compressor/sessionSpaceNormalizer.js +76 -0
- package/lib/id-compressor/sessionSpaceNormalizer.js.map +1 -0
- package/lib/id-compressor/sessions.d.ts +115 -0
- package/lib/id-compressor/sessions.d.ts.map +1 -0
- package/lib/id-compressor/sessions.js +290 -0
- package/lib/id-compressor/sessions.js.map +1 -0
- package/lib/id-compressor/utilities.d.ts +49 -0
- package/lib/id-compressor/utilities.d.ts.map +1 -0
- package/lib/id-compressor/utilities.js +148 -0
- package/lib/id-compressor/utilities.js.map +1 -0
- package/lib/index.d.ts +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/metadata.d.ts +18 -0
- package/lib/metadata.d.ts.map +1 -0
- package/lib/metadata.js +6 -0
- package/lib/metadata.js.map +1 -0
- package/lib/opLifecycle/batchManager.d.ts +2 -1
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +15 -7
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +11 -0
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts +2 -2
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +10 -5
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +2 -2
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +22 -13
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +17 -11
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +2 -2
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +15 -10
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +39 -6
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +132 -56
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +6 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +23 -9
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/opProperties.js +1 -2
- package/lib/opProperties.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +25 -10
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +90 -53
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +25 -15
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/index.d.ts +4 -4
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +2 -2
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +3 -3
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +21 -22
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +31 -10
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +265 -133
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +8 -7
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +75 -74
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +2 -2
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js +6 -10
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.js +9 -13
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/index.d.ts +1 -1
- package/lib/summary/summarizerNode/index.d.ts.map +1 -1
- package/lib/summary/summarizerNode/index.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +40 -23
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +132 -137
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +25 -29
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js +2 -4
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +21 -16
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +70 -119
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +44 -24
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +2 -2
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +9 -6
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +4 -0
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +7 -4
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +21 -6
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +109 -47
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +8 -7
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +35 -25
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +30 -32
- package/src/batchTracker.ts +7 -5
- package/src/blobManager.ts +235 -172
- package/src/connectionTelemetry.ts +19 -5
- package/src/containerRuntime.ts +853 -431
- package/src/dataStore.ts +12 -4
- package/src/dataStoreContext.ts +49 -46
- package/src/dataStoreContexts.ts +4 -4
- package/src/dataStoreRegistry.ts +1 -1
- package/src/dataStores.ts +119 -80
- package/src/deltaManagerProxyBase.ts +111 -0
- package/src/deltaManagerSummarizerProxy.ts +4 -1
- package/src/deltaScheduler.ts +7 -11
- package/src/error.ts +18 -0
- package/src/gc/garbageCollection.md +53 -5
- package/src/gc/garbageCollection.ts +58 -51
- package/src/gc/gcConfigs.ts +4 -2
- package/src/gc/gcDefinitions.ts +17 -21
- package/src/gc/gcEarlyAdoption.md +145 -0
- package/src/gc/gcHelpers.ts +1 -12
- package/src/gc/gcSummaryStateTracker.ts +19 -65
- package/src/gc/gcTelemetry.ts +15 -13
- package/src/gc/gcUnreferencedStateTracker.ts +1 -1
- package/src/gc/index.ts +2 -4
- package/src/id-compressor/appendOnlySortedMap.ts +26 -87
- package/src/id-compressor/finalSpace.ts +67 -0
- package/src/id-compressor/idCompressor.ts +458 -1682
- package/src/id-compressor/identifiers.ts +42 -0
- package/src/id-compressor/index.ts +11 -20
- package/src/id-compressor/persistanceUtilities.ts +58 -0
- package/src/id-compressor/sessionSpaceNormalizer.ts +83 -0
- package/src/id-compressor/sessions.ts +405 -0
- package/src/id-compressor/utilities.ts +187 -0
- package/src/index.ts +9 -2
- package/src/metadata.ts +19 -0
- package/src/opLifecycle/README.md +20 -0
- package/src/opLifecycle/batchManager.ts +9 -1
- package/src/opLifecycle/definitions.ts +11 -0
- package/src/opLifecycle/index.ts +1 -1
- package/src/opLifecycle/opCompressor.ts +6 -5
- package/src/opLifecycle/opDecompressor.ts +47 -17
- package/src/opLifecycle/opGroupingManager.ts +18 -8
- package/src/opLifecycle/opSplitter.ts +10 -7
- package/src/opLifecycle/outbox.ts +177 -72
- package/src/opLifecycle/remoteMessageProcessor.ts +32 -9
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +123 -78
- package/src/scheduleManager.ts +22 -11
- package/src/summary/index.ts +7 -4
- package/src/summary/orderedClientElection.ts +10 -6
- package/src/summary/runWhileConnectedCoordinator.ts +1 -1
- package/src/summary/runningSummarizer.ts +291 -163
- package/src/summary/summarizer.ts +27 -16
- package/src/summary/summarizerClientElection.ts +2 -2
- package/src/summary/summarizerHeuristics.ts +1 -1
- package/src/summary/summarizerNode/index.ts +2 -2
- package/src/summary/summarizerNode/summarizerNode.ts +142 -184
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +27 -35
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +72 -148
- package/src/summary/summarizerTypes.ts +49 -24
- package/src/summary/summaryCollection.ts +9 -4
- package/src/summary/summaryFormat.ts +9 -2
- package/src/summary/summaryGenerator.ts +72 -49
- package/src/summary/summaryManager.ts +44 -16
- package/dist/id-compressor/idRange.d.ts +0 -11
- package/dist/id-compressor/idRange.d.ts.map +0 -1
- package/dist/id-compressor/idRange.js +0 -29
- package/dist/id-compressor/idRange.js.map +0 -1
- package/dist/id-compressor/numericUuid.d.ts +0 -59
- package/dist/id-compressor/numericUuid.d.ts.map +0 -1
- package/dist/id-compressor/numericUuid.js +0 -325
- package/dist/id-compressor/numericUuid.js.map +0 -1
- package/dist/id-compressor/sessionIdNormalizer.d.ts +0 -138
- package/dist/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
- package/dist/id-compressor/sessionIdNormalizer.js +0 -488
- package/dist/id-compressor/sessionIdNormalizer.js.map +0 -1
- package/dist/id-compressor/utils.d.ts +0 -57
- package/dist/id-compressor/utils.d.ts.map +0 -1
- package/dist/id-compressor/utils.js +0 -90
- package/dist/id-compressor/utils.js.map +0 -1
- package/dist/id-compressor/uuidUtilities.d.ts +0 -30
- package/dist/id-compressor/uuidUtilities.d.ts.map +0 -1
- package/dist/id-compressor/uuidUtilities.js +0 -106
- package/dist/id-compressor/uuidUtilities.js.map +0 -1
- package/lib/id-compressor/idRange.d.ts +0 -11
- package/lib/id-compressor/idRange.d.ts.map +0 -1
- package/lib/id-compressor/idRange.js +0 -25
- package/lib/id-compressor/idRange.js.map +0 -1
- package/lib/id-compressor/numericUuid.d.ts +0 -59
- package/lib/id-compressor/numericUuid.d.ts.map +0 -1
- package/lib/id-compressor/numericUuid.js +0 -315
- package/lib/id-compressor/numericUuid.js.map +0 -1
- package/lib/id-compressor/sessionIdNormalizer.d.ts +0 -138
- package/lib/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
- package/lib/id-compressor/sessionIdNormalizer.js +0 -484
- package/lib/id-compressor/sessionIdNormalizer.js.map +0 -1
- package/lib/id-compressor/utils.d.ts +0 -57
- package/lib/id-compressor/utils.d.ts.map +0 -1
- package/lib/id-compressor/utils.js +0 -79
- package/lib/id-compressor/utils.js.map +0 -1
- package/lib/id-compressor/uuidUtilities.d.ts +0 -30
- package/lib/id-compressor/uuidUtilities.d.ts.map +0 -1
- package/lib/id-compressor/uuidUtilities.js +0 -98
- package/lib/id-compressor/uuidUtilities.js.map +0 -1
- package/src/id-compressor/idRange.ts +0 -35
- package/src/id-compressor/numericUuid.ts +0 -383
- package/src/id-compressor/sessionIdNormalizer.ts +0 -609
- package/src/id-compressor/utils.ts +0 -114
- package/src/id-compressor/uuidUtilities.ts +0 -123
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,11 +36,16 @@ 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
|
+
import { IBlobMetadata } from "./metadata";
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
51
|
* This class represents blob (long string)
|
|
@@ -70,12 +71,16 @@ export class BlobHandle implements IFluidHandle<ArrayBufferLike> {
|
|
|
70
71
|
public readonly path: string,
|
|
71
72
|
public readonly routeContext: IFluidHandleContext,
|
|
72
73
|
public get: () => Promise<any>,
|
|
74
|
+
private readonly onAttachGraph?: () => void,
|
|
73
75
|
) {
|
|
74
76
|
this.absolutePath = generateHandleContextPath(path, this.routeContext);
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
public attachGraph() {
|
|
78
|
-
this.attached
|
|
80
|
+
if (!this.attached) {
|
|
81
|
+
this.attached = true;
|
|
82
|
+
this.onAttachGraph?.();
|
|
83
|
+
}
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
public bind(handle: IFluidHandle) {
|
|
@@ -117,29 +122,31 @@ export type IBlobManagerRuntime = Pick<
|
|
|
117
122
|
Pick<ContainerRuntime, "gcTombstoneEnforcementAllowed"> &
|
|
118
123
|
TypedEventEmitter<IContainerRuntimeEvents>;
|
|
119
124
|
|
|
120
|
-
// Note that while offline we "submit" an op before uploading the blob, but we always
|
|
121
|
-
// expect blobs to be uploaded before we actually see the op round-trip
|
|
122
|
-
enum PendingBlobStatus {
|
|
123
|
-
OnlinePendingUpload,
|
|
124
|
-
OnlinePendingOp,
|
|
125
|
-
OfflinePendingUpload,
|
|
126
|
-
OfflinePendingOp,
|
|
127
|
-
}
|
|
128
|
-
|
|
129
125
|
type ICreateBlobResponseWithTTL = ICreateBlobResponse & Partial<Record<"minTTLInSeconds", number>>;
|
|
130
126
|
|
|
131
127
|
interface PendingBlob {
|
|
132
128
|
blob: ArrayBufferLike;
|
|
133
|
-
|
|
129
|
+
uploading?: boolean;
|
|
130
|
+
opsent?: boolean;
|
|
134
131
|
storageId?: string;
|
|
135
|
-
handleP: Deferred<
|
|
136
|
-
uploadP?: Promise<ICreateBlobResponse>;
|
|
132
|
+
handleP: Deferred<BlobHandle>;
|
|
133
|
+
uploadP?: Promise<ICreateBlobResponse | void>;
|
|
137
134
|
uploadTime?: number;
|
|
138
135
|
minTTLInSeconds?: number;
|
|
136
|
+
attached?: boolean;
|
|
137
|
+
acked?: boolean;
|
|
138
|
+
abortSignal?: AbortSignal;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
export interface IPendingBlobs {
|
|
142
|
-
[id: string]: {
|
|
142
|
+
[id: string]: {
|
|
143
|
+
blob: string;
|
|
144
|
+
storageId?: string;
|
|
145
|
+
uploadTime?: number;
|
|
146
|
+
minTTLInSeconds?: number;
|
|
147
|
+
attached?: boolean;
|
|
148
|
+
acked?: boolean;
|
|
149
|
+
};
|
|
143
150
|
}
|
|
144
151
|
|
|
145
152
|
export interface IBlobManagerEvents {
|
|
@@ -161,9 +168,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
161
168
|
private readonly redirectTable: Map<string, string | undefined>;
|
|
162
169
|
|
|
163
170
|
/**
|
|
164
|
-
* Blobs which
|
|
165
|
-
* Until we see the op round-trip, there is a possibility we may need to re-upload the blob, so
|
|
166
|
-
* 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.
|
|
167
172
|
*/
|
|
168
173
|
private readonly pendingBlobs: Map<string, PendingBlob> = new Map();
|
|
169
174
|
|
|
@@ -219,50 +224,65 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
219
224
|
private readonly closeContainer: (error?: ICriticalContainerError) => void,
|
|
220
225
|
) {
|
|
221
226
|
super();
|
|
222
|
-
this.mc =
|
|
227
|
+
this.mc = createChildMonitoringContext({
|
|
228
|
+
logger: this.runtime.logger,
|
|
229
|
+
namespace: "BlobManager",
|
|
230
|
+
});
|
|
223
231
|
// Read the feature flag that tells whether to throw when a tombstone blob is requested.
|
|
224
232
|
this.throwOnTombstoneLoad =
|
|
225
233
|
this.mc.config.getBoolean(throwOnTombstoneLoadKey) === true &&
|
|
226
234
|
this.runtime.gcTombstoneEnforcementAllowed &&
|
|
227
235
|
this.runtime.clientDetails.type !== summarizerClientType;
|
|
228
236
|
|
|
229
|
-
this.runtime.on("disconnected", () => this.onDisconnected());
|
|
230
237
|
this.redirectTable = this.load(snapshot);
|
|
231
238
|
|
|
232
239
|
// Begin uploading stashed blobs from previous container instance
|
|
233
240
|
Object.entries(stashedBlobs).forEach(([localId, entry]) => {
|
|
234
241
|
const blob = stringToBuffer(entry.blob, "base64");
|
|
242
|
+
const attached = entry.attached;
|
|
243
|
+
const acked = entry.acked;
|
|
244
|
+
const storageId = entry.storageId; // entry.storageId = response.id
|
|
235
245
|
if (entry.minTTLInSeconds && entry.uploadTime) {
|
|
236
246
|
const timeLapseSinceLocalUpload = (Date.now() - entry.uploadTime) / 1000;
|
|
237
247
|
// stashed entries with more than half-life in storage will not be reuploaded
|
|
238
248
|
if (entry.minTTLInSeconds - timeLapseSinceLocalUpload > entry.minTTLInSeconds / 2) {
|
|
239
249
|
this.pendingBlobs.set(localId, {
|
|
240
250
|
blob,
|
|
241
|
-
|
|
251
|
+
uploading: false,
|
|
252
|
+
opsent: true,
|
|
242
253
|
handleP: new Deferred(),
|
|
254
|
+
storageId,
|
|
243
255
|
uploadP: undefined,
|
|
244
256
|
uploadTime: entry.uploadTime,
|
|
245
257
|
minTTLInSeconds: entry.minTTLInSeconds,
|
|
258
|
+
attached,
|
|
259
|
+
acked,
|
|
246
260
|
});
|
|
247
261
|
return;
|
|
248
262
|
}
|
|
249
263
|
}
|
|
250
264
|
this.pendingBlobs.set(localId, {
|
|
251
265
|
blob,
|
|
252
|
-
|
|
266
|
+
uploading: true,
|
|
253
267
|
handleP: new Deferred(),
|
|
254
268
|
uploadP: this.uploadBlob(localId, blob),
|
|
269
|
+
attached,
|
|
270
|
+
acked,
|
|
271
|
+
opsent: true,
|
|
255
272
|
});
|
|
256
273
|
});
|
|
257
274
|
|
|
258
275
|
this.sendBlobAttachOp = (localId: string, blobId?: string) => {
|
|
259
276
|
const pendingEntry = this.pendingBlobs.get(localId);
|
|
277
|
+
assert(
|
|
278
|
+
pendingEntry !== undefined,
|
|
279
|
+
0x725 /* Must have pending blob entry for upcoming op */,
|
|
280
|
+
);
|
|
260
281
|
if (pendingEntry?.uploadTime && pendingEntry?.minTTLInSeconds) {
|
|
261
282
|
const secondsSinceUpload = (Date.now() - pendingEntry.uploadTime) / 1000;
|
|
262
283
|
const expired = pendingEntry.minTTLInSeconds - secondsSinceUpload < 0;
|
|
263
284
|
this.mc.logger.sendTelemetryEvent({
|
|
264
285
|
eventName: "sendBlobAttach",
|
|
265
|
-
entryStatus: pendingEntry.status,
|
|
266
286
|
secondsSinceUpload,
|
|
267
287
|
minTTLInSeconds: pendingEntry.minTTLInSeconds,
|
|
268
288
|
expired,
|
|
@@ -276,25 +296,24 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
276
296
|
{
|
|
277
297
|
localId,
|
|
278
298
|
blobId,
|
|
279
|
-
entryStatus: pendingEntry.status,
|
|
280
299
|
secondsSinceUpload,
|
|
281
300
|
},
|
|
282
301
|
),
|
|
283
302
|
);
|
|
284
303
|
}
|
|
285
304
|
}
|
|
305
|
+
pendingEntry.opsent = true;
|
|
286
306
|
return sendBlobAttachOp(localId, blobId);
|
|
287
307
|
};
|
|
288
308
|
}
|
|
289
309
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
(
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
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;
|
|
298
317
|
}
|
|
299
318
|
|
|
300
319
|
public get hasPendingBlobs(): boolean {
|
|
@@ -304,16 +323,24 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
304
323
|
);
|
|
305
324
|
}
|
|
306
325
|
|
|
326
|
+
private createAbortError(pending?: PendingBlob) {
|
|
327
|
+
return new LoggingError("uploadBlob aborted", {
|
|
328
|
+
acked: pending?.acked,
|
|
329
|
+
uploadTime: pending?.uploadTime,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
307
332
|
/**
|
|
308
333
|
* Upload blobs added while offline. This must be completed before connecting and resubmitting ops.
|
|
309
334
|
*/
|
|
310
|
-
public async
|
|
335
|
+
public async processStashedChanges() {
|
|
311
336
|
this.retryThrottler.cancel();
|
|
312
|
-
const pendingUploads = this.
|
|
337
|
+
const pendingUploads = Array.from(this.pendingBlobs.values())
|
|
338
|
+
.filter((e) => e.uploading === true)
|
|
339
|
+
.map(async (e) => e.uploadP);
|
|
313
340
|
await PerformanceEvent.timedExecAsync(
|
|
314
341
|
this.mc.logger,
|
|
315
342
|
{
|
|
316
|
-
eventName: "
|
|
343
|
+
eventName: "BlobUploadProcessStashedChanges",
|
|
317
344
|
count: pendingUploads.length,
|
|
318
345
|
},
|
|
319
346
|
async () => Promise.all(pendingUploads),
|
|
@@ -321,20 +348,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
321
348
|
);
|
|
322
349
|
}
|
|
323
350
|
|
|
324
|
-
/**
|
|
325
|
-
* Transition online blobs waiting for BlobAttach op round-trip since we will not see the op until we are connected
|
|
326
|
-
* again
|
|
327
|
-
*/
|
|
328
|
-
private onDisconnected() {
|
|
329
|
-
for (const [localId, entry] of this.pendingBlobs) {
|
|
330
|
-
if (entry.status === PendingBlobStatus.OnlinePendingOp) {
|
|
331
|
-
// This will submit another BlobAttach op for this blob. This is necessary because the one we sent
|
|
332
|
-
// already didn't have the local ID.
|
|
333
|
-
this.transitionToOffline(localId);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
351
|
/**
|
|
339
352
|
* Set of actual storage IDs (i.e., IDs that can be requested from storage). This will be empty if the container is
|
|
340
353
|
* detached or there are no (non-pending) attachment blobs in the document
|
|
@@ -391,13 +404,24 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
391
404
|
);
|
|
392
405
|
}
|
|
393
406
|
|
|
394
|
-
private getBlobHandle(id: string):
|
|
407
|
+
private getBlobHandle(id: string): BlobHandle {
|
|
395
408
|
assert(
|
|
396
409
|
this.redirectTable.has(id) || this.pendingBlobs.has(id),
|
|
397
410
|
0x384 /* requesting handle for unknown blob */,
|
|
398
411
|
);
|
|
399
|
-
|
|
400
|
-
|
|
412
|
+
const pending = this.pendingBlobs.get(id);
|
|
413
|
+
const callback = pending
|
|
414
|
+
? () => {
|
|
415
|
+
pending.attached = true;
|
|
416
|
+
this.emit("blobAttached", pending);
|
|
417
|
+
this.deletePendingBlobMaybe(id);
|
|
418
|
+
}
|
|
419
|
+
: undefined;
|
|
420
|
+
return new BlobHandle(
|
|
421
|
+
`${BlobManager.basePath}/${id}`,
|
|
422
|
+
this.routeContext,
|
|
423
|
+
async () => this.getBlob(id),
|
|
424
|
+
callback,
|
|
401
425
|
);
|
|
402
426
|
}
|
|
403
427
|
|
|
@@ -411,7 +435,10 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
411
435
|
return this.getBlobHandle(response.id);
|
|
412
436
|
}
|
|
413
437
|
|
|
414
|
-
public async createBlob(
|
|
438
|
+
public async createBlob(
|
|
439
|
+
blob: ArrayBufferLike,
|
|
440
|
+
signal?: AbortSignal,
|
|
441
|
+
): Promise<IFluidHandle<ArrayBufferLike>> {
|
|
415
442
|
if (this.runtime.attachState === AttachState.Detached) {
|
|
416
443
|
return this.createBlobDetached(blob);
|
|
417
444
|
}
|
|
@@ -425,21 +452,41 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
425
452
|
0x385 /* For clarity and paranoid defense against adding future attachment states */,
|
|
426
453
|
);
|
|
427
454
|
|
|
455
|
+
if (signal?.aborted) {
|
|
456
|
+
throw this.createAbortError();
|
|
457
|
+
}
|
|
458
|
+
|
|
428
459
|
// Create a local ID for the blob. After uploading it to storage and before returning it, a local ID to
|
|
429
460
|
// storage ID mapping is created.
|
|
430
461
|
const localId = uuid();
|
|
431
462
|
const pendingEntry: PendingBlob = {
|
|
432
463
|
blob,
|
|
433
|
-
|
|
464
|
+
uploading: true,
|
|
434
465
|
handleP: new Deferred(),
|
|
435
466
|
uploadP: this.uploadBlob(localId, blob),
|
|
467
|
+
attached: false,
|
|
468
|
+
acked: false,
|
|
469
|
+
abortSignal: signal,
|
|
470
|
+
opsent: false,
|
|
436
471
|
};
|
|
437
472
|
this.pendingBlobs.set(localId, pendingEntry);
|
|
438
473
|
|
|
439
|
-
|
|
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
|
+
});
|
|
440
484
|
}
|
|
441
485
|
|
|
442
|
-
private async uploadBlob(
|
|
486
|
+
private async uploadBlob(
|
|
487
|
+
localId: string,
|
|
488
|
+
blob: ArrayBufferLike,
|
|
489
|
+
): Promise<ICreateBlobResponse | void> {
|
|
443
490
|
return PerformanceEvent.timedExecAsync(
|
|
444
491
|
this.mc.logger,
|
|
445
492
|
{ eventName: "createBlob" },
|
|
@@ -459,73 +506,71 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
459
506
|
this.redirectTable.set(fromId, toId);
|
|
460
507
|
}
|
|
461
508
|
|
|
462
|
-
private
|
|
509
|
+
private deletePendingBlobMaybe(id: string) {
|
|
463
510
|
if (this.pendingBlobs.has(id)) {
|
|
464
|
-
this.pendingBlobs.
|
|
465
|
-
if (
|
|
466
|
-
this.
|
|
511
|
+
const entry = this.pendingBlobs.get(id);
|
|
512
|
+
if (entry?.attached && entry?.acked) {
|
|
513
|
+
this.deletePendingBlob(id);
|
|
467
514
|
}
|
|
468
515
|
}
|
|
469
516
|
}
|
|
470
517
|
|
|
518
|
+
private deletePendingBlob(id: string) {
|
|
519
|
+
if (this.pendingBlobs.delete(id) && !this.hasPendingBlobs) {
|
|
520
|
+
this.emit("noPendingBlobs");
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
471
524
|
private onUploadResolve(localId: string, response: ICreateBlobResponseWithTTL) {
|
|
472
525
|
const entry = this.pendingBlobs.get(localId);
|
|
473
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
|
+
}
|
|
474
531
|
assert(
|
|
475
|
-
entry.
|
|
476
|
-
entry.status === PendingBlobStatus.OfflinePendingUpload,
|
|
532
|
+
entry.uploading === true,
|
|
477
533
|
0x386 /* Must have pending blob entry for uploaded blob */,
|
|
478
534
|
);
|
|
479
535
|
entry.storageId = response.id;
|
|
480
536
|
entry.uploadTime = Date.now();
|
|
481
537
|
entry.minTTLInSeconds = response.minTTLInSeconds;
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
} else {
|
|
498
|
-
// If there is already an op for this storage ID, append the local ID to the list. Once any op for
|
|
499
|
-
// this storage ID is ack'd, all pending blobs for it can be resolved since the op will keep the
|
|
500
|
-
// blob alive in storage.
|
|
501
|
-
this.opsInFlight.set(
|
|
502
|
-
response.id,
|
|
503
|
-
(this.opsInFlight.get(response.id) ?? []).concat(localId),
|
|
504
|
-
);
|
|
505
|
-
entry.status = PendingBlobStatus.OnlinePendingOp;
|
|
506
|
-
}
|
|
507
|
-
} else if (entry.status === PendingBlobStatus.OfflinePendingUpload) {
|
|
508
|
-
// We already submitted a BlobAttach op for this blob when it was transitioned to offline flow
|
|
509
|
-
entry.status = PendingBlobStatus.OfflinePendingOp;
|
|
510
|
-
}
|
|
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);
|
|
511
553
|
} else {
|
|
512
|
-
//
|
|
513
|
-
this
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
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
|
+
);
|
|
518
561
|
}
|
|
562
|
+
|
|
519
563
|
return response;
|
|
520
564
|
}
|
|
521
565
|
|
|
522
|
-
private async onUploadReject(localId: string, error) {
|
|
566
|
+
private async onUploadReject(localId: string, error: any) {
|
|
523
567
|
const entry = this.pendingBlobs.get(localId);
|
|
524
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
|
+
}
|
|
525
573
|
if (!this.runtime.connected) {
|
|
526
|
-
if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
|
|
527
|
-
this.transitionToOffline(localId);
|
|
528
|
-
}
|
|
529
574
|
// we are probably not connected to storage but start another upload request in case we are
|
|
530
575
|
entry.uploadP = this.retryThrottler
|
|
531
576
|
.getDelay()
|
|
@@ -537,39 +582,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
537
582
|
}
|
|
538
583
|
}
|
|
539
584
|
|
|
540
|
-
private transitionToOffline(localId: string) {
|
|
541
|
-
assert(
|
|
542
|
-
!this.runtime.connected,
|
|
543
|
-
0x388 /* Must only transition to offline flow while runtime is disconnected */,
|
|
544
|
-
);
|
|
545
|
-
const entry = this.pendingBlobs.get(localId);
|
|
546
|
-
assert(!!entry, 0x389 /* No pending blob entry */);
|
|
547
|
-
assert(
|
|
548
|
-
[PendingBlobStatus.OnlinePendingUpload, PendingBlobStatus.OnlinePendingOp].includes(
|
|
549
|
-
entry.status,
|
|
550
|
-
),
|
|
551
|
-
0x38a /* Blob must be in online flow to transition to offline flow */,
|
|
552
|
-
);
|
|
553
|
-
|
|
554
|
-
/**
|
|
555
|
-
* If we haven't already submitted a BlobAttach op for this entry, send it before returning the blob handle.
|
|
556
|
-
* This will make sure that the BlobAttach op is sequenced prior to any ops referencing the handle. Otherwise,
|
|
557
|
-
* an invalid handle could be added to the document.
|
|
558
|
-
* storageId may be undefined but since we are not connected we will have a chance to add it when reSubmit()
|
|
559
|
-
* is called on reconnection.
|
|
560
|
-
*/
|
|
561
|
-
if (entry.status !== PendingBlobStatus.OnlinePendingOp) {
|
|
562
|
-
this.sendBlobAttachOp(localId, entry.storageId);
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
entry.status =
|
|
566
|
-
entry.status === PendingBlobStatus.OnlinePendingUpload
|
|
567
|
-
? PendingBlobStatus.OfflinePendingUpload
|
|
568
|
-
: PendingBlobStatus.OfflinePendingOp;
|
|
569
|
-
|
|
570
|
-
entry.handleP.resolve(this.getBlobHandle(localId));
|
|
571
|
-
}
|
|
572
|
-
|
|
573
585
|
/**
|
|
574
586
|
* Resubmit a BlobAttach op. Used to add storage IDs to ops that were
|
|
575
587
|
* submitted to runtime while disconnected.
|
|
@@ -584,18 +596,25 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
584
596
|
if (!blobId) {
|
|
585
597
|
// We submitted this op while offline. The blob should have been uploaded by now.
|
|
586
598
|
assert(
|
|
587
|
-
pendingEntry?.
|
|
588
|
-
!!pendingEntry?.storageId,
|
|
599
|
+
pendingEntry?.opsent === true && !!pendingEntry?.storageId,
|
|
589
600
|
0x38d /* blob must be uploaded before resubmitting BlobAttach op */,
|
|
590
601
|
);
|
|
591
|
-
return this.sendBlobAttachOp(localId, pendingEntry
|
|
602
|
+
return this.sendBlobAttachOp(localId, pendingEntry?.storageId);
|
|
592
603
|
}
|
|
593
604
|
return this.sendBlobAttachOp(localId, blobId);
|
|
594
605
|
}
|
|
595
606
|
|
|
596
607
|
public processBlobAttachOp(message: ISequencedDocumentMessage, local: boolean) {
|
|
597
|
-
const localId = message.metadata?.localId;
|
|
598
|
-
const blobId = message.metadata?.blobId;
|
|
608
|
+
const localId = (message.metadata as IBlobMetadata | undefined)?.localId;
|
|
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
|
+
}
|
|
599
618
|
assert(blobId !== undefined, 0x12a /* "Missing blob id on metadata" */);
|
|
600
619
|
|
|
601
620
|
// Set up a mapping from local ID to storage ID. This is crucial since without this the blob cannot be
|
|
@@ -616,23 +635,24 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
616
635
|
// This is safe because the server will keep the blob alive and the op containing the local ID to
|
|
617
636
|
// storage ID is already in flight and any op containing this local ID will be sequenced after that.
|
|
618
637
|
waitingBlobs.forEach((pendingLocalId) => {
|
|
619
|
-
const
|
|
638
|
+
const entry = this.pendingBlobs.get(pendingLocalId);
|
|
620
639
|
assert(
|
|
621
|
-
|
|
640
|
+
entry !== undefined,
|
|
622
641
|
0x38f /* local online BlobAttach op with no pending blob entry */,
|
|
623
642
|
);
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
pendingBlobEntry.handleP.resolve(this.getBlobHandle(pendingLocalId));
|
|
629
|
-
this.deleteAndEmitsIfEmpty(pendingLocalId);
|
|
630
|
-
}
|
|
643
|
+
this.setRedirection(pendingLocalId, blobId);
|
|
644
|
+
entry.acked = true;
|
|
645
|
+
entry.handleP.resolve(this.getBlobHandle(pendingLocalId));
|
|
646
|
+
this.deletePendingBlobMaybe(pendingLocalId);
|
|
631
647
|
});
|
|
632
648
|
this.opsInFlight.delete(blobId);
|
|
633
649
|
}
|
|
634
|
-
|
|
635
|
-
|
|
650
|
+
const localEntry = this.pendingBlobs.get(localId);
|
|
651
|
+
if (localEntry) {
|
|
652
|
+
localEntry.acked = true;
|
|
653
|
+
localEntry.handleP.resolve(this.getBlobHandle(localId));
|
|
654
|
+
this.deletePendingBlobMaybe(localId);
|
|
655
|
+
}
|
|
636
656
|
}
|
|
637
657
|
}
|
|
638
658
|
|
|
@@ -739,11 +759,11 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
739
759
|
* Delete attachment blobs that are sweep ready.
|
|
740
760
|
* @param sweepReadyBlobRoutes - The routes of blobs that are sweep ready and should be deleted. These routes will
|
|
741
761
|
* be based off of local ids.
|
|
742
|
-
* @returns
|
|
762
|
+
* @returns The routes of blobs that were deleted.
|
|
743
763
|
*/
|
|
744
764
|
public deleteSweepReadyNodes(sweepReadyBlobRoutes: string[]): string[] {
|
|
745
765
|
// If sweep for attachment blobs is not enabled, return empty list indicating nothing is deleted.
|
|
746
|
-
if (this.mc.config.getBoolean(
|
|
766
|
+
if (this.mc.config.getBoolean(disableAttachmentBlobSweepKey) === true) {
|
|
747
767
|
return [];
|
|
748
768
|
}
|
|
749
769
|
|
|
@@ -902,18 +922,61 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
902
922
|
}
|
|
903
923
|
}
|
|
904
924
|
|
|
905
|
-
public getPendingBlobs(): IPendingBlobs {
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
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] = {
|
|
910
969
|
blob: bufferToString(entry.blob, "base64"),
|
|
911
|
-
|
|
970
|
+
storageId: entry.storageId,
|
|
971
|
+
attached: entry.attached,
|
|
972
|
+
acked: entry.acked,
|
|
912
973
|
minTTLInSeconds: entry.minTTLInSeconds,
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
974
|
+
uploadTime: entry.uploadTime,
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
return blobs;
|
|
978
|
+
},
|
|
979
|
+
);
|
|
917
980
|
}
|
|
918
981
|
}
|
|
919
982
|
|