@fluidframework/container-runtime 2.0.0-dev.3.1.0.125672 → 2.0.0-dev.4.2.0.153917
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 +58 -0
- package/README.md +69 -0
- package/dist/blobManager.d.ts +29 -24
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +162 -92
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +74 -76
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +328 -264
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +39 -13
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +112 -49
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +28 -4
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +107 -41
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts +19 -0
- package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -0
- package/dist/deltaManagerSummarizerProxy.js +40 -0
- package/dist/deltaManagerSummarizerProxy.js.map +1 -0
- package/dist/gc/garbageCollection.d.ts +204 -0
- package/dist/gc/garbageCollection.d.ts.map +1 -0
- package/dist/{garbageCollection.js → gc/garbageCollection.js} +190 -554
- package/dist/gc/garbageCollection.js.map +1 -0
- package/dist/gc/gcConfigs.d.ts +22 -0
- package/dist/gc/gcConfigs.d.ts.map +1 -0
- package/dist/gc/gcConfigs.js +143 -0
- package/dist/gc/gcConfigs.js.map +1 -0
- package/dist/gc/gcDefinitions.d.ts +320 -0
- package/dist/gc/gcDefinitions.d.ts.map +1 -0
- package/dist/gc/gcDefinitions.js +81 -0
- package/dist/gc/gcDefinitions.js.map +1 -0
- package/dist/gc/gcHelpers.d.ts +86 -0
- package/dist/gc/gcHelpers.d.ts.map +1 -0
- package/dist/gc/gcHelpers.js +268 -0
- package/dist/gc/gcHelpers.js.map +1 -0
- package/dist/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
- package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
- package/dist/gc/gcReferenceGraphAlgorithm.js +49 -0
- package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -0
- package/dist/gc/gcSummaryDefinitions.d.ts +52 -0
- package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -0
- package/dist/gc/gcSummaryDefinitions.js +7 -0
- package/dist/gc/gcSummaryDefinitions.js.map +1 -0
- package/dist/gc/gcSummaryStateTracker.d.ts +93 -0
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
- package/dist/gc/gcSummaryStateTracker.js +239 -0
- package/dist/gc/gcSummaryStateTracker.js.map +1 -0
- package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
- package/dist/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +2 -2
- package/dist/gc/gcSweepReadyUsageDetection.js.map +1 -0
- package/dist/gc/gcUnreferencedStateTracker.d.ts +34 -0
- package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
- package/dist/gc/gcUnreferencedStateTracker.js +94 -0
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -0
- package/dist/gc/index.d.ts +13 -0
- package/dist/gc/index.d.ts.map +1 -0
- package/dist/gc/index.js +50 -0
- package/dist/gc/index.js.map +1 -0
- package/dist/index.d.ts +3 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -9
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +11 -13
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +26 -38
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +4 -0
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +2 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +4 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +25 -10
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +4 -0
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +43 -4
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +14 -0
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -0
- package/dist/opLifecycle/opGroupingManager.js +56 -0
- package/dist/opLifecycle/opGroupingManager.js.map +1 -0
- package/dist/opLifecycle/opSplitter.d.ts +16 -4
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +39 -15
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +21 -3
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +90 -51
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +4 -2
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +30 -20
- package/dist/opLifecycle/remoteMessageProcessor.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 +3 -3
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +20 -21
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/storageServiceWithAttachBlobs.d.ts +17 -0
- package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -0
- package/dist/storageServiceWithAttachBlobs.js +32 -0
- package/dist/storageServiceWithAttachBlobs.js.map +1 -0
- package/dist/summary/index.d.ts +17 -0
- package/dist/summary/index.d.ts.map +1 -0
- package/dist/summary/index.js +48 -0
- package/dist/summary/index.js.map +1 -0
- package/dist/summary/orderedClientElection.d.ts.map +1 -0
- package/dist/summary/orderedClientElection.js.map +1 -0
- package/dist/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +3 -2
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
- package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +5 -4
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -0
- package/{lib → dist/summary}/runningSummarizer.d.ts +23 -20
- package/dist/summary/runningSummarizer.d.ts.map +1 -0
- package/dist/{runningSummarizer.js → summary/runningSummarizer.js} +191 -74
- package/dist/summary/runningSummarizer.js.map +1 -0
- package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +4 -9
- package/dist/summary/summarizer.d.ts.map +1 -0
- package/dist/{summarizer.js → summary/summarizer.js} +10 -79
- package/dist/summary/summarizer.js.map +1 -0
- package/dist/summary/summarizerClientElection.d.ts.map +1 -0
- package/dist/summary/summarizerClientElection.js.map +1 -0
- package/dist/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +2 -1
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
- package/dist/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -3
- package/dist/summary/summarizerHeuristics.js.map +1 -0
- package/dist/summary/summarizerNode/index.d.ts +8 -0
- package/dist/summary/summarizerNode/index.d.ts.map +1 -0
- package/dist/summary/summarizerNode/index.js +12 -0
- package/dist/summary/summarizerNode/index.js.map +1 -0
- package/dist/summary/summarizerNode/summarizerNode.d.ts +149 -0
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
- package/dist/summary/summarizerNode/summarizerNode.js +531 -0
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +125 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.js +132 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +148 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +424 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
- package/{lib → dist/summary}/summarizerTypes.d.ts +21 -19
- package/dist/summary/summarizerTypes.d.ts.map +1 -0
- package/dist/{summarizerTypes.js → summary/summarizerTypes.js} +0 -5
- package/dist/summary/summarizerTypes.js.map +1 -0
- package/dist/summary/summaryCollection.d.ts.map +1 -0
- package/dist/summary/summaryCollection.js.map +1 -0
- package/{lib → dist/summary}/summaryFormat.d.ts +3 -21
- package/dist/summary/summaryFormat.d.ts.map +1 -0
- package/dist/{summaryFormat.js → summary/summaryFormat.js} +1 -10
- package/dist/summary/summaryFormat.js.map +1 -0
- package/{lib → dist/summary}/summaryGenerator.d.ts +28 -2
- package/dist/summary/summaryGenerator.d.ts.map +1 -0
- package/dist/{summaryGenerator.js → summary/summaryGenerator.js} +23 -20
- package/dist/summary/summaryGenerator.js.map +1 -0
- package/dist/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
- package/dist/summary/summaryManager.d.ts.map +1 -0
- package/dist/summary/summaryManager.js.map +1 -0
- package/lib/blobManager.d.ts +29 -24
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +159 -89
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +74 -76
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +301 -237
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +39 -13
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +101 -38
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +28 -4
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +100 -34
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaManagerSummarizerProxy.d.ts +19 -0
- package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -0
- package/lib/deltaManagerSummarizerProxy.js +36 -0
- package/lib/deltaManagerSummarizerProxy.js.map +1 -0
- package/lib/gc/garbageCollection.d.ts +204 -0
- package/lib/gc/garbageCollection.d.ts.map +1 -0
- package/lib/{garbageCollection.js → gc/garbageCollection.js} +172 -535
- package/lib/gc/garbageCollection.js.map +1 -0
- package/lib/gc/gcConfigs.d.ts +22 -0
- package/lib/gc/gcConfigs.d.ts.map +1 -0
- package/lib/gc/gcConfigs.js +139 -0
- package/lib/gc/gcConfigs.js.map +1 -0
- package/lib/gc/gcDefinitions.d.ts +320 -0
- package/lib/gc/gcDefinitions.d.ts.map +1 -0
- package/lib/gc/gcDefinitions.js +78 -0
- package/lib/gc/gcDefinitions.js.map +1 -0
- package/lib/gc/gcHelpers.d.ts +86 -0
- package/lib/gc/gcHelpers.d.ts.map +1 -0
- package/lib/gc/gcHelpers.js +254 -0
- package/lib/gc/gcHelpers.js.map +1 -0
- package/lib/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
- package/lib/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
- package/lib/gc/gcReferenceGraphAlgorithm.js +45 -0
- package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -0
- package/lib/gc/gcSummaryDefinitions.d.ts +52 -0
- package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -0
- package/lib/gc/gcSummaryDefinitions.js +6 -0
- package/lib/gc/gcSummaryDefinitions.js.map +1 -0
- package/lib/gc/gcSummaryStateTracker.d.ts +93 -0
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
- package/lib/gc/gcSummaryStateTracker.js +235 -0
- package/lib/gc/gcSummaryStateTracker.js.map +1 -0
- package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
- package/lib/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +1 -1
- package/lib/gc/gcSweepReadyUsageDetection.js.map +1 -0
- package/lib/gc/gcUnreferencedStateTracker.d.ts +34 -0
- package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
- package/lib/gc/gcUnreferencedStateTracker.js +90 -0
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -0
- package/lib/gc/index.d.ts +13 -0
- package/lib/gc/index.d.ts.map +1 -0
- package/lib/gc/index.js +12 -0
- package/lib/gc/index.js.map +1 -0
- package/lib/index.d.ts +3 -7
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -4
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +11 -13
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +24 -37
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +4 -0
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +2 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +2 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +26 -11
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +4 -0
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +43 -4
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +14 -0
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -0
- package/lib/opLifecycle/opGroupingManager.js +52 -0
- package/lib/opLifecycle/opGroupingManager.js.map +1 -0
- package/lib/opLifecycle/opSplitter.d.ts +16 -4
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +39 -15
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +21 -3
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +92 -53
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +4 -2
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +30 -20
- package/lib/opLifecycle/remoteMessageProcessor.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 +3 -3
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +20 -21
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/storageServiceWithAttachBlobs.d.ts +17 -0
- package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -0
- package/lib/storageServiceWithAttachBlobs.js +28 -0
- package/lib/storageServiceWithAttachBlobs.js.map +1 -0
- package/lib/summary/index.d.ts +17 -0
- package/lib/summary/index.d.ts.map +1 -0
- package/lib/summary/index.js +16 -0
- package/lib/summary/index.js.map +1 -0
- package/lib/summary/orderedClientElection.d.ts.map +1 -0
- package/lib/summary/orderedClientElection.js.map +1 -0
- package/lib/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +3 -2
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
- package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +5 -4
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
- package/{dist → lib/summary}/runningSummarizer.d.ts +23 -20
- package/lib/summary/runningSummarizer.d.ts.map +1 -0
- package/lib/{runningSummarizer.js → summary/runningSummarizer.js} +192 -75
- package/lib/summary/runningSummarizer.js.map +1 -0
- package/lib/{summarizer.d.ts → summary/summarizer.d.ts} +4 -9
- package/lib/summary/summarizer.d.ts.map +1 -0
- package/lib/{summarizer.js → summary/summarizer.js} +12 -81
- package/lib/summary/summarizer.js.map +1 -0
- package/lib/summary/summarizerClientElection.d.ts.map +1 -0
- package/lib/summary/summarizerClientElection.js.map +1 -0
- package/lib/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +2 -1
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
- package/lib/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -3
- package/lib/summary/summarizerHeuristics.js.map +1 -0
- package/lib/summary/summarizerNode/index.d.ts +8 -0
- package/lib/summary/summarizerNode/index.d.ts.map +1 -0
- package/lib/summary/summarizerNode/index.js +7 -0
- package/lib/summary/summarizerNode/index.js.map +1 -0
- package/lib/summary/summarizerNode/summarizerNode.d.ts +149 -0
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
- package/lib/summary/summarizerNode/summarizerNode.js +526 -0
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +125 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.js +125 -0
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +148 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +419 -0
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
- package/{dist → lib/summary}/summarizerTypes.d.ts +21 -19
- package/lib/summary/summarizerTypes.d.ts.map +1 -0
- package/lib/summary/summarizerTypes.js +6 -0
- package/lib/summary/summarizerTypes.js.map +1 -0
- package/lib/summary/summaryCollection.d.ts.map +1 -0
- package/lib/summary/summaryCollection.js.map +1 -0
- package/{dist → lib/summary}/summaryFormat.d.ts +3 -21
- package/lib/summary/summaryFormat.d.ts.map +1 -0
- package/lib/{summaryFormat.js → summary/summaryFormat.js} +0 -8
- package/lib/summary/summaryFormat.js.map +1 -0
- package/{dist → lib/summary}/summaryGenerator.d.ts +28 -2
- package/lib/summary/summaryGenerator.d.ts.map +1 -0
- package/lib/{summaryGenerator.js → summary/summaryGenerator.js} +21 -19
- package/lib/summary/summaryGenerator.js.map +1 -0
- package/lib/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
- package/lib/summary/summaryManager.d.ts.map +1 -0
- package/lib/summary/summaryManager.js.map +1 -0
- package/package.json +66 -60
- package/src/blobManager.ts +196 -110
- package/src/containerRuntime.ts +491 -391
- package/src/dataStoreContext.ts +140 -49
- package/src/dataStores.ts +139 -41
- package/src/deltaManagerSummarizerProxy.ts +46 -0
- package/{garbageCollection.md → src/gc/garbageCollection.md} +2 -2
- package/src/{garbageCollection.ts → gc/garbageCollection.ts} +245 -890
- package/src/gc/gcConfigs.ts +193 -0
- package/src/gc/gcDefinitions.ts +387 -0
- package/src/gc/gcHelpers.ts +335 -0
- package/src/gc/gcReferenceGraphAlgorithm.ts +52 -0
- package/src/gc/gcSummaryDefinitions.ts +54 -0
- package/src/gc/gcSummaryStateTracker.ts +329 -0
- package/src/{gcSweepReadyUsageDetection.ts → gc/gcSweepReadyUsageDetection.ts} +1 -1
- package/src/gc/gcUnreferencedStateTracker.ts +114 -0
- package/src/gc/index.ts +65 -0
- package/src/index.ts +10 -22
- package/src/opLifecycle/README.md +263 -0
- package/src/opLifecycle/batchManager.ts +26 -55
- package/src/opLifecycle/definitions.ts +4 -0
- package/src/opLifecycle/index.ts +2 -1
- package/src/opLifecycle/opCompressor.ts +32 -12
- package/src/opLifecycle/opDecompressor.ts +50 -5
- package/src/opLifecycle/opGroupingManager.ts +78 -0
- package/src/opLifecycle/opSplitter.ts +56 -17
- package/src/opLifecycle/outbox.ts +126 -62
- package/src/opLifecycle/remoteMessageProcessor.ts +38 -22
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +34 -27
- package/src/storageServiceWithAttachBlobs.ts +38 -0
- package/src/summary/index.ts +105 -0
- package/src/{runWhileConnectedCoordinator.ts → summary/runWhileConnectedCoordinator.ts} +7 -7
- package/src/{runningSummarizer.ts → summary/runningSummarizer.ts} +318 -156
- package/src/{summarizer.ts → summary/summarizer.ts} +12 -105
- package/src/{summarizerHeuristics.ts → summary/summarizerHeuristics.ts} +13 -4
- package/src/summary/summarizerNode/index.ts +12 -0
- package/src/summary/summarizerNode/summarizerNode.ts +766 -0
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +214 -0
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +644 -0
- package/src/{summarizerTypes.ts → summary/summarizerTypes.ts} +28 -25
- package/src/{summaryFormat.ts → summary/summaryFormat.ts} +3 -29
- package/src/{summaryGenerator.ts → summary/summaryGenerator.ts} +34 -27
- package/src/{summaryManager.ts → summary/summaryManager.ts} +1 -1
- package/dist/garbageCollection.d.ts +0 -411
- package/dist/garbageCollection.d.ts.map +0 -1
- package/dist/garbageCollection.js.map +0 -1
- package/dist/garbageCollectionConstants.d.ts +0 -23
- package/dist/garbageCollectionConstants.d.ts.map +0 -1
- package/dist/garbageCollectionConstants.js +0 -36
- package/dist/garbageCollectionConstants.js.map +0 -1
- package/dist/garbageCollectionHelpers.d.ts +0 -15
- package/dist/garbageCollectionHelpers.d.ts.map +0 -1
- package/dist/garbageCollectionHelpers.js +0 -27
- package/dist/garbageCollectionHelpers.js.map +0 -1
- package/dist/gcSweepReadyUsageDetection.d.ts.map +0 -1
- package/dist/gcSweepReadyUsageDetection.js.map +0 -1
- package/dist/orderedClientElection.d.ts.map +0 -1
- package/dist/orderedClientElection.js.map +0 -1
- package/dist/runWhileConnectedCoordinator.d.ts.map +0 -1
- package/dist/runWhileConnectedCoordinator.js.map +0 -1
- package/dist/runningSummarizer.d.ts.map +0 -1
- package/dist/runningSummarizer.js.map +0 -1
- package/dist/serializedSnapshotStorage.d.ts +0 -58
- package/dist/serializedSnapshotStorage.d.ts.map +0 -1
- package/dist/serializedSnapshotStorage.js +0 -110
- package/dist/serializedSnapshotStorage.js.map +0 -1
- package/dist/summarizer.d.ts.map +0 -1
- package/dist/summarizer.js.map +0 -1
- package/dist/summarizerClientElection.d.ts.map +0 -1
- package/dist/summarizerClientElection.js.map +0 -1
- package/dist/summarizerHandle.d.ts +0 -12
- package/dist/summarizerHandle.d.ts.map +0 -1
- package/dist/summarizerHandle.js +0 -22
- package/dist/summarizerHandle.js.map +0 -1
- package/dist/summarizerHeuristics.d.ts.map +0 -1
- package/dist/summarizerHeuristics.js.map +0 -1
- package/dist/summarizerTypes.d.ts.map +0 -1
- package/dist/summarizerTypes.js.map +0 -1
- package/dist/summaryCollection.d.ts.map +0 -1
- package/dist/summaryCollection.js.map +0 -1
- package/dist/summaryFormat.d.ts.map +0 -1
- package/dist/summaryFormat.js.map +0 -1
- package/dist/summaryGenerator.d.ts.map +0 -1
- package/dist/summaryGenerator.js.map +0 -1
- package/dist/summaryManager.d.ts.map +0 -1
- package/dist/summaryManager.js.map +0 -1
- package/lib/garbageCollection.d.ts +0 -411
- package/lib/garbageCollection.d.ts.map +0 -1
- package/lib/garbageCollection.js.map +0 -1
- package/lib/garbageCollectionConstants.d.ts +0 -23
- package/lib/garbageCollectionConstants.d.ts.map +0 -1
- package/lib/garbageCollectionConstants.js +0 -33
- package/lib/garbageCollectionConstants.js.map +0 -1
- package/lib/garbageCollectionHelpers.d.ts +0 -15
- package/lib/garbageCollectionHelpers.d.ts.map +0 -1
- package/lib/garbageCollectionHelpers.js +0 -23
- package/lib/garbageCollectionHelpers.js.map +0 -1
- package/lib/gcSweepReadyUsageDetection.d.ts.map +0 -1
- package/lib/gcSweepReadyUsageDetection.js.map +0 -1
- package/lib/orderedClientElection.d.ts.map +0 -1
- package/lib/orderedClientElection.js.map +0 -1
- package/lib/runWhileConnectedCoordinator.d.ts.map +0 -1
- package/lib/runWhileConnectedCoordinator.js.map +0 -1
- package/lib/runningSummarizer.d.ts.map +0 -1
- package/lib/runningSummarizer.js.map +0 -1
- package/lib/serializedSnapshotStorage.d.ts +0 -58
- package/lib/serializedSnapshotStorage.d.ts.map +0 -1
- package/lib/serializedSnapshotStorage.js +0 -106
- package/lib/serializedSnapshotStorage.js.map +0 -1
- package/lib/summarizer.d.ts.map +0 -1
- package/lib/summarizer.js.map +0 -1
- package/lib/summarizerClientElection.d.ts.map +0 -1
- package/lib/summarizerClientElection.js.map +0 -1
- package/lib/summarizerHandle.d.ts +0 -12
- package/lib/summarizerHandle.d.ts.map +0 -1
- package/lib/summarizerHandle.js +0 -18
- package/lib/summarizerHandle.js.map +0 -1
- package/lib/summarizerHeuristics.d.ts.map +0 -1
- package/lib/summarizerHeuristics.js.map +0 -1
- package/lib/summarizerTypes.d.ts.map +0 -1
- package/lib/summarizerTypes.js +0 -9
- package/lib/summarizerTypes.js.map +0 -1
- package/lib/summaryCollection.d.ts.map +0 -1
- package/lib/summaryCollection.js.map +0 -1
- package/lib/summaryFormat.d.ts.map +0 -1
- package/lib/summaryFormat.js.map +0 -1
- package/lib/summaryGenerator.d.ts.map +0 -1
- package/lib/summaryGenerator.js.map +0 -1
- package/lib/summaryManager.d.ts.map +0 -1
- package/lib/summaryManager.js.map +0 -1
- package/src/garbageCollectionConstants.ts +0 -38
- package/src/garbageCollectionHelpers.ts +0 -37
- package/src/serializedSnapshotStorage.ts +0 -151
- package/src/summarizerHandle.ts +0 -23
- /package/dist/{gcSweepReadyUsageDetection.d.ts → gc/gcSweepReadyUsageDetection.d.ts} +0 -0
- /package/dist/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
- /package/dist/{orderedClientElection.js → summary/orderedClientElection.js} +0 -0
- /package/dist/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
- /package/dist/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
- /package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
- /package/dist/{summaryCollection.js → summary/summaryCollection.js} +0 -0
- /package/dist/{summaryManager.js → summary/summaryManager.js} +0 -0
- /package/lib/{gcSweepReadyUsageDetection.d.ts → gc/gcSweepReadyUsageDetection.d.ts} +0 -0
- /package/lib/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
- /package/lib/{orderedClientElection.js → summary/orderedClientElection.js} +0 -0
- /package/lib/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
- /package/lib/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
- /package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
- /package/lib/{summaryCollection.js → summary/summaryCollection.js} +0 -0
- /package/lib/{summaryManager.js → summary/summaryManager.js} +0 -0
- /package/src/{orderedClientElection.ts → summary/orderedClientElection.ts} +0 -0
- /package/src/{summarizerClientElection.ts → summary/summarizerClientElection.ts} +0 -0
- /package/src/{summaryCollection.ts → summary/summaryCollection.ts} +0 -0
package/dist/containerRuntime.js
CHANGED
|
@@ -10,29 +10,22 @@ const container_utils_1 = require("@fluidframework/container-utils");
|
|
|
10
10
|
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
|
|
11
11
|
const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
|
|
12
12
|
const runtime_utils_1 = require("@fluidframework/runtime-utils");
|
|
13
|
-
const garbage_collector_1 = require("@fluidframework/garbage-collector");
|
|
14
13
|
const uuid_1 = require("uuid");
|
|
15
14
|
const containerHandleContext_1 = require("./containerHandleContext");
|
|
16
15
|
const dataStoreRegistry_1 = require("./dataStoreRegistry");
|
|
17
|
-
const summarizer_1 = require("./summarizer");
|
|
18
|
-
const summaryManager_1 = require("./summaryManager");
|
|
19
16
|
const connectionTelemetry_1 = require("./connectionTelemetry");
|
|
20
17
|
const pendingStateManager_1 = require("./pendingStateManager");
|
|
21
18
|
const packageVersion_1 = require("./packageVersion");
|
|
22
19
|
const blobManager_1 = require("./blobManager");
|
|
23
20
|
const dataStores_1 = require("./dataStores");
|
|
24
|
-
const
|
|
25
|
-
const summaryCollection_1 = require("./summaryCollection");
|
|
26
|
-
const orderedClientElection_1 = require("./orderedClientElection");
|
|
27
|
-
const summarizerClientElection_1 = require("./summarizerClientElection");
|
|
21
|
+
const summary_1 = require("./summary");
|
|
28
22
|
const throttler_1 = require("./throttler");
|
|
29
|
-
const
|
|
30
|
-
const garbageCollection_1 = require("./garbageCollection");
|
|
23
|
+
const gc_1 = require("./gc");
|
|
31
24
|
const dataStore_1 = require("./dataStore");
|
|
32
25
|
const batchTracker_1 = require("./batchTracker");
|
|
33
|
-
const serializedSnapshotStorage_1 = require("./serializedSnapshotStorage");
|
|
34
26
|
const scheduleManager_1 = require("./scheduleManager");
|
|
35
27
|
const opLifecycle_1 = require("./opLifecycle");
|
|
28
|
+
const deltaManagerSummarizerProxy_1 = require("./deltaManagerSummarizerProxy");
|
|
36
29
|
var ContainerMessageType;
|
|
37
30
|
(function (ContainerMessageType) {
|
|
38
31
|
// An op to be delivered to store
|
|
@@ -55,7 +48,7 @@ exports.DefaultSummaryConfiguration = {
|
|
|
55
48
|
maxTime: 60 * 1000,
|
|
56
49
|
maxOps: 100,
|
|
57
50
|
minOpsForLastSummaryAttempt: 10,
|
|
58
|
-
maxAckWaitTime:
|
|
51
|
+
maxAckWaitTime: 3 * 60 * 1000,
|
|
59
52
|
maxOpsSinceLastSummary: 7000,
|
|
60
53
|
initialSummarizerDelayMs: 5 * 1000,
|
|
61
54
|
nonRuntimeOpWeight: 0.1,
|
|
@@ -69,11 +62,6 @@ var RuntimeHeaders;
|
|
|
69
62
|
(function (RuntimeHeaders) {
|
|
70
63
|
/** True to wait for a data store to be created and loaded before returning it. */
|
|
71
64
|
RuntimeHeaders["wait"] = "wait";
|
|
72
|
-
/**
|
|
73
|
-
* True if the request is from an external app. Used for GC to handle scenarios where a data store
|
|
74
|
-
* is deleted and requested via an external app.
|
|
75
|
-
*/
|
|
76
|
-
RuntimeHeaders["externalRequest"] = "externalRequest";
|
|
77
65
|
/** True if the request is coming from an IFluidHandle. */
|
|
78
66
|
RuntimeHeaders["viaHandle"] = "viaHandle";
|
|
79
67
|
})(RuntimeHeaders = exports.RuntimeHeaders || (exports.RuntimeHeaders = {}));
|
|
@@ -84,7 +72,6 @@ exports.TombstoneResponseHeaderKey = "isTombstoned";
|
|
|
84
72
|
/** Default values for Runtime Headers */
|
|
85
73
|
exports.defaultRuntimeHeaderData = {
|
|
86
74
|
wait: true,
|
|
87
|
-
externalRequest: false,
|
|
88
75
|
viaHandle: false,
|
|
89
76
|
allowTombstone: false,
|
|
90
77
|
};
|
|
@@ -101,7 +88,13 @@ const defaultFlushMode = runtime_definitions_1.FlushMode.TurnBased;
|
|
|
101
88
|
// We can't estimate it fully, as we
|
|
102
89
|
// - do not know what properties relay service will add
|
|
103
90
|
// - we do not stringify final op, thus we do not know how much escaping will be added.
|
|
104
|
-
const defaultMaxBatchSizeInBytes =
|
|
91
|
+
const defaultMaxBatchSizeInBytes = 700 * 1024;
|
|
92
|
+
const defaultCompressionConfig = {
|
|
93
|
+
// Batches with content size exceeding this value will be compressed
|
|
94
|
+
minimumBatchSizeInBytes: 614400,
|
|
95
|
+
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
96
|
+
};
|
|
97
|
+
const defaultChunkSizeInBytes = 204800;
|
|
105
98
|
/**
|
|
106
99
|
* @deprecated - use ContainerRuntimeMessage instead
|
|
107
100
|
*/
|
|
@@ -150,8 +143,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
150
143
|
/**
|
|
151
144
|
* @internal
|
|
152
145
|
*/
|
|
153
|
-
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, requestHandler, summaryConfiguration) {
|
|
154
|
-
var _a, _b, _c, _d, _e, _f;
|
|
146
|
+
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, requestHandler, summaryConfiguration, initializeEntryPoint) {
|
|
147
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
155
148
|
if (summaryConfiguration === void 0) { summaryConfiguration = Object.assign(Object.assign({}, exports.DefaultSummaryConfiguration), (_a = runtimeOptions.summaryOptions) === null || _a === void 0 ? void 0 : _a.summaryConfigOverrides); }
|
|
156
149
|
super();
|
|
157
150
|
this.context = context;
|
|
@@ -164,8 +157,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
164
157
|
this.summaryConfiguration = summaryConfiguration;
|
|
165
158
|
this.defaultMaxConsecutiveReconnects = 7;
|
|
166
159
|
this._orderSequentiallyCalls = 0;
|
|
167
|
-
this.
|
|
168
|
-
this.savedOps = [];
|
|
160
|
+
this.flushTaskExists = false;
|
|
169
161
|
this.consecutiveReconnects = 0;
|
|
170
162
|
this.ensureNoDataModelChangesCalls = 0;
|
|
171
163
|
/**
|
|
@@ -185,7 +177,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
185
177
|
trackingSignalSequenceNumber: undefined,
|
|
186
178
|
};
|
|
187
179
|
this.summarizeOnDemand = (...args) => {
|
|
188
|
-
if (this.clientDetails.type ===
|
|
180
|
+
if (this.clientDetails.type === summary_1.summarizerClientType) {
|
|
189
181
|
return this.summarizer.summarizeOnDemand(...args);
|
|
190
182
|
}
|
|
191
183
|
else if (this.summaryManager !== undefined) {
|
|
@@ -199,7 +191,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
199
191
|
}
|
|
200
192
|
};
|
|
201
193
|
this.enqueueSummarize = (...args) => {
|
|
202
|
-
if (this.clientDetails.type ===
|
|
194
|
+
if (this.clientDetails.type === summary_1.summarizerClientType) {
|
|
203
195
|
return this.summarizer.enqueueSummarize(...args);
|
|
204
196
|
}
|
|
205
197
|
else if (this.summaryManager !== undefined) {
|
|
@@ -212,6 +204,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
212
204
|
throw new container_utils_1.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
|
|
213
205
|
}
|
|
214
206
|
};
|
|
207
|
+
this.innerDeltaManager = context.deltaManager;
|
|
208
|
+
this.deltaManager = new deltaManagerSummarizerProxy_1.DeltaManagerSummarizerProxy(context.deltaManager);
|
|
215
209
|
let loadSummaryNumber;
|
|
216
210
|
// Get the container creation metadata. For new container, we initialize these. For existing containers,
|
|
217
211
|
// get the values from the metadata blob.
|
|
@@ -234,29 +228,47 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
234
228
|
this.nextSummaryNumber = loadSummaryNumber + 1;
|
|
235
229
|
this.messageAtLastSummary = metadata === null || metadata === void 0 ? void 0 : metadata.message;
|
|
236
230
|
this._connected = this.context.connected;
|
|
231
|
+
this.gcTombstoneEnforcementAllowed = (0, gc_1.shouldAllowGcTombstoneEnforcement)((_c = metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix) === null || _c === void 0 ? void 0 : _c.tombstoneGeneration /* persisted */, this.runtimeOptions.gcOptions[gc_1.gcTombstoneGenerationOptionName] /* current */);
|
|
237
232
|
this.mc = (0, telemetry_utils_1.loggerToMonitoringContext)(telemetry_utils_1.ChildLogger.create(this.logger, "ContainerRuntime"));
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
:
|
|
241
|
-
|
|
233
|
+
this.mc.logger.sendTelemetryEvent({
|
|
234
|
+
eventName: "GCFeatureMatrix",
|
|
235
|
+
metadataValue: JSON.stringify(metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix),
|
|
236
|
+
inputs: JSON.stringify({
|
|
237
|
+
gcOptions_gcTombstoneGeneration: this.runtimeOptions.gcOptions[gc_1.gcTombstoneGenerationOptionName],
|
|
238
|
+
}),
|
|
239
|
+
});
|
|
240
|
+
this.telemetryDocumentId = (_d = metadata === null || metadata === void 0 ? void 0 : metadata.telemetryDocumentId) !== null && _d !== void 0 ? _d : (0, uuid_1.v4)();
|
|
241
|
+
this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
|
|
242
|
+
const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionChunkingDisabled");
|
|
243
|
+
const opGroupingManager = new opLifecycle_1.OpGroupingManager(this.groupedBatchingEnabled);
|
|
244
|
+
const opSplitter = new opLifecycle_1.OpSplitter(chunks, this.context.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
|
|
245
|
+
this.remoteMessageProcessor = new opLifecycle_1.RemoteMessageProcessor(opSplitter, new opLifecycle_1.OpDecompressor(this.mc.logger), opGroupingManager);
|
|
242
246
|
this.handleContext = new containerHandleContext_1.ContainerFluidHandleContext("", this);
|
|
243
247
|
if (this.summaryConfiguration.state === "enabled") {
|
|
244
248
|
this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
|
|
245
249
|
}
|
|
250
|
+
const disableOpReentryCheck = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableOpReentryCheck");
|
|
246
251
|
this.enableOpReentryCheck =
|
|
247
252
|
runtimeOptions.enableOpReentryCheck === true &&
|
|
248
253
|
// Allow for a break-glass config to override the options
|
|
249
|
-
|
|
254
|
+
disableOpReentryCheck !== true;
|
|
250
255
|
this.summariesDisabled = this.isSummariesDisabled();
|
|
251
256
|
this.heuristicsDisabled = this.isHeuristicsDisabled();
|
|
252
257
|
this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
|
|
253
258
|
this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
|
|
254
259
|
this.maxConsecutiveReconnects =
|
|
255
|
-
(
|
|
256
|
-
|
|
260
|
+
(_e = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _e !== void 0 ? _e : this.defaultMaxConsecutiveReconnects;
|
|
261
|
+
if (runtimeOptions.flushMode === runtime_definitions_1.FlushModeExperimental.Async &&
|
|
262
|
+
((_f = context.supportedFeatures) === null || _f === void 0 ? void 0 : _f.get("referenceSequenceNumbers")) !== true) {
|
|
263
|
+
// The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
|
|
264
|
+
this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
|
|
265
|
+
this._flushMode = runtime_definitions_1.FlushMode.TurnBased;
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
this._flushMode = runtimeOptions.flushMode;
|
|
269
|
+
}
|
|
257
270
|
const pendingRuntimeState = context.pendingLocalState;
|
|
258
|
-
const
|
|
259
|
-
const maxSnapshotCacheDurationMs = (_f = (_e = this._storage) === null || _e === void 0 ? void 0 : _e.policies) === null || _f === void 0 ? void 0 : _f.maximumCacheDurationMs;
|
|
271
|
+
const maxSnapshotCacheDurationMs = (_h = (_g = this._storage) === null || _g === void 0 ? void 0 : _g.policies) === null || _h === void 0 ? void 0 : _h.maximumCacheDurationMs;
|
|
260
272
|
if (maxSnapshotCacheDurationMs !== undefined &&
|
|
261
273
|
maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
|
|
262
274
|
// This is a runtime enforcement of what's already explicit in the policy's type itself,
|
|
@@ -264,29 +276,31 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
264
276
|
// As long as the actual value is less than 5 days, the assumptions GC makes here are valid.
|
|
265
277
|
throw new container_utils_1.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
|
|
266
278
|
}
|
|
267
|
-
this.garbageCollector =
|
|
279
|
+
this.garbageCollector = gc_1.GarbageCollector.create({
|
|
268
280
|
runtime: this,
|
|
269
281
|
gcOptions: this.runtimeOptions.gcOptions,
|
|
270
|
-
baseSnapshot,
|
|
282
|
+
baseSnapshot: context.baseSnapshot,
|
|
271
283
|
baseLogger: this.mc.logger,
|
|
272
284
|
existing,
|
|
273
285
|
metadata,
|
|
274
286
|
createContainerMetadata: this.createContainerMetadata,
|
|
275
|
-
isSummarizerClient: this.context.clientDetails.type ===
|
|
287
|
+
isSummarizerClient: this.context.clientDetails.type === summary_1.summarizerClientType,
|
|
276
288
|
getNodePackagePath: async (nodePath) => this.getGCNodePackagePath(nodePath),
|
|
277
289
|
getLastSummaryTimestampMs: () => { var _a; return (_a = this.messageAtLastSummary) === null || _a === void 0 ? void 0 : _a.timestamp; },
|
|
278
290
|
readAndParseBlob: async (id) => (0, driver_utils_1.readAndParse)(this.storage, id),
|
|
279
291
|
getContainerDiagnosticId: () => this.context.id,
|
|
280
|
-
|
|
292
|
+
// GC runs in summarizer client and needs access to the real (non-proxy) active information. The proxy
|
|
293
|
+
// delta manager would always return false for summarizer client.
|
|
294
|
+
activeConnection: () => this.innerDeltaManager.active,
|
|
281
295
|
});
|
|
282
296
|
const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
|
|
283
|
-
this.summarizerNode = (0,
|
|
297
|
+
this.summarizerNode = (0, summary_1.createRootSummarizerNodeWithGC)(telemetry_utils_1.ChildLogger.create(this.logger, "SummarizerNode"),
|
|
284
298
|
// Summarize function to call when summarize is called. Summarizer node always tracks summary state.
|
|
285
299
|
async (fullTree, trackState, telemetryContext) => this.summarizeInternal(fullTree, trackState, telemetryContext),
|
|
286
300
|
// Latest change sequence number, no changes since summary applied yet
|
|
287
301
|
loadedFromSequenceNumber,
|
|
288
302
|
// Summary reference sequence number, undefined if no summary yet
|
|
289
|
-
baseSnapshot ? loadedFromSequenceNumber : undefined, {
|
|
303
|
+
context.baseSnapshot ? loadedFromSequenceNumber : undefined, {
|
|
290
304
|
// Must set to false to prevent sending summary handle which would be pointing to
|
|
291
305
|
// a summary with an older protocol state.
|
|
292
306
|
canReuseHandle: false,
|
|
@@ -300,18 +314,24 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
300
314
|
async (fullGC) => this.getGCDataInternal(fullGC),
|
|
301
315
|
// Function to get the GC details from the base snapshot we loaded from.
|
|
302
316
|
async () => this.garbageCollector.getBaseGCDetails());
|
|
303
|
-
if (baseSnapshot) {
|
|
304
|
-
this.summarizerNode.updateBaseSummaryState(baseSnapshot);
|
|
317
|
+
if (context.baseSnapshot) {
|
|
318
|
+
this.summarizerNode.updateBaseSummaryState(context.baseSnapshot);
|
|
305
319
|
}
|
|
306
|
-
this.dataStores = new dataStores_1.DataStores((0, dataStores_1.getSummaryForDatastores)(baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn
|
|
320
|
+
this.dataStores = new dataStores_1.DataStores((0, dataStores_1.getSummaryForDatastores)(context.baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn), (id) => this.summarizerNode.deleteChild(id), this.mc.logger, (path, timestampMs, packagePath) => this.garbageCollector.nodeUpdated(path, "Changed", timestampMs, packagePath), (path) => this.garbageCollector.isNodeDeleted(path), new Map(dataStoreAliasMap));
|
|
307
321
|
this.blobManager = new blobManager_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
|
|
308
322
|
if (!this.disposed) {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
323
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
324
|
+
Promise.resolve().then(() => {
|
|
325
|
+
// Blob attaches need to be in their own batch (grouped batching would hide metadata)
|
|
326
|
+
this.flush();
|
|
327
|
+
this.submit(ContainerMessageType.BlobAttach, undefined, undefined, {
|
|
328
|
+
localId,
|
|
329
|
+
blobId,
|
|
330
|
+
});
|
|
331
|
+
this.flush();
|
|
312
332
|
});
|
|
313
333
|
}
|
|
314
|
-
}, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (
|
|
334
|
+
}, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs, (error) => this.closeFn(error));
|
|
315
335
|
this.scheduleManager = new scheduleManager_1.ScheduleManager(context.deltaManager, this, () => this.clientId, telemetry_utils_1.ChildLogger.create(this.logger, "ScheduleManager"));
|
|
316
336
|
this.pendingStateManager = new pendingStateManager_1.PendingStateManager({
|
|
317
337
|
applyStashedOp: this.applyStashedOp.bind(this),
|
|
@@ -322,12 +342,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
322
342
|
rollback: this.rollback.bind(this),
|
|
323
343
|
orderSequentially: this.orderSequentially.bind(this),
|
|
324
344
|
}, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pending);
|
|
325
|
-
const
|
|
345
|
+
const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
|
|
346
|
+
const compressionOptions = disableCompression === true
|
|
326
347
|
? {
|
|
327
348
|
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
|
|
328
349
|
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
329
350
|
}
|
|
330
351
|
: runtimeOptions.compressionOptions;
|
|
352
|
+
const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
|
|
331
353
|
this.outbox = new opLifecycle_1.Outbox({
|
|
332
354
|
shouldSend: () => this.canSendOps(),
|
|
333
355
|
pendingStateManager: this.pendingStateManager,
|
|
@@ -337,14 +359,15 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
337
359
|
config: {
|
|
338
360
|
compressionOptions,
|
|
339
361
|
maxBatchSizeInBytes: runtimeOptions.maxBatchSizeInBytes,
|
|
340
|
-
|
|
362
|
+
disablePartialFlush: disablePartialFlush === true,
|
|
341
363
|
},
|
|
342
364
|
logger: this.mc.logger,
|
|
365
|
+
groupingManager: opGroupingManager,
|
|
343
366
|
});
|
|
344
367
|
this.context.quorum.on("removeMember", (clientId) => {
|
|
345
368
|
this.remoteMessageProcessor.clearPartialMessagesFor(clientId);
|
|
346
369
|
});
|
|
347
|
-
this.summaryCollection = new
|
|
370
|
+
this.summaryCollection = new summary_1.SummaryCollection(this.deltaManager, this.logger);
|
|
348
371
|
this.dirtyContainer =
|
|
349
372
|
this.context.attachState !== container_definitions_1.AttachState.Attached ||
|
|
350
373
|
this.pendingStateManager.hasPendingMessages();
|
|
@@ -354,13 +377,16 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
354
377
|
}
|
|
355
378
|
else {
|
|
356
379
|
const orderedClientLogger = telemetry_utils_1.ChildLogger.create(this.logger, "OrderedClientElection");
|
|
357
|
-
const orderedClientCollection = new
|
|
358
|
-
const orderedClientElectionForSummarizer = new
|
|
359
|
-
this.summarizerClientElection = new
|
|
360
|
-
if (this.context.clientDetails.type ===
|
|
361
|
-
this._summarizer = new
|
|
380
|
+
const orderedClientCollection = new summary_1.OrderedClientCollection(orderedClientLogger, this.context.deltaManager, this.context.quorum);
|
|
381
|
+
const orderedClientElectionForSummarizer = new summary_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData !== null && electedSummarizerData !== void 0 ? electedSummarizerData : this.context.deltaManager.lastSequenceNumber, summary_1.SummarizerClientElection.isClientEligible);
|
|
382
|
+
this.summarizerClientElection = new summary_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
|
|
383
|
+
if (this.context.clientDetails.type === summary_1.summarizerClientType) {
|
|
384
|
+
this._summarizer = new summary_1.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => summary_1.RunWhileConnectedCoordinator.create(runtime,
|
|
385
|
+
// Summarization runs in summarizer client and needs access to the real (non-proxy) active
|
|
386
|
+
// information. The proxy delta manager would always return false for summarizer client.
|
|
387
|
+
() => this.innerDeltaManager.active));
|
|
362
388
|
}
|
|
363
|
-
else if (
|
|
389
|
+
else if (summary_1.SummarizerClientElection.clientDetailsPermitElection(this.context.clientDetails)) {
|
|
364
390
|
// Only create a SummaryManager and SummarizerClientElection
|
|
365
391
|
// if summaries are enabled and we are not the summarizer client.
|
|
366
392
|
const defaultAction = () => {
|
|
@@ -380,7 +406,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
380
406
|
};
|
|
381
407
|
this.summaryCollection.on("default", defaultAction);
|
|
382
408
|
// Create the SummaryManager and mark the initial state
|
|
383
|
-
this.summaryManager = new
|
|
409
|
+
this.summaryManager = new summary_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
|
|
384
410
|
this.summaryCollection, this.logger, this.formRequestSummarizerFn(this.context.loader), new throttler_1.Throttler(60 * 1000, // 60 sec delay window
|
|
385
411
|
30 * 1000, // 30 sec max delay
|
|
386
412
|
// throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
|
|
@@ -393,7 +419,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
393
419
|
this.deltaManager.on("readonly", (readonly) => {
|
|
394
420
|
// we accumulate ops while being in read-only state.
|
|
395
421
|
// once user gets write permissions and we have active connection, flush all pending ops.
|
|
396
|
-
(
|
|
422
|
+
// Note that the inner (non-proxy) delta manager is needed here to get the readonly information.
|
|
423
|
+
(0, common_utils_1.assert)(readonly === this.innerDeltaManager.readOnlyInfo.readonly, 0x124 /* "inconsistent readonly property/event state" */);
|
|
397
424
|
// We need to be very careful with when we (re)send pending ops, to ensure that we only send ops
|
|
398
425
|
// when we either never send an op, or attempted to send it but we know for sure it was not
|
|
399
426
|
// sequenced by server and will never be sequenced (i.e. was lost)
|
|
@@ -411,9 +438,22 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
411
438
|
});
|
|
412
439
|
// logging hardware telemetry
|
|
413
440
|
logger.sendTelemetryEvent(Object.assign({ eventName: "DeviceSpec" }, getDeviceSpec()));
|
|
414
|
-
this.logger.sendTelemetryEvent(Object.assign(Object.assign(Object.assign({ eventName: "ContainerLoadStats" }, this.createContainerMetadata), this.dataStores.containerLoadStats), { summaryNumber: loadSummaryNumber, summaryFormatVersion: metadata === null || metadata === void 0 ? void 0 : metadata.summaryFormatVersion, disableIsolatedChannels: metadata === null || metadata === void 0 ? void 0 : metadata.disableIsolatedChannels, gcVersion: metadata === null || metadata === void 0 ? void 0 : metadata.gcFeature
|
|
441
|
+
this.logger.sendTelemetryEvent(Object.assign(Object.assign(Object.assign({ eventName: "ContainerLoadStats" }, this.createContainerMetadata), this.dataStores.containerLoadStats), { summaryNumber: loadSummaryNumber, summaryFormatVersion: metadata === null || metadata === void 0 ? void 0 : metadata.summaryFormatVersion, disableIsolatedChannels: metadata === null || metadata === void 0 ? void 0 : metadata.disableIsolatedChannels, gcVersion: metadata === null || metadata === void 0 ? void 0 : metadata.gcFeature, options: JSON.stringify(runtimeOptions), featureGates: JSON.stringify({
|
|
442
|
+
disableCompression,
|
|
443
|
+
disableOpReentryCheck,
|
|
444
|
+
disableChunking,
|
|
445
|
+
disableAttachReorder: this.disableAttachReorder,
|
|
446
|
+
disablePartialFlush,
|
|
447
|
+
}), telemetryDocumentId: this.telemetryDocumentId, groupedBatchingEnabled: this.groupedBatchingEnabled }));
|
|
415
448
|
(0, connectionTelemetry_1.ReportOpPerfTelemetry)(this.context.clientId, this.deltaManager, this.logger);
|
|
416
449
|
(0, batchTracker_1.BindBatchTracker)(this, this.logger);
|
|
450
|
+
this.entryPoint = new common_utils_1.LazyPromise(async () => {
|
|
451
|
+
if (this.context.clientDetails.type === summary_1.summarizerClientType) {
|
|
452
|
+
(0, common_utils_1.assert)(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
|
|
453
|
+
return this._summarizer;
|
|
454
|
+
}
|
|
455
|
+
return initializeEntryPoint === null || initializeEntryPoint === void 0 ? void 0 : initializeEntryPoint(this);
|
|
456
|
+
});
|
|
417
457
|
}
|
|
418
458
|
get IContainerRuntime() {
|
|
419
459
|
return this;
|
|
@@ -451,17 +491,20 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
451
491
|
* Load the stores from a snapshot and returns the runtime.
|
|
452
492
|
* @param params - An object housing the runtime properties:
|
|
453
493
|
* - context - Context of the container.
|
|
454
|
-
* - registryEntries - Mapping to
|
|
455
|
-
* - existing -
|
|
456
|
-
* - requestHandler - Request
|
|
494
|
+
* - registryEntries - Mapping from data store types to their corresponding factories.
|
|
495
|
+
* - existing - Pass 'true' if loading from an existing snapshot.
|
|
496
|
+
* - requestHandler - (optional) Request handler for the request() method of the container runtime.
|
|
497
|
+
* Only relevant for back-compat while we remove the request() method and move fully to entryPoint as the main pattern.
|
|
457
498
|
* - runtimeOptions - Additional options to be passed to the runtime
|
|
458
499
|
* - containerScope - runtime services provided with context
|
|
459
500
|
* - containerRuntimeCtor - Constructor to use to create the ContainerRuntime instance.
|
|
460
501
|
* This allows mixin classes to leverage this method to define their own async initializer.
|
|
502
|
+
* - initializeEntryPoint - Promise that resolves to an object which will act as entryPoint for the Container.
|
|
503
|
+
* This object should provide all the functionality that the Container is expected to provide to the loader layer.
|
|
461
504
|
*/
|
|
462
505
|
static async loadRuntime(params) {
|
|
463
506
|
var _a, _b, _c, _d;
|
|
464
|
-
const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, } = params;
|
|
507
|
+
const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, initializeEntryPoint, } = params;
|
|
465
508
|
// If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
|
|
466
509
|
// back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
|
|
467
510
|
const backCompatContext = context;
|
|
@@ -471,45 +514,36 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
471
514
|
runtimeVersion: packageVersion_1.pkgVersion,
|
|
472
515
|
},
|
|
473
516
|
});
|
|
474
|
-
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode,
|
|
475
|
-
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
|
|
476
|
-
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
477
|
-
}, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, chunkSizeInBytes = Number.POSITIVE_INFINITY, enableOpReentryCheck = false, } = runtimeOptions;
|
|
478
|
-
const pendingRuntimeState = context.pendingLocalState;
|
|
479
|
-
const baseSnapshot = (_b = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _b !== void 0 ? _b : context.baseSnapshot;
|
|
480
|
-
const storage = !pendingRuntimeState
|
|
481
|
-
? context.storage
|
|
482
|
-
: new serializedSnapshotStorage_1.SerializedSnapshotStorage(() => {
|
|
483
|
-
return context.storage;
|
|
484
|
-
}, pendingRuntimeState.snapshotBlobs);
|
|
517
|
+
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
|
|
485
518
|
const registry = new dataStoreRegistry_1.FluidDataStoreRegistry(registryEntries);
|
|
486
519
|
const tryFetchBlob = async (blobName) => {
|
|
487
|
-
|
|
488
|
-
|
|
520
|
+
var _a;
|
|
521
|
+
const blobId = (_a = context.baseSnapshot) === null || _a === void 0 ? void 0 : _a.blobs[blobName];
|
|
522
|
+
if (context.baseSnapshot && blobId) {
|
|
489
523
|
// IContainerContext storage api return type still has undefined in 0.39 package version.
|
|
490
524
|
// So once we release 0.40 container-defn package we can remove this check.
|
|
491
|
-
(0, common_utils_1.assert)(storage !== undefined, 0x1f5 /* "Attached state should have storage" */);
|
|
492
|
-
return (0, driver_utils_1.readAndParse)(storage, blobId);
|
|
525
|
+
(0, common_utils_1.assert)(context.storage !== undefined, 0x1f5 /* "Attached state should have storage" */);
|
|
526
|
+
return (0, driver_utils_1.readAndParse)(context.storage, blobId);
|
|
493
527
|
}
|
|
494
528
|
};
|
|
495
529
|
const [chunks, metadata, electedSummarizerData, aliases] = await Promise.all([
|
|
496
|
-
tryFetchBlob(
|
|
497
|
-
tryFetchBlob(
|
|
498
|
-
tryFetchBlob(
|
|
499
|
-
tryFetchBlob(
|
|
530
|
+
tryFetchBlob(summary_1.chunksBlobName),
|
|
531
|
+
tryFetchBlob(summary_1.metadataBlobName),
|
|
532
|
+
tryFetchBlob(summary_1.electedSummarizerBlobName),
|
|
533
|
+
tryFetchBlob(summary_1.aliasBlobName),
|
|
500
534
|
]);
|
|
501
535
|
const loadExisting = existing === true || context.existing === true;
|
|
502
536
|
// read snapshot blobs needed for BlobManager to load
|
|
503
|
-
const blobManagerSnapshot = await blobManager_1.BlobManager.load(baseSnapshot === null ||
|
|
537
|
+
const blobManagerSnapshot = await blobManager_1.BlobManager.load((_b = context.baseSnapshot) === null || _b === void 0 ? void 0 : _b.trees[summary_1.blobsTreeName], async (id) => {
|
|
504
538
|
// IContainerContext storage api return type still has undefined in 0.39 package version.
|
|
505
539
|
// So once we release 0.40 container-defn package we can remove this check.
|
|
506
|
-
(0, common_utils_1.assert)(storage !== undefined, 0x256 /* "storage undefined in attached container" */);
|
|
507
|
-
return (0, driver_utils_1.readAndParse)(storage, id);
|
|
540
|
+
(0, common_utils_1.assert)(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
|
|
541
|
+
return (0, driver_utils_1.readAndParse)(context.storage, id);
|
|
508
542
|
});
|
|
509
543
|
// Verify summary runtime sequence number matches protocol sequence number.
|
|
510
544
|
const runtimeSequenceNumber = (_c = metadata === null || metadata === void 0 ? void 0 : metadata.message) === null || _c === void 0 ? void 0 : _c.sequenceNumber;
|
|
511
545
|
// When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
|
|
512
|
-
if (!
|
|
546
|
+
if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
|
|
513
547
|
const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
|
|
514
548
|
// Unless bypass is explicitly set, then take action when sequence numbers mismatch.
|
|
515
549
|
if (loadSequenceNumberVerification !== "bypass" &&
|
|
@@ -533,17 +567,16 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
533
567
|
gcOptions,
|
|
534
568
|
loadSequenceNumberVerification,
|
|
535
569
|
flushMode,
|
|
536
|
-
enableOfflineLoad,
|
|
537
570
|
compressionOptions,
|
|
538
571
|
maxBatchSizeInBytes,
|
|
539
572
|
chunkSizeInBytes,
|
|
540
573
|
enableOpReentryCheck,
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
574
|
+
enableGroupedBatching,
|
|
575
|
+
}, containerScope, logger, loadExisting, blobManagerSnapshot, context.storage, requestHandler, undefined, // summaryConfiguration
|
|
576
|
+
initializeEntryPoint);
|
|
577
|
+
// It's possible to have ops with a reference sequence number of 0. Op sequence numbers start
|
|
578
|
+
// at 1, so we won't see a replayed saved op with a sequence number of 0.
|
|
579
|
+
await runtime.pendingStateManager.applyStashedOpsAt(0);
|
|
547
580
|
// Initialize the base state of the runtime before it's returned.
|
|
548
581
|
await runtime.initializeBaseState();
|
|
549
582
|
return runtime;
|
|
@@ -557,9 +590,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
557
590
|
get clientDetails() {
|
|
558
591
|
return this.context.clientDetails;
|
|
559
592
|
}
|
|
560
|
-
get deltaManager() {
|
|
561
|
-
return this.context.deltaManager;
|
|
562
|
-
}
|
|
563
593
|
get storage() {
|
|
564
594
|
return this._storage;
|
|
565
595
|
}
|
|
@@ -652,7 +682,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
652
682
|
* Initializes the state from the base snapshot this container runtime loaded from.
|
|
653
683
|
*/
|
|
654
684
|
async initializeBaseState() {
|
|
655
|
-
await this.initializeBaseSnapshotBlobs();
|
|
656
685
|
await this.garbageCollector.initializeBaseState();
|
|
657
686
|
}
|
|
658
687
|
dispose(error) {
|
|
@@ -677,16 +706,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
677
706
|
this.emit("dispose");
|
|
678
707
|
this.removeAllListeners();
|
|
679
708
|
}
|
|
680
|
-
get IFluidTokenProvider() {
|
|
681
|
-
var _a;
|
|
682
|
-
if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.intelligence) {
|
|
683
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
684
|
-
return {
|
|
685
|
-
intelligence: this.options.intelligence,
|
|
686
|
-
};
|
|
687
|
-
}
|
|
688
|
-
return undefined;
|
|
689
|
-
}
|
|
690
709
|
/**
|
|
691
710
|
* Notifies this object about the request made to the container.
|
|
692
711
|
* @param request - Request made to the handler.
|
|
@@ -749,12 +768,18 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
749
768
|
return (0, runtime_utils_1.exceptionToResponse)(error);
|
|
750
769
|
}
|
|
751
770
|
}
|
|
771
|
+
/**
|
|
772
|
+
* {@inheritDoc @fluidframework/container-definitions#IRuntime.getEntryPoint}
|
|
773
|
+
*/
|
|
774
|
+
async getEntryPoint() {
|
|
775
|
+
return this.entryPoint;
|
|
776
|
+
}
|
|
752
777
|
internalId(maybeAlias) {
|
|
753
778
|
var _a;
|
|
754
779
|
return (_a = this.dataStores.aliases.get(maybeAlias)) !== null && _a !== void 0 ? _a : maybeAlias;
|
|
755
780
|
}
|
|
756
781
|
async getDataStoreFromRequest(id, request) {
|
|
757
|
-
var _a, _b, _c
|
|
782
|
+
var _a, _b, _c;
|
|
758
783
|
const headerData = {};
|
|
759
784
|
if (typeof ((_a = request.headers) === null || _a === void 0 ? void 0 : _a[RuntimeHeaders.wait]) === "boolean") {
|
|
760
785
|
headerData.wait = request.headers[RuntimeHeaders.wait];
|
|
@@ -768,27 +793,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
768
793
|
await this.dataStores.waitIfPendingAlias(id);
|
|
769
794
|
const internalId = this.internalId(id);
|
|
770
795
|
const dataStoreContext = await this.dataStores.getDataStore(internalId, headerData);
|
|
771
|
-
/**
|
|
772
|
-
* If GC should run and this an external app request with "externalRequest" header, we need to return
|
|
773
|
-
* an error if the data store being requested is marked as unreferenced as per the data store's base
|
|
774
|
-
* GC data.
|
|
775
|
-
*
|
|
776
|
-
* This is a workaround to handle scenarios where a data store shared with an external app is deleted
|
|
777
|
-
* and marked as unreferenced by GC. Returning an error will fail to load the data store for the app.
|
|
778
|
-
*/
|
|
779
|
-
if (((_d = request.headers) === null || _d === void 0 ? void 0 : _d[RuntimeHeaders.externalRequest]) &&
|
|
780
|
-
this.garbageCollector.shouldRunGC) {
|
|
781
|
-
// The data store is referenced if used routes in the base summary has a route to self.
|
|
782
|
-
// Older documents may not have used routes in the summary. They are considered referenced.
|
|
783
|
-
const usedRoutes = (await dataStoreContext.getBaseGCDetails()).usedRoutes;
|
|
784
|
-
if (!(usedRoutes === undefined || usedRoutes.includes("") || usedRoutes.includes("/"))) {
|
|
785
|
-
throw (0, runtime_utils_1.responseToException)((0, runtime_utils_1.create404Response)(request), request);
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
796
|
const dataStoreChannel = await dataStoreContext.realize();
|
|
789
797
|
// Remove query params, leading and trailing slashes from the url. This is done to make sure the format is
|
|
790
798
|
// the same as GC nodes id.
|
|
791
|
-
const urlWithoutQuery = (0,
|
|
799
|
+
const urlWithoutQuery = (0, gc_1.trimLeadingAndTrailingSlashes)(request.url.split("?")[0]);
|
|
792
800
|
this.garbageCollector.nodeUpdated(`/${urlWithoutQuery}`, "Loaded", undefined /* timestampMs */, dataStoreContext.packagePath, request === null || request === void 0 ? void 0 : request.headers);
|
|
793
801
|
return dataStoreChannel;
|
|
794
802
|
}
|
|
@@ -800,29 +808,29 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
800
808
|
summaryNumber: this.nextSummaryNumber++, summaryFormatVersion: 1 }), this.garbageCollector.getMetadata()), {
|
|
801
809
|
// The last message processed at the time of summary. If there are no new messages, use the message from the
|
|
802
810
|
// last summary.
|
|
803
|
-
message: (_a = (0,
|
|
804
|
-
(0, runtime_utils_1.addBlobToSummary)(summaryTree,
|
|
811
|
+
message: (_a = (0, summary_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage)) !== null && _a !== void 0 ? _a : this.messageAtLastSummary, telemetryDocumentId: this.telemetryDocumentId });
|
|
812
|
+
(0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.metadataBlobName, JSON.stringify(metadata));
|
|
805
813
|
}
|
|
806
814
|
addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
|
|
807
815
|
var _a;
|
|
808
816
|
this.addMetadataToSummary(summaryTree);
|
|
809
817
|
if (this.remoteMessageProcessor.partialMessages.size > 0) {
|
|
810
818
|
const content = JSON.stringify([...this.remoteMessageProcessor.partialMessages]);
|
|
811
|
-
(0, runtime_utils_1.addBlobToSummary)(summaryTree,
|
|
819
|
+
(0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.chunksBlobName, content);
|
|
812
820
|
}
|
|
813
821
|
const dataStoreAliases = this.dataStores.aliases;
|
|
814
822
|
if (dataStoreAliases.size > 0) {
|
|
815
|
-
(0, runtime_utils_1.addBlobToSummary)(summaryTree,
|
|
823
|
+
(0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
|
|
816
824
|
}
|
|
817
825
|
if (this.summarizerClientElection) {
|
|
818
826
|
const electedSummarizerContent = JSON.stringify((_a = this.summarizerClientElection) === null || _a === void 0 ? void 0 : _a.serialize());
|
|
819
|
-
(0, runtime_utils_1.addBlobToSummary)(summaryTree,
|
|
827
|
+
(0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.electedSummarizerBlobName, electedSummarizerContent);
|
|
820
828
|
}
|
|
821
829
|
const blobManagerSummary = this.blobManager.summarize();
|
|
822
830
|
// Some storage (like git) doesn't allow empty tree, so we can omit it.
|
|
823
831
|
// and the blob manager can handle the tree not existing when loading
|
|
824
832
|
if (Object.keys(blobManagerSummary.summary.tree).length > 0) {
|
|
825
|
-
(0, runtime_utils_1.addTreeToSummary)(summaryTree,
|
|
833
|
+
(0, runtime_utils_1.addTreeToSummary)(summaryTree, summary_1.blobsTreeName, blobManagerSummary);
|
|
826
834
|
}
|
|
827
835
|
const gcSummary = this.garbageCollector.summarize(fullTree, trackState, telemetryContext);
|
|
828
836
|
if (gcSummary !== undefined) {
|
|
@@ -916,7 +924,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
916
924
|
// If attachment blobs were added while disconnected, we need to delay
|
|
917
925
|
// propagation of the "connected" event until we have uploaded them to
|
|
918
926
|
// ensure we don't submit ops referencing a blob that has not been uploaded
|
|
919
|
-
|
|
927
|
+
// Note that the inner (non-proxy) delta manager is needed here to get the readonly information.
|
|
928
|
+
const connecting = connected && !this._connected && !this.innerDeltaManager.readOnlyInfo.readonly;
|
|
920
929
|
if (connecting && this.blobManager.hasPendingOfflineUploads) {
|
|
921
930
|
(0, common_utils_1.assert)(!this.delayConnectClientId, 0x392 /* Connect event delay must be canceled before subsequent connect event */);
|
|
922
931
|
(0, common_utils_1.assert)(!!clientId, 0x393 /* Must have clientId when connecting */);
|
|
@@ -966,19 +975,23 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
966
975
|
this.garbageCollector.setConnectionState(connected, clientId);
|
|
967
976
|
(0, telemetry_utils_1.raiseConnectedEvent)(this.mc.logger, this, connected, clientId);
|
|
968
977
|
}
|
|
978
|
+
async notifyOpReplay(message) {
|
|
979
|
+
await this.pendingStateManager.applyStashedOpsAt(message.sequenceNumber);
|
|
980
|
+
}
|
|
969
981
|
process(messageArg, local) {
|
|
970
|
-
var _a;
|
|
971
982
|
this.verifyNotClosed();
|
|
972
|
-
if ((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) {
|
|
973
|
-
this.savedOps.push(messageArg);
|
|
974
|
-
}
|
|
975
983
|
// Whether or not the message is actually a runtime message.
|
|
976
984
|
// It may be a legacy runtime message (ie already unpacked and ContainerMessageType)
|
|
977
985
|
// or something different, like a system message.
|
|
978
986
|
const runtimeMessage = messageArg.type === protocol_definitions_1.MessageType.Operation;
|
|
979
987
|
// Do shallow copy of message, as the processing flow will modify it.
|
|
980
988
|
const messageCopy = Object.assign({}, messageArg);
|
|
981
|
-
const message
|
|
989
|
+
for (const message of this.remoteMessageProcessor.process(messageCopy)) {
|
|
990
|
+
this.processCore(message, local, runtimeMessage);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
processCore(message, local, runtimeMessage) {
|
|
994
|
+
var _a;
|
|
982
995
|
// Surround the actual processing of the operation with messages to the schedule manager indicating
|
|
983
996
|
// the beginning and end. This allows it to emit appropriate events and/or pause the processing of new
|
|
984
997
|
// messages once a batch has been fully processed.
|
|
@@ -1011,10 +1024,21 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1011
1024
|
case ContainerMessageType.Rejoin:
|
|
1012
1025
|
break;
|
|
1013
1026
|
default:
|
|
1014
|
-
|
|
1027
|
+
if (runtimeMessage) {
|
|
1028
|
+
const error = container_utils_1.DataProcessingError.create(
|
|
1029
|
+
// Former assert 0x3ce
|
|
1030
|
+
"Runtime message of unknown type", "OpProcessing", message, {
|
|
1031
|
+
local,
|
|
1032
|
+
type: message.type,
|
|
1033
|
+
contentType: typeof message.contents,
|
|
1034
|
+
batch: (_a = message.metadata) === null || _a === void 0 ? void 0 : _a.batch,
|
|
1035
|
+
compression: message.compression,
|
|
1036
|
+
});
|
|
1037
|
+
this.closeFn(error);
|
|
1038
|
+
throw error;
|
|
1039
|
+
}
|
|
1015
1040
|
}
|
|
1016
|
-
|
|
1017
|
-
if (runtimeMessage) {
|
|
1041
|
+
if (runtimeMessage || this.groupedBatchingEnabled) {
|
|
1018
1042
|
this.emit("op", message, runtimeMessage);
|
|
1019
1043
|
}
|
|
1020
1044
|
this.scheduleManager.afterOpProcessing(undefined, message);
|
|
@@ -1072,7 +1096,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1072
1096
|
}
|
|
1073
1097
|
else if (envelope.clientSignalSequenceNumber ===
|
|
1074
1098
|
this._perfSignalData.trackingSignalSequenceNumber) {
|
|
1075
|
-
|
|
1099
|
+
// only logging for the first connection and the trackingSignalSequenceNUmber.
|
|
1100
|
+
if (this.consecutiveReconnects === 0) {
|
|
1101
|
+
this.sendSignalTelemetryEvent(envelope.clientSignalSequenceNumber);
|
|
1102
|
+
}
|
|
1076
1103
|
this._perfSignalData.trackingSignalSequenceNumber = undefined;
|
|
1077
1104
|
}
|
|
1078
1105
|
}
|
|
@@ -1169,13 +1196,15 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1169
1196
|
.realize();
|
|
1170
1197
|
}
|
|
1171
1198
|
canSendOps() {
|
|
1172
|
-
|
|
1199
|
+
// Note that the real (non-proxy) delta manager is needed here to get the readonly info. This is because
|
|
1200
|
+
// container runtime's ability to send ops depend on the actual readonly state of the delta manager.
|
|
1201
|
+
return this.connected && !this.innerDeltaManager.readOnlyInfo.readonly;
|
|
1173
1202
|
}
|
|
1174
1203
|
/**
|
|
1175
1204
|
* Are we in the middle of batching ops together?
|
|
1176
1205
|
*/
|
|
1177
1206
|
currentlyBatching() {
|
|
1178
|
-
return this.flushMode
|
|
1207
|
+
return this.flushMode !== runtime_definitions_1.FlushMode.Immediate || this._orderSequentiallyCalls !== 0;
|
|
1179
1208
|
}
|
|
1180
1209
|
getQuorum() {
|
|
1181
1210
|
return this.context.quorum;
|
|
@@ -1264,7 +1293,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1264
1293
|
}
|
|
1265
1294
|
const summarizeResult = this.dataStores.createSummary(telemetryContext);
|
|
1266
1295
|
// Wrap data store summaries in .channels subtree.
|
|
1267
|
-
(0,
|
|
1296
|
+
(0, summary_1.wrapSummaryInChannelsTree)(summarizeResult);
|
|
1268
1297
|
this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
|
|
1269
1298
|
return summarizeResult.summary;
|
|
1270
1299
|
}
|
|
@@ -1280,7 +1309,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1280
1309
|
async summarizeInternal(fullTree, trackState, telemetryContext) {
|
|
1281
1310
|
const summarizeResult = await this.dataStores.summarize(fullTree, trackState, telemetryContext);
|
|
1282
1311
|
// Wrap data store summaries in .channels subtree.
|
|
1283
|
-
(0,
|
|
1312
|
+
(0, summary_1.wrapSummaryInChannelsTree)(summarizeResult);
|
|
1284
1313
|
const pathPartsForChildren = [runtime_definitions_1.channelsTreeName];
|
|
1285
1314
|
this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
|
|
1286
1315
|
return Object.assign(Object.assign({}, summarizeResult), { id: "", pathPartsForChildren });
|
|
@@ -1291,11 +1320,19 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1291
1320
|
async summarize(options) {
|
|
1292
1321
|
this.verifyNotClosed();
|
|
1293
1322
|
const { fullTree = false, trackState = true, summaryLogger = this.mc.logger, runGC = this.garbageCollector.shouldRunGC, runSweep, fullGC, } = options;
|
|
1323
|
+
const telemetryContext = new runtime_utils_1.TelemetryContext();
|
|
1324
|
+
// Add the options that are used to generate this summary to the telemetry context.
|
|
1325
|
+
telemetryContext.setMultiple("fluid_Summarize", "Options", {
|
|
1326
|
+
fullTree,
|
|
1327
|
+
trackState,
|
|
1328
|
+
runGC,
|
|
1329
|
+
fullGC,
|
|
1330
|
+
runSweep,
|
|
1331
|
+
});
|
|
1294
1332
|
let gcStats;
|
|
1295
1333
|
if (runGC) {
|
|
1296
|
-
gcStats = await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC });
|
|
1334
|
+
gcStats = await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC }, telemetryContext);
|
|
1297
1335
|
}
|
|
1298
|
-
const telemetryContext = new runtime_utils_1.TelemetryContext();
|
|
1299
1336
|
const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
|
|
1300
1337
|
this.logger.sendTelemetryEvent({
|
|
1301
1338
|
eventName: "SummarizeTelemetry",
|
|
@@ -1305,10 +1342,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1305
1342
|
return { stats, summary, gcStats };
|
|
1306
1343
|
}
|
|
1307
1344
|
/**
|
|
1308
|
-
* Implementation of IGarbageCollectionRuntime::updateStateBeforeGC.
|
|
1309
1345
|
* Before GC runs, called by the garbage collector to update any pending GC state. This is mainly used to notify
|
|
1310
1346
|
* the garbage collector of references detected since the last GC run. Most references are notified immediately
|
|
1311
1347
|
* but there can be some for which async operation is required (such as detecting new root data stores).
|
|
1348
|
+
* @see IGarbageCollectionRuntime.updateStateBeforeGC
|
|
1312
1349
|
*/
|
|
1313
1350
|
async updateStateBeforeGC() {
|
|
1314
1351
|
return this.dataStores.updateStateBeforeGC();
|
|
@@ -1317,12 +1354,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1317
1354
|
return this.dataStores.getGCData(fullGC);
|
|
1318
1355
|
}
|
|
1319
1356
|
/**
|
|
1320
|
-
* Implementation of IGarbageCollectionRuntime::getGCData.
|
|
1321
1357
|
* Generates and returns the GC data for this container.
|
|
1322
1358
|
* @param fullGC - true to bypass optimizations and force full generation of GC data.
|
|
1359
|
+
* @see IGarbageCollectionRuntime.getGCData
|
|
1323
1360
|
*/
|
|
1324
1361
|
async getGCData(fullGC) {
|
|
1325
|
-
const builder = new
|
|
1362
|
+
const builder = new runtime_utils_1.GCDataBuilder();
|
|
1326
1363
|
const dsGCData = await this.summarizerNode.getGCData(fullGC);
|
|
1327
1364
|
builder.addNodes(dsGCData.gcNodes);
|
|
1328
1365
|
const blobsGCData = this.blobManager.getGCData(fullGC);
|
|
@@ -1330,9 +1367,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1330
1367
|
return builder.getGCData();
|
|
1331
1368
|
}
|
|
1332
1369
|
/**
|
|
1333
|
-
* Implementation of IGarbageCollectionRuntime::updateUsedRoutes.
|
|
1334
1370
|
* After GC has run, called to notify this container's nodes of routes that are used in it.
|
|
1335
1371
|
* @param usedRoutes - The routes that are used in all nodes in this Container.
|
|
1372
|
+
* @see IGarbageCollectionRuntime.updateUsedRoutes
|
|
1336
1373
|
*/
|
|
1337
1374
|
updateUsedRoutes(usedRoutes) {
|
|
1338
1375
|
// Update our summarizer node's used routes. Updating used routes in summarizer node before
|
|
@@ -1351,6 +1388,22 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1351
1388
|
this.blobManager.updateUnusedRoutes(blobManagerRoutes);
|
|
1352
1389
|
this.dataStores.updateUnusedRoutes(dataStoreRoutes);
|
|
1353
1390
|
}
|
|
1391
|
+
/**
|
|
1392
|
+
* @deprecated - Replaced by deleteSweepReadyNodes.
|
|
1393
|
+
*/
|
|
1394
|
+
deleteUnusedNodes(unusedRoutes) {
|
|
1395
|
+
throw new Error("deleteUnusedRoutes should not be called");
|
|
1396
|
+
}
|
|
1397
|
+
/**
|
|
1398
|
+
* After GC has run and identified nodes that are sweep ready, this is called to delete the sweep ready nodes.
|
|
1399
|
+
* @param sweepReadyRoutes - The routes of nodes that are sweep ready and should be deleted.
|
|
1400
|
+
* @returns - The routes of nodes that were deleted.
|
|
1401
|
+
*/
|
|
1402
|
+
deleteSweepReadyNodes(sweepReadyRoutes) {
|
|
1403
|
+
const { dataStoreRoutes, blobManagerRoutes } = this.getDataStoreAndBlobManagerRoutes(sweepReadyRoutes);
|
|
1404
|
+
const deletedRoutes = this.dataStores.deleteSweepReadyNodes(dataStoreRoutes);
|
|
1405
|
+
return deletedRoutes.concat(this.blobManager.deleteSweepReadyNodes(blobManagerRoutes));
|
|
1406
|
+
}
|
|
1354
1407
|
/**
|
|
1355
1408
|
* This is called to update objects that are tombstones.
|
|
1356
1409
|
* @param tombstonedRoutes - Data store and attachment blob routes that are tombstones in this Container.
|
|
@@ -1376,9 +1429,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1376
1429
|
getNodeType(nodePath) {
|
|
1377
1430
|
var _a;
|
|
1378
1431
|
if (this.isBlobPath(nodePath)) {
|
|
1379
|
-
return
|
|
1432
|
+
return gc_1.GCNodeType.Blob;
|
|
1380
1433
|
}
|
|
1381
|
-
return (_a = this.dataStores.getGCNodeType(nodePath)) !== null && _a !== void 0 ? _a :
|
|
1434
|
+
return (_a = this.dataStores.getGCNodeType(nodePath)) !== null && _a !== void 0 ? _a : gc_1.GCNodeType.Other;
|
|
1382
1435
|
}
|
|
1383
1436
|
/**
|
|
1384
1437
|
* Called by GC to retrieve the package path of the node with the given path. The node should belong to a
|
|
@@ -1386,10 +1439,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1386
1439
|
*/
|
|
1387
1440
|
async getGCNodePackagePath(nodePath) {
|
|
1388
1441
|
switch (this.getNodeType(nodePath)) {
|
|
1389
|
-
case
|
|
1442
|
+
case gc_1.GCNodeType.Blob:
|
|
1390
1443
|
return [blobManager_1.BlobManager.basePath];
|
|
1391
|
-
case
|
|
1392
|
-
case
|
|
1444
|
+
case gc_1.GCNodeType.DataStore:
|
|
1445
|
+
case gc_1.GCNodeType.SubDataStore:
|
|
1393
1446
|
return this.dataStores.getDataStorePackagePath(nodePath);
|
|
1394
1447
|
default:
|
|
1395
1448
|
(0, common_utils_1.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
|
|
@@ -1428,8 +1481,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1428
1481
|
* Runs garbage collection and updates the reference / used state of the nodes in the container.
|
|
1429
1482
|
* @returns the statistics of the garbage collection run; undefined if GC did not run.
|
|
1430
1483
|
*/
|
|
1431
|
-
async collectGarbage(options) {
|
|
1432
|
-
return this.garbageCollector.collectGarbage(options);
|
|
1484
|
+
async collectGarbage(options, telemetryContext) {
|
|
1485
|
+
return this.garbageCollector.collectGarbage(options, telemetryContext);
|
|
1433
1486
|
}
|
|
1434
1487
|
/**
|
|
1435
1488
|
* Called when a new outbound reference is added to another node. This is used by garbage collection to identify
|
|
@@ -1450,7 +1503,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1450
1503
|
*/
|
|
1451
1504
|
async submitSummary(options) {
|
|
1452
1505
|
var _a, _b;
|
|
1453
|
-
const { fullTree, refreshLatestAck, summaryLogger } = options;
|
|
1506
|
+
const { fullTree = false, refreshLatestAck, summaryLogger } = options;
|
|
1454
1507
|
// The summary number for this summary. This will be updated during the summary process, so get it now and
|
|
1455
1508
|
// use it for all events logged during this summary.
|
|
1456
1509
|
const summaryNumber = this.nextSummaryNumber;
|
|
@@ -1466,8 +1519,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1466
1519
|
// We might need to catch up to the latest summary's reference sequence number before pausing.
|
|
1467
1520
|
await this.waitForDeltaManagerToCatchup(latestSnapshotRefSeq, summaryNumberLogger);
|
|
1468
1521
|
}
|
|
1522
|
+
const shouldPauseInboundSignal = this.mc.config.getBoolean("Fluid.ContainerRuntime.SubmitSummary.disableInboundSignalPause") !== true;
|
|
1469
1523
|
try {
|
|
1470
1524
|
await this.deltaManager.inbound.pause();
|
|
1525
|
+
if (shouldPauseInboundSignal) {
|
|
1526
|
+
await this.deltaManager.inboundSignal.pause();
|
|
1527
|
+
}
|
|
1471
1528
|
const summaryRefSeqNum = this.deltaManager.lastSequenceNumber;
|
|
1472
1529
|
const minimumSequenceNumber = this.deltaManager.minimumSequenceNumber;
|
|
1473
1530
|
const message = `Summary @${summaryRefSeqNum}:${this.deltaManager.minimumSequenceNumber}`;
|
|
@@ -1523,7 +1580,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1523
1580
|
const forcedFullTree = this.garbageCollector.summaryStateNeedsReset;
|
|
1524
1581
|
try {
|
|
1525
1582
|
summarizeResult = await this.summarize({
|
|
1526
|
-
fullTree: fullTree
|
|
1583
|
+
fullTree: fullTree || forcedFullTree,
|
|
1527
1584
|
trackState: true,
|
|
1528
1585
|
summaryLogger: summaryNumberLogger,
|
|
1529
1586
|
runGC: this.garbageCollector.shouldRunGC,
|
|
@@ -1612,7 +1669,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1612
1669
|
}
|
|
1613
1670
|
let clientSequenceNumber;
|
|
1614
1671
|
try {
|
|
1615
|
-
clientSequenceNumber = this.submitSummaryMessage(summaryMessage);
|
|
1672
|
+
clientSequenceNumber = this.submitSummaryMessage(summaryMessage, summaryRefSeqNum);
|
|
1616
1673
|
}
|
|
1617
1674
|
catch (error) {
|
|
1618
1675
|
return Object.assign(Object.assign({ stage: "upload" }, uploadData), { error });
|
|
@@ -1626,6 +1683,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1626
1683
|
this.summarizerNode.clearSummary();
|
|
1627
1684
|
// Restart the delta manager
|
|
1628
1685
|
this.deltaManager.inbound.resume();
|
|
1686
|
+
if (shouldPauseInboundSignal) {
|
|
1687
|
+
this.deltaManager.inboundSignal.resume();
|
|
1688
|
+
}
|
|
1629
1689
|
}
|
|
1630
1690
|
}
|
|
1631
1691
|
hasPendingMessages() {
|
|
@@ -1671,9 +1731,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1671
1731
|
this.verifyCanSubmitOps();
|
|
1672
1732
|
// There should be no ops in detached container state!
|
|
1673
1733
|
(0, common_utils_1.assert)(this.attachState !== container_definitions_1.AttachState.Detached, 0x132 /* "sending ops in detached container" */);
|
|
1674
|
-
const
|
|
1675
|
-
|
|
1676
|
-
|
|
1734
|
+
const serializedContent = JSON.stringify({ type, contents });
|
|
1735
|
+
// Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
|
|
1736
|
+
// container runtime's ability to submit ops depend on the actual readonly state of the delta manager.
|
|
1737
|
+
if (this.innerDeltaManager.readOnlyInfo.readonly) {
|
|
1677
1738
|
this.logger.sendTelemetryEvent({
|
|
1678
1739
|
eventName: "SubmitOpInReadonly",
|
|
1679
1740
|
connected: this.connected,
|
|
@@ -1681,7 +1742,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1681
1742
|
}
|
|
1682
1743
|
const message = {
|
|
1683
1744
|
contents: serializedContent,
|
|
1684
|
-
deserializedContent,
|
|
1745
|
+
deserializedContent: JSON.parse(serializedContent),
|
|
1685
1746
|
metadata,
|
|
1686
1747
|
localOpMetadata,
|
|
1687
1748
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
@@ -1709,7 +1770,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1709
1770
|
// optimization no longer makes sense (for example, batch compression may make it less appealing).
|
|
1710
1771
|
if (this.currentlyBatching() &&
|
|
1711
1772
|
type === ContainerMessageType.Attach &&
|
|
1712
|
-
this.
|
|
1773
|
+
this.disableAttachReorder !== true) {
|
|
1713
1774
|
this.outbox.submitAttach(message);
|
|
1714
1775
|
}
|
|
1715
1776
|
else {
|
|
@@ -1718,17 +1779,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1718
1779
|
if (!this.currentlyBatching()) {
|
|
1719
1780
|
this.flush();
|
|
1720
1781
|
}
|
|
1721
|
-
else
|
|
1722
|
-
this.
|
|
1723
|
-
// Queue a microtask to detect the end of the turn and force a flush.
|
|
1724
|
-
Promise.resolve()
|
|
1725
|
-
.then(() => {
|
|
1726
|
-
this.flushMicroTaskExists = false;
|
|
1727
|
-
this.flush();
|
|
1728
|
-
})
|
|
1729
|
-
.catch((error) => {
|
|
1730
|
-
this.closeFn(error);
|
|
1731
|
-
});
|
|
1782
|
+
else {
|
|
1783
|
+
this.scheduleFlush();
|
|
1732
1784
|
}
|
|
1733
1785
|
}
|
|
1734
1786
|
catch (error) {
|
|
@@ -1739,14 +1791,47 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1739
1791
|
this.updateDocumentDirtyState(true);
|
|
1740
1792
|
}
|
|
1741
1793
|
}
|
|
1742
|
-
|
|
1794
|
+
scheduleFlush() {
|
|
1795
|
+
if (this.flushTaskExists) {
|
|
1796
|
+
return;
|
|
1797
|
+
}
|
|
1798
|
+
this.flushTaskExists = true;
|
|
1799
|
+
const flush = () => {
|
|
1800
|
+
this.flushTaskExists = false;
|
|
1801
|
+
try {
|
|
1802
|
+
this.flush();
|
|
1803
|
+
}
|
|
1804
|
+
catch (error) {
|
|
1805
|
+
this.closeFn(error);
|
|
1806
|
+
}
|
|
1807
|
+
};
|
|
1808
|
+
switch (this.flushMode) {
|
|
1809
|
+
case runtime_definitions_1.FlushMode.TurnBased:
|
|
1810
|
+
// When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
|
|
1811
|
+
// batch at the end of the turn
|
|
1812
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1813
|
+
Promise.resolve().then(flush);
|
|
1814
|
+
break;
|
|
1815
|
+
// FlushModeExperimental is experimental and not exposed directly in the runtime APIs
|
|
1816
|
+
case runtime_definitions_1.FlushModeExperimental.Async:
|
|
1817
|
+
// When in Async flush mode, the runtime will accumulate all operations across JS turns and send them as a single
|
|
1818
|
+
// batch when all micro-tasks are complete.
|
|
1819
|
+
// Compared to TurnBased, this flush mode will capture more ops into the same batch.
|
|
1820
|
+
setTimeout(flush, 0);
|
|
1821
|
+
break;
|
|
1822
|
+
default:
|
|
1823
|
+
(0, common_utils_1.assert)(this._orderSequentiallyCalls > 0, 0x587 /* Unreachable unless running under orderSequentially */);
|
|
1824
|
+
break;
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
submitSummaryMessage(contents, referenceSequenceNumber) {
|
|
1743
1828
|
this.verifyNotClosed();
|
|
1744
1829
|
(0, common_utils_1.assert)(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
|
|
1745
1830
|
// System message should not be sent in the middle of the batch.
|
|
1746
1831
|
(0, common_utils_1.assert)(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
|
|
1747
1832
|
// back-compat: ADO #1385: Make this call unconditional in the future
|
|
1748
1833
|
return this.context.submitSummaryFn !== undefined
|
|
1749
|
-
? this.context.submitSummaryFn(contents)
|
|
1834
|
+
? this.context.submitSummaryFn(contents, referenceSequenceNumber)
|
|
1750
1835
|
: this.context.submitFn(protocol_definitions_1.MessageType.Summarize, contents, false);
|
|
1751
1836
|
}
|
|
1752
1837
|
/**
|
|
@@ -1842,14 +1927,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1842
1927
|
// The call to fetch the snapshot is very expensive and not always needed.
|
|
1843
1928
|
// It should only be done by the summarizerNode, if required.
|
|
1844
1929
|
// When fetching from storage we will always get the latest version and do not use the ackHandle.
|
|
1845
|
-
const
|
|
1846
|
-
|
|
1847
|
-
eventName: "
|
|
1930
|
+
const fetchLatestSnapshot = async () => {
|
|
1931
|
+
let fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
|
|
1932
|
+
eventName: "RefreshLatestSummaryAckFetch",
|
|
1848
1933
|
ackHandle,
|
|
1849
|
-
summaryRefSeq,
|
|
1850
|
-
|
|
1851
|
-
});
|
|
1852
|
-
const latestSnapshotRefSeq = await (0, runtime_utils_1.seqFromTree)(fetchResult.snapshotTree, readAndParseBlob);
|
|
1934
|
+
targetSequenceNumber: summaryRefSeq,
|
|
1935
|
+
}, readAndParseBlob);
|
|
1853
1936
|
/**
|
|
1854
1937
|
* If the fetched snapshot is older than the one for which the ack was received, close the container.
|
|
1855
1938
|
* This should never happen because an ack should be sent after the latest summary is updated in the server.
|
|
@@ -1860,29 +1943,34 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1860
1943
|
* such cases, the file will be rolled back along with the ack and we will eventually reach a consistent
|
|
1861
1944
|
* state.
|
|
1862
1945
|
*/
|
|
1863
|
-
if (latestSnapshotRefSeq < summaryRefSeq) {
|
|
1864
|
-
|
|
1946
|
+
if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
|
|
1947
|
+
/* before failing, let's try to retrieve the latest snapshot for that specific ackHandle */
|
|
1948
|
+
fetchResult = await this.fetchSnapshotFromStorage(summaryLogger, {
|
|
1949
|
+
eventName: "RefreshLatestSummaryAckFetch",
|
|
1865
1950
|
ackHandle,
|
|
1866
|
-
summaryRefSeq,
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1951
|
+
targetSequenceNumber: summaryRefSeq,
|
|
1952
|
+
}, readAndParseBlob, ackHandle);
|
|
1953
|
+
if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
|
|
1954
|
+
const error = container_utils_1.DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
|
|
1955
|
+
ackHandle,
|
|
1956
|
+
summaryRefSeq,
|
|
1957
|
+
fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
|
|
1958
|
+
});
|
|
1959
|
+
this.closeFn(error);
|
|
1960
|
+
throw error;
|
|
1961
|
+
}
|
|
1871
1962
|
}
|
|
1872
|
-
summaryLogger.sendTelemetryEvent({
|
|
1873
|
-
eventName: "LatestSummaryRetrieved",
|
|
1874
|
-
ackHandle,
|
|
1875
|
-
lastSequenceNumber: latestSnapshotRefSeq,
|
|
1876
|
-
targetSequenceNumber: summaryRefSeq,
|
|
1877
|
-
});
|
|
1878
1963
|
// In case we had to retrieve the latest snapshot and it is different than summaryRefSeq,
|
|
1879
1964
|
// wait for the delta manager to catch up before refreshing the latest Summary.
|
|
1880
|
-
await this.waitForDeltaManagerToCatchup(latestSnapshotRefSeq, summaryLogger);
|
|
1881
|
-
return
|
|
1965
|
+
await this.waitForDeltaManagerToCatchup(fetchResult.latestSnapshotRefSeq, summaryLogger);
|
|
1966
|
+
return {
|
|
1967
|
+
snapshotTree: fetchResult.snapshotTree,
|
|
1968
|
+
snapshotRefSeq: fetchResult.latestSnapshotRefSeq,
|
|
1969
|
+
};
|
|
1882
1970
|
};
|
|
1883
|
-
const result = await this.summarizerNode.refreshLatestSummary(proposalHandle, summaryRefSeq,
|
|
1971
|
+
const result = await this.summarizerNode.refreshLatestSummary(proposalHandle, summaryRefSeq, fetchLatestSnapshot, readAndParseBlob, summaryLogger);
|
|
1884
1972
|
// Notify the garbage collector so it can update its latest summary state.
|
|
1885
|
-
await this.garbageCollector.refreshLatestSummary(
|
|
1973
|
+
await this.garbageCollector.refreshLatestSummary(proposalHandle, result, readAndParseBlob);
|
|
1886
1974
|
}
|
|
1887
1975
|
/**
|
|
1888
1976
|
* Fetches the latest snapshot from storage and uses it to refresh SummarizerNode's
|
|
@@ -1891,53 +1979,54 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1891
1979
|
* @returns downloaded snapshot's reference sequence number
|
|
1892
1980
|
*/
|
|
1893
1981
|
async refreshLatestSummaryAckFromServer(summaryLogger) {
|
|
1894
|
-
const { snapshotTree, versionId } = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
|
|
1895
|
-
eventName: "RefreshLatestSummaryGetSnapshot",
|
|
1896
|
-
fetchLatest: true,
|
|
1897
|
-
});
|
|
1898
1982
|
const readAndParseBlob = async (id) => (0, driver_utils_1.readAndParse)(this.storage, id);
|
|
1899
|
-
const latestSnapshotRefSeq = await
|
|
1900
|
-
|
|
1983
|
+
const { snapshotTree, versionId, latestSnapshotRefSeq } = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
|
|
1984
|
+
eventName: "RefreshLatestSummaryFromServerFetch",
|
|
1985
|
+
}, readAndParseBlob);
|
|
1986
|
+
const fetchLatestSnapshot = {
|
|
1987
|
+
snapshotTree,
|
|
1988
|
+
snapshotRefSeq: latestSnapshotRefSeq,
|
|
1989
|
+
};
|
|
1990
|
+
const result = await this.summarizerNode.refreshLatestSummary(undefined /* proposalHandle */, latestSnapshotRefSeq, async () => fetchLatestSnapshot, readAndParseBlob, summaryLogger);
|
|
1901
1991
|
// Notify the garbage collector so it can update its latest summary state.
|
|
1902
|
-
await this.garbageCollector.refreshLatestSummary(
|
|
1992
|
+
await this.garbageCollector.refreshLatestSummary(undefined /* proposalHandle */, result, readAndParseBlob);
|
|
1903
1993
|
return { latestSnapshotRefSeq, latestSnapshotVersionId: versionId };
|
|
1904
1994
|
}
|
|
1905
|
-
async fetchLatestSnapshotFromStorage(logger, event) {
|
|
1995
|
+
async fetchLatestSnapshotFromStorage(logger, event, readAndParseBlob) {
|
|
1996
|
+
return this.fetchSnapshotFromStorage(logger, event, readAndParseBlob, null /* latest */);
|
|
1997
|
+
}
|
|
1998
|
+
async fetchSnapshotFromStorage(logger, event, readAndParseBlob, versionId) {
|
|
1999
|
+
var _a;
|
|
2000
|
+
const recoveryMethod = this.mc.config.getString("Fluid.ContainerRuntime.Test.SummarizationRecoveryMethod");
|
|
2001
|
+
if (recoveryMethod === "restart") {
|
|
2002
|
+
const error = new container_utils_1.GenericError("Restarting summarizer instead of refreshing");
|
|
2003
|
+
this.mc.logger.sendTelemetryEvent(Object.assign(Object.assign({}, event), { eventName: "ClosingSummarizerOnSummaryStale", codePath: event.eventName, message: "Stopping fetch from storage", versionId: versionId != null ? versionId : undefined }), error);
|
|
2004
|
+
(_a = this._summarizer) === null || _a === void 0 ? void 0 : _a.stop("latestSummaryStateStale");
|
|
2005
|
+
this.closeFn();
|
|
2006
|
+
throw error;
|
|
2007
|
+
}
|
|
1906
2008
|
return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
|
|
1907
2009
|
const stats = {};
|
|
1908
2010
|
const trace = common_utils_1.Trace.start();
|
|
1909
|
-
const versions = await this.storage.getVersions(
|
|
2011
|
+
const versions = await this.storage.getVersions(versionId, 1, "refreshLatestSummaryAckFromServer", versionId === null ? driver_definitions_1.FetchSource.noCache : undefined);
|
|
1910
2012
|
(0, common_utils_1.assert)(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
|
|
1911
2013
|
stats.getVersionDuration = trace.trace().duration;
|
|
1912
2014
|
const maybeSnapshot = await this.storage.getSnapshotTree(versions[0]);
|
|
1913
2015
|
(0, common_utils_1.assert)(!!maybeSnapshot, 0x138 /* "Failed to get snapshot from storage" */);
|
|
1914
2016
|
stats.getSnapshotDuration = trace.trace().duration;
|
|
2017
|
+
const latestSnapshotRefSeq = await (0, runtime_utils_1.seqFromTree)(maybeSnapshot, readAndParseBlob);
|
|
2018
|
+
stats.snapshotRefSeq = latestSnapshotRefSeq;
|
|
2019
|
+
stats.snapshotVersion = versions[0].id;
|
|
1915
2020
|
perfEvent.end(stats);
|
|
1916
|
-
return {
|
|
2021
|
+
return {
|
|
2022
|
+
snapshotTree: maybeSnapshot,
|
|
2023
|
+
versionId: versions[0].id,
|
|
2024
|
+
latestSnapshotRefSeq,
|
|
2025
|
+
};
|
|
1917
2026
|
});
|
|
1918
2027
|
}
|
|
1919
|
-
notifyAttaching(
|
|
1920
|
-
var _a;
|
|
1921
|
-
if ((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) {
|
|
1922
|
-
this.baseSnapshotBlobs =
|
|
1923
|
-
serializedSnapshotStorage_1.SerializedSnapshotStorage.serializeTreeWithBlobContents(snapshot);
|
|
1924
|
-
}
|
|
1925
|
-
}
|
|
1926
|
-
async initializeBaseSnapshotBlobs() {
|
|
1927
|
-
var _a;
|
|
1928
|
-
if (!((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) ||
|
|
1929
|
-
this.attachState !== container_definitions_1.AttachState.Attached ||
|
|
1930
|
-
this.context.pendingLocalState) {
|
|
1931
|
-
return;
|
|
1932
|
-
}
|
|
1933
|
-
(0, common_utils_1.assert)(!!this.context.baseSnapshot, 0x2e5 /* "Must have a base snapshot" */);
|
|
1934
|
-
this.baseSnapshotBlobs = await serializedSnapshotStorage_1.SerializedSnapshotStorage.serializeTree(this.context.baseSnapshot, this.storage);
|
|
1935
|
-
}
|
|
2028
|
+
notifyAttaching() { } // do nothing (deprecated method)
|
|
1936
2029
|
getPendingLocalState() {
|
|
1937
|
-
var _a;
|
|
1938
|
-
if (!((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad)) {
|
|
1939
|
-
throw new container_utils_1.UsageError("can't get state when offline load disabled");
|
|
1940
|
-
}
|
|
1941
2030
|
if (this._orderSequentiallyCalls !== 0) {
|
|
1942
2031
|
throw new container_utils_1.UsageError("can't get state during orderSequentially");
|
|
1943
2032
|
}
|
|
@@ -1945,24 +2034,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1945
2034
|
// getPendingLocalState() is only exposed through Container.closeAndGetPendingLocalState(), so it's safe
|
|
1946
2035
|
// to close current batch.
|
|
1947
2036
|
this.flush();
|
|
1948
|
-
const previousPendingState = this.context.pendingLocalState;
|
|
1949
|
-
if (previousPendingState) {
|
|
1950
|
-
return {
|
|
1951
|
-
pending: this.pendingStateManager.getLocalState(),
|
|
1952
|
-
pendingAttachmentBlobs: this.blobManager.getPendingBlobs(),
|
|
1953
|
-
snapshotBlobs: previousPendingState.snapshotBlobs,
|
|
1954
|
-
baseSnapshot: previousPendingState.baseSnapshot,
|
|
1955
|
-
savedOps: this.savedOps,
|
|
1956
|
-
};
|
|
1957
|
-
}
|
|
1958
|
-
(0, common_utils_1.assert)(!!this.context.baseSnapshot, 0x2e6 /* "Must have a base snapshot" */);
|
|
1959
|
-
(0, common_utils_1.assert)(!!this.baseSnapshotBlobs, 0x2e7 /* "Must serialize base snapshot blobs before getting runtime state" */);
|
|
1960
2037
|
return {
|
|
1961
2038
|
pending: this.pendingStateManager.getLocalState(),
|
|
1962
2039
|
pendingAttachmentBlobs: this.blobManager.getPendingBlobs(),
|
|
1963
|
-
snapshotBlobs: this.baseSnapshotBlobs,
|
|
1964
|
-
baseSnapshot: this.context.baseSnapshot,
|
|
1965
|
-
savedOps: this.savedOps,
|
|
1966
2040
|
};
|
|
1967
2041
|
}
|
|
1968
2042
|
/**
|
|
@@ -1976,7 +2050,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1976
2050
|
[container_definitions_1.LoaderHeader.cache]: false,
|
|
1977
2051
|
[container_definitions_1.LoaderHeader.clientDetails]: {
|
|
1978
2052
|
capabilities: { interactive: false },
|
|
1979
|
-
type:
|
|
2053
|
+
type: summary_1.summarizerClientType,
|
|
1980
2054
|
},
|
|
1981
2055
|
[driver_definitions_1.DriverHeader.summarizingClient]: true,
|
|
1982
2056
|
[container_definitions_1.LoaderHeader.reconnect]: false,
|
|
@@ -1991,20 +2065,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1991
2065
|
return summarizer;
|
|
1992
2066
|
};
|
|
1993
2067
|
}
|
|
1994
|
-
async processSavedOps(state) {
|
|
1995
|
-
for (const op of state.savedOps) {
|
|
1996
|
-
this.process(op, false);
|
|
1997
|
-
await this.pendingStateManager.applyStashedOpsAt(op.sequenceNumber);
|
|
1998
|
-
}
|
|
1999
|
-
// we may not have seen every sequence number (because of system ops) so apply everything once we
|
|
2000
|
-
// don't have any more saved ops
|
|
2001
|
-
await this.pendingStateManager.applyStashedOpsAt();
|
|
2002
|
-
// If it's not the case, we should take it into account when calculating dirty state.
|
|
2003
|
-
(0, common_utils_1.assert)(this.context.attachState === container_definitions_1.AttachState.Attached, 0x3d5 /* this function is called for attached containers only */);
|
|
2004
|
-
if (!this.hasPendingMessages()) {
|
|
2005
|
-
this.updateDocumentDirtyState(false);
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
2068
|
validateSummaryHeuristicConfiguration(configuration) {
|
|
2009
2069
|
// eslint-disable-next-line no-restricted-syntax
|
|
2010
2070
|
for (const prop in configuration) {
|
|
@@ -2016,6 +2076,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
2016
2076
|
throw new container_utils_1.UsageError(`"minIdleTime" [${configuration.minIdleTime}] cannot be greater than "maxIdleTime" [${configuration.maxIdleTime}]`);
|
|
2017
2077
|
}
|
|
2018
2078
|
}
|
|
2079
|
+
get groupedBatchingEnabled() {
|
|
2080
|
+
const killSwitch = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableGroupedBatching");
|
|
2081
|
+
return killSwitch !== true && this.runtimeOptions.enableGroupedBatching;
|
|
2082
|
+
}
|
|
2019
2083
|
}
|
|
2020
2084
|
exports.ContainerRuntime = ContainerRuntime;
|
|
2021
2085
|
/**
|