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