@fluidframework/container-runtime 2.0.0-internal.4.3.0 → 2.0.0-internal.5.0.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/CHANGELOG.md +45 -0
- package/dist/batchTracker.d.ts +4 -4
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +2 -2
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +3 -2
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +2 -2
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +12 -11
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +46 -19
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts +2 -2
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +1 -1
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +3 -3
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +1 -2
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/deltaScheduler.d.ts +2 -2
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +1 -1
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +57 -45
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +219 -203
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +8 -10
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +5 -3
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +11 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +18 -3
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +6 -2
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +16 -6
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +7 -7
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +42 -22
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/index.d.ts +1 -2
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +2 -5
- package/dist/gc/index.js.map +1 -1
- package/dist/id-compressor/idCompressor.d.ts +2 -2
- package/dist/id-compressor/idCompressor.d.ts.map +1 -1
- package/dist/id-compressor/idCompressor.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +2 -2
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts +2 -2
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +3 -6
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +2 -2
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +5 -6
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +2 -2
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +3 -3
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +2 -2
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +7 -3
- 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 +18 -14
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +35 -55
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts +2 -2
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +15 -4
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +4 -3
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +1 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +4 -3
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +5 -6
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +2 -3
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +2 -3
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +3 -2
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.d.ts +2 -2
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +10 -9
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +3 -3
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +6 -6
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +8 -8
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +3 -2
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +2 -2
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +1 -1
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +3 -2
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/batchTracker.d.ts +4 -4
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +2 -2
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +3 -2
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +2 -2
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +12 -11
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +46 -19
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts +2 -2
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +1 -1
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +3 -3
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +1 -2
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/deltaScheduler.d.ts +2 -2
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +1 -1
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +57 -45
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +219 -203
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +8 -10
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +5 -3
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +11 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +16 -2
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +6 -2
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +16 -6
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +7 -7
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +43 -23
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/index.d.ts +1 -2
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -2
- package/lib/gc/index.js.map +1 -1
- package/lib/id-compressor/idCompressor.d.ts +2 -2
- package/lib/id-compressor/idCompressor.d.ts.map +1 -1
- package/lib/id-compressor/idCompressor.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +2 -2
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts +2 -2
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +3 -6
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +2 -2
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +5 -6
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +2 -2
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +3 -3
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +2 -2
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +7 -3
- 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 +18 -14
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +35 -55
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts +2 -2
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +15 -4
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +4 -3
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +4 -3
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +5 -6
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +2 -3
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +2 -3
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +3 -2
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.d.ts +2 -2
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +10 -9
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +3 -3
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +6 -6
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +8 -8
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +3 -2
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +2 -2
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +1 -1
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +3 -2
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +1 -1
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +18 -16
- package/src/batchTracker.ts +5 -6
- package/src/blobManager.ts +3 -2
- package/src/connectionTelemetry.ts +4 -5
- package/src/containerRuntime.ts +61 -32
- package/src/dataStore.ts +3 -4
- package/src/dataStoreContext.ts +4 -8
- package/src/dataStoreContexts.ts +3 -7
- package/src/deltaScheduler.ts +2 -3
- package/src/gc/garbageCollection.ts +276 -259
- package/src/gc/gcConfigs.ts +12 -11
- package/src/gc/gcDefinitions.ts +5 -3
- package/src/gc/gcHelpers.ts +20 -2
- package/src/gc/gcSummaryStateTracker.ts +19 -7
- package/src/gc/gcTelemetry.ts +56 -37
- package/src/gc/index.ts +1 -5
- package/src/id-compressor/idCompressor.ts +2 -2
- package/src/opLifecycle/definitions.ts +2 -2
- package/src/opLifecycle/opCompressor.ts +4 -8
- package/src/opLifecycle/opDecompressor.ts +2 -3
- package/src/opLifecycle/opGroupingManager.ts +6 -7
- package/src/opLifecycle/opSplitter.ts +4 -5
- package/src/opLifecycle/outbox.ts +10 -9
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +60 -91
- package/src/scheduleManager.ts +22 -11
- package/src/summary/orderedClientElection.ts +5 -5
- package/src/summary/runningSummarizer.ts +11 -10
- package/src/summary/summarizer.ts +8 -8
- package/src/summary/summarizerClientElection.ts +3 -2
- package/src/summary/summarizerHeuristics.ts +2 -2
- package/src/summary/summarizerNode/summarizerNode.ts +15 -14
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +3 -3
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +10 -7
- package/src/summary/summarizerTypes.ts +8 -13
- package/src/summary/summaryCollection.ts +3 -2
- package/src/summary/summaryGenerator.ts +7 -3
- package/src/summary/summaryManager.ts +8 -9
- package/dist/gc/gcSweepReadyUsageDetection.d.ts +0 -53
- package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +0 -1
- package/dist/gc/gcSweepReadyUsageDetection.js +0 -130
- package/dist/gc/gcSweepReadyUsageDetection.js.map +0 -1
- package/lib/gc/gcSweepReadyUsageDetection.d.ts +0 -53
- package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +0 -1
- package/lib/gc/gcSweepReadyUsageDetection.js +0 -125
- package/lib/gc/gcSweepReadyUsageDetection.js.map +0 -1
- package/src/gc/gcSweepReadyUsageDetection.ts +0 -145
|
@@ -94,8 +94,7 @@ class GarbageCollector {
|
|
|
94
94
|
// in the snapshot cannot be interpreted correctly. Set everything to undefined except for
|
|
95
95
|
// deletedNodes because irrespective of GC versions, these nodes have been deleted and cannot be
|
|
96
96
|
// brought back. The deletedNodes info is needed to identify when these nodes are used.
|
|
97
|
-
if (this.configs.gcVersionInBaseSnapshot
|
|
98
|
-
this.summaryStateTracker.currentGCVersion) {
|
|
97
|
+
if (this.configs.gcVersionInEffect !== this.configs.gcVersionInBaseSnapshot) {
|
|
99
98
|
return {
|
|
100
99
|
gcState: undefined,
|
|
101
100
|
tombstones: undefined,
|
|
@@ -184,6 +183,10 @@ class GarbageCollector {
|
|
|
184
183
|
get summaryStateNeedsReset() {
|
|
185
184
|
return this.summaryStateTracker.doesSummaryStateNeedReset;
|
|
186
185
|
}
|
|
186
|
+
/** Returns the count of data stores whose GC state updated since the last summary. */
|
|
187
|
+
get updatedDSCountSinceLastSummary() {
|
|
188
|
+
return this.summaryStateTracker.updatedDSCountSinceLastSummary;
|
|
189
|
+
}
|
|
187
190
|
/**
|
|
188
191
|
* Called during container initialization. Initialize from the tombstone state in the base snapshot. This is done
|
|
189
192
|
* during initialization so that deleted or tombstoned objects are marked as such before they are loaded or used.
|
|
@@ -305,6 +308,13 @@ class GarbageCollector {
|
|
|
305
308
|
this.initializeGCStateFromBaseSnapshotP.catch((error) => { });
|
|
306
309
|
}
|
|
307
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* Returns a the GC details generated from the base summary. This is used to initialize the GC state of the nodes
|
|
313
|
+
* in the container.
|
|
314
|
+
*/
|
|
315
|
+
async getBaseGCDetails() {
|
|
316
|
+
return this.baseGCDetailsP;
|
|
317
|
+
}
|
|
308
318
|
/**
|
|
309
319
|
* Runs garbage collection and updates the reference / used state of the nodes in the container.
|
|
310
320
|
* @returns stats of the GC run or undefined if GC did not run.
|
|
@@ -340,53 +350,224 @@ class GarbageCollector {
|
|
|
340
350
|
return undefined;
|
|
341
351
|
}
|
|
342
352
|
return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, { eventName: "GarbageCollection" }, async (event) => {
|
|
343
|
-
|
|
344
|
-
//
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
353
|
+
/** Pre-GC steps */
|
|
354
|
+
// Ensure that state has been initialized from the base snapshot data.
|
|
355
|
+
await this.initializeGCStateFromBaseSnapshotP;
|
|
356
|
+
// Let the runtime update its pending state before GC runs.
|
|
357
|
+
await this.runtime.updateStateBeforeGC();
|
|
358
|
+
/** GC step */
|
|
359
|
+
const gcStats = await this.runGC(fullGC, currentReferenceTimestampMs, logger);
|
|
348
360
|
event.end(Object.assign(Object.assign({}, gcStats), { timestamp: currentReferenceTimestampMs }));
|
|
361
|
+
/** Post-GC steps */
|
|
362
|
+
// Log pending unreferenced events such as a node being used after inactive. This is done after GC runs and
|
|
363
|
+
// updates its state so that we don't send false positives based on intermediate state. For example, we may get
|
|
364
|
+
// reference to an unreferenced node from another unreferenced node which means the node wasn't revived.
|
|
365
|
+
await this.telemetryTracker.logPendingEvents(logger);
|
|
366
|
+
// Update the state of summary state tracker from this run's stats.
|
|
367
|
+
this.summaryStateTracker.updateStateFromGCRunStats(gcStats);
|
|
368
|
+
this.newReferencesSinceLastRun.clear();
|
|
349
369
|
this.completedRuns++;
|
|
350
370
|
return gcStats;
|
|
351
371
|
}, { end: true, cancel: "error" });
|
|
352
372
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
373
|
+
/**
|
|
374
|
+
* Runs garbage collection. It does the following:
|
|
375
|
+
* 1. It generates / analyzes the runtime's reference graph.
|
|
376
|
+
* 2. Generates stats for the GC run based on previous / current GC state.
|
|
377
|
+
* 3. Runs Mark phase.
|
|
378
|
+
* 4. Runs Sweep phase.
|
|
379
|
+
*/
|
|
380
|
+
async runGC(fullGC, currentReferenceTimestampMs, logger) {
|
|
381
|
+
var _a;
|
|
382
|
+
// 1. Generate / analyze the runtime's reference graph.
|
|
383
|
+
// Get the reference graph (gcData) and run GC algorithm to get referenced / unreferenced nodes.
|
|
384
|
+
const gcData = await this.runtime.getGCData(fullGC);
|
|
385
|
+
const gcResult = (0, gcReferenceGraphAlgorithm_1.runGarbageCollection)(gcData.gcNodes, ["/"]);
|
|
386
|
+
// Get all referenced nodes - References in this run + references between the previous and current runs.
|
|
387
|
+
const allReferencedNodeIds = (_a = this.findAllNodesReferencedBetweenGCs(gcData, this.gcDataFromLastRun, logger)) !== null && _a !== void 0 ? _a : gcResult.referencedNodeIds;
|
|
388
|
+
// 2. Generate stats based on the previous / current GC state.
|
|
389
|
+
// Must happen before running Mark / Sweep phase because previous GC state will be updated in these stages.
|
|
362
390
|
const gcStats = this.generateStats(gcResult);
|
|
363
|
-
//
|
|
364
|
-
|
|
391
|
+
// 3. Run the Mark phase.
|
|
392
|
+
// It will mark nodes as referenced / unreferenced and return a list of node ids that are ready to be swept.
|
|
393
|
+
const sweepReadyNodeIds = this.runMarkPhase(gcResult, allReferencedNodeIds, currentReferenceTimestampMs);
|
|
394
|
+
// 4. Run the Sweep phase.
|
|
395
|
+
// It will delete sweep ready nodes and return a list of deleted node ids.
|
|
396
|
+
const deletedNodeIds = this.runSweepPhase(gcResult, sweepReadyNodeIds, currentReferenceTimestampMs, logger);
|
|
397
|
+
this.gcDataFromLastRun = (0, gcHelpers_1.cloneGCData)(gcData, (id) => deletedNodeIds.includes(id) /* filter out deleted nodes */);
|
|
398
|
+
return gcStats;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Runs the GC Mark phase. It does the following:
|
|
402
|
+
* 1. Marks all referenced nodes in this run by clearing tracking for them.
|
|
403
|
+
* 2. Marks unreferenced nodes in this run by starting tracking for them.
|
|
404
|
+
* 3. Calls the runtime to update nodes that were marked referenced.
|
|
405
|
+
*
|
|
406
|
+
* @param gcResult - The result of the GC run on the gcData.
|
|
407
|
+
* @param allReferencedNodeIds - Nodes referenced in this GC run + referenced between previous and current GC run.
|
|
408
|
+
* @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
|
|
409
|
+
* @returns - A list of sweep ready nodes, i.e., nodes that ready to be deleted.
|
|
410
|
+
*/
|
|
411
|
+
runMarkPhase(gcResult, allReferencedNodeIds, currentReferenceTimestampMs) {
|
|
412
|
+
// 1. Marks all referenced nodes by clearing their unreferenced tracker, if any.
|
|
413
|
+
for (const nodeId of allReferencedNodeIds) {
|
|
414
|
+
const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
|
|
415
|
+
if (nodeStateTracker !== undefined) {
|
|
416
|
+
// Stop tracking so as to clear out any running timers.
|
|
417
|
+
nodeStateTracker.stopTracking();
|
|
418
|
+
// Delete the node as we don't need to track it any more.
|
|
419
|
+
this.unreferencedNodesState.delete(nodeId);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
// 2. Mark unreferenced nodes in this run by starting unreferenced tracking for them.
|
|
423
|
+
const sweepReadyNodeIds = [];
|
|
424
|
+
for (const nodeId of gcResult.deletedNodeIds) {
|
|
425
|
+
const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
|
|
426
|
+
if (nodeStateTracker === undefined) {
|
|
427
|
+
this.unreferencedNodesState.set(nodeId, new gcUnreferencedStateTracker_1.UnreferencedStateTracker(currentReferenceTimestampMs, this.configs.inactiveTimeoutMs, currentReferenceTimestampMs, this.configs.sweepTimeoutMs));
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
// If a node was already unreferenced, update its tracking information. Since the current reference time
|
|
431
|
+
// is from the ops seen, this will ensure that we keep updating unreferenced state as time moves forward.
|
|
432
|
+
nodeStateTracker.updateTracking(currentReferenceTimestampMs);
|
|
433
|
+
// If a node is sweep ready, store it so it can be returned.
|
|
434
|
+
if (nodeStateTracker.state === gcDefinitions_1.UnreferencedState.SweepReady) {
|
|
435
|
+
sweepReadyNodeIds.push(nodeId);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
// 3. Call the runtime to update referenced nodes in this run.
|
|
365
440
|
this.runtime.updateUsedRoutes(gcResult.referencedNodeIds);
|
|
366
|
-
|
|
441
|
+
return sweepReadyNodeIds;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Runs the GC Sweep phase. It does the following:
|
|
445
|
+
* 1. Calls the runtime to delete nodes that are sweep ready.
|
|
446
|
+
* 2. Clears tracking for deleted nodes.
|
|
447
|
+
*
|
|
448
|
+
* @param gcResult - The result of the GC run on the gcData.
|
|
449
|
+
* @param sweepReadyNodes - List of nodes that are sweep ready.
|
|
450
|
+
* @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
|
|
451
|
+
* @param logger - The logger to be used to log any telemetry.
|
|
452
|
+
* @returns - A list of nodes that have been deleted.
|
|
453
|
+
*/
|
|
454
|
+
runSweepPhase(gcResult, sweepReadyNodes, currentReferenceTimestampMs, logger) {
|
|
455
|
+
// Log events for objects that are ready to be deleted by sweep. This will give us data on sweep when
|
|
456
|
+
// its not enabled.
|
|
367
457
|
this.telemetryTracker.logSweepEvents(logger, currentReferenceTimestampMs, this.unreferencedNodesState, this.completedRuns, this.getLastSummaryTimestampMs());
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
458
|
+
/**
|
|
459
|
+
* Currently, there are 3 modes for sweep:
|
|
460
|
+
* Test mode - Unreferenced nodes are immediately deleted without waiting for them to be sweep ready.
|
|
461
|
+
* Tombstone mode - Sweep ready modes are marked as tombstones instead of being deleted.
|
|
462
|
+
* Sweep mode - Sweep ready modes are deleted.
|
|
463
|
+
*
|
|
464
|
+
* These modes serve as staging for applications that want to enable sweep by providing an incremental
|
|
465
|
+
* way to test and validate sweep works as expected.
|
|
466
|
+
*/
|
|
467
|
+
if (this.configs.testMode) {
|
|
468
|
+
// If we are running in GC test mode, unreferenced nodes (gcResult.deletedNodeIds) are deleted.
|
|
375
469
|
this.runtime.updateUnusedRoutes(gcResult.deletedNodeIds);
|
|
470
|
+
return [];
|
|
376
471
|
}
|
|
377
|
-
|
|
472
|
+
if (this.configs.tombstoneMode) {
|
|
378
473
|
this.tombstones = sweepReadyNodes;
|
|
379
474
|
// If we are running in GC tombstone mode, update tombstoned routes. This enables testing scenarios
|
|
380
475
|
// involving access to "deleted" data without actually deleting the data from summaries.
|
|
381
|
-
// Note: we will not tombstone in test mode.
|
|
382
476
|
this.runtime.updateTombstonedRoutes(this.tombstones);
|
|
477
|
+
return [];
|
|
383
478
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
//
|
|
388
|
-
|
|
389
|
-
|
|
479
|
+
if (!this.configs.shouldRunSweep) {
|
|
480
|
+
return [];
|
|
481
|
+
}
|
|
482
|
+
// 1. Call the runtime to delete sweep ready nodes. The runtime returns a list of nodes it deleted.
|
|
483
|
+
// TODO: GC:Validation - validate that removed routes are not double delete and that the child routes of
|
|
484
|
+
// removed routes are deleted as well.
|
|
485
|
+
const deletedNodeIds = this.runtime.deleteSweepReadyNodes(sweepReadyNodes);
|
|
486
|
+
// 2. Clear unreferenced state tracking for deleted nodes.
|
|
487
|
+
for (const nodeId of deletedNodeIds) {
|
|
488
|
+
const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
|
|
489
|
+
// TODO: GC:Validation - assert that the nodeStateTracker is defined
|
|
490
|
+
if (nodeStateTracker !== undefined) {
|
|
491
|
+
// Stop tracking so as to clear out any running timers.
|
|
492
|
+
nodeStateTracker.stopTracking();
|
|
493
|
+
// Delete the node as we don't need to track it any more.
|
|
494
|
+
this.unreferencedNodesState.delete(nodeId);
|
|
495
|
+
}
|
|
496
|
+
// TODO: GC:Validation - assert that the deleted node is not a duplicate
|
|
497
|
+
this.deletedNodes.add(nodeId);
|
|
498
|
+
}
|
|
499
|
+
return deletedNodeIds;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Since GC runs periodically, the GC data that is generated only tells us the state of the world at that point in
|
|
503
|
+
* time. There can be nodes that were referenced in between two runs and their unreferenced state needs to be
|
|
504
|
+
* updated. For example, in the following scenarios not updating the unreferenced timestamp can lead to deletion of
|
|
505
|
+
* these objects while there can be in-memory referenced to it:
|
|
506
|
+
* 1. A node transitions from `unreferenced -> referenced -> unreferenced` between two runs. When the reference is
|
|
507
|
+
* added, the object may have been accessed and in-memory reference to it added.
|
|
508
|
+
* 2. A reference is added from one unreferenced node to one or more unreferenced nodes. Even though the node[s] were
|
|
509
|
+
* unreferenced, they could have been accessed and in-memory reference to them added.
|
|
510
|
+
*
|
|
511
|
+
* This function identifies nodes that were referenced since the last run.
|
|
512
|
+
* If these nodes are currently unreferenced, they will be assigned new unreferenced state by the current run.
|
|
513
|
+
*
|
|
514
|
+
* @returns - a list of all nodes referenced from the last local summary until now.
|
|
515
|
+
*/
|
|
516
|
+
findAllNodesReferencedBetweenGCs(currentGCData, previousGCData, logger) {
|
|
517
|
+
// If we haven't run GC before there is nothing to do.
|
|
518
|
+
// No previousGCData, means nothing is unreferenced, and there are no reference state trackers to clear
|
|
519
|
+
if (previousGCData === undefined) {
|
|
520
|
+
return undefined;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* If there are references that were not explicitly notified to GC, log an error because this should never happen.
|
|
524
|
+
* If it does, this may result in the unreferenced timestamps of these nodes not updated when they were referenced.
|
|
525
|
+
*/
|
|
526
|
+
this.telemetryTracker.logIfMissingExplicitReferences(currentGCData, previousGCData, this.newReferencesSinceLastRun, logger);
|
|
527
|
+
// No references were added since the last run so we don't have to update reference states of any unreferenced
|
|
528
|
+
// nodes. There is no in between state at this point.
|
|
529
|
+
if (this.newReferencesSinceLastRun.size === 0) {
|
|
530
|
+
return undefined;
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Generate a super set of the GC data that contains the nodes and edges from last run, plus any new node and
|
|
534
|
+
* edges that have been added since then. To do this, combine the GC data from the last run and the current
|
|
535
|
+
* run, and then add the references since last run.
|
|
536
|
+
*
|
|
537
|
+
* Note on why we need to combine the data from previous run, current run and all references in between -
|
|
538
|
+
* 1. We need data from last run because some of its references may have been deleted since then. If those
|
|
539
|
+
* references added new outbound references before they were deleted, we need to detect them.
|
|
540
|
+
*
|
|
541
|
+
* 2. We need new outbound references since last run because some of them may have been deleted later. If those
|
|
542
|
+
* references added new outbound references before they were deleted, we need to detect them.
|
|
543
|
+
*
|
|
544
|
+
* 3. We need data from the current run because currently we may not detect when DDSes are referenced:
|
|
545
|
+
* - We don't require DDSes handles to be stored in a referenced DDS.
|
|
546
|
+
* - A new data store may have "root" DDSes already created and we don't detect them today.
|
|
547
|
+
*/
|
|
548
|
+
const gcDataSuperSet = (0, gcHelpers_1.concatGarbageCollectionData)(previousGCData, currentGCData);
|
|
549
|
+
const newOutboundRoutesSinceLastRun = [];
|
|
550
|
+
this.newReferencesSinceLastRun.forEach((outboundRoutes, sourceNodeId) => {
|
|
551
|
+
if (gcDataSuperSet.gcNodes[sourceNodeId] === undefined) {
|
|
552
|
+
gcDataSuperSet.gcNodes[sourceNodeId] = outboundRoutes;
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
gcDataSuperSet.gcNodes[sourceNodeId].push(...outboundRoutes);
|
|
556
|
+
}
|
|
557
|
+
newOutboundRoutesSinceLastRun.push(...outboundRoutes);
|
|
558
|
+
});
|
|
559
|
+
/**
|
|
560
|
+
* Run GC on the above reference graph starting with root and all new outbound routes. This will generate a
|
|
561
|
+
* list of all nodes that could have been referenced since the last run. If any of these nodes are unreferenced,
|
|
562
|
+
* unreferenced, stop tracking them and remove from unreferenced list.
|
|
563
|
+
* Note that some of these nodes may be unreferenced now and if so, the current run will mark them as
|
|
564
|
+
* unreferenced and add unreferenced state.
|
|
565
|
+
*/
|
|
566
|
+
const gcResult = (0, gcReferenceGraphAlgorithm_1.runGarbageCollection)(gcDataSuperSet.gcNodes, [
|
|
567
|
+
"/",
|
|
568
|
+
...newOutboundRoutesSinceLastRun,
|
|
569
|
+
]);
|
|
570
|
+
return gcResult.referencedNodeIds;
|
|
390
571
|
}
|
|
391
572
|
/**
|
|
392
573
|
* Summarizes the GC data and returns it as a summary tree.
|
|
@@ -410,23 +591,16 @@ class GarbageCollector {
|
|
|
410
591
|
getMetadata() {
|
|
411
592
|
return {
|
|
412
593
|
/**
|
|
413
|
-
* If GC is enabled, the GC data is written using the
|
|
594
|
+
* If GC is enabled, the GC data is written using the GC version in effect and that is the gcFeature that goes
|
|
414
595
|
* into the metadata blob. If GC is disabled, the gcFeature is 0.
|
|
415
596
|
*/
|
|
416
|
-
gcFeature: this.configs.gcEnabled ? this.
|
|
597
|
+
gcFeature: this.configs.gcEnabled ? this.configs.gcVersionInEffect : 0,
|
|
417
598
|
gcFeatureMatrix: this.configs.persistedGcFeatureMatrix,
|
|
418
599
|
sessionExpiryTimeoutMs: this.configs.sessionExpiryTimeoutMs,
|
|
419
600
|
sweepEnabled: false,
|
|
420
601
|
sweepTimeoutMs: this.configs.sweepTimeoutMs,
|
|
421
602
|
};
|
|
422
603
|
}
|
|
423
|
-
/**
|
|
424
|
-
* Returns a the GC details generated from the base summary. This is used to initialize the GC state of the nodes
|
|
425
|
-
* in the container.
|
|
426
|
-
*/
|
|
427
|
-
async getBaseGCDetails() {
|
|
428
|
-
return this.baseGCDetailsP;
|
|
429
|
-
}
|
|
430
604
|
/**
|
|
431
605
|
* Called to refresh the latest summary state. This happens when either a pending summary is acked or a snapshot
|
|
432
606
|
* is downloaded and should be used to update the state.
|
|
@@ -462,7 +636,7 @@ class GarbageCollector {
|
|
|
462
636
|
return;
|
|
463
637
|
}
|
|
464
638
|
this.telemetryTracker.nodeUsed({
|
|
465
|
-
|
|
639
|
+
id: nodePath,
|
|
466
640
|
usageType: reason,
|
|
467
641
|
currentReferenceTimestampMs: timestampMs !== null && timestampMs !== void 0 ? timestampMs : this.runtime.getCurrentReferenceTimestampMs(),
|
|
468
642
|
packagePath,
|
|
@@ -488,7 +662,7 @@ class GarbageCollector {
|
|
|
488
662
|
outboundRoutes.push(toNodePath);
|
|
489
663
|
this.newReferencesSinceLastRun.set(fromNodePath, outboundRoutes);
|
|
490
664
|
this.telemetryTracker.nodeUsed({
|
|
491
|
-
|
|
665
|
+
id: toNodePath,
|
|
492
666
|
usageType: "Revived",
|
|
493
667
|
currentReferenceTimestampMs: this.runtime.getCurrentReferenceTimestampMs(),
|
|
494
668
|
packagePath: undefined,
|
|
@@ -510,164 +684,6 @@ class GarbageCollector {
|
|
|
510
684
|
(_a = this.sessionExpiryTimer) === null || _a === void 0 ? void 0 : _a.clear();
|
|
511
685
|
this.sessionExpiryTimer = undefined;
|
|
512
686
|
}
|
|
513
|
-
/**
|
|
514
|
-
* Updates the state of the system as per the current GC run. It does the following:
|
|
515
|
-
* 1. Sets up the current GC state as per the gcData.
|
|
516
|
-
* 2. Starts tracking for nodes that have become unreferenced in this run.
|
|
517
|
-
* 3. Clears tracking for nodes that were unreferenced but became referenced in this run.
|
|
518
|
-
* @param gcData - The data representing the reference graph on which GC is run.
|
|
519
|
-
* @param gcResult - The result of the GC run on the gcData.
|
|
520
|
-
* @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
|
|
521
|
-
* @returns - A list of sweep ready nodes. (Nodes ready to be deleted)
|
|
522
|
-
*/
|
|
523
|
-
updateMarkPhase(gcData, gcResult, currentReferenceTimestampMs, logger) {
|
|
524
|
-
var _a;
|
|
525
|
-
// Get references from the current GC run + references between previous and current run and then update each
|
|
526
|
-
// node's state
|
|
527
|
-
const allNodesReferencedBetweenGCs = (_a = this.findAllNodesReferencedBetweenGCs(gcData, this.gcDataFromLastRun, logger)) !== null && _a !== void 0 ? _a : gcResult.referencedNodeIds;
|
|
528
|
-
this.newReferencesSinceLastRun.clear();
|
|
529
|
-
// Iterate through the referenced nodes and stop tracking if they were unreferenced before.
|
|
530
|
-
for (const nodeId of allNodesReferencedBetweenGCs) {
|
|
531
|
-
const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
|
|
532
|
-
if (nodeStateTracker !== undefined) {
|
|
533
|
-
// Stop tracking so as to clear out any running timers.
|
|
534
|
-
nodeStateTracker.stopTracking();
|
|
535
|
-
// Delete the node as we don't need to track it any more.
|
|
536
|
-
this.unreferencedNodesState.delete(nodeId);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
/**
|
|
540
|
-
* If a node became unreferenced in this run, start tracking it.
|
|
541
|
-
* If a node was already unreferenced, update its tracking information. Since the current reference time is
|
|
542
|
-
* from the ops seen, this will ensure that we keep updating the unreferenced state as time moves forward.
|
|
543
|
-
*
|
|
544
|
-
* If a node is sweep ready, store and then return it.
|
|
545
|
-
*/
|
|
546
|
-
const sweepReadyNodes = [];
|
|
547
|
-
for (const nodeId of gcResult.deletedNodeIds) {
|
|
548
|
-
const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
|
|
549
|
-
if (nodeStateTracker === undefined) {
|
|
550
|
-
this.unreferencedNodesState.set(nodeId, new gcUnreferencedStateTracker_1.UnreferencedStateTracker(currentReferenceTimestampMs, this.configs.inactiveTimeoutMs, currentReferenceTimestampMs, this.configs.sweepTimeoutMs));
|
|
551
|
-
}
|
|
552
|
-
else {
|
|
553
|
-
nodeStateTracker.updateTracking(currentReferenceTimestampMs);
|
|
554
|
-
if (nodeStateTracker.state === gcDefinitions_1.UnreferencedState.SweepReady) {
|
|
555
|
-
sweepReadyNodes.push(nodeId);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
return sweepReadyNodes;
|
|
560
|
-
}
|
|
561
|
-
/**
|
|
562
|
-
* Deletes nodes from both the runtime and garbage collection
|
|
563
|
-
* @param sweepReadyNodes - nodes that are ready to be deleted
|
|
564
|
-
*/
|
|
565
|
-
runSweepPhase(sweepReadyNodes, gcData) {
|
|
566
|
-
// TODO: GC:Validation - validate that removed routes are not double deleted
|
|
567
|
-
// TODO: GC:Validation - validate that the child routes of removed routes are deleted as well
|
|
568
|
-
const sweptRoutes = this.runtime.deleteSweepReadyNodes(sweepReadyNodes);
|
|
569
|
-
const updatedGCData = this.deleteSweptRoutes(sweptRoutes, gcData);
|
|
570
|
-
for (const nodeId of sweptRoutes) {
|
|
571
|
-
const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
|
|
572
|
-
// TODO: GC:Validation - assert that the nodeStateTracker is defined
|
|
573
|
-
if (nodeStateTracker !== undefined) {
|
|
574
|
-
// Stop tracking so as to clear out any running timers.
|
|
575
|
-
nodeStateTracker.stopTracking();
|
|
576
|
-
// Delete the node as we don't need to track it any more.
|
|
577
|
-
this.unreferencedNodesState.delete(nodeId);
|
|
578
|
-
}
|
|
579
|
-
// TODO: GC:Validation - assert that the deleted node is not a duplicate
|
|
580
|
-
this.deletedNodes.add(nodeId);
|
|
581
|
-
}
|
|
582
|
-
return updatedGCData;
|
|
583
|
-
}
|
|
584
|
-
/**
|
|
585
|
-
* @returns IGarbageCollectionData after deleting the sweptRoutes from the gcData
|
|
586
|
-
*/
|
|
587
|
-
deleteSweptRoutes(sweptRoutes, gcData) {
|
|
588
|
-
const sweptRoutesSet = new Set(sweptRoutes);
|
|
589
|
-
const gcNodes = {};
|
|
590
|
-
for (const [id, outboundRoutes] of Object.entries(gcData.gcNodes)) {
|
|
591
|
-
if (!sweptRoutesSet.has(id)) {
|
|
592
|
-
gcNodes[id] = Array.from(outboundRoutes);
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
// TODO: GC:Validation - assert that the nodeId is in gcData
|
|
596
|
-
return {
|
|
597
|
-
gcNodes,
|
|
598
|
-
};
|
|
599
|
-
}
|
|
600
|
-
/**
|
|
601
|
-
* Since GC runs periodically, the GC data that is generated only tells us the state of the world at that point in
|
|
602
|
-
* time. There can be nodes that were referenced in between two runs and their unreferenced state needs to be
|
|
603
|
-
* updated. For example, in the following scenarios not updating the unreferenced timestamp can lead to deletion of
|
|
604
|
-
* these objects while there can be in-memory referenced to it:
|
|
605
|
-
* 1. A node transitions from `unreferenced -> referenced -> unreferenced` between two runs. When the reference is
|
|
606
|
-
* added, the object may have been accessed and in-memory reference to it added.
|
|
607
|
-
* 2. A reference is added from one unreferenced node to one or more unreferenced nodes. Even though the node[s] were
|
|
608
|
-
* unreferenced, they could have been accessed and in-memory reference to them added.
|
|
609
|
-
*
|
|
610
|
-
* This function identifies nodes that were referenced since the last run.
|
|
611
|
-
* If these nodes are currently unreferenced, they will be assigned new unreferenced state by the current run.
|
|
612
|
-
*
|
|
613
|
-
* @returns - a list of all nodes referenced from the last local summary until now.
|
|
614
|
-
*/
|
|
615
|
-
findAllNodesReferencedBetweenGCs(currentGCData, previousGCData, logger) {
|
|
616
|
-
// If we haven't run GC before there is nothing to do.
|
|
617
|
-
// No previousGCData, means nothing is unreferenced, and there are no reference state trackers to clear
|
|
618
|
-
if (previousGCData === undefined) {
|
|
619
|
-
return undefined;
|
|
620
|
-
}
|
|
621
|
-
/**
|
|
622
|
-
* If there are references that were not explicitly notified to GC, log an error because this should never happen.
|
|
623
|
-
* If it does, this may result in the unreferenced timestamps of these nodes not updated when they were referenced.
|
|
624
|
-
*/
|
|
625
|
-
this.telemetryTracker.logIfMissingExplicitReferences(currentGCData, previousGCData, this.newReferencesSinceLastRun, logger);
|
|
626
|
-
// No references were added since the last run so we don't have to update reference states of any unreferenced
|
|
627
|
-
// nodes. There is no in between state at this point.
|
|
628
|
-
if (this.newReferencesSinceLastRun.size === 0) {
|
|
629
|
-
return undefined;
|
|
630
|
-
}
|
|
631
|
-
/**
|
|
632
|
-
* Generate a super set of the GC data that contains the nodes and edges from last run, plus any new node and
|
|
633
|
-
* edges that have been added since then. To do this, combine the GC data from the last run and the current
|
|
634
|
-
* run, and then add the references since last run.
|
|
635
|
-
*
|
|
636
|
-
* Note on why we need to combine the data from previous run, current run and all references in between -
|
|
637
|
-
* 1. We need data from last run because some of its references may have been deleted since then. If those
|
|
638
|
-
* references added new outbound references before they were deleted, we need to detect them.
|
|
639
|
-
*
|
|
640
|
-
* 2. We need new outbound references since last run because some of them may have been deleted later. If those
|
|
641
|
-
* references added new outbound references before they were deleted, we need to detect them.
|
|
642
|
-
*
|
|
643
|
-
* 3. We need data from the current run because currently we may not detect when DDSes are referenced:
|
|
644
|
-
* - We don't require DDSes handles to be stored in a referenced DDS.
|
|
645
|
-
* - A new data store may have "root" DDSes already created and we don't detect them today.
|
|
646
|
-
*/
|
|
647
|
-
const gcDataSuperSet = (0, gcHelpers_1.concatGarbageCollectionData)(previousGCData, currentGCData);
|
|
648
|
-
const newOutboundRoutesSinceLastRun = [];
|
|
649
|
-
this.newReferencesSinceLastRun.forEach((outboundRoutes, sourceNodeId) => {
|
|
650
|
-
if (gcDataSuperSet.gcNodes[sourceNodeId] === undefined) {
|
|
651
|
-
gcDataSuperSet.gcNodes[sourceNodeId] = outboundRoutes;
|
|
652
|
-
}
|
|
653
|
-
else {
|
|
654
|
-
gcDataSuperSet.gcNodes[sourceNodeId].push(...outboundRoutes);
|
|
655
|
-
}
|
|
656
|
-
newOutboundRoutesSinceLastRun.push(...outboundRoutes);
|
|
657
|
-
});
|
|
658
|
-
/**
|
|
659
|
-
* Run GC on the above reference graph starting with root and all new outbound routes. This will generate a
|
|
660
|
-
* list of all nodes that could have been referenced since the last run. If any of these nodes are unreferenced,
|
|
661
|
-
* unreferenced, stop tracking them and remove from unreferenced list.
|
|
662
|
-
* Note that some of these nodes may be unreferenced now and if so, the current run will mark them as
|
|
663
|
-
* unreferenced and add unreferenced state.
|
|
664
|
-
*/
|
|
665
|
-
const gcResult = (0, gcReferenceGraphAlgorithm_1.runGarbageCollection)(gcDataSuperSet.gcNodes, [
|
|
666
|
-
"/",
|
|
667
|
-
...newOutboundRoutesSinceLastRun,
|
|
668
|
-
]);
|
|
669
|
-
return gcResult.referencedNodeIds;
|
|
670
|
-
}
|
|
671
687
|
/**
|
|
672
688
|
* Generates the stats of a garbage collection run from the given results of the run.
|
|
673
689
|
* @param gcResult - The result of a GC run.
|