@fluidframework/container-runtime 2.0.0-internal.3.1.0 → 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/dist/blobManager.d.ts +6 -0
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +31 -6
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +17 -15
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +158 -121
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +21 -12
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +76 -50
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +9 -10
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +42 -49
- package/dist/dataStores.js.map +1 -1
- package/dist/{garbageCollection.d.ts → gc/garbageCollection.d.ts} +5 -200
- package/dist/gc/garbageCollection.d.ts.map +1 -0
- package/dist/{garbageCollection.js → gc/garbageCollection.js} +77 -353
- 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} +24 -2
- package/dist/gc/gcDefinitions.js.map +1 -0
- package/{lib/garbageCollectionHelpers.d.ts → dist/gc/gcHelpers.d.ts} +5 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -0
- package/dist/{garbageCollectionHelpers.js → gc/gcHelpers.js} +27 -7
- 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/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 +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 +7 -36
- 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/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +1 -0
- package/dist/opLifecycle/opCompressor.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 +20 -12
- 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 +59 -28
- package/dist/opLifecycle/outbox.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 +1 -2
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +14 -9
- package/dist/pendingStateManager.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/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} +158 -56
- package/dist/summary/runningSummarizer.js.map +1 -0
- package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +2 -4
- package/dist/summary/summarizer.d.ts.map +1 -0
- package/dist/{summarizer.js → summary/summarizer.js} +1 -61
- 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/dist/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +1 -1
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
- package/dist/summary/summarizerHeuristics.js.map +1 -0
- package/{lib → dist/summary}/summarizerTypes.d.ts +1 -1
- 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/summary/summaryCollection.js.map +1 -0
- package/{lib → dist/summary}/summaryFormat.d.ts +1 -43
- 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/dist/summary/summaryGenerator.d.ts.map +1 -0
- package/dist/{summaryGenerator.js → summary/summaryGenerator.js} +1 -2
- 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 +6 -0
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +28 -3
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +17 -15
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +127 -90
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +21 -12
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +64 -38
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +9 -10
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +33 -40
- package/lib/dataStores.js.map +1 -1
- package/lib/{garbageCollection.d.ts → gc/garbageCollection.d.ts} +5 -200
- package/lib/gc/garbageCollection.d.ts.map +1 -0
- package/lib/{garbageCollection.js → gc/garbageCollection.js} +44 -319
- 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} +23 -1
- package/lib/gc/gcDefinitions.js.map +1 -0
- package/{dist/garbageCollectionHelpers.d.ts → lib/gc/gcHelpers.d.ts} +5 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -0
- package/lib/{garbageCollectionHelpers.js → gc/gcHelpers.js} +20 -2
- 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/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 +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 +7 -36
- 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/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +1 -0
- package/lib/opLifecycle/opCompressor.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 +20 -12
- 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 +60 -29
- package/lib/opLifecycle/outbox.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 +1 -2
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +14 -9
- package/lib/pendingStateManager.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/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} +159 -57
- package/lib/summary/runningSummarizer.js.map +1 -0
- package/lib/{summarizer.d.ts → summary/summarizer.d.ts} +2 -4
- package/lib/summary/summarizer.d.ts.map +1 -0
- package/lib/{summarizer.js → summary/summarizer.js} +3 -63
- 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/lib/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +1 -1
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
- package/lib/summary/summarizerHeuristics.js.map +1 -0
- package/{dist → lib/summary}/summarizerTypes.d.ts +1 -1
- 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/summary/summaryCollection.js.map +1 -0
- package/{dist → lib/summary}/summaryFormat.d.ts +1 -43
- 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/lib/summary/summaryGenerator.d.ts.map +1 -0
- package/lib/{summaryGenerator.js → summary/summaryGenerator.js} +1 -2
- 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 +125 -122
- package/src/blobManager.ts +33 -3
- package/src/containerRuntime.ts +178 -106
- package/src/dataStoreContext.ts +90 -49
- package/src/dataStores.ts +44 -51
- package/{garbageCollection.md → src/gc/garbageCollection.md} +2 -2
- package/src/{garbageCollection.ts → gc/garbageCollection.ts} +90 -560
- package/src/gc/gcDefinitions.ts +244 -0
- package/src/{garbageCollectionHelpers.ts → gc/gcHelpers.ts} +26 -1
- package/src/gc/gcSummaryStateTracker.ts +339 -0
- package/src/{gcSweepReadyUsageDetection.ts → gc/gcSweepReadyUsageDetection.ts} +1 -1
- package/src/gc/gcUnreferencedStateTracker.ts +114 -0
- package/src/gc/index.ts +40 -0
- package/src/index.ts +10 -14
- package/src/opLifecycle/batchManager.ts +7 -54
- package/src/opLifecycle/definitions.ts +4 -0
- package/src/opLifecycle/opCompressor.ts +1 -0
- package/src/opLifecycle/opSplitter.ts +33 -14
- package/src/opLifecycle/outbox.ts +84 -38
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +26 -14
- package/src/summary/index.ts +99 -0
- package/src/{runningSummarizer.ts → summary/runningSummarizer.ts} +279 -139
- package/src/{summarizer.ts → summary/summarizer.ts} +5 -76
- package/src/{summarizerHeuristics.ts → summary/summarizerHeuristics.ts} +1 -1
- package/src/{summarizerTypes.ts → summary/summarizerTypes.ts} +1 -1
- package/src/{summaryFormat.ts → summary/summaryFormat.ts} +1 -53
- package/src/{summaryGenerator.ts → summary/summaryGenerator.ts} +9 -9
- package/src/{summaryManager.ts → summary/summaryManager.ts} +1 -1
- package/dist/garbageCollection.d.ts.map +0 -1
- package/dist/garbageCollection.js.map +0 -1
- package/dist/garbageCollectionConstants.d.ts +0 -26
- package/dist/garbageCollectionConstants.d.ts.map +0 -1
- package/dist/garbageCollectionConstants.js.map +0 -1
- package/dist/garbageCollectionHelpers.d.ts.map +0 -1
- 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/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 -26
- package/lib/garbageCollectionConstants.d.ts.map +0 -1
- package/lib/garbageCollectionConstants.js.map +0 -1
- package/lib/garbageCollectionHelpers.d.ts.map +0 -1
- 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/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/garbageCollectionConstants.ts +0 -44
- /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/{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/{summarizerHeuristics.js → summary/summarizerHeuristics.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/{summaryCollection.js → summary/summaryCollection.js} +0 -0
- /package/dist/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +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/{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/{summarizerHeuristics.js → summary/summarizerHeuristics.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/{summaryCollection.js → summary/summaryCollection.js} +0 -0
- /package/lib/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
- /package/lib/{summaryManager.js → summary/summaryManager.js} +0 -0
- /package/src/{orderedClientElection.ts → summary/orderedClientElection.ts} +0 -0
- /package/src/{runWhileConnectedCoordinator.ts → summary/runWhileConnectedCoordinator.ts} +0 -0
- /package/src/{summarizerClientElection.ts → summary/summarizerClientElection.ts} +0 -0
- /package/src/{summarizerHandle.ts → summary/summarizerHandle.ts} +0 -0
- /package/src/{summaryCollection.ts → summary/summaryCollection.ts} +0 -0
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
7
7
|
import { assert, LazyPromise, Timer } from "@fluidframework/common-utils";
|
|
8
|
-
import { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
9
8
|
import {
|
|
10
9
|
ClientSessionExpiredError,
|
|
11
10
|
DataProcessingError,
|
|
@@ -20,28 +19,20 @@ import {
|
|
|
20
19
|
runGarbageCollection,
|
|
21
20
|
trimLeadingSlashes,
|
|
22
21
|
} from "@fluidframework/garbage-collector";
|
|
23
|
-
import { ISnapshotTree, SummaryType } from "@fluidframework/protocol-definitions";
|
|
24
22
|
import {
|
|
25
23
|
gcTreeKey,
|
|
26
|
-
gcBlobPrefix,
|
|
27
|
-
gcTombstoneBlobKey,
|
|
28
24
|
IGarbageCollectionData,
|
|
29
25
|
IGarbageCollectionDetailsBase,
|
|
30
26
|
IGarbageCollectionSnapshotData,
|
|
31
27
|
IGarbageCollectionState,
|
|
32
28
|
ISummarizeResult,
|
|
33
29
|
ITelemetryContext,
|
|
34
|
-
IGarbageCollectionNodeData,
|
|
35
30
|
IGarbageCollectionSummaryDetailsLegacy,
|
|
36
|
-
ISummaryTreeWithStats,
|
|
37
|
-
gcDeletedBlobKey,
|
|
38
31
|
} from "@fluidframework/runtime-definitions";
|
|
39
32
|
import {
|
|
40
|
-
mergeStats,
|
|
41
33
|
packagePathToTelemetryProperty,
|
|
42
34
|
ReadAndParseBlob,
|
|
43
35
|
RefreshSummaryResult,
|
|
44
|
-
SummaryTreeBuilder,
|
|
45
36
|
} from "@fluidframework/runtime-utils";
|
|
46
37
|
import {
|
|
47
38
|
ChildLogger,
|
|
@@ -52,174 +43,38 @@ import {
|
|
|
52
43
|
TelemetryDataTag,
|
|
53
44
|
} from "@fluidframework/telemetry-utils";
|
|
54
45
|
|
|
55
|
-
import { IGCRuntimeOptions, RuntimeHeaders } from "
|
|
56
|
-
import { getSummaryForDatastores } from "
|
|
46
|
+
import { IGCRuntimeOptions, RuntimeHeaders } from "../containerRuntime";
|
|
47
|
+
import { getSummaryForDatastores } from "../dataStores";
|
|
48
|
+
import {
|
|
49
|
+
ReadFluidDataStoreAttributes,
|
|
50
|
+
dataStoreAttributesBlobName,
|
|
51
|
+
ICreateContainerMetadata,
|
|
52
|
+
} from "../summary";
|
|
57
53
|
import {
|
|
58
|
-
currentGCVersion,
|
|
59
54
|
defaultInactiveTimeoutMs,
|
|
60
55
|
defaultSessionExpiryDurationMs,
|
|
61
56
|
disableSweepLogKey,
|
|
62
57
|
disableTombstoneKey,
|
|
63
|
-
|
|
58
|
+
GCNodeType,
|
|
64
59
|
gcTestModeKey,
|
|
60
|
+
IGarbageCollector,
|
|
61
|
+
IGarbageCollectorCreateParams,
|
|
62
|
+
IGarbageCollectionRuntime,
|
|
63
|
+
IGCStats,
|
|
65
64
|
oneDayMs,
|
|
66
65
|
runGCKey,
|
|
67
66
|
runSessionExpiryKey,
|
|
68
67
|
runSweepKey,
|
|
69
|
-
stableGCVersion,
|
|
70
68
|
trackGCStateKey,
|
|
71
69
|
gcTombstoneGenerationOptionName,
|
|
72
|
-
|
|
73
|
-
import { sendGCUnexpectedUsageEvent } from "./garbageCollectionHelpers";
|
|
74
|
-
import { SweepReadyUsageDetectionHandler } from "./gcSweepReadyUsageDetection";
|
|
75
|
-
import {
|
|
76
|
-
getGCVersion,
|
|
77
|
-
GCVersion,
|
|
78
|
-
IContainerRuntimeMetadata,
|
|
79
|
-
metadataBlobName,
|
|
80
|
-
ReadFluidDataStoreAttributes,
|
|
81
|
-
dataStoreAttributesBlobName,
|
|
82
|
-
IGCMetadata,
|
|
83
|
-
ICreateContainerMetadata,
|
|
70
|
+
UnreferencedState,
|
|
84
71
|
GCFeatureMatrix,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
/** The number of data stores in the container. */
|
|
92
|
-
dataStoreCount: number;
|
|
93
|
-
/** The number of attachment blobs in the container. */
|
|
94
|
-
attachmentBlobCount: number;
|
|
95
|
-
/** The number of unreferenced nodes in the container. */
|
|
96
|
-
unrefNodeCount: number;
|
|
97
|
-
/** The number of unreferenced data stores in the container. */
|
|
98
|
-
unrefDataStoreCount: number;
|
|
99
|
-
/** The number of unreferenced attachment blobs in the container. */
|
|
100
|
-
unrefAttachmentBlobCount: number;
|
|
101
|
-
/** The number of nodes whose reference state updated since last GC run. */
|
|
102
|
-
updatedNodeCount: number;
|
|
103
|
-
/** The number of data stores whose reference state updated since last GC run. */
|
|
104
|
-
updatedDataStoreCount: number;
|
|
105
|
-
/** The number of attachment blobs whose reference state updated since last GC run. */
|
|
106
|
-
updatedAttachmentBlobCount: number;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/** The types of GC nodes in the GC reference graph. */
|
|
110
|
-
export const GCNodeType = {
|
|
111
|
-
// Nodes that are for data stores.
|
|
112
|
-
DataStore: "DataStore",
|
|
113
|
-
// Nodes that are within a data store. For example, DDS nodes.
|
|
114
|
-
SubDataStore: "SubDataStore",
|
|
115
|
-
// Nodes that are for attachment blobs, i.e., blobs uploaded via BlobManager.
|
|
116
|
-
Blob: "Blob",
|
|
117
|
-
// Nodes that are neither of the above. For example, root node.
|
|
118
|
-
Other: "Other",
|
|
119
|
-
};
|
|
120
|
-
export type GCNodeType = typeof GCNodeType[keyof typeof GCNodeType];
|
|
121
|
-
|
|
122
|
-
/** Defines the APIs for the runtime object to be passed to the garbage collector. */
|
|
123
|
-
export interface IGarbageCollectionRuntime {
|
|
124
|
-
/** Before GC runs, called to notify the runtime to update any pending GC state. */
|
|
125
|
-
updateStateBeforeGC(): Promise<void>;
|
|
126
|
-
/** Returns the garbage collection data of the runtime. */
|
|
127
|
-
getGCData(fullGC?: boolean): Promise<IGarbageCollectionData>;
|
|
128
|
-
/** After GC has run, called to notify the runtime of routes that are used in it. */
|
|
129
|
-
updateUsedRoutes(usedRoutes: string[]): void;
|
|
130
|
-
/** After GC has run, called to notify the runtime of routes that are unused in it. */
|
|
131
|
-
updateUnusedRoutes(unusedRoutes: string[]): void;
|
|
132
|
-
/**
|
|
133
|
-
* After GC has run, called to notify the runtime of deletable routes. The runtime is responsible
|
|
134
|
-
* for telling the garbage collector the routes of the objects it has deleted
|
|
135
|
-
*/
|
|
136
|
-
deleteUnusedNodes(unusedNodes: string[]): string[];
|
|
137
|
-
/** Called to notify the runtime of routes that are tombstones. */
|
|
138
|
-
updateTombstonedRoutes(tombstoneRoutes: string[]): void;
|
|
139
|
-
/** Returns a referenced timestamp to be used to track unreferenced nodes. */
|
|
140
|
-
getCurrentReferenceTimestampMs(): number | undefined;
|
|
141
|
-
/** Returns the type of the GC node. */
|
|
142
|
-
getNodeType(nodePath: string): GCNodeType;
|
|
143
|
-
/** Called when the runtime should close because of an error. */
|
|
144
|
-
closeFn: (error?: ICriticalContainerError) => void;
|
|
145
|
-
/** If false, loading or using a Tombstoned object should merely log, not fail */
|
|
146
|
-
gcTombstoneEnforcementAllowed: boolean;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/** Defines the contract for the garbage collector. */
|
|
150
|
-
export interface IGarbageCollector {
|
|
151
|
-
/** Tells whether GC should run or not. */
|
|
152
|
-
readonly shouldRunGC: boolean;
|
|
153
|
-
/** Tells whether the GC state in summary needs to be reset in the next summary. */
|
|
154
|
-
readonly summaryStateNeedsReset: boolean;
|
|
155
|
-
readonly trackGCState: boolean;
|
|
156
|
-
/** Initialize the state from the base snapshot after its creation. */
|
|
157
|
-
initializeBaseState(): Promise<void>;
|
|
158
|
-
/** Run garbage collection and update the reference / used state of the system. */
|
|
159
|
-
collectGarbage(options: {
|
|
160
|
-
logger?: ITelemetryLogger;
|
|
161
|
-
runSweep?: boolean;
|
|
162
|
-
fullGC?: boolean;
|
|
163
|
-
}): Promise<IGCStats | undefined>;
|
|
164
|
-
/** Summarizes the GC data and returns it as a summary tree. */
|
|
165
|
-
summarize(
|
|
166
|
-
fullTree: boolean,
|
|
167
|
-
trackState: boolean,
|
|
168
|
-
telemetryContext?: ITelemetryContext,
|
|
169
|
-
): ISummarizeResult | undefined;
|
|
170
|
-
/** Returns the garbage collector specific metadata to be written into the summary. */
|
|
171
|
-
getMetadata(): IGCMetadata;
|
|
172
|
-
/** Returns the GC details generated from the base snapshot. */
|
|
173
|
-
getBaseGCDetails(): Promise<IGarbageCollectionDetailsBase>;
|
|
174
|
-
/** Called when the latest summary of the system has been refreshed. */
|
|
175
|
-
refreshLatestSummary(
|
|
176
|
-
proposalHandle: string | undefined,
|
|
177
|
-
result: RefreshSummaryResult,
|
|
178
|
-
readAndParseBlob: ReadAndParseBlob,
|
|
179
|
-
): Promise<void>;
|
|
180
|
-
/** Called when a node is updated. Used to detect and log when an inactive node is changed or loaded. */
|
|
181
|
-
nodeUpdated(
|
|
182
|
-
nodePath: string,
|
|
183
|
-
reason: "Loaded" | "Changed",
|
|
184
|
-
timestampMs?: number,
|
|
185
|
-
packagePath?: readonly string[],
|
|
186
|
-
requestHeaders?: IRequestHeader,
|
|
187
|
-
): void;
|
|
188
|
-
/** Called when a reference is added to a node. Used to identify nodes that were referenced between summaries. */
|
|
189
|
-
addedOutboundReference(fromNodePath: string, toNodePath: string): void;
|
|
190
|
-
/** Returns true if this node has been deleted by GC during sweep phase. */
|
|
191
|
-
isNodeDeleted(nodePath: string): boolean;
|
|
192
|
-
setConnectionState(connected: boolean, clientId?: string): void;
|
|
193
|
-
dispose(): void;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/** Parameters necessary for creating a GarbageCollector. */
|
|
197
|
-
export interface IGarbageCollectorCreateParams {
|
|
198
|
-
readonly runtime: IGarbageCollectionRuntime;
|
|
199
|
-
readonly gcOptions: IGCRuntimeOptions;
|
|
200
|
-
readonly baseLogger: ITelemetryLogger;
|
|
201
|
-
readonly existing: boolean;
|
|
202
|
-
readonly metadata: IContainerRuntimeMetadata | undefined;
|
|
203
|
-
readonly createContainerMetadata: ICreateContainerMetadata;
|
|
204
|
-
readonly baseSnapshot: ISnapshotTree | undefined;
|
|
205
|
-
readonly isSummarizerClient: boolean;
|
|
206
|
-
readonly getNodePackagePath: (nodePath: string) => Promise<readonly string[] | undefined>;
|
|
207
|
-
readonly getLastSummaryTimestampMs: () => number | undefined;
|
|
208
|
-
readonly readAndParseBlob: ReadAndParseBlob;
|
|
209
|
-
readonly activeConnection: () => boolean;
|
|
210
|
-
readonly getContainerDiagnosticId: () => string;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/** The state of node that is unreferenced. */
|
|
214
|
-
export const UnreferencedState = {
|
|
215
|
-
/** The node is active, i.e., it can become referenced again. */
|
|
216
|
-
Active: "Active",
|
|
217
|
-
/** The node is inactive, i.e., it should not become referenced. */
|
|
218
|
-
Inactive: "Inactive",
|
|
219
|
-
/** The node is ready to be deleted by the sweep phase. */
|
|
220
|
-
SweepReady: "SweepReady",
|
|
221
|
-
} as const;
|
|
222
|
-
export type UnreferencedState = typeof UnreferencedState[keyof typeof UnreferencedState];
|
|
72
|
+
IGCMetadata,
|
|
73
|
+
} from "./gcDefinitions";
|
|
74
|
+
import { getGCVersion, sendGCUnexpectedUsageEvent } from "./gcHelpers";
|
|
75
|
+
import { GCSummaryStateTracker } from "./gcSummaryStateTracker";
|
|
76
|
+
import { SweepReadyUsageDetectionHandler } from "./gcSweepReadyUsageDetection";
|
|
77
|
+
import { UnreferencedStateTracker } from "./gcUnreferencedStateTracker";
|
|
223
78
|
|
|
224
79
|
/** The event that is logged when unreferenced node is used after a certain time. */
|
|
225
80
|
interface IUnreferencedEventProps {
|
|
@@ -233,108 +88,9 @@ interface IUnreferencedEventProps {
|
|
|
233
88
|
fromId?: string;
|
|
234
89
|
timeout?: number;
|
|
235
90
|
lastSummaryTime?: number;
|
|
236
|
-
externalRequest?: boolean;
|
|
237
91
|
viaHandle?: boolean;
|
|
238
92
|
}
|
|
239
93
|
|
|
240
|
-
/**
|
|
241
|
-
* The GC data that is tracked for a summary that is submitted.
|
|
242
|
-
*/
|
|
243
|
-
interface IGCSummaryTrackingData {
|
|
244
|
-
serializedGCState: string | undefined;
|
|
245
|
-
serializedTombstones: string | undefined;
|
|
246
|
-
serializedDeletedNodes: string | undefined;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Helper class that tracks the state of an unreferenced node such as the time it was unreferenced and if it can
|
|
251
|
-
* be deleted by the sweep phase.
|
|
252
|
-
*/
|
|
253
|
-
export class UnreferencedStateTracker {
|
|
254
|
-
private _state: UnreferencedState = UnreferencedState.Active;
|
|
255
|
-
public get state(): UnreferencedState {
|
|
256
|
-
return this._state;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/** Timer to indicate when an unreferenced object is considered Inactive */
|
|
260
|
-
private readonly inactiveTimer: TimerWithNoDefaultTimeout;
|
|
261
|
-
/** Timer to indicate when an unreferenced object is Sweep-Ready */
|
|
262
|
-
private readonly sweepTimer: TimerWithNoDefaultTimeout;
|
|
263
|
-
|
|
264
|
-
constructor(
|
|
265
|
-
public readonly unreferencedTimestampMs: number,
|
|
266
|
-
/** The time after which node transitions to Inactive state. */
|
|
267
|
-
private readonly inactiveTimeoutMs: number,
|
|
268
|
-
/** The current reference timestamp used to track how long this node has been unreferenced for. */
|
|
269
|
-
currentReferenceTimestampMs: number,
|
|
270
|
-
/** The time after which node transitions to SweepReady state; undefined if session expiry is disabled. */
|
|
271
|
-
private readonly sweepTimeoutMs: number | undefined,
|
|
272
|
-
) {
|
|
273
|
-
if (this.sweepTimeoutMs !== undefined) {
|
|
274
|
-
assert(
|
|
275
|
-
this.inactiveTimeoutMs <= this.sweepTimeoutMs,
|
|
276
|
-
0x3b0 /* inactive timeout must not be greater than the sweep timeout */,
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
this.sweepTimer = new TimerWithNoDefaultTimeout(() => {
|
|
281
|
-
this._state = UnreferencedState.SweepReady;
|
|
282
|
-
assert(
|
|
283
|
-
!this.inactiveTimer.hasTimer,
|
|
284
|
-
0x3b1 /* inactiveTimer still running after sweepTimer fired! */,
|
|
285
|
-
);
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
this.inactiveTimer = new TimerWithNoDefaultTimeout(() => {
|
|
289
|
-
this._state = UnreferencedState.Inactive;
|
|
290
|
-
|
|
291
|
-
// After the node becomes inactive, start the sweep timer after which the node will be ready for sweep.
|
|
292
|
-
if (this.sweepTimeoutMs !== undefined) {
|
|
293
|
-
this.sweepTimer.restart(this.sweepTimeoutMs - this.inactiveTimeoutMs);
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
this.updateTracking(currentReferenceTimestampMs);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/* Updates the unreferenced state based on the provided timestamp. */
|
|
300
|
-
public updateTracking(currentReferenceTimestampMs: number) {
|
|
301
|
-
const unreferencedDurationMs = currentReferenceTimestampMs - this.unreferencedTimestampMs;
|
|
302
|
-
|
|
303
|
-
// If the node has been unreferenced for sweep timeout amount of time, update the state to SweepReady.
|
|
304
|
-
if (this.sweepTimeoutMs !== undefined && unreferencedDurationMs >= this.sweepTimeoutMs) {
|
|
305
|
-
this._state = UnreferencedState.SweepReady;
|
|
306
|
-
this.clearTimers();
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// If the node has been unreferenced for inactive timeoutMs amount of time, update the state to inactive.
|
|
311
|
-
// Also, start a timer for the sweep timeout.
|
|
312
|
-
if (unreferencedDurationMs >= this.inactiveTimeoutMs) {
|
|
313
|
-
this._state = UnreferencedState.Inactive;
|
|
314
|
-
this.inactiveTimer.clear();
|
|
315
|
-
|
|
316
|
-
if (this.sweepTimeoutMs !== undefined) {
|
|
317
|
-
this.sweepTimer.restart(this.sweepTimeoutMs - unreferencedDurationMs);
|
|
318
|
-
}
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// The node is still active. Ensure the inactive timer is running with the proper remaining duration.
|
|
323
|
-
this.inactiveTimer.restart(this.inactiveTimeoutMs - unreferencedDurationMs);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
private clearTimers() {
|
|
327
|
-
this.inactiveTimer.clear();
|
|
328
|
-
this.sweepTimer.clear();
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/** Stop tracking this node. Reset the unreferenced timers and state, if any. */
|
|
332
|
-
public stopTracking() {
|
|
333
|
-
this.clearTimers();
|
|
334
|
-
this._state = UnreferencedState.Active;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
94
|
/**
|
|
339
95
|
* The garbage collector for the container runtime. It consolidates the garbage collection functionality and maintains
|
|
340
96
|
* its state across summaries.
|
|
@@ -362,28 +118,6 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
362
118
|
return new GarbageCollector(createParams);
|
|
363
119
|
}
|
|
364
120
|
|
|
365
|
-
/**
|
|
366
|
-
* Tells whether the GC state needs to be reset in the next summary. We need to do this if:
|
|
367
|
-
*
|
|
368
|
-
* 1. GC was enabled and is now disabled. The GC state needs to be removed and everything becomes referenced.
|
|
369
|
-
*
|
|
370
|
-
* 2. GC was disabled and is now enabled. The GC state needs to be regenerated and added to summary.
|
|
371
|
-
*
|
|
372
|
-
* 3. GC is enabled and the latest summary state is refreshed from a snapshot that had GC disabled and vice-versa.
|
|
373
|
-
*
|
|
374
|
-
* 4. The GC version in the latest summary is different from the current GC version. This can happen if:
|
|
375
|
-
*
|
|
376
|
-
* 4.1. The summary this client loaded with has data from a different GC version.
|
|
377
|
-
*
|
|
378
|
-
* 4.2. This client's latest summary was updated from a snapshot that has a different GC version.
|
|
379
|
-
*/
|
|
380
|
-
public get summaryStateNeedsReset(): boolean {
|
|
381
|
-
return (
|
|
382
|
-
this.gcStateNeedsReset ||
|
|
383
|
-
(this.shouldRunGC && this.latestSummaryGCVersion !== this.currentGCVersion)
|
|
384
|
-
);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
121
|
/**
|
|
388
122
|
* Tracks if GC is enabled for this document. This is specified during document creation and doesn't change
|
|
389
123
|
* throughout its lifetime.
|
|
@@ -412,31 +146,6 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
412
146
|
private readonly tombstoneMode: boolean;
|
|
413
147
|
private readonly mc: MonitoringContext;
|
|
414
148
|
|
|
415
|
-
/**
|
|
416
|
-
* Tells whether the GC state needs to be reset. This can happen under 3 conditions:
|
|
417
|
-
*
|
|
418
|
-
* 1. The base snapshot contains GC state but GC is disabled. This will happen the first time GC is disabled after
|
|
419
|
-
* it was enabled before. GC state needs to be removed from summary and all nodes should be marked referenced.
|
|
420
|
-
*
|
|
421
|
-
* 2. The base snapshot does not have GC state but GC is enabled. This will happen the very first time GC runs on
|
|
422
|
-
* a document and the first time GC is enabled after is was disabled before.
|
|
423
|
-
*
|
|
424
|
-
* 3. GC is enabled and the latest summary state is refreshed from a snapshot that had GC disabled and vice-versa.
|
|
425
|
-
*
|
|
426
|
-
* Note that the state will be reset only once for the first summary generated after this returns true. After that,
|
|
427
|
-
* this will return false.
|
|
428
|
-
*/
|
|
429
|
-
private get gcStateNeedsReset(): boolean {
|
|
430
|
-
return this.wasGCRunInLatestSummary !== this.shouldRunGC;
|
|
431
|
-
}
|
|
432
|
-
// Tracks whether there was GC was run in latest summary being tracked.
|
|
433
|
-
private wasGCRunInLatestSummary: boolean;
|
|
434
|
-
|
|
435
|
-
// The current GC version that this container is running.
|
|
436
|
-
private readonly currentGCVersion: GCVersion;
|
|
437
|
-
// This is the version of GC data in the latest summary being tracked.
|
|
438
|
-
private latestSummaryGCVersion: GCVersion;
|
|
439
|
-
|
|
440
149
|
// Feature Support info persisted to this container's summary
|
|
441
150
|
private readonly persistedGcFeatureMatrix: GCFeatureMatrix | undefined;
|
|
442
151
|
|
|
@@ -450,15 +159,6 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
450
159
|
// A list of nodes that have been deleted during sweep phase.
|
|
451
160
|
private deletedNodes: Set<string> = new Set();
|
|
452
161
|
|
|
453
|
-
/**
|
|
454
|
-
* Keeps track of the GC data from the latest summary successfully submitted to and acked from the server.
|
|
455
|
-
*/
|
|
456
|
-
private latestSummaryData: IGCSummaryTrackingData | undefined;
|
|
457
|
-
/**
|
|
458
|
-
* Keeps track of the GC data from the last summary submitted to the server but not yet acked.
|
|
459
|
-
*/
|
|
460
|
-
private pendingSummaryData: IGCSummaryTrackingData | undefined;
|
|
461
|
-
|
|
462
162
|
// Promise when resolved returns the GC data data in the base snapshot.
|
|
463
163
|
private readonly baseSnapshotDataP: Promise<IGarbageCollectionSnapshotData | undefined>;
|
|
464
164
|
// Promise when resolved initializes the GC state from the data in the base snapshot.
|
|
@@ -491,6 +191,8 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
491
191
|
/** The time after which an unreferenced node is ready to be swept. */
|
|
492
192
|
private readonly sweepTimeoutMs: number | undefined;
|
|
493
193
|
|
|
194
|
+
private readonly summaryStateTracker: GCSummaryStateTracker;
|
|
195
|
+
|
|
494
196
|
/** For a given node path, returns the node's package path. */
|
|
495
197
|
private readonly getNodePackagePath: (
|
|
496
198
|
nodePath: string,
|
|
@@ -517,6 +219,10 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
517
219
|
};
|
|
518
220
|
}
|
|
519
221
|
|
|
222
|
+
public get summaryStateNeedsReset(): boolean {
|
|
223
|
+
return this.summaryStateTracker.doesSummaryStateNeedReset();
|
|
224
|
+
}
|
|
225
|
+
|
|
520
226
|
/** Handler to respond to when a SweepReady object is used */
|
|
521
227
|
private readonly sweepReadyUsageHandler: SweepReadyUsageDetectionHandler;
|
|
522
228
|
|
|
@@ -539,19 +245,13 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
539
245
|
}),
|
|
540
246
|
);
|
|
541
247
|
|
|
542
|
-
// If version upgrade is not enabled, fall back to the stable GC version.
|
|
543
|
-
this.currentGCVersion =
|
|
544
|
-
this.mc.config.getBoolean(gcVersionUpgradeToV2Key) === true
|
|
545
|
-
? currentGCVersion
|
|
546
|
-
: stableGCVersion;
|
|
547
|
-
|
|
548
248
|
this.sweepReadyUsageHandler = new SweepReadyUsageDetectionHandler(
|
|
549
249
|
createParams.getContainerDiagnosticId(),
|
|
550
250
|
this.mc,
|
|
551
251
|
this.runtime.closeFn,
|
|
552
252
|
);
|
|
553
253
|
|
|
554
|
-
let
|
|
254
|
+
let gcVersionInBaseSnapshot: number | undefined;
|
|
555
255
|
|
|
556
256
|
/**
|
|
557
257
|
* Sweep timeout is the time after which unreferenced content can be swept.
|
|
@@ -578,10 +278,10 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
578
278
|
* For existing containers, we get this information from the metadata blob of its summary.
|
|
579
279
|
*/
|
|
580
280
|
if (createParams.existing) {
|
|
581
|
-
|
|
281
|
+
gcVersionInBaseSnapshot = getGCVersion(metadata);
|
|
582
282
|
// Existing documents which did not have metadata blob or had GC disabled have version as 0. For all
|
|
583
283
|
// other existing documents, GC is enabled.
|
|
584
|
-
this.gcEnabled =
|
|
284
|
+
this.gcEnabled = gcVersionInBaseSnapshot > 0;
|
|
585
285
|
this.sweepEnabled = metadata?.sweepEnabled ?? false;
|
|
586
286
|
this.sessionExpiryTimeoutMs = metadata?.sessionExpiryTimeoutMs;
|
|
587
287
|
this.sweepTimeoutMs =
|
|
@@ -637,10 +337,6 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
637
337
|
this.sessionExpiryTimer.start();
|
|
638
338
|
}
|
|
639
339
|
|
|
640
|
-
// For existing document, the latest summary is the one that we loaded from. So, use its GC version as the
|
|
641
|
-
// latest tracked GC version. For new documents, we will be writing the first summary with the current version.
|
|
642
|
-
this.latestSummaryGCVersion = prevSummaryGCVersion ?? this.currentGCVersion;
|
|
643
|
-
|
|
644
340
|
/**
|
|
645
341
|
* Whether GC should run or not. The following conditions have to be met to run sweep:
|
|
646
342
|
*
|
|
@@ -693,8 +389,14 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
693
389
|
this.tombstoneMode =
|
|
694
390
|
!this.shouldRunSweep && this.mc.config.getBoolean(disableTombstoneKey) !== true;
|
|
695
391
|
|
|
696
|
-
|
|
697
|
-
|
|
392
|
+
this.summaryStateTracker = new GCSummaryStateTracker(
|
|
393
|
+
this.shouldRunGC,
|
|
394
|
+
this.trackGCState,
|
|
395
|
+
this.tombstoneMode,
|
|
396
|
+
this.mc,
|
|
397
|
+
baseSnapshot?.trees[gcTreeKey] !== undefined /* wasGCRunInBaseSnapshot */,
|
|
398
|
+
gcVersionInBaseSnapshot,
|
|
399
|
+
);
|
|
698
400
|
|
|
699
401
|
// Get the GC data from the base snapshot. Use LazyPromise because we only want to do this once since it
|
|
700
402
|
// it involves fetching blobs from storage which is expensive.
|
|
@@ -936,10 +638,12 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
936
638
|
this.runtime.updateTombstonedRoutes(this.tombstones);
|
|
937
639
|
}
|
|
938
640
|
|
|
641
|
+
// Update the summary state tracker's state from this snapshot.
|
|
642
|
+
this.summaryStateTracker.updateStateFromSnapshotData(snapshotData);
|
|
643
|
+
|
|
939
644
|
// If there is no snapshot data, it means this snapshot was generated with GC disabled. Unset all GC state.
|
|
940
645
|
if (snapshotData === undefined) {
|
|
941
646
|
this.gcDataFromLastRun = undefined;
|
|
942
|
-
this.latestSummaryData = undefined;
|
|
943
647
|
return;
|
|
944
648
|
}
|
|
945
649
|
|
|
@@ -961,15 +665,6 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
961
665
|
gcNodes[nodeId] = Array.from(nodeData.outboundRoutes);
|
|
962
666
|
}
|
|
963
667
|
this.gcDataFromLastRun = { gcNodes };
|
|
964
|
-
|
|
965
|
-
// If tracking state across summaries, update latest summary data from the snapshot's GC data.
|
|
966
|
-
if (this.trackGCState) {
|
|
967
|
-
this.latestSummaryData = {
|
|
968
|
-
serializedGCState: JSON.stringify(generateSortedGCState(snapshotData.gcState)),
|
|
969
|
-
serializedTombstones: JSON.stringify(snapshotData.tombstones),
|
|
970
|
-
serializedDeletedNodes: JSON.stringify(snapshotData.deletedNodes),
|
|
971
|
-
};
|
|
972
|
-
}
|
|
973
668
|
}
|
|
974
669
|
|
|
975
670
|
/**
|
|
@@ -1001,16 +696,21 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1001
696
|
* Runs garbage collection and updates the reference / used state of the nodes in the container.
|
|
1002
697
|
* @returns stats of the GC run or undefined if GC did not run.
|
|
1003
698
|
*/
|
|
1004
|
-
public async collectGarbage(
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
699
|
+
public async collectGarbage(
|
|
700
|
+
options: {
|
|
701
|
+
/** Logger to use for logging GC events */
|
|
702
|
+
logger?: ITelemetryLogger;
|
|
703
|
+
/** True to run GC sweep phase after the mark phase */
|
|
704
|
+
runSweep?: boolean;
|
|
705
|
+
/** True to generate full GC data */
|
|
706
|
+
fullGC?: boolean;
|
|
707
|
+
},
|
|
708
|
+
telemetryContext?: ITelemetryContext,
|
|
709
|
+
): Promise<IGCStats | undefined> {
|
|
1012
710
|
const fullGC =
|
|
1013
|
-
options.fullGC ??
|
|
711
|
+
options.fullGC ??
|
|
712
|
+
(this.gcOptions.runFullGC === true ||
|
|
713
|
+
this.summaryStateTracker.doesSummaryStateNeedReset());
|
|
1014
714
|
const logger = options.logger
|
|
1015
715
|
? ChildLogger.create(options.logger, undefined, {
|
|
1016
716
|
all: { completedGCRuns: () => this.completedRuns },
|
|
@@ -1035,6 +735,12 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1035
735
|
return undefined;
|
|
1036
736
|
}
|
|
1037
737
|
|
|
738
|
+
// Add the options that are used to run GC to the telemetry context.
|
|
739
|
+
telemetryContext?.setMultiple("fluid_GC", "Options", {
|
|
740
|
+
fullGC,
|
|
741
|
+
runSweep: options.runSweep,
|
|
742
|
+
});
|
|
743
|
+
|
|
1038
744
|
return PerformanceEvent.timedExecAsync(
|
|
1039
745
|
logger,
|
|
1040
746
|
{ eventName: "GarbageCollection" },
|
|
@@ -1138,139 +844,22 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1138
844
|
};
|
|
1139
845
|
}
|
|
1140
846
|
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
this.deletedNodes
|
|
1146
|
-
|
|
1147
|
-
: undefined;
|
|
1148
|
-
// If running in tombstone mode, serialize and write tombstones, if any.
|
|
1149
|
-
const serializedTombstones = this.tombstoneMode
|
|
1150
|
-
? this.tombstones.length > 0
|
|
1151
|
-
? JSON.stringify(this.tombstones.sort())
|
|
1152
|
-
: undefined
|
|
1153
|
-
: undefined;
|
|
1154
|
-
|
|
1155
|
-
/**
|
|
1156
|
-
* Incremental summary of GC data - If none of GC state, deleted nodes or tombstones changed since last summary,
|
|
1157
|
-
* write summary handle instead of summary tree for GC.
|
|
1158
|
-
* Otherwise, write the GC summary tree. In the tree, for each of these that changed, write a summary blob and
|
|
1159
|
-
* for each of these that did not change, write a summary handle.
|
|
1160
|
-
*/
|
|
1161
|
-
if (this.trackGCState) {
|
|
1162
|
-
this.pendingSummaryData = {
|
|
1163
|
-
serializedGCState,
|
|
1164
|
-
serializedTombstones,
|
|
1165
|
-
serializedDeletedNodes,
|
|
1166
|
-
};
|
|
1167
|
-
if (trackState && !fullTree && this.latestSummaryData !== undefined) {
|
|
1168
|
-
// If nothing changed since last summary, send a summary handle for the entire GC data.
|
|
1169
|
-
if (
|
|
1170
|
-
this.latestSummaryData.serializedGCState === serializedGCState &&
|
|
1171
|
-
this.latestSummaryData.serializedTombstones === serializedTombstones
|
|
1172
|
-
) {
|
|
1173
|
-
const stats = mergeStats();
|
|
1174
|
-
stats.handleNodeCount++;
|
|
1175
|
-
return {
|
|
1176
|
-
summary: {
|
|
1177
|
-
type: SummaryType.Handle,
|
|
1178
|
-
handle: `/${gcTreeKey}`,
|
|
1179
|
-
handleType: SummaryType.Tree,
|
|
1180
|
-
},
|
|
1181
|
-
stats,
|
|
1182
|
-
};
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
// If some state changed, build a GC summary tree.
|
|
1186
|
-
return this.buildGCSummaryTree(
|
|
1187
|
-
serializedGCState,
|
|
1188
|
-
serializedTombstones,
|
|
1189
|
-
serializedDeletedNodes,
|
|
1190
|
-
true /* trackState */,
|
|
1191
|
-
);
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
// If not tracking GC state, build a GC summary tree without any summary handles.
|
|
1195
|
-
return this.buildGCSummaryTree(
|
|
1196
|
-
serializedGCState,
|
|
1197
|
-
serializedTombstones,
|
|
1198
|
-
serializedDeletedNodes,
|
|
1199
|
-
false /* trackState */,
|
|
847
|
+
return this.summaryStateTracker.summarize(
|
|
848
|
+
fullTree,
|
|
849
|
+
trackState,
|
|
850
|
+
gcState,
|
|
851
|
+
this.deletedNodes,
|
|
852
|
+
this.tombstones,
|
|
1200
853
|
);
|
|
1201
854
|
}
|
|
1202
855
|
|
|
1203
|
-
/**
|
|
1204
|
-
* Builds the GC summary tree which contains GC state, deleted nodes and tombstones.
|
|
1205
|
-
* If trackState is false, all of GC state, deleted nodes and tombstones are written as summary blobs.
|
|
1206
|
-
* If trackState is true, only states that changed are written. Rest are written as handles.
|
|
1207
|
-
* @param serializedGCState - The GC state serialized as string.
|
|
1208
|
-
* @param serializedTombstones - The tombstone state serialized as string.
|
|
1209
|
-
* @param serializedDeletedNodes - Deleted nodes serialized as string.
|
|
1210
|
-
* @param trackState - Whether we are tracking GC state across summaries.
|
|
1211
|
-
* @returns the GC summary tree.
|
|
1212
|
-
*/
|
|
1213
|
-
private buildGCSummaryTree(
|
|
1214
|
-
serializedGCState: string,
|
|
1215
|
-
serializedTombstones: string | undefined,
|
|
1216
|
-
serializedDeletedNodes: string | undefined,
|
|
1217
|
-
trackState: boolean,
|
|
1218
|
-
): ISummaryTreeWithStats {
|
|
1219
|
-
const gcStateBlobKey = `${gcBlobPrefix}_root`;
|
|
1220
|
-
const builder = new SummaryTreeBuilder();
|
|
1221
|
-
|
|
1222
|
-
// If the GC state hasn't changed, write a summary handle, else write a summary blob for it.
|
|
1223
|
-
if (this.latestSummaryData?.serializedGCState === serializedGCState && trackState) {
|
|
1224
|
-
builder.addHandle(gcStateBlobKey, SummaryType.Blob, `/${gcTreeKey}/${gcStateBlobKey}`);
|
|
1225
|
-
} else {
|
|
1226
|
-
builder.addBlob(gcStateBlobKey, serializedGCState);
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
// If tombstones exist, write a summary handle if it hasn't changed. If it has changed, write a
|
|
1230
|
-
// summary blob.
|
|
1231
|
-
if (serializedTombstones !== undefined) {
|
|
1232
|
-
if (
|
|
1233
|
-
this.latestSummaryData?.serializedTombstones === serializedTombstones &&
|
|
1234
|
-
trackState
|
|
1235
|
-
) {
|
|
1236
|
-
builder.addHandle(
|
|
1237
|
-
gcTombstoneBlobKey,
|
|
1238
|
-
SummaryType.Blob,
|
|
1239
|
-
`/${gcTreeKey}/${gcTombstoneBlobKey}`,
|
|
1240
|
-
);
|
|
1241
|
-
} else {
|
|
1242
|
-
builder.addBlob(gcTombstoneBlobKey, serializedTombstones);
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
// If there are no deleted nodes, return the summary tree.
|
|
1247
|
-
if (serializedDeletedNodes === undefined) {
|
|
1248
|
-
return builder.getSummaryTree();
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
|
-
// If the deleted nodes hasn't changed, write a summary handle, else write a summary blob for it.
|
|
1252
|
-
if (
|
|
1253
|
-
this.latestSummaryData?.serializedDeletedNodes === serializedDeletedNodes &&
|
|
1254
|
-
trackState
|
|
1255
|
-
) {
|
|
1256
|
-
builder.addHandle(
|
|
1257
|
-
gcDeletedBlobKey,
|
|
1258
|
-
SummaryType.Blob,
|
|
1259
|
-
`/${gcTreeKey}/${gcDeletedBlobKey}`,
|
|
1260
|
-
);
|
|
1261
|
-
} else {
|
|
1262
|
-
builder.addBlob(gcDeletedBlobKey, serializedDeletedNodes);
|
|
1263
|
-
}
|
|
1264
|
-
return builder.getSummaryTree();
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
856
|
public getMetadata(): IGCMetadata {
|
|
1268
857
|
return {
|
|
1269
858
|
/**
|
|
1270
859
|
* If GC is enabled, the GC data is written using the current GC version and that is the gcFeature that goes
|
|
1271
860
|
* into the metadata blob. If GC is disabled, the gcFeature is 0.
|
|
1272
861
|
*/
|
|
1273
|
-
gcFeature: this.gcEnabled ? this.currentGCVersion : 0,
|
|
862
|
+
gcFeature: this.gcEnabled ? this.summaryStateTracker.currentGCVersion : 0,
|
|
1274
863
|
gcFeatureMatrix: this.persistedGcFeatureMatrix,
|
|
1275
864
|
sessionExpiryTimeoutMs: this.sessionExpiryTimeoutMs,
|
|
1276
865
|
sweepEnabled: this.sweepEnabled,
|
|
@@ -1295,61 +884,32 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1295
884
|
result: RefreshSummaryResult,
|
|
1296
885
|
readAndParseBlob: ReadAndParseBlob,
|
|
1297
886
|
): Promise<void> {
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
this.wasGCRunInLatestSummary = this.shouldRunGC;
|
|
1304
|
-
}
|
|
1305
|
-
|
|
1306
|
-
if (!result.latestSummaryUpdated || !this.shouldRunGC) {
|
|
1307
|
-
return;
|
|
1308
|
-
}
|
|
887
|
+
const latestSnapshotData = await this.summaryStateTracker.refreshLatestSummary(
|
|
888
|
+
proposalHandle,
|
|
889
|
+
result,
|
|
890
|
+
readAndParseBlob,
|
|
891
|
+
);
|
|
1309
892
|
|
|
1310
|
-
// If the summary was tracked by this client,
|
|
1311
|
-
//
|
|
1312
|
-
if (result.wasSummaryTracked) {
|
|
1313
|
-
|
|
1314
|
-
if
|
|
1315
|
-
|
|
1316
|
-
|
|
893
|
+
// If the latest summary was updated but it was not tracked by this client, our state needs to be updated from
|
|
894
|
+
// this snapshot data.
|
|
895
|
+
if (this.shouldRunGC && result.latestSummaryUpdated && !result.wasSummaryTracked) {
|
|
896
|
+
// The current reference timestamp should be available if we are refreshing state from a snapshot. There has
|
|
897
|
+
// to be at least one op (summary op / ack, if nothing else) if a snapshot was taken.
|
|
898
|
+
const currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();
|
|
899
|
+
if (currentReferenceTimestampMs === undefined) {
|
|
900
|
+
throw DataProcessingError.create(
|
|
901
|
+
"No reference timestamp when updating GC state from snapshot",
|
|
902
|
+
"refreshLatestSummary",
|
|
903
|
+
undefined,
|
|
904
|
+
{
|
|
905
|
+
proposalHandle,
|
|
906
|
+
summaryRefSeq: result.summaryRefSeq,
|
|
907
|
+
details: JSON.stringify(this.configs),
|
|
908
|
+
},
|
|
909
|
+
);
|
|
1317
910
|
}
|
|
1318
|
-
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
// If the summary was not tracked by this client, the state should be updated from the downloaded snapshot.
|
|
1322
|
-
const snapshotTree = result.snapshotTree;
|
|
1323
|
-
const metadataBlobId = snapshotTree.blobs[metadataBlobName];
|
|
1324
|
-
if (metadataBlobId) {
|
|
1325
|
-
const metadata = await readAndParseBlob<IContainerRuntimeMetadata>(metadataBlobId);
|
|
1326
|
-
this.latestSummaryGCVersion = getGCVersion(metadata);
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
// The current reference timestamp should be available if we are refreshing state from a snapshot. There has
|
|
1330
|
-
// to be at least one op (summary op / ack, if nothing else) if a snapshot was taken.
|
|
1331
|
-
const currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();
|
|
1332
|
-
if (currentReferenceTimestampMs === undefined) {
|
|
1333
|
-
throw DataProcessingError.create(
|
|
1334
|
-
"No reference timestamp when updating GC state from snapshot",
|
|
1335
|
-
"refreshLatestSummary",
|
|
1336
|
-
undefined,
|
|
1337
|
-
{
|
|
1338
|
-
proposalHandle,
|
|
1339
|
-
summaryRefSeq: result.summaryRefSeq,
|
|
1340
|
-
details: JSON.stringify(this.configs),
|
|
1341
|
-
},
|
|
1342
|
-
);
|
|
1343
|
-
}
|
|
1344
|
-
const gcSnapshotTree = snapshotTree.trees[gcTreeKey];
|
|
1345
|
-
// If GC ran in the container that generated this snapshot, it will have a GC tree.
|
|
1346
|
-
this.wasGCRunInLatestSummary = gcSnapshotTree !== undefined;
|
|
1347
|
-
let latestGCData: IGarbageCollectionSnapshotData | undefined;
|
|
1348
|
-
if (gcSnapshotTree !== undefined) {
|
|
1349
|
-
latestGCData = await getGCDataFromSnapshot(gcSnapshotTree, readAndParseBlob);
|
|
911
|
+
this.updateStateFromSnapshotData(latestSnapshotData, currentReferenceTimestampMs);
|
|
1350
912
|
}
|
|
1351
|
-
this.updateStateFromSnapshotData(latestGCData, currentReferenceTimestampMs);
|
|
1352
|
-
this.pendingSummaryData = undefined;
|
|
1353
913
|
}
|
|
1354
914
|
|
|
1355
915
|
/**
|
|
@@ -1515,7 +1075,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1515
1075
|
private runSweepPhase(sweepReadyNodes: string[], gcData: IGarbageCollectionData) {
|
|
1516
1076
|
// TODO: GC:Validation - validate that removed routes are not double deleted
|
|
1517
1077
|
// TODO: GC:Validation - validate that the child routes of removed routes are deleted as well
|
|
1518
|
-
const sweptRoutes = this.runtime.
|
|
1078
|
+
const sweptRoutes = this.runtime.deleteSweepReadyNodes(sweepReadyNodes);
|
|
1519
1079
|
const updatedGCData = this.deleteSweptRoutes(sweptRoutes, gcData);
|
|
1520
1080
|
|
|
1521
1081
|
for (const nodeId of sweptRoutes) {
|
|
@@ -1855,7 +1415,6 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1855
1415
|
completedGCRuns: this.completedRuns,
|
|
1856
1416
|
lastSummaryTime: this.getLastSummaryTimestampMs(),
|
|
1857
1417
|
...this.createContainerMetadata,
|
|
1858
|
-
externalRequest: requestHeaders?.[RuntimeHeaders.externalRequest],
|
|
1859
1418
|
viaHandle: requestHeaders?.[RuntimeHeaders.viaHandle],
|
|
1860
1419
|
fromId: fromNodeId,
|
|
1861
1420
|
};
|
|
@@ -1945,32 +1504,3 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1945
1504
|
this.pendingEventsQueue = [];
|
|
1946
1505
|
}
|
|
1947
1506
|
}
|
|
1948
|
-
|
|
1949
|
-
function generateSortedGCState(gcState: IGarbageCollectionState): IGarbageCollectionState {
|
|
1950
|
-
const sortableArray: [string, IGarbageCollectionNodeData][] = Object.entries(gcState.gcNodes);
|
|
1951
|
-
sortableArray.sort(([a], [b]) => a.localeCompare(b));
|
|
1952
|
-
const sortedGCState: IGarbageCollectionState = { gcNodes: {} };
|
|
1953
|
-
for (const [nodeId, nodeData] of sortableArray) {
|
|
1954
|
-
nodeData.outboundRoutes.sort();
|
|
1955
|
-
sortedGCState.gcNodes[nodeId] = nodeData;
|
|
1956
|
-
}
|
|
1957
|
-
return sortedGCState;
|
|
1958
|
-
}
|
|
1959
|
-
|
|
1960
|
-
/** A wrapper around common-utils Timer that requires the timeout when calling start/restart */
|
|
1961
|
-
class TimerWithNoDefaultTimeout extends Timer {
|
|
1962
|
-
constructor(private readonly callback: () => void) {
|
|
1963
|
-
// The default timeout/handlers will never be used since start/restart pass overrides below
|
|
1964
|
-
super(0, () => {
|
|
1965
|
-
throw new Error("DefaultHandler should not be used");
|
|
1966
|
-
});
|
|
1967
|
-
}
|
|
1968
|
-
|
|
1969
|
-
start(timeoutMs: number) {
|
|
1970
|
-
super.start(timeoutMs, this.callback);
|
|
1971
|
-
}
|
|
1972
|
-
|
|
1973
|
-
restart(timeoutMs: number): void {
|
|
1974
|
-
super.restart(timeoutMs, this.callback);
|
|
1975
|
-
}
|
|
1976
|
-
}
|