@fluidframework/container-runtime 2.0.0-internal.3.0.2 → 2.0.0-internal.3.2.0
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/.eslintrc.js +19 -19
- package/.mocharc.js +2 -2
- package/api-extractor.json +2 -2
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +2 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +15 -2
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +109 -37
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +11 -9
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js +3 -1
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +23 -11
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +225 -132
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +11 -9
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +27 -13
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +95 -56
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +7 -3
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/dataStoreRegistry.js +3 -1
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/dataStores.d.ts +28 -4
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +122 -44
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +8 -3
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/{garbageCollection.d.ts → gc/garbageCollection.d.ts} +27 -203
- package/dist/gc/garbageCollection.d.ts.map +1 -0
- package/dist/{garbageCollection.js → gc/garbageCollection.js} +210 -400
- package/dist/gc/garbageCollection.js.map +1 -0
- package/dist/gc/gcDefinitions.d.ts +189 -0
- package/dist/gc/gcDefinitions.d.ts.map +1 -0
- package/dist/{garbageCollectionConstants.js → gc/gcDefinitions.js} +27 -2
- package/dist/gc/gcDefinitions.js.map +1 -0
- package/dist/gc/gcHelpers.d.ts +30 -0
- package/dist/gc/gcHelpers.d.ts.map +1 -0
- package/dist/gc/gcHelpers.js +65 -0
- package/dist/gc/gcHelpers.js.map +1 -0
- package/dist/gc/gcSummaryStateTracker.d.ts +86 -0
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
- package/dist/gc/gcSummaryStateTracker.js +246 -0
- package/dist/gc/gcSummaryStateTracker.js.map +1 -0
- package/{lib → dist/gc}/gcSweepReadyUsageDetection.d.ts +5 -5
- package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
- package/dist/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +15 -11
- 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 +11 -0
- package/dist/gc/index.d.ts.map +1 -0
- package/dist/gc/index.js +40 -0
- package/dist/gc/index.js.map +1 -0
- package/dist/index.d.ts +2 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -9
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +2 -13
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +19 -41
- 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.map +1 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +1 -0
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +5 -2
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +24 -13
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +19 -3
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +78 -45
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/opProperties.d.ts.map +1 -1
- package/dist/opProperties.js +1 -3
- package/dist/opProperties.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +8 -2
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +21 -13
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +3 -2
- package/dist/scheduleManager.js.map +1 -1
- package/dist/serializedSnapshotStorage.d.ts +2 -2
- package/dist/serializedSnapshotStorage.d.ts.map +1 -1
- package/dist/serializedSnapshotStorage.js +5 -3
- package/dist/serializedSnapshotStorage.js.map +1 -1
- package/dist/summary/index.d.ts +17 -0
- package/dist/summary/index.d.ts.map +1 -0
- package/dist/summary/index.js +47 -0
- package/dist/summary/index.js.map +1 -0
- package/dist/summary/orderedClientElection.d.ts.map +1 -0
- package/dist/{orderedClientElection.js → summary/orderedClientElection.js} +10 -4
- package/dist/summary/orderedClientElection.js.map +1 -0
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -0
- package/{lib → dist/summary}/runningSummarizer.d.ts +19 -18
- package/dist/summary/runningSummarizer.d.ts.map +1 -0
- package/dist/{runningSummarizer.js → summary/runningSummarizer.js} +191 -76
- package/dist/summary/runningSummarizer.js.map +1 -0
- package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +4 -6
- package/dist/summary/summarizer.d.ts.map +1 -0
- package/dist/{summarizer.js → summary/summarizer.js} +31 -71
- 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/summary/summarizerHandle.d.ts.map +1 -0
- package/dist/summary/summarizerHandle.js.map +1 -0
- package/{lib → dist/summary}/summarizerHeuristics.d.ts +1 -1
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
- package/dist/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -9
- package/dist/summary/summarizerHeuristics.js.map +1 -0
- package/{lib → dist/summary}/summarizerTypes.d.ts +22 -22
- package/dist/summary/summarizerTypes.d.ts.map +1 -0
- package/dist/summary/summarizerTypes.js.map +1 -0
- package/dist/summary/summaryCollection.d.ts.map +1 -0
- package/dist/{summaryCollection.js → summary/summaryCollection.js} +18 -8
- package/dist/summary/summaryCollection.js.map +1 -0
- package/{lib → dist/summary}/summaryFormat.d.ts +1 -40
- package/dist/summary/summaryFormat.d.ts.map +1 -0
- package/dist/{summaryFormat.js → summary/summaryFormat.js} +19 -20
- package/dist/summary/summaryFormat.js.map +1 -0
- package/dist/summary/summaryGenerator.d.ts.map +1 -0
- package/dist/{summaryGenerator.js → summary/summaryGenerator.js} +33 -15
- 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/{summaryManager.js → summary/summaryManager.js} +21 -9
- package/dist/summary/summaryManager.js.map +1 -0
- package/dist/throttler.d.ts +2 -2
- package/dist/throttler.d.ts.map +1 -1
- package/dist/throttler.js +4 -4
- package/dist/throttler.js.map +1 -1
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +2 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +15 -2
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +109 -37
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +11 -9
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js +3 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +23 -11
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +201 -108
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +11 -9
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +27 -13
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +84 -45
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +7 -3
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.d.ts.map +1 -1
- package/lib/dataStoreRegistry.js +3 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/dataStores.d.ts +28 -4
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +120 -42
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +9 -4
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/{garbageCollection.d.ts → gc/garbageCollection.d.ts} +27 -203
- package/lib/gc/garbageCollection.d.ts.map +1 -0
- package/lib/{garbageCollection.js → gc/garbageCollection.js} +190 -379
- package/lib/gc/garbageCollection.js.map +1 -0
- package/lib/gc/gcDefinitions.d.ts +189 -0
- package/lib/gc/gcDefinitions.d.ts.map +1 -0
- package/lib/{garbageCollectionConstants.js → gc/gcDefinitions.js} +26 -1
- package/lib/gc/gcDefinitions.js.map +1 -0
- package/lib/gc/gcHelpers.d.ts +30 -0
- package/lib/gc/gcHelpers.d.ts.map +1 -0
- package/lib/gc/gcHelpers.js +58 -0
- package/lib/gc/gcHelpers.js.map +1 -0
- package/lib/gc/gcSummaryStateTracker.d.ts +86 -0
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
- package/lib/gc/gcSummaryStateTracker.js +242 -0
- package/lib/gc/gcSummaryStateTracker.js.map +1 -0
- package/{dist → lib/gc}/gcSweepReadyUsageDetection.d.ts +5 -5
- package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
- package/lib/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +15 -11
- 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 +11 -0
- package/lib/gc/index.d.ts.map +1 -0
- package/lib/gc/index.js +11 -0
- package/lib/gc/index.js.map +1 -0
- package/lib/index.d.ts +2 -5
- 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 +2 -13
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +19 -41
- 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.map +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +1 -0
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +5 -2
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +25 -14
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +19 -3
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +79 -46
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/opProperties.d.ts.map +1 -1
- package/lib/opProperties.js +1 -3
- package/lib/opProperties.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +8 -2
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +21 -13
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +3 -2
- package/lib/scheduleManager.js.map +1 -1
- package/lib/serializedSnapshotStorage.d.ts +2 -2
- package/lib/serializedSnapshotStorage.d.ts.map +1 -1
- package/lib/serializedSnapshotStorage.js +5 -3
- package/lib/serializedSnapshotStorage.js.map +1 -1
- 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/{orderedClientElection.js → summary/orderedClientElection.js} +10 -4
- package/lib/summary/orderedClientElection.js.map +1 -0
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
- package/{dist → lib/summary}/runningSummarizer.d.ts +19 -18
- package/lib/summary/runningSummarizer.d.ts.map +1 -0
- package/lib/{runningSummarizer.js → summary/runningSummarizer.js} +193 -78
- package/lib/summary/runningSummarizer.js.map +1 -0
- package/lib/{summarizer.d.ts → summary/summarizer.d.ts} +4 -6
- package/lib/summary/summarizer.d.ts.map +1 -0
- package/lib/{summarizer.js → summary/summarizer.js} +33 -73
- 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/summary/summarizerHandle.d.ts.map +1 -0
- package/lib/summary/summarizerHandle.js.map +1 -0
- package/{dist → lib/summary}/summarizerHeuristics.d.ts +1 -1
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
- package/lib/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -9
- package/lib/summary/summarizerHeuristics.js.map +1 -0
- package/{dist → lib/summary}/summarizerTypes.d.ts +22 -22
- package/lib/summary/summarizerTypes.d.ts.map +1 -0
- package/lib/summary/summarizerTypes.js.map +1 -0
- package/lib/summary/summaryCollection.d.ts.map +1 -0
- package/lib/{summaryCollection.js → summary/summaryCollection.js} +18 -8
- package/lib/summary/summaryCollection.js.map +1 -0
- package/{dist → lib/summary}/summaryFormat.d.ts +1 -40
- package/lib/summary/summaryFormat.d.ts.map +1 -0
- package/lib/{summaryFormat.js → summary/summaryFormat.js} +20 -20
- package/lib/summary/summaryFormat.js.map +1 -0
- package/lib/summary/summaryGenerator.d.ts.map +1 -0
- package/lib/{summaryGenerator.js → summary/summaryGenerator.js} +33 -15
- 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/{summaryManager.js → summary/summaryManager.js} +21 -9
- package/lib/summary/summaryManager.js.map +1 -0
- package/lib/throttler.d.ts +2 -2
- package/lib/throttler.d.ts.map +1 -1
- package/lib/throttler.js +4 -4
- package/lib/throttler.js.map +1 -1
- package/package.json +60 -51
- package/prettier.config.cjs +1 -1
- package/src/batchTracker.ts +54 -49
- package/src/blobManager.ts +825 -674
- package/src/connectionTelemetry.ts +280 -249
- package/src/containerHandleContext.ts +27 -29
- package/src/containerRuntime.ts +3249 -2978
- package/src/dataStore.ts +172 -159
- package/src/dataStoreContext.ts +1141 -1057
- package/src/dataStoreContexts.ts +178 -161
- package/src/dataStoreRegistry.ts +25 -20
- package/src/dataStores.ts +880 -731
- package/src/deltaScheduler.ts +158 -150
- package/{garbageCollection.md → src/gc/garbageCollection.md} +16 -3
- package/src/gc/garbageCollection.ts +1506 -0
- package/src/gc/gcDefinitions.ts +244 -0
- package/src/gc/gcHelpers.ts +86 -0
- package/src/gc/gcSummaryStateTracker.ts +339 -0
- package/src/gc/gcSweepReadyUsageDetection.ts +145 -0
- package/src/gc/gcUnreferencedStateTracker.ts +114 -0
- package/src/gc/index.ts +40 -0
- package/src/index.ts +67 -70
- package/src/opLifecycle/README.md +152 -0
- package/src/opLifecycle/batchManager.ts +101 -144
- package/src/opLifecycle/definitions.ts +33 -29
- package/src/opLifecycle/index.ts +5 -5
- package/src/opLifecycle/opCompressor.ts +55 -53
- package/src/opLifecycle/opDecompressor.ts +100 -81
- package/src/opLifecycle/opSplitter.ts +233 -188
- package/src/opLifecycle/outbox.ts +251 -195
- package/src/opLifecycle/remoteMessageProcessor.ts +62 -62
- package/src/opProperties.ts +11 -9
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +396 -338
- package/src/scheduleManager.ts +299 -269
- package/src/serializedSnapshotStorage.ts +126 -112
- package/src/summary/index.ts +99 -0
- package/src/summary/orderedClientElection.ts +564 -0
- package/src/summary/runWhileConnectedCoordinator.ts +113 -0
- package/src/summary/runningSummarizer.ts +788 -0
- package/src/summary/summarizer.ts +386 -0
- package/src/summary/summarizerClientElection.ts +139 -0
- package/src/{summarizerHandle.ts → summary/summarizerHandle.ts} +11 -9
- package/src/summary/summarizerHeuristics.ts +219 -0
- package/src/summary/summarizerTypes.ts +521 -0
- package/src/summary/summaryCollection.ts +450 -0
- package/src/summary/summaryFormat.ts +226 -0
- package/src/summary/summaryGenerator.ts +505 -0
- package/src/summary/summaryManager.ts +423 -0
- package/src/throttler.ts +131 -122
- package/tsconfig.esnext.json +6 -6
- package/tsconfig.json +9 -13
- package/dist/garbageCollection.d.ts.map +0 -1
- package/dist/garbageCollection.js.map +0 -1
- package/dist/garbageCollectionConstants.d.ts +0 -25
- package/dist/garbageCollectionConstants.d.ts.map +0 -1
- package/dist/garbageCollectionConstants.js.map +0 -1
- package/dist/garbageCollectionTombstoneUtils.d.ts +0 -14
- package/dist/garbageCollectionTombstoneUtils.d.ts.map +0 -1
- package/dist/garbageCollectionTombstoneUtils.js +0 -23
- package/dist/garbageCollectionTombstoneUtils.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/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.map +0 -1
- 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.map +0 -1
- package/lib/garbageCollection.js.map +0 -1
- package/lib/garbageCollectionConstants.d.ts +0 -25
- package/lib/garbageCollectionConstants.d.ts.map +0 -1
- package/lib/garbageCollectionConstants.js.map +0 -1
- package/lib/garbageCollectionTombstoneUtils.d.ts +0 -14
- package/lib/garbageCollectionTombstoneUtils.d.ts.map +0 -1
- package/lib/garbageCollectionTombstoneUtils.js +0 -19
- package/lib/garbageCollectionTombstoneUtils.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/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.map +0 -1
- 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.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/garbageCollection.ts +0 -1800
- package/src/garbageCollectionConstants.ts +0 -41
- package/src/garbageCollectionTombstoneUtils.ts +0 -28
- package/src/gcSweepReadyUsageDetection.ts +0 -139
- package/src/orderedClientElection.ts +0 -532
- package/src/runWhileConnectedCoordinator.ts +0 -106
- package/src/runningSummarizer.ts +0 -610
- package/src/summarizer.ts +0 -421
- package/src/summarizerClientElection.ts +0 -132
- package/src/summarizerHeuristics.ts +0 -222
- package/src/summarizerTypes.ts +0 -507
- package/src/summaryCollection.ts +0 -421
- package/src/summaryFormat.ts +0 -256
- package/src/summaryGenerator.ts +0 -450
- package/src/summaryManager.ts +0 -394
- /package/dist/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
- /package/dist/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +0 -0
- /package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.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/{summarizerHandle.d.ts → summary/summarizerHandle.d.ts} +0 -0
- /package/dist/{summarizerHandle.js → summary/summarizerHandle.js} +0 -0
- /package/dist/{summarizerTypes.js → summary/summarizerTypes.js} +0 -0
- /package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
- /package/dist/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
- /package/lib/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
- /package/lib/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +0 -0
- /package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.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/{summarizerHandle.d.ts → summary/summarizerHandle.d.ts} +0 -0
- /package/lib/{summarizerHandle.js → summary/summarizerHandle.js} +0 -0
- /package/lib/{summarizerTypes.js → summary/summarizerTypes.js} +0 -0
- /package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
- /package/lib/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
package/lib/containerRuntime.js
CHANGED
|
@@ -1,33 +1,27 @@
|
|
|
1
1
|
import { AttachState, LoaderHeader, } from "@fluidframework/container-definitions";
|
|
2
|
-
import { assert, Trace, TypedEventEmitter, unreachableCase
|
|
2
|
+
import { assert, Trace, TypedEventEmitter, unreachableCase } from "@fluidframework/common-utils";
|
|
3
3
|
import { ChildLogger, raiseConnectedEvent, PerformanceEvent, TaggedLoggerAdapter, loggerToMonitoringContext, wrapError, } from "@fluidframework/telemetry-utils";
|
|
4
4
|
import { DriverHeader, FetchSource, } from "@fluidframework/driver-definitions";
|
|
5
5
|
import { readAndParse } from "@fluidframework/driver-utils";
|
|
6
6
|
import { DataCorruptionError, DataProcessingError, GenericError, UsageError, } from "@fluidframework/container-utils";
|
|
7
7
|
import { MessageType, SummaryType, } from "@fluidframework/protocol-definitions";
|
|
8
|
-
import { FlushMode, gcTreeKey, channelsTreeName, } from "@fluidframework/runtime-definitions";
|
|
9
|
-
import { addBlobToSummary, addSummarizeResultToSummary, addTreeToSummary, createRootSummarizerNodeWithGC, RequestParser, create404Response, exceptionToResponse, requestFluidObject,
|
|
8
|
+
import { FlushMode, FlushModeExperimental, gcTreeKey, channelsTreeName, } from "@fluidframework/runtime-definitions";
|
|
9
|
+
import { addBlobToSummary, addSummarizeResultToSummary, addTreeToSummary, createRootSummarizerNodeWithGC, RequestParser, create404Response, exceptionToResponse, requestFluidObject, seqFromTree, calculateStats, TelemetryContext, } from "@fluidframework/runtime-utils";
|
|
10
10
|
import { GCDataBuilder, trimLeadingAndTrailingSlashes } from "@fluidframework/garbage-collector";
|
|
11
11
|
import { v4 as uuid } from "uuid";
|
|
12
12
|
import { ContainerFluidHandleContext } from "./containerHandleContext";
|
|
13
13
|
import { FluidDataStoreRegistry } from "./dataStoreRegistry";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { ReportOpPerfTelemetry, } from "./connectionTelemetry";
|
|
17
|
-
import { PendingStateManager, } from "./pendingStateManager";
|
|
14
|
+
import { ReportOpPerfTelemetry } from "./connectionTelemetry";
|
|
15
|
+
import { PendingStateManager } from "./pendingStateManager";
|
|
18
16
|
import { pkgVersion } from "./packageVersion";
|
|
19
17
|
import { BlobManager } from "./blobManager";
|
|
20
18
|
import { DataStores, getSummaryForDatastores } from "./dataStores";
|
|
21
|
-
import { aliasBlobName, blobsTreeName, chunksBlobName, electedSummarizerBlobName, extractSummaryMetadataMessage, metadataBlobName, wrapSummaryInChannelsTree, } from "./
|
|
22
|
-
import { SummaryCollection } from "./summaryCollection";
|
|
23
|
-
import { OrderedClientCollection, OrderedClientElection } from "./orderedClientElection";
|
|
24
|
-
import { SummarizerClientElection, summarizerClientType } from "./summarizerClientElection";
|
|
19
|
+
import { aliasBlobName, blobsTreeName, chunksBlobName, electedSummarizerBlobName, extractSummaryMetadataMessage, metadataBlobName, Summarizer, SummaryManager, wrapSummaryInChannelsTree, SummaryCollection, OrderedClientCollection, OrderedClientElection, SummarizerClientElection, summarizerClientType, RunWhileConnectedCoordinator, } from "./summary";
|
|
25
20
|
import { formExponentialFn, Throttler } from "./throttler";
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import { channelToDataStore, isDataStoreAliasMessage, } from "./dataStore";
|
|
21
|
+
import { GarbageCollector, GCNodeType, gcTombstoneGenerationOptionName, shouldAllowGcTombstoneEnforcement, } from "./gc";
|
|
22
|
+
import { channelToDataStore, isDataStoreAliasMessage } from "./dataStore";
|
|
29
23
|
import { BindBatchTracker } from "./batchTracker";
|
|
30
|
-
import { SerializedSnapshotStorage } from "./serializedSnapshotStorage";
|
|
24
|
+
import { SerializedSnapshotStorage, } from "./serializedSnapshotStorage";
|
|
31
25
|
import { ScheduleManager } from "./scheduleManager";
|
|
32
26
|
import { OpCompressor, OpDecompressor, Outbox, OpSplitter, RemoteMessageProcessor, } from "./opLifecycle";
|
|
33
27
|
export var ContainerMessageType;
|
|
@@ -66,11 +60,6 @@ export var RuntimeHeaders;
|
|
|
66
60
|
(function (RuntimeHeaders) {
|
|
67
61
|
/** True to wait for a data store to be created and loaded before returning it. */
|
|
68
62
|
RuntimeHeaders["wait"] = "wait";
|
|
69
|
-
/**
|
|
70
|
-
* True if the request is from an external app. Used for GC to handle scenarios where a data store
|
|
71
|
-
* is deleted and requested via an external app.
|
|
72
|
-
*/
|
|
73
|
-
RuntimeHeaders["externalRequest"] = "externalRequest";
|
|
74
63
|
/** True if the request is coming from an IFluidHandle. */
|
|
75
64
|
RuntimeHeaders["viaHandle"] = "viaHandle";
|
|
76
65
|
})(RuntimeHeaders || (RuntimeHeaders = {}));
|
|
@@ -81,7 +70,6 @@ export const TombstoneResponseHeaderKey = "isTombstoned";
|
|
|
81
70
|
/** Default values for Runtime Headers */
|
|
82
71
|
export const defaultRuntimeHeaderData = {
|
|
83
72
|
wait: true,
|
|
84
|
-
externalRequest: false,
|
|
85
73
|
viaHandle: false,
|
|
86
74
|
allowTombstone: false,
|
|
87
75
|
};
|
|
@@ -134,8 +122,7 @@ export function getDeviceSpec() {
|
|
|
134
122
|
};
|
|
135
123
|
}
|
|
136
124
|
}
|
|
137
|
-
catch (_a) {
|
|
138
|
-
}
|
|
125
|
+
catch (_a) { }
|
|
139
126
|
return {};
|
|
140
127
|
}
|
|
141
128
|
/**
|
|
@@ -147,7 +134,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
147
134
|
* @internal
|
|
148
135
|
*/
|
|
149
136
|
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, requestHandler, summaryConfiguration) {
|
|
150
|
-
var _a, _b, _c, _d, _e, _f;
|
|
137
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
151
138
|
if (summaryConfiguration === void 0) { summaryConfiguration = Object.assign(Object.assign({}, DefaultSummaryConfiguration), (_a = runtimeOptions.summaryOptions) === null || _a === void 0 ? void 0 : _a.summaryConfigOverrides); }
|
|
152
139
|
super();
|
|
153
140
|
this.context = context;
|
|
@@ -160,7 +147,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
160
147
|
this.summaryConfiguration = summaryConfiguration;
|
|
161
148
|
this.defaultMaxConsecutiveReconnects = 7;
|
|
162
149
|
this._orderSequentiallyCalls = 0;
|
|
163
|
-
this.
|
|
150
|
+
this.flushTaskExists = false;
|
|
164
151
|
this.savedOps = [];
|
|
165
152
|
this.consecutiveReconnects = 0;
|
|
166
153
|
this.ensureNoDataModelChangesCalls = 0;
|
|
@@ -230,28 +217,48 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
230
217
|
this.nextSummaryNumber = loadSummaryNumber + 1;
|
|
231
218
|
this.messageAtLastSummary = metadata === null || metadata === void 0 ? void 0 : metadata.message;
|
|
232
219
|
this._connected = this.context.connected;
|
|
220
|
+
this.gcTombstoneEnforcementAllowed = shouldAllowGcTombstoneEnforcement((_c = metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix) === null || _c === void 0 ? void 0 : _c.tombstoneGeneration /* persisted */, this.runtimeOptions.gcOptions[gcTombstoneGenerationOptionName] /* current */);
|
|
233
221
|
this.mc = loggerToMonitoringContext(ChildLogger.create(this.logger, "ContainerRuntime"));
|
|
234
|
-
|
|
235
|
-
|
|
222
|
+
this.mc.logger.sendTelemetryEvent({
|
|
223
|
+
eventName: "GCFeatureMatrix",
|
|
224
|
+
metadataValue: JSON.stringify(metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix),
|
|
225
|
+
inputs: JSON.stringify({
|
|
226
|
+
gcOptions_gcTombstoneGeneration: this.runtimeOptions.gcOptions[gcTombstoneGenerationOptionName],
|
|
227
|
+
}),
|
|
228
|
+
});
|
|
229
|
+
this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
|
|
230
|
+
const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompressionChunking");
|
|
231
|
+
const opSplitter = new OpSplitter(chunks, this.context.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
|
|
236
232
|
this.remoteMessageProcessor = new RemoteMessageProcessor(opSplitter, new OpDecompressor());
|
|
237
233
|
this.handleContext = new ContainerFluidHandleContext("", this);
|
|
238
234
|
if (this.summaryConfiguration.state === "enabled") {
|
|
239
235
|
this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
|
|
240
236
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
237
|
+
const disableOpReentryCheck = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableOpReentryCheck");
|
|
238
|
+
this.enableOpReentryCheck =
|
|
239
|
+
runtimeOptions.enableOpReentryCheck === true &&
|
|
240
|
+
// Allow for a break-glass config to override the options
|
|
241
|
+
disableOpReentryCheck !== true;
|
|
244
242
|
this.summariesDisabled = this.isSummariesDisabled();
|
|
245
243
|
this.heuristicsDisabled = this.isHeuristicsDisabled();
|
|
246
244
|
this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
|
|
247
245
|
this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
|
|
248
246
|
this.maxConsecutiveReconnects =
|
|
249
|
-
(
|
|
250
|
-
|
|
247
|
+
(_d = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _d !== void 0 ? _d : this.defaultMaxConsecutiveReconnects;
|
|
248
|
+
if (runtimeOptions.flushMode === FlushModeExperimental.Async &&
|
|
249
|
+
((_e = context.supportedFeatures) === null || _e === void 0 ? void 0 : _e.get("referenceSequenceNumbers")) !== true) {
|
|
250
|
+
// The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
|
|
251
|
+
this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
|
|
252
|
+
this._flushMode = FlushMode.TurnBased;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
this._flushMode = runtimeOptions.flushMode;
|
|
256
|
+
}
|
|
251
257
|
const pendingRuntimeState = context.pendingLocalState;
|
|
252
|
-
const baseSnapshot = (
|
|
253
|
-
const maxSnapshotCacheDurationMs = (
|
|
254
|
-
if (maxSnapshotCacheDurationMs !== undefined &&
|
|
258
|
+
const baseSnapshot = (_f = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _f !== void 0 ? _f : context.baseSnapshot;
|
|
259
|
+
const maxSnapshotCacheDurationMs = (_h = (_g = this._storage) === null || _g === void 0 ? void 0 : _g.policies) === null || _h === void 0 ? void 0 : _h.maximumCacheDurationMs;
|
|
260
|
+
if (maxSnapshotCacheDurationMs !== undefined &&
|
|
261
|
+
maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
|
|
255
262
|
// This is a runtime enforcement of what's already explicit in the policy's type itself,
|
|
256
263
|
// which dictates the value is either undefined or exactly 5 days in ms.
|
|
257
264
|
// As long as the actual value is less than 5 days, the assumptions GC makes here are valid.
|
|
@@ -296,12 +303,15 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
296
303
|
if (baseSnapshot) {
|
|
297
304
|
this.summarizerNode.updateBaseSummaryState(baseSnapshot);
|
|
298
305
|
}
|
|
299
|
-
this.dataStores = new DataStores(getSummaryForDatastores(baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn
|
|
306
|
+
this.dataStores = new DataStores(getSummaryForDatastores(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));
|
|
300
307
|
this.blobManager = new BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
|
|
301
308
|
if (!this.disposed) {
|
|
302
|
-
this.submit(ContainerMessageType.BlobAttach, undefined, undefined, {
|
|
309
|
+
this.submit(ContainerMessageType.BlobAttach, undefined, undefined, {
|
|
310
|
+
localId,
|
|
311
|
+
blobId,
|
|
312
|
+
});
|
|
303
313
|
}
|
|
304
|
-
}, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (fromPath, toPath) => this.garbageCollector.addedOutboundReference(fromPath, toPath), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs, () => this.getCurrentReferenceTimestampMs());
|
|
314
|
+
}, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (fromPath, toPath) => this.garbageCollector.addedOutboundReference(fromPath, toPath), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs, () => this.getCurrentReferenceTimestampMs());
|
|
305
315
|
this.scheduleManager = new ScheduleManager(context.deltaManager, this, () => this.clientId, ChildLogger.create(this.logger, "ScheduleManager"));
|
|
306
316
|
this.pendingStateManager = new PendingStateManager({
|
|
307
317
|
applyStashedOp: this.applyStashedOp.bind(this),
|
|
@@ -312,11 +322,14 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
312
322
|
rollback: this.rollback.bind(this),
|
|
313
323
|
orderSequentially: this.orderSequentially.bind(this),
|
|
314
324
|
}, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pending);
|
|
315
|
-
const
|
|
316
|
-
|
|
325
|
+
const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompression");
|
|
326
|
+
const compressionOptions = disableCompression === true
|
|
327
|
+
? {
|
|
317
328
|
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
|
|
318
|
-
compressionAlgorithm: CompressionAlgorithms.lz4
|
|
319
|
-
}
|
|
329
|
+
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
330
|
+
}
|
|
331
|
+
: runtimeOptions.compressionOptions;
|
|
332
|
+
const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
|
|
320
333
|
this.outbox = new Outbox({
|
|
321
334
|
shouldSend: () => this.canSendOps(),
|
|
322
335
|
pendingStateManager: this.pendingStateManager,
|
|
@@ -326,7 +339,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
326
339
|
config: {
|
|
327
340
|
compressionOptions,
|
|
328
341
|
maxBatchSizeInBytes: runtimeOptions.maxBatchSizeInBytes,
|
|
329
|
-
|
|
342
|
+
disablePartialFlush: disablePartialFlush === true,
|
|
330
343
|
},
|
|
331
344
|
logger: this.mc.logger,
|
|
332
345
|
});
|
|
@@ -334,8 +347,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
334
347
|
this.remoteMessageProcessor.clearPartialMessagesFor(clientId);
|
|
335
348
|
});
|
|
336
349
|
this.summaryCollection = new SummaryCollection(this.deltaManager, this.logger);
|
|
337
|
-
this.dirtyContainer =
|
|
338
|
-
|
|
350
|
+
this.dirtyContainer =
|
|
351
|
+
this.context.attachState !== AttachState.Attached ||
|
|
352
|
+
this.pendingStateManager.hasPendingMessages();
|
|
339
353
|
this.context.updateDirtyContainerState(this.dirtyContainer);
|
|
340
354
|
if (this.summariesDisabled) {
|
|
341
355
|
this.mc.logger.sendTelemetryEvent({ eventName: "SummariesDisabled" });
|
|
@@ -399,12 +413,22 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
399
413
|
});
|
|
400
414
|
// logging hardware telemetry
|
|
401
415
|
logger.sendTelemetryEvent(Object.assign({ eventName: "DeviceSpec" }, getDeviceSpec()));
|
|
402
|
-
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
|
|
416
|
+
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({
|
|
417
|
+
disableCompression,
|
|
418
|
+
disableOpReentryCheck,
|
|
419
|
+
disableChunking,
|
|
420
|
+
disableAttachReorder: this.disableAttachReorder,
|
|
421
|
+
disablePartialFlush,
|
|
422
|
+
}) }));
|
|
403
423
|
ReportOpPerfTelemetry(this.context.clientId, this.deltaManager, this.logger);
|
|
404
424
|
BindBatchTracker(this, this.logger);
|
|
405
425
|
}
|
|
406
|
-
get IContainerRuntime() {
|
|
407
|
-
|
|
426
|
+
get IContainerRuntime() {
|
|
427
|
+
return this;
|
|
428
|
+
}
|
|
429
|
+
get IFluidRouter() {
|
|
430
|
+
return this;
|
|
431
|
+
}
|
|
408
432
|
/**
|
|
409
433
|
* @deprecated - use loadRuntime instead.
|
|
410
434
|
* Load the stores from a snapshot and returns the runtime.
|
|
@@ -445,7 +469,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
445
469
|
*/
|
|
446
470
|
static async loadRuntime(params) {
|
|
447
471
|
var _a, _b, _c, _d;
|
|
448
|
-
const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime } = params;
|
|
472
|
+
const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, } = params;
|
|
449
473
|
// If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
|
|
450
474
|
// back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
|
|
451
475
|
const backCompatContext = context;
|
|
@@ -457,13 +481,15 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
457
481
|
});
|
|
458
482
|
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, enableOfflineLoad = false, compressionOptions = {
|
|
459
483
|
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
|
|
460
|
-
compressionAlgorithm: CompressionAlgorithms.lz4
|
|
484
|
+
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
461
485
|
}, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, chunkSizeInBytes = Number.POSITIVE_INFINITY, enableOpReentryCheck = false, } = runtimeOptions;
|
|
462
486
|
const pendingRuntimeState = context.pendingLocalState;
|
|
463
487
|
const baseSnapshot = (_b = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _b !== void 0 ? _b : context.baseSnapshot;
|
|
464
|
-
const storage = !pendingRuntimeState
|
|
465
|
-
context.storage
|
|
466
|
-
new SerializedSnapshotStorage(() => {
|
|
488
|
+
const storage = !pendingRuntimeState
|
|
489
|
+
? context.storage
|
|
490
|
+
: new SerializedSnapshotStorage(() => {
|
|
491
|
+
return context.storage;
|
|
492
|
+
}, pendingRuntimeState.snapshotBlobs);
|
|
467
493
|
const registry = new FluidDataStoreRegistry(registryEntries);
|
|
468
494
|
const tryFetchBlob = async (blobName) => {
|
|
469
495
|
const blobId = baseSnapshot === null || baseSnapshot === void 0 ? void 0 : baseSnapshot.blobs[blobName];
|
|
@@ -494,7 +520,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
494
520
|
if (!pendingRuntimeState && runtimeSequenceNumber !== undefined) {
|
|
495
521
|
const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
|
|
496
522
|
// Unless bypass is explicitly set, then take action when sequence numbers mismatch.
|
|
497
|
-
if (loadSequenceNumberVerification !== "bypass" &&
|
|
523
|
+
if (loadSequenceNumberVerification !== "bypass" &&
|
|
524
|
+
runtimeSequenceNumber !== protocolSequenceNumber) {
|
|
498
525
|
// "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
|
|
499
526
|
const error = new DataCorruptionError(
|
|
500
527
|
// pre-0.58 error message: SummaryMetadataMismatch
|
|
@@ -601,7 +628,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
601
628
|
var _a;
|
|
602
629
|
return (_a = this.summarizerClientElection) === null || _a === void 0 ? void 0 : _a.electedClientId;
|
|
603
630
|
}
|
|
604
|
-
get disposed() {
|
|
631
|
+
get disposed() {
|
|
632
|
+
return this._disposed;
|
|
633
|
+
}
|
|
605
634
|
get summarizer() {
|
|
606
635
|
assert(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
|
|
607
636
|
return this._summarizer;
|
|
@@ -656,6 +685,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
656
685
|
this.emit("dispose");
|
|
657
686
|
this.removeAllListeners();
|
|
658
687
|
}
|
|
688
|
+
/**
|
|
689
|
+
* @deprecated 2.0.0-internal.3.2.0 ContainerRuntime is not an IFluidTokenProvider. Token providers should be accessed using normal provider patterns.
|
|
690
|
+
*/
|
|
659
691
|
get IFluidTokenProvider() {
|
|
660
692
|
var _a;
|
|
661
693
|
if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.intelligence) {
|
|
@@ -711,7 +743,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
711
743
|
status: 200,
|
|
712
744
|
mimeType: "fluid/object",
|
|
713
745
|
value: blob,
|
|
714
|
-
}
|
|
746
|
+
}
|
|
747
|
+
: create404Response(request);
|
|
715
748
|
}
|
|
716
749
|
else if (requestParser.pathParts.length > 0) {
|
|
717
750
|
const dataStore = await this.getDataStoreFromRequest(id, request);
|
|
@@ -732,7 +765,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
732
765
|
return (_a = this.dataStores.aliases.get(maybeAlias)) !== null && _a !== void 0 ? _a : maybeAlias;
|
|
733
766
|
}
|
|
734
767
|
async getDataStoreFromRequest(id, request) {
|
|
735
|
-
var _a, _b, _c
|
|
768
|
+
var _a, _b, _c;
|
|
736
769
|
const headerData = {};
|
|
737
770
|
if (typeof ((_a = request.headers) === null || _a === void 0 ? void 0 : _a[RuntimeHeaders.wait]) === "boolean") {
|
|
738
771
|
headerData.wait = request.headers[RuntimeHeaders.wait];
|
|
@@ -746,22 +779,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
746
779
|
await this.dataStores.waitIfPendingAlias(id);
|
|
747
780
|
const internalId = this.internalId(id);
|
|
748
781
|
const dataStoreContext = await this.dataStores.getDataStore(internalId, headerData);
|
|
749
|
-
/**
|
|
750
|
-
* If GC should run and this an external app request with "externalRequest" header, we need to return
|
|
751
|
-
* an error if the data store being requested is marked as unreferenced as per the data store's base
|
|
752
|
-
* GC data.
|
|
753
|
-
*
|
|
754
|
-
* This is a workaround to handle scenarios where a data store shared with an external app is deleted
|
|
755
|
-
* and marked as unreferenced by GC. Returning an error will fail to load the data store for the app.
|
|
756
|
-
*/
|
|
757
|
-
if (((_d = request.headers) === null || _d === void 0 ? void 0 : _d[RuntimeHeaders.externalRequest]) && this.garbageCollector.shouldRunGC) {
|
|
758
|
-
// The data store is referenced if used routes in the base summary has a route to self.
|
|
759
|
-
// Older documents may not have used routes in the summary. They are considered referenced.
|
|
760
|
-
const usedRoutes = (await dataStoreContext.getBaseGCDetails()).usedRoutes;
|
|
761
|
-
if (!(usedRoutes === undefined || usedRoutes.includes("") || usedRoutes.includes("/"))) {
|
|
762
|
-
throw responseToException(create404Response(request), request);
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
782
|
const dataStoreChannel = await dataStoreContext.realize();
|
|
766
783
|
// Remove query params, leading and trailing slashes from the url. This is done to make sure the format is
|
|
767
784
|
// the same as GC nodes id.
|
|
@@ -928,7 +945,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
928
945
|
if (reconnection) {
|
|
929
946
|
this.consecutiveReconnects++;
|
|
930
947
|
if (!this.shouldContinueReconnecting()) {
|
|
931
|
-
this.closeFn(DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops.
|
|
948
|
+
this.closeFn(DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops.", "setConnectionState", undefined, {
|
|
932
949
|
dataLoss: 1,
|
|
933
950
|
attempts: this.consecutiveReconnects,
|
|
934
951
|
pendingMessages: this.pendingStateManager.pendingMessagesCount,
|
|
@@ -1035,7 +1052,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1035
1052
|
if (message.clientId === this.clientId && this.connected) {
|
|
1036
1053
|
// Check to see if the signal was lost.
|
|
1037
1054
|
if (this._perfSignalData.trackingSignalSequenceNumber !== undefined &&
|
|
1038
|
-
envelope.clientSignalSequenceNumber >
|
|
1055
|
+
envelope.clientSignalSequenceNumber >
|
|
1056
|
+
this._perfSignalData.trackingSignalSequenceNumber) {
|
|
1039
1057
|
this._perfSignalData.signalsLost++;
|
|
1040
1058
|
this._perfSignalData.trackingSignalSequenceNumber = undefined;
|
|
1041
1059
|
this.logger.sendErrorEvent({
|
|
@@ -1046,7 +1064,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1046
1064
|
clientSignalSequenceNumber: envelope.clientSignalSequenceNumber,
|
|
1047
1065
|
});
|
|
1048
1066
|
}
|
|
1049
|
-
else if (
|
|
1067
|
+
else if (this.consecutiveReconnects === 0 &&
|
|
1068
|
+
envelope.clientSignalSequenceNumber ===
|
|
1069
|
+
this._perfSignalData.trackingSignalSequenceNumber) {
|
|
1070
|
+
// only logging for the first connection and the trackingSignalSequenceNUmber.
|
|
1050
1071
|
this.sendSignalTelemetryEvent(envelope.clientSignalSequenceNumber);
|
|
1051
1072
|
this._perfSignalData.trackingSignalSequenceNumber = undefined;
|
|
1052
1073
|
}
|
|
@@ -1133,7 +1154,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1133
1154
|
return this.dataStores.createDetachedDataStoreCore(pkg, false);
|
|
1134
1155
|
}
|
|
1135
1156
|
async _createDataStoreWithProps(pkg, props, id = uuid()) {
|
|
1136
|
-
const fluidDataStore = await this.dataStores
|
|
1157
|
+
const fluidDataStore = await this.dataStores
|
|
1158
|
+
._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props)
|
|
1159
|
+
.realize();
|
|
1137
1160
|
return channelToDataStore(fluidDataStore, id, this, this.dataStores, this.mc.logger);
|
|
1138
1161
|
}
|
|
1139
1162
|
async _createDataStore(pkg, id = uuid(), props) {
|
|
@@ -1148,7 +1171,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1148
1171
|
* Are we in the middle of batching ops together?
|
|
1149
1172
|
*/
|
|
1150
1173
|
currentlyBatching() {
|
|
1151
|
-
return this.flushMode
|
|
1174
|
+
return this.flushMode !== FlushMode.Immediate || this._orderSequentiallyCalls !== 0;
|
|
1152
1175
|
}
|
|
1153
1176
|
getQuorum() {
|
|
1154
1177
|
return this.context.quorum;
|
|
@@ -1266,7 +1289,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1266
1289
|
const { fullTree = false, trackState = true, summaryLogger = this.mc.logger, runGC = this.garbageCollector.shouldRunGC, runSweep, fullGC, } = options;
|
|
1267
1290
|
const telemetryContext = new TelemetryContext();
|
|
1268
1291
|
// Add the options that are used to generate this summary to the telemetry context.
|
|
1269
|
-
telemetryContext.
|
|
1292
|
+
telemetryContext.setMultiple("fluid_Summarize", "Options", {
|
|
1270
1293
|
fullTree,
|
|
1271
1294
|
trackState,
|
|
1272
1295
|
runGC,
|
|
@@ -1278,7 +1301,10 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1278
1301
|
gcStats = await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC }, telemetryContext);
|
|
1279
1302
|
}
|
|
1280
1303
|
const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
|
|
1281
|
-
this.logger.sendTelemetryEvent({
|
|
1304
|
+
this.logger.sendTelemetryEvent({
|
|
1305
|
+
eventName: "SummarizeTelemetry",
|
|
1306
|
+
details: telemetryContext.serialize(),
|
|
1307
|
+
});
|
|
1282
1308
|
assert(summary.type === SummaryType.Tree, 0x12f /* "Container Runtime's summarize should always return a tree" */);
|
|
1283
1309
|
return { stats, summary, gcStats };
|
|
1284
1310
|
}
|
|
@@ -1329,6 +1355,22 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1329
1355
|
this.blobManager.updateUnusedRoutes(blobManagerRoutes);
|
|
1330
1356
|
this.dataStores.updateUnusedRoutes(dataStoreRoutes);
|
|
1331
1357
|
}
|
|
1358
|
+
/**
|
|
1359
|
+
* @deprecated - Replaced by deleteSweepReadyNodes.
|
|
1360
|
+
*/
|
|
1361
|
+
deleteUnusedNodes(unusedRoutes) {
|
|
1362
|
+
throw new Error("deleteUnusedRoutes should not be called");
|
|
1363
|
+
}
|
|
1364
|
+
/**
|
|
1365
|
+
* After GC has run and identified nodes that are sweep ready, this is called to delete the sweep ready nodes.
|
|
1366
|
+
* @param sweepReadyRoutes - The routes of nodes that are sweep ready and should be deleted.
|
|
1367
|
+
* @returns - The routes of nodes that were deleted.
|
|
1368
|
+
*/
|
|
1369
|
+
deleteSweepReadyNodes(sweepReadyRoutes) {
|
|
1370
|
+
const { dataStoreRoutes, blobManagerRoutes } = this.getDataStoreAndBlobManagerRoutes(sweepReadyRoutes);
|
|
1371
|
+
const deletedRoutes = this.dataStores.deleteSweepReadyNodes(dataStoreRoutes);
|
|
1372
|
+
return deletedRoutes.concat(this.blobManager.deleteSweepReadyNodes(blobManagerRoutes));
|
|
1373
|
+
}
|
|
1332
1374
|
/**
|
|
1333
1375
|
* This is called to update objects that are tombstones.
|
|
1334
1376
|
* @param tombstonedRoutes - Data store and attachment blob routes that are tombstones in this Container.
|
|
@@ -1444,8 +1486,12 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1444
1486
|
// We might need to catch up to the latest summary's reference sequence number before pausing.
|
|
1445
1487
|
await this.waitForDeltaManagerToCatchup(latestSnapshotRefSeq, summaryNumberLogger);
|
|
1446
1488
|
}
|
|
1489
|
+
const shouldPauseInboundSignal = this.mc.config.getBoolean("Fluid.ContainerRuntime.SubmitSummary.disableInboundSignalPause") !== true;
|
|
1447
1490
|
try {
|
|
1448
1491
|
await this.deltaManager.inbound.pause();
|
|
1492
|
+
if (shouldPauseInboundSignal) {
|
|
1493
|
+
await this.deltaManager.inboundSignal.pause();
|
|
1494
|
+
}
|
|
1449
1495
|
const summaryRefSeqNum = this.deltaManager.lastSequenceNumber;
|
|
1450
1496
|
const minimumSequenceNumber = this.deltaManager.minimumSequenceNumber;
|
|
1451
1497
|
const message = `Summary @${summaryRefSeqNum}:${this.deltaManager.minimumSequenceNumber}`;
|
|
@@ -1546,8 +1592,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1546
1592
|
// latestSnapshotVersionId from storage and it does not match with the lastAck ackHandle, then use
|
|
1547
1593
|
// the one fetched from storage as parent as that is the latest.
|
|
1548
1594
|
let summaryContext;
|
|
1549
|
-
if ((lastAck === null || lastAck === void 0 ? void 0 : lastAck.summaryAck.contents.handle) !== latestSnapshotVersionId
|
|
1550
|
-
|
|
1595
|
+
if ((lastAck === null || lastAck === void 0 ? void 0 : lastAck.summaryAck.contents.handle) !== latestSnapshotVersionId &&
|
|
1596
|
+
latestSnapshotVersionId !== undefined) {
|
|
1551
1597
|
summaryContext = {
|
|
1552
1598
|
proposalHandle: undefined,
|
|
1553
1599
|
ackHandle: latestSnapshotVersionId,
|
|
@@ -1590,7 +1636,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1590
1636
|
}
|
|
1591
1637
|
let clientSequenceNumber;
|
|
1592
1638
|
try {
|
|
1593
|
-
clientSequenceNumber = this.submitSummaryMessage(summaryMessage);
|
|
1639
|
+
clientSequenceNumber = this.submitSummaryMessage(summaryMessage, summaryRefSeqNum);
|
|
1594
1640
|
}
|
|
1595
1641
|
catch (error) {
|
|
1596
1642
|
return Object.assign(Object.assign({ stage: "upload" }, uploadData), { error });
|
|
@@ -1604,6 +1650,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1604
1650
|
this.summarizerNode.clearSummary();
|
|
1605
1651
|
// Restart the delta manager
|
|
1606
1652
|
this.deltaManager.inbound.resume();
|
|
1653
|
+
if (shouldPauseInboundSignal) {
|
|
1654
|
+
this.deltaManager.inboundSignal.resume();
|
|
1655
|
+
}
|
|
1607
1656
|
}
|
|
1608
1657
|
}
|
|
1609
1658
|
hasPendingMessages() {
|
|
@@ -1649,14 +1698,16 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1649
1698
|
this.verifyCanSubmitOps();
|
|
1650
1699
|
// There should be no ops in detached container state!
|
|
1651
1700
|
assert(this.attachState !== AttachState.Detached, 0x132 /* "sending ops in detached container" */);
|
|
1652
|
-
const
|
|
1653
|
-
const serializedContent = JSON.stringify(deserializedContent);
|
|
1701
|
+
const serializedContent = JSON.stringify({ type, contents });
|
|
1654
1702
|
if (this.deltaManager.readOnlyInfo.readonly) {
|
|
1655
|
-
this.logger.sendTelemetryEvent({
|
|
1703
|
+
this.logger.sendTelemetryEvent({
|
|
1704
|
+
eventName: "SubmitOpInReadonly",
|
|
1705
|
+
connected: this.connected,
|
|
1706
|
+
});
|
|
1656
1707
|
}
|
|
1657
1708
|
const message = {
|
|
1658
1709
|
contents: serializedContent,
|
|
1659
|
-
deserializedContent,
|
|
1710
|
+
deserializedContent: JSON.parse(serializedContent),
|
|
1660
1711
|
metadata,
|
|
1661
1712
|
localOpMetadata,
|
|
1662
1713
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
@@ -1682,8 +1733,9 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1682
1733
|
// issue than sending.
|
|
1683
1734
|
// Please note that this does not change file format, so it can be disabled in the future if this
|
|
1684
1735
|
// optimization no longer makes sense (for example, batch compression may make it less appealing).
|
|
1685
|
-
if (this.currentlyBatching() &&
|
|
1686
|
-
|
|
1736
|
+
if (this.currentlyBatching() &&
|
|
1737
|
+
type === ContainerMessageType.Attach &&
|
|
1738
|
+
this.disableAttachReorder !== true) {
|
|
1687
1739
|
this.outbox.submitAttach(message);
|
|
1688
1740
|
}
|
|
1689
1741
|
else {
|
|
@@ -1692,13 +1744,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1692
1744
|
if (!this.currentlyBatching()) {
|
|
1693
1745
|
this.flush();
|
|
1694
1746
|
}
|
|
1695
|
-
else
|
|
1696
|
-
this.
|
|
1697
|
-
// Queue a microtask to detect the end of the turn and force a flush.
|
|
1698
|
-
Promise.resolve().then(() => {
|
|
1699
|
-
this.flushMicroTaskExists = false;
|
|
1700
|
-
this.flush();
|
|
1701
|
-
}).catch((error) => { this.closeFn(error); });
|
|
1747
|
+
else {
|
|
1748
|
+
this.scheduleFlush();
|
|
1702
1749
|
}
|
|
1703
1750
|
}
|
|
1704
1751
|
catch (error) {
|
|
@@ -1709,14 +1756,47 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1709
1756
|
this.updateDocumentDirtyState(true);
|
|
1710
1757
|
}
|
|
1711
1758
|
}
|
|
1712
|
-
|
|
1759
|
+
scheduleFlush() {
|
|
1760
|
+
if (this.flushTaskExists) {
|
|
1761
|
+
return;
|
|
1762
|
+
}
|
|
1763
|
+
this.flushTaskExists = true;
|
|
1764
|
+
const flush = () => {
|
|
1765
|
+
this.flushTaskExists = false;
|
|
1766
|
+
try {
|
|
1767
|
+
this.flush();
|
|
1768
|
+
}
|
|
1769
|
+
catch (error) {
|
|
1770
|
+
this.closeFn(error);
|
|
1771
|
+
}
|
|
1772
|
+
};
|
|
1773
|
+
switch (this.flushMode) {
|
|
1774
|
+
case FlushMode.TurnBased:
|
|
1775
|
+
// When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
|
|
1776
|
+
// batch at the end of the turn
|
|
1777
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1778
|
+
Promise.resolve().then(flush);
|
|
1779
|
+
break;
|
|
1780
|
+
// FlushModeExperimental is experimental and not exposed directly in the runtime APIs
|
|
1781
|
+
case FlushModeExperimental.Async:
|
|
1782
|
+
// When in Async flush mode, the runtime will accumulate all operations across JS turns and send them as a single
|
|
1783
|
+
// batch when all micro-tasks are complete.
|
|
1784
|
+
// Compared to TurnBased, this flush mode will capture more ops into the same batch.
|
|
1785
|
+
setTimeout(flush, 0);
|
|
1786
|
+
break;
|
|
1787
|
+
default:
|
|
1788
|
+
assert(this._orderSequentiallyCalls > 0, 0x587 /* Unreachable unless running under orderSequentially */);
|
|
1789
|
+
break;
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
submitSummaryMessage(contents, referenceSequenceNumber) {
|
|
1713
1793
|
this.verifyNotClosed();
|
|
1714
1794
|
assert(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
|
|
1715
1795
|
// System message should not be sent in the middle of the batch.
|
|
1716
1796
|
assert(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
|
|
1717
1797
|
// back-compat: ADO #1385: Make this call unconditional in the future
|
|
1718
1798
|
return this.context.submitSummaryFn !== undefined
|
|
1719
|
-
? this.context.submitSummaryFn(contents)
|
|
1799
|
+
? this.context.submitSummaryFn(contents, referenceSequenceNumber)
|
|
1720
1800
|
: this.context.submitFn(MessageType.Summarize, contents, false);
|
|
1721
1801
|
}
|
|
1722
1802
|
/**
|
|
@@ -1813,7 +1893,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1813
1893
|
// It should only be done by the summarizerNode, if required.
|
|
1814
1894
|
// When fetching from storage we will always get the latest version and do not use the ackHandle.
|
|
1815
1895
|
const fetchLatestSnapshot = async () => {
|
|
1816
|
-
|
|
1896
|
+
let fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
|
|
1817
1897
|
eventName: "RefreshLatestSummaryAckFetch",
|
|
1818
1898
|
ackHandle,
|
|
1819
1899
|
targetSequenceNumber: summaryRefSeq,
|
|
@@ -1829,13 +1909,21 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1829
1909
|
* state.
|
|
1830
1910
|
*/
|
|
1831
1911
|
if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
|
|
1832
|
-
|
|
1912
|
+
/* before failing, let's try to retrieve the latest snapshot for that specific ackHandle */
|
|
1913
|
+
fetchResult = await this.fetchSnapshotFromStorage(summaryLogger, {
|
|
1914
|
+
eventName: "RefreshLatestSummaryAckFetch",
|
|
1833
1915
|
ackHandle,
|
|
1834
|
-
summaryRefSeq,
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1916
|
+
targetSequenceNumber: summaryRefSeq,
|
|
1917
|
+
}, readAndParseBlob, ackHandle);
|
|
1918
|
+
if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
|
|
1919
|
+
const error = DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
|
|
1920
|
+
ackHandle,
|
|
1921
|
+
summaryRefSeq,
|
|
1922
|
+
fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
|
|
1923
|
+
});
|
|
1924
|
+
this.closeFn(error);
|
|
1925
|
+
throw error;
|
|
1926
|
+
}
|
|
1839
1927
|
}
|
|
1840
1928
|
// In case we had to retrieve the latest snapshot and it is different than summaryRefSeq,
|
|
1841
1929
|
// wait for the delta manager to catch up before refreshing the latest Summary.
|
|
@@ -1870,10 +1958,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1870
1958
|
return { latestSnapshotRefSeq, latestSnapshotVersionId: versionId };
|
|
1871
1959
|
}
|
|
1872
1960
|
async fetchLatestSnapshotFromStorage(logger, event, readAndParseBlob) {
|
|
1961
|
+
return this.fetchSnapshotFromStorage(logger, event, readAndParseBlob, null /* latest */);
|
|
1962
|
+
}
|
|
1963
|
+
async fetchSnapshotFromStorage(logger, event, readAndParseBlob, versionId) {
|
|
1873
1964
|
return PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
|
|
1874
1965
|
const stats = {};
|
|
1875
1966
|
const trace = Trace.start();
|
|
1876
|
-
const versions = await this.storage.getVersions(
|
|
1967
|
+
const versions = await this.storage.getVersions(versionId, 1, "refreshLatestSummaryAckFromServer", versionId === null ? FetchSource.noCache : undefined);
|
|
1877
1968
|
assert(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
|
|
1878
1969
|
stats.getVersionDuration = trace.trace().duration;
|
|
1879
1970
|
const maybeSnapshot = await this.storage.getSnapshotTree(versions[0]);
|
|
@@ -1893,13 +1984,15 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1893
1984
|
notifyAttaching(snapshot) {
|
|
1894
1985
|
var _a;
|
|
1895
1986
|
if ((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) {
|
|
1896
|
-
this.baseSnapshotBlobs =
|
|
1987
|
+
this.baseSnapshotBlobs =
|
|
1988
|
+
SerializedSnapshotStorage.serializeTreeWithBlobContents(snapshot);
|
|
1897
1989
|
}
|
|
1898
1990
|
}
|
|
1899
1991
|
async initializeBaseSnapshotBlobs() {
|
|
1900
1992
|
var _a;
|
|
1901
1993
|
if (!((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) ||
|
|
1902
|
-
this.attachState !== AttachState.Attached ||
|
|
1994
|
+
this.attachState !== AttachState.Attached ||
|
|
1995
|
+
this.context.pendingLocalState) {
|
|
1903
1996
|
return;
|
|
1904
1997
|
}
|
|
1905
1998
|
assert(!!this.context.baseSnapshot, 0x2e5 /* "Must have a base snapshot" */);
|