@fluidframework/container-runtime 2.0.0-dev.7.4.0.217212 → 2.0.0-dev.7.4.0.221926
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 +18 -0
- package/api-extractor.json +0 -3
- package/api-report/container-runtime.api.md +77 -73
- package/dist/blobManager.d.ts +4 -4
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js.map +1 -1
- package/dist/container-runtime-alpha.d.ts +1361 -132
- package/dist/container-runtime-beta.d.ts +40 -2
- package/dist/container-runtime-public.d.ts +40 -2
- package/dist/container-runtime-untrimmed.d.ts +106 -93
- package/dist/containerRuntime.d.ts +19 -17
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +44 -24
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStores.d.ts +10 -15
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +63 -36
- package/dist/dataStores.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +29 -10
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +149 -67
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +34 -37
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +97 -44
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +26 -16
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +18 -25
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +29 -45
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +14 -3
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.d.ts +11 -5
- package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.js +43 -19
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/dist/gc/index.d.ts +1 -1
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +4 -4
- package/dist/gc/index.js.map +1 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -5
- package/dist/index.js.map +1 -1
- package/dist/messageTypes.d.ts +13 -5
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js +5 -0
- package/dist/messageTypes.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 -0
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +1 -0
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +1 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +28 -28
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +3 -3
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +3 -3
- package/dist/summary/summaryFormat.js.map +1 -1
- package/lib/blobManager.d.ts +4 -4
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js.map +1 -1
- package/lib/container-runtime-alpha.d.ts +1361 -132
- package/lib/container-runtime-beta.d.ts +40 -2
- package/lib/container-runtime-public.d.ts +40 -2
- package/lib/container-runtime-untrimmed.d.ts +106 -93
- package/lib/containerRuntime.d.ts +19 -17
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +46 -26
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStores.d.ts +10 -15
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +65 -38
- package/lib/dataStores.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +29 -10
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +151 -69
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +37 -40
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +97 -44
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +25 -15
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +18 -25
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +27 -43
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +14 -3
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.d.ts +11 -5
- package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js +43 -19
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/lib/gc/index.d.ts +1 -1
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -1
- package/lib/gc/index.js.map +1 -1
- package/lib/index.d.ts +13 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +15 -1
- package/lib/index.js.map +1 -1
- package/lib/messageTypes.d.ts +13 -5
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js +5 -0
- package/lib/messageTypes.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 -0
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +1 -0
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +28 -28
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +3 -3
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +3 -3
- package/lib/summary/summaryFormat.js.map +1 -1
- package/package.json +18 -15
- package/src/blobManager.ts +5 -5
- package/src/containerRuntime.ts +66 -40
- package/src/dataStores.ts +118 -59
- package/src/gc/garbageCollection.md +14 -15
- package/src/gc/garbageCollection.ts +182 -75
- package/src/gc/gcConfigs.ts +50 -52
- package/src/gc/gcDefinitions.ts +112 -50
- package/src/gc/gcHelpers.ts +31 -52
- package/src/gc/gcTelemetry.ts +16 -4
- package/src/gc/gcUnreferencedStateTracker.ts +61 -22
- package/src/gc/index.ts +4 -3
- package/src/index.ts +17 -1
- package/src/messageTypes.ts +16 -2
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +1 -0
- package/src/summary/orderedClientElection.ts +1 -1
- package/src/summary/summarizerTypes.ts +28 -28
- package/src/summary/summaryCollection.ts +3 -3
- package/src/summary/summaryFormat.ts +3 -3
- package/dist/id-compressor/appendOnlySortedMap.d.ts +0 -124
- package/dist/id-compressor/appendOnlySortedMap.d.ts.map +0 -1
- package/dist/id-compressor/appendOnlySortedMap.js +0 -318
- package/dist/id-compressor/appendOnlySortedMap.js.map +0 -1
- package/dist/id-compressor/finalSpace.d.ts +0 -29
- package/dist/id-compressor/finalSpace.d.ts.map +0 -1
- package/dist/id-compressor/finalSpace.js +0 -62
- package/dist/id-compressor/finalSpace.js.map +0 -1
- package/dist/id-compressor/idCompressor.d.ts +0 -54
- package/dist/id-compressor/idCompressor.d.ts.map +0 -1
- package/dist/id-compressor/idCompressor.js +0 -495
- package/dist/id-compressor/idCompressor.js.map +0 -1
- package/dist/id-compressor/identifiers.d.ts +0 -32
- package/dist/id-compressor/identifiers.d.ts.map +0 -1
- package/dist/id-compressor/identifiers.js +0 -15
- package/dist/id-compressor/identifiers.js.map +0 -1
- package/dist/id-compressor/index.d.ts +0 -13
- package/dist/id-compressor/index.d.ts.map +0 -1
- package/dist/id-compressor/index.js +0 -32
- package/dist/id-compressor/index.js.map +0 -1
- package/dist/id-compressor/persistanceUtilities.d.ts +0 -22
- package/dist/id-compressor/persistanceUtilities.d.ts.map +0 -1
- package/dist/id-compressor/persistanceUtilities.js +0 -43
- package/dist/id-compressor/persistanceUtilities.js.map +0 -1
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts +0 -46
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts.map +0 -1
- package/dist/id-compressor/sessionSpaceNormalizer.js +0 -80
- package/dist/id-compressor/sessionSpaceNormalizer.js.map +0 -1
- package/dist/id-compressor/sessions.d.ts +0 -115
- package/dist/id-compressor/sessions.d.ts.map +0 -1
- package/dist/id-compressor/sessions.js +0 -305
- package/dist/id-compressor/sessions.js.map +0 -1
- package/dist/id-compressor/utilities.d.ts +0 -52
- package/dist/id-compressor/utilities.d.ts.map +0 -1
- package/dist/id-compressor/utilities.js +0 -169
- package/dist/id-compressor/utilities.js.map +0 -1
- package/lib/id-compressor/appendOnlySortedMap.d.ts +0 -124
- package/lib/id-compressor/appendOnlySortedMap.d.ts.map +0 -1
- package/lib/id-compressor/appendOnlySortedMap.js +0 -314
- package/lib/id-compressor/appendOnlySortedMap.js.map +0 -1
- package/lib/id-compressor/finalSpace.d.ts +0 -29
- package/lib/id-compressor/finalSpace.d.ts.map +0 -1
- package/lib/id-compressor/finalSpace.js +0 -58
- package/lib/id-compressor/finalSpace.js.map +0 -1
- package/lib/id-compressor/idCompressor.d.ts +0 -54
- package/lib/id-compressor/idCompressor.d.ts.map +0 -1
- package/lib/id-compressor/idCompressor.js +0 -491
- package/lib/id-compressor/idCompressor.js.map +0 -1
- package/lib/id-compressor/identifiers.d.ts +0 -32
- package/lib/id-compressor/identifiers.d.ts.map +0 -1
- package/lib/id-compressor/identifiers.js +0 -11
- package/lib/id-compressor/identifiers.js.map +0 -1
- package/lib/id-compressor/index.d.ts +0 -13
- package/lib/id-compressor/index.d.ts.map +0 -1
- package/lib/id-compressor/index.js +0 -13
- package/lib/id-compressor/index.js.map +0 -1
- package/lib/id-compressor/persistanceUtilities.d.ts +0 -22
- package/lib/id-compressor/persistanceUtilities.d.ts.map +0 -1
- package/lib/id-compressor/persistanceUtilities.js +0 -34
- package/lib/id-compressor/persistanceUtilities.js.map +0 -1
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts +0 -46
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts.map +0 -1
- package/lib/id-compressor/sessionSpaceNormalizer.js +0 -76
- package/lib/id-compressor/sessionSpaceNormalizer.js.map +0 -1
- package/lib/id-compressor/sessions.d.ts +0 -115
- package/lib/id-compressor/sessions.d.ts.map +0 -1
- package/lib/id-compressor/sessions.js +0 -290
- package/lib/id-compressor/sessions.js.map +0 -1
- package/lib/id-compressor/utilities.d.ts +0 -52
- package/lib/id-compressor/utilities.d.ts.map +0 -1
- package/lib/id-compressor/utilities.js +0 -151
- package/lib/id-compressor/utilities.js.map +0 -1
- package/src/id-compressor/README.md +0 -69
- package/src/id-compressor/appendOnlySortedMap.ts +0 -366
- package/src/id-compressor/finalSpace.ts +0 -67
- package/src/id-compressor/idCompressor.ts +0 -630
- package/src/id-compressor/identifiers.ts +0 -42
- package/src/id-compressor/index.ts +0 -26
- package/src/id-compressor/persistanceUtilities.ts +0 -58
- package/src/id-compressor/sessionSpaceNormalizer.ts +0 -83
- package/src/id-compressor/sessions.ts +0 -405
- package/src/id-compressor/utilities.ts +0 -190
|
@@ -21,13 +21,13 @@ import {
|
|
|
21
21
|
MonitoringContext,
|
|
22
22
|
PerformanceEvent,
|
|
23
23
|
} from "@fluidframework/telemetry-utils";
|
|
24
|
-
|
|
25
24
|
import {
|
|
26
25
|
InactiveResponseHeaderKey,
|
|
27
26
|
RuntimeHeaderData,
|
|
28
27
|
TombstoneResponseHeaderKey,
|
|
29
28
|
} from "../containerRuntime";
|
|
30
29
|
import { ClientSessionExpiredError } from "../error";
|
|
30
|
+
import { ContainerMessageType, ContainerRuntimeGCMessage } from "../messageTypes";
|
|
31
31
|
import { IRefreshSummaryResult } from "../summary";
|
|
32
32
|
import { generateGCConfigs } from "./gcConfigs";
|
|
33
33
|
import {
|
|
@@ -42,8 +42,15 @@ import {
|
|
|
42
42
|
IGarbageCollectorConfigs,
|
|
43
43
|
IMarkPhaseStats,
|
|
44
44
|
ISweepPhaseStats,
|
|
45
|
+
GarbageCollectionMessage,
|
|
46
|
+
GarbageCollectionMessageType,
|
|
45
47
|
} from "./gcDefinitions";
|
|
46
|
-
import {
|
|
48
|
+
import {
|
|
49
|
+
cloneGCData,
|
|
50
|
+
compatBehaviorAllowsGCMessageType,
|
|
51
|
+
concatGarbageCollectionData,
|
|
52
|
+
getGCDataFromSnapshot,
|
|
53
|
+
} from "./gcHelpers";
|
|
47
54
|
import { runGarbageCollection } from "./gcReferenceGraphAlgorithm";
|
|
48
55
|
import { IGarbageCollectionSnapshotData, IGarbageCollectionState } from "./gcSummaryDefinitions";
|
|
49
56
|
import { GCSummaryStateTracker } from "./gcSummaryStateTracker";
|
|
@@ -117,7 +124,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
117
124
|
|
|
118
125
|
/** If false, loading or using a Tombstoned object should merely log, not fail */
|
|
119
126
|
public get tombstoneEnforcementAllowed(): boolean {
|
|
120
|
-
return this.configs.
|
|
127
|
+
return this.configs.sweepEnabled;
|
|
121
128
|
}
|
|
122
129
|
/** If true, throw an error when a tombstone data store is retrieved */
|
|
123
130
|
public get throwOnTombstoneLoad(): boolean {
|
|
@@ -137,6 +144,8 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
137
144
|
/** Returns true if connection is active, i.e. it's "write" connection and the runtime is connected. */
|
|
138
145
|
private readonly activeConnection: () => boolean;
|
|
139
146
|
|
|
147
|
+
private readonly submitMessage: (message: ContainerRuntimeGCMessage) => void;
|
|
148
|
+
|
|
140
149
|
public get summaryStateNeedsReset(): boolean {
|
|
141
150
|
return this.summaryStateTracker.doesSummaryStateNeedReset;
|
|
142
151
|
}
|
|
@@ -152,6 +161,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
152
161
|
this.getNodePackagePath = createParams.getNodePackagePath;
|
|
153
162
|
this.getLastSummaryTimestampMs = createParams.getLastSummaryTimestampMs;
|
|
154
163
|
this.activeConnection = createParams.activeConnection;
|
|
164
|
+
this.submitMessage = createParams.submitMessage;
|
|
155
165
|
|
|
156
166
|
const baseSnapshot = createParams.baseSnapshot;
|
|
157
167
|
const readAndParseBlob = createParams.readAndParseBlob;
|
|
@@ -247,7 +257,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
247
257
|
/**
|
|
248
258
|
* Set up the initializer which initializes the GC state from the data in base snapshot. This is done when
|
|
249
259
|
* connected in write mode or when GC runs the first time. It sets up all unreferenced nodes from the base
|
|
250
|
-
* GC state and updates their inactive or sweep
|
|
260
|
+
* GC state and updates their inactive or sweep-ready state.
|
|
251
261
|
*/
|
|
252
262
|
this.initializeGCStateFromBaseSnapshotP = new LazyPromise<void>(async () => {
|
|
253
263
|
/**
|
|
@@ -418,6 +428,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
418
428
|
this.configs.inactiveTimeoutMs,
|
|
419
429
|
currentReferenceTimestampMs,
|
|
420
430
|
this.configs.sweepTimeoutMs,
|
|
431
|
+
this.configs.sweepGracePeriodMs,
|
|
421
432
|
),
|
|
422
433
|
);
|
|
423
434
|
}
|
|
@@ -428,7 +439,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
428
439
|
|
|
429
440
|
/**
|
|
430
441
|
* Called when the connection state of the runtime changes, i.e., it connects or disconnects. GC subscribes to this
|
|
431
|
-
* to initialize the base state for non-summarizer clients so that they can track inactive / sweep
|
|
442
|
+
* to initialize the base state for non-summarizer clients so that they can track inactive / sweep-ready nodes.
|
|
432
443
|
* @param connected - Whether the runtime connected / disconnected.
|
|
433
444
|
* @param clientId - The clientId of this runtime.
|
|
434
445
|
*/
|
|
@@ -444,7 +455,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
444
455
|
* the receiving summarizer client.
|
|
445
456
|
*
|
|
446
457
|
* Ideally, this initialization should only be done for summarizer client. However, we are currently rolling out
|
|
447
|
-
* sweep in phases and we want to track when inactive and sweep
|
|
458
|
+
* sweep in phases and we want to track when inactive and sweep-ready objects are used in any client.
|
|
448
459
|
*/
|
|
449
460
|
if (this.activeConnection() && this.configs.shouldRunGC) {
|
|
450
461
|
this.initializeGCStateFromBaseSnapshotP.catch((error) => {});
|
|
@@ -547,10 +558,15 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
547
558
|
|
|
548
559
|
/**
|
|
549
560
|
* Runs garbage collection. It does the following:
|
|
561
|
+
*
|
|
550
562
|
* 1. It generates / analyzes the runtime's reference graph.
|
|
563
|
+
*
|
|
551
564
|
* 2. Generates mark phase stats.
|
|
565
|
+
*
|
|
552
566
|
* 3. Runs Mark phase.
|
|
567
|
+
*
|
|
553
568
|
* 4. Runs Sweep phase.
|
|
569
|
+
*
|
|
554
570
|
* 5. Generates sweep phase stats.
|
|
555
571
|
*/
|
|
556
572
|
private async runGC(
|
|
@@ -572,26 +588,24 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
572
588
|
const markPhaseStats = this.getMarkPhaseStats(gcResult);
|
|
573
589
|
|
|
574
590
|
// 3. Run the Mark phase.
|
|
575
|
-
// It will mark nodes as referenced / unreferenced and return
|
|
576
|
-
const sweepReadyNodeIds = this.runMarkPhase(
|
|
591
|
+
// It will mark nodes as referenced / unreferenced and return lists of tombstone-ready and sweep-ready nodes.
|
|
592
|
+
const { tombstoneReadyNodeIds, sweepReadyNodeIds } = this.runMarkPhase(
|
|
577
593
|
gcResult,
|
|
578
594
|
allReferencedNodeIds,
|
|
579
595
|
currentReferenceTimestampMs,
|
|
580
596
|
);
|
|
581
597
|
|
|
582
598
|
// 4. Run the Sweep phase.
|
|
583
|
-
// It will
|
|
584
|
-
|
|
599
|
+
// It will tombstone any tombstone-ready nodes, and initiate the deletion of sweep-ready nodes by sending a
|
|
600
|
+
// sweep op. All clients, including this one, will delete these nodes once it processes the op.
|
|
601
|
+
this.runSweepPhase(gcResult, tombstoneReadyNodeIds, sweepReadyNodeIds);
|
|
585
602
|
|
|
586
|
-
this.gcDataFromLastRun = cloneGCData(
|
|
587
|
-
gcData,
|
|
588
|
-
(id: string) => deletedNodeIds.includes(id) /* filter out deleted nodes */,
|
|
589
|
-
);
|
|
603
|
+
this.gcDataFromLastRun = cloneGCData(gcData);
|
|
590
604
|
|
|
591
605
|
// 5. Get the sweep phase stats.
|
|
592
606
|
const sweepPhaseStats = this.getSweepPhaseStats(
|
|
593
|
-
this.
|
|
594
|
-
|
|
607
|
+
this.deletedNodes,
|
|
608
|
+
sweepReadyNodeIds,
|
|
595
609
|
markPhaseStats,
|
|
596
610
|
);
|
|
597
611
|
|
|
@@ -610,13 +624,13 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
610
624
|
* @param gcResult - The result of the GC run on the gcData.
|
|
611
625
|
* @param allReferencedNodeIds - Nodes referenced in this GC run + referenced between previous and current GC run.
|
|
612
626
|
* @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
|
|
613
|
-
* @returns
|
|
627
|
+
* @returns The sets of tombstone-ready and sweep-ready nodes, i.e., nodes that ready to be tombstoned or deleted.
|
|
614
628
|
*/
|
|
615
629
|
private runMarkPhase(
|
|
616
630
|
gcResult: IGCResult,
|
|
617
631
|
allReferencedNodeIds: string[],
|
|
618
632
|
currentReferenceTimestampMs: number,
|
|
619
|
-
): Set<string> {
|
|
633
|
+
): { tombstoneReadyNodeIds: Set<string>; sweepReadyNodeIds: Set<string> } {
|
|
620
634
|
// 1. Marks all referenced nodes by clearing their unreferenced tracker, if any.
|
|
621
635
|
for (const nodeId of allReferencedNodeIds) {
|
|
622
636
|
const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
|
|
@@ -629,6 +643,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
629
643
|
}
|
|
630
644
|
|
|
631
645
|
// 2. Mark unreferenced nodes in this run by starting unreferenced tracking for them.
|
|
646
|
+
const tombstoneReadyNodeIds: Set<string> = new Set();
|
|
632
647
|
const sweepReadyNodeIds: Set<string> = new Set();
|
|
633
648
|
for (const nodeId of gcResult.deletedNodeIds) {
|
|
634
649
|
const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
|
|
@@ -640,6 +655,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
640
655
|
this.configs.inactiveTimeoutMs,
|
|
641
656
|
currentReferenceTimestampMs,
|
|
642
657
|
this.configs.sweepTimeoutMs,
|
|
658
|
+
this.configs.sweepGracePeriodMs,
|
|
643
659
|
),
|
|
644
660
|
);
|
|
645
661
|
} else {
|
|
@@ -647,7 +663,10 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
647
663
|
// is from the ops seen, this will ensure that we keep updating unreferenced state as time moves forward.
|
|
648
664
|
nodeStateTracker.updateTracking(currentReferenceTimestampMs);
|
|
649
665
|
|
|
650
|
-
// If a node is sweep
|
|
666
|
+
// If a node is tombstone or sweep-ready, store it so it can be returned.
|
|
667
|
+
if (nodeStateTracker.state === UnreferencedState.TombstoneReady) {
|
|
668
|
+
tombstoneReadyNodeIds.add(nodeId);
|
|
669
|
+
}
|
|
651
670
|
if (nodeStateTracker.state === UnreferencedState.SweepReady) {
|
|
652
671
|
sweepReadyNodeIds.add(nodeId);
|
|
653
672
|
}
|
|
@@ -657,67 +676,82 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
657
676
|
// 3. Call the runtime to update referenced nodes in this run.
|
|
658
677
|
this.runtime.updateUsedRoutes(gcResult.referencedNodeIds);
|
|
659
678
|
|
|
660
|
-
return sweepReadyNodeIds;
|
|
679
|
+
return { tombstoneReadyNodeIds, sweepReadyNodeIds };
|
|
661
680
|
}
|
|
662
681
|
|
|
663
682
|
/**
|
|
664
683
|
* Runs the GC Sweep phase. It does the following:
|
|
665
|
-
*
|
|
666
|
-
*
|
|
684
|
+
*
|
|
685
|
+
* 1. Marks tombstone-ready nodes as tombstones.
|
|
686
|
+
*
|
|
687
|
+
* 2. Sends a sweep op to delete nodes that are sweep-ready. Once the op is ack'd, these nodes will be deleted.
|
|
667
688
|
*
|
|
668
689
|
* @param gcResult - The result of the GC run on the gcData.
|
|
669
|
-
* @param
|
|
670
|
-
* @param
|
|
671
|
-
* @param logger - The logger to be used to log any telemetry.
|
|
672
|
-
* @returns A list of nodes that have been deleted.
|
|
690
|
+
* @param tombstoneReadyNodes - List of nodes that are tombstone-ready.
|
|
691
|
+
* @param sweepReadyNodes - List of nodes that are sweep-ready.
|
|
673
692
|
*/
|
|
674
|
-
private runSweepPhase(
|
|
693
|
+
private runSweepPhase(
|
|
694
|
+
gcResult: IGCResult,
|
|
695
|
+
tombstoneReadyNodes: Set<string>,
|
|
696
|
+
sweepReadyNodes: Set<string>,
|
|
697
|
+
) {
|
|
675
698
|
/**
|
|
676
|
-
*
|
|
677
|
-
* Test mode - Unreferenced nodes are immediately deleted without waiting for them to be sweep ready.
|
|
678
|
-
* Tombstone mode - Sweep ready modes are marked as tombstones instead of being deleted.
|
|
679
|
-
* Sweep mode - Sweep ready modes are deleted.
|
|
699
|
+
* Under "Test Mode", unreferenced nodes are immediately deleted without waiting for them to be sweep-ready.
|
|
680
700
|
*
|
|
681
|
-
*
|
|
682
|
-
*
|
|
701
|
+
* Otherwise, depending on how long it's been since the node was unreferenced, it will either be
|
|
702
|
+
* marked as Tombstone, or deleted by Sweep.
|
|
683
703
|
*/
|
|
704
|
+
|
|
684
705
|
if (this.configs.testMode) {
|
|
685
706
|
// If we are running in GC test mode, unreferenced nodes (gcResult.deletedNodeIds) are deleted.
|
|
686
707
|
this.runtime.updateUnusedRoutes(gcResult.deletedNodeIds);
|
|
687
|
-
return
|
|
708
|
+
return;
|
|
688
709
|
}
|
|
689
710
|
|
|
711
|
+
// If sweep is disabled, we'll tombstone both tombstone-ready and sweep-ready nodes.
|
|
712
|
+
// This is important because a container may never load during a node's Sweep Grace Period,
|
|
713
|
+
// so that node would directly become sweep-ready skipping over tombstone-ready state,
|
|
714
|
+
// but should be Tombstoned since Sweep is disabled.
|
|
715
|
+
const { nodesToTombstone, nodesToDelete } = this.configs.shouldRunSweep
|
|
716
|
+
? {
|
|
717
|
+
nodesToTombstone: [...tombstoneReadyNodes],
|
|
718
|
+
nodesToDelete: [...sweepReadyNodes],
|
|
719
|
+
}
|
|
720
|
+
: {
|
|
721
|
+
nodesToTombstone: [...tombstoneReadyNodes, ...sweepReadyNodes],
|
|
722
|
+
nodesToDelete: [],
|
|
723
|
+
};
|
|
724
|
+
|
|
690
725
|
if (this.configs.tombstoneMode) {
|
|
691
|
-
this.tombstones =
|
|
692
|
-
// If we are running in GC tombstone mode, update tombstoned routes.
|
|
693
|
-
// involving access to "deleted" data without actually deleting the data from summaries.
|
|
726
|
+
this.tombstones = nodesToTombstone;
|
|
727
|
+
// If we are running in GC tombstone mode, update tombstoned routes.
|
|
694
728
|
this.runtime.updateTombstonedRoutes(this.tombstones);
|
|
695
|
-
return [];
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
if (!this.configs.shouldRunSweep) {
|
|
699
|
-
return [];
|
|
700
729
|
}
|
|
701
730
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
731
|
+
if (this.configs.shouldRunSweep && nodesToDelete.length > 0) {
|
|
732
|
+
// Do not send DDS node ids in the GC op. This is an optimization to reduce its size. Since GC applies to
|
|
733
|
+
// to data store only, all its DDSes are deleted along with it. The DDS ids will be retrieved from the
|
|
734
|
+
// local state when processing the op.
|
|
735
|
+
const sweepReadyDSAndBlobs = nodesToDelete.filter((nodeId) => {
|
|
736
|
+
const nodeType = this.runtime.getNodeType(nodeId);
|
|
737
|
+
return nodeType === GCNodeType.DataStore || nodeType === GCNodeType.Blob;
|
|
738
|
+
});
|
|
739
|
+
const contents: GarbageCollectionMessage = {
|
|
740
|
+
type: GarbageCollectionMessageType.Sweep,
|
|
741
|
+
deletedNodeIds: sweepReadyDSAndBlobs,
|
|
742
|
+
};
|
|
706
743
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
// TODO: GC:Validation - assert that the deleted node is not a duplicate
|
|
718
|
-
this.deletedNodes.add(nodeId);
|
|
744
|
+
// Its fine for older clients to ignore this op because it doesn't have any functional impact. This op
|
|
745
|
+
// is an optimization to ensure that all clients are in sync when it comes to deleted nodes to prevent their
|
|
746
|
+
// accidental usage. The clients will sync without the delete op too but it may take longer.
|
|
747
|
+
const containerGCMessage: ContainerRuntimeGCMessage = {
|
|
748
|
+
type: ContainerMessageType.GC,
|
|
749
|
+
contents,
|
|
750
|
+
compatDetails: { behavior: "Ignore" },
|
|
751
|
+
};
|
|
752
|
+
this.submitMessage(containerGCMessage);
|
|
753
|
+
return;
|
|
719
754
|
}
|
|
720
|
-
return deletedNodeIds;
|
|
721
755
|
}
|
|
722
756
|
|
|
723
757
|
/**
|
|
@@ -857,6 +891,78 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
857
891
|
return this.summaryStateTracker.refreshLatestSummary(result);
|
|
858
892
|
}
|
|
859
893
|
|
|
894
|
+
/**
|
|
895
|
+
* Process a GC message.
|
|
896
|
+
* @param message - The GC message from the container runtime.
|
|
897
|
+
* @param local - Whether it was send by this client.
|
|
898
|
+
*/
|
|
899
|
+
public processMessage(message: ContainerRuntimeGCMessage, local: boolean) {
|
|
900
|
+
switch (message.contents.type) {
|
|
901
|
+
case "Sweep": {
|
|
902
|
+
// Delete the nodes whose ids are present in the contents.
|
|
903
|
+
this.deleteSweepReadyNodes(message.contents.deletedNodeIds);
|
|
904
|
+
break;
|
|
905
|
+
}
|
|
906
|
+
default: {
|
|
907
|
+
if (
|
|
908
|
+
!compatBehaviorAllowsGCMessageType(
|
|
909
|
+
message.contents.type,
|
|
910
|
+
message.compatDetails?.behavior,
|
|
911
|
+
)
|
|
912
|
+
) {
|
|
913
|
+
const error = DataProcessingError.create(
|
|
914
|
+
`Garbage collection message of unknown type ${message.contents.type}`,
|
|
915
|
+
"processMessage",
|
|
916
|
+
);
|
|
917
|
+
throw error;
|
|
918
|
+
}
|
|
919
|
+
break;
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Delete nodes that are sweep-ready. Call the runtime to delete these nodes and clear the unreferenced state
|
|
926
|
+
* tracking for nodes that are actually deleted by the runtime.
|
|
927
|
+
* @param sweepReadyNodeIds - The ids of nodes that are ready to be deleted.
|
|
928
|
+
*/
|
|
929
|
+
private deleteSweepReadyNodes(sweepReadyNodeIds: readonly string[]) {
|
|
930
|
+
// Use a set for lookup because its much faster than array or map.
|
|
931
|
+
const sweepReadyNodesSet: Set<string> = new Set(sweepReadyNodeIds);
|
|
932
|
+
|
|
933
|
+
// The ids in the sweep-ready nodes do not contain DDS node ids. This is an optimization to reduce the size
|
|
934
|
+
// of the GC op. Since GC applies to data store only, all its DDSes are deleted along with it. So, get the
|
|
935
|
+
// DDS nodes ID from the unreferenced nodes state.
|
|
936
|
+
const allSweepReadyNodeIds = Array.from(sweepReadyNodeIds);
|
|
937
|
+
for (const [id] of this.unreferencedNodesState) {
|
|
938
|
+
// Ignore data store nodes since they would already be in the list.
|
|
939
|
+
const pathParts = id.split("/");
|
|
940
|
+
if (pathParts.length <= 2) {
|
|
941
|
+
continue;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// Get the data store id part. Note that this may include blobs but that's okay since the part would just
|
|
945
|
+
// be "_blobs" and it won't be found.
|
|
946
|
+
const dsId = `/${pathParts[1]}`;
|
|
947
|
+
if (sweepReadyNodesSet.has(dsId)) {
|
|
948
|
+
allSweepReadyNodeIds.push(id);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
const deletedNodeIds = this.runtime.deleteSweepReadyNodes(allSweepReadyNodeIds);
|
|
952
|
+
|
|
953
|
+
// Clear unreferenced state tracking for deleted nodes.
|
|
954
|
+
for (const nodeId of deletedNodeIds) {
|
|
955
|
+
const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
|
|
956
|
+
if (nodeStateTracker !== undefined) {
|
|
957
|
+
// Stop tracking so as to clear out any running timers.
|
|
958
|
+
nodeStateTracker.stopTracking();
|
|
959
|
+
// Delete the node as we don't need to track it any more.
|
|
960
|
+
this.unreferencedNodesState.delete(nodeId);
|
|
961
|
+
}
|
|
962
|
+
this.deletedNodes.add(nodeId);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
|
|
860
966
|
/**
|
|
861
967
|
* Called when a node with the given id is updated. If the node is inactive or tombstoned, this will log an error
|
|
862
968
|
* or throw an error if failing on incorrect usage is configured.
|
|
@@ -1036,14 +1142,14 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1036
1142
|
|
|
1037
1143
|
/**
|
|
1038
1144
|
* Generates the stats of a garbage collection sweep phase run.
|
|
1039
|
-
* @param
|
|
1040
|
-
* @param
|
|
1145
|
+
* @param deletedNodes - The nodes that have been deleted until this run.
|
|
1146
|
+
* @param sweepReadyNodes - The nodes that are sweep-ready in this GC run.
|
|
1041
1147
|
* @param markPhaseStats - The stats of the mark phase run.
|
|
1042
1148
|
* @returns the stats of the sweep phase run.
|
|
1043
1149
|
*/
|
|
1044
1150
|
private getSweepPhaseStats(
|
|
1045
|
-
|
|
1046
|
-
|
|
1151
|
+
deletedNodes: Set<string>,
|
|
1152
|
+
sweepReadyNodes: Set<string>,
|
|
1047
1153
|
markPhaseStats: IMarkPhaseStats,
|
|
1048
1154
|
): ISweepPhaseStats {
|
|
1049
1155
|
// Initialize the life time node counts to the mark phase node counts. If sweep is not enabled,
|
|
@@ -1057,7 +1163,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1057
1163
|
deletedAttachmentBlobCount: 0,
|
|
1058
1164
|
};
|
|
1059
1165
|
|
|
1060
|
-
for (const nodeId of
|
|
1166
|
+
for (const nodeId of deletedNodes) {
|
|
1061
1167
|
sweepPhaseStats.deletedNodeCount++;
|
|
1062
1168
|
const nodeType = this.runtime.getNodeType(nodeId);
|
|
1063
1169
|
if (nodeType === GCNodeType.DataStore) {
|
|
@@ -1067,25 +1173,26 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1067
1173
|
}
|
|
1068
1174
|
}
|
|
1069
1175
|
|
|
1070
|
-
if (!this.configs.shouldRunSweep) {
|
|
1071
|
-
return sweepPhaseStats;
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
1176
|
// If sweep is enabled, the counts from the mark phase stats do not include nodes that have been
|
|
1075
|
-
// deleted in previous runs.
|
|
1177
|
+
// deleted in previous runs. So, add the deleted node counts to life time stats.
|
|
1076
1178
|
sweepPhaseStats.lifetimeNodeCount += sweepPhaseStats.deletedNodeCount;
|
|
1077
1179
|
sweepPhaseStats.lifetimeDataStoreCount += sweepPhaseStats.deletedDataStoreCount;
|
|
1078
1180
|
sweepPhaseStats.lifetimeAttachmentBlobCount += sweepPhaseStats.deletedAttachmentBlobCount;
|
|
1079
1181
|
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1182
|
+
if (this.configs.shouldRunSweep) {
|
|
1183
|
+
return sweepPhaseStats;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
// If sweep is not enabled, the current sweep-ready node stats should be added to deleted stats since this
|
|
1187
|
+
// is the final state the node will be in.
|
|
1188
|
+
// If sweep is enabled, this will happen in the run after the GC op round trips back.
|
|
1189
|
+
for (const nodeId of sweepReadyNodes) {
|
|
1190
|
+
sweepPhaseStats.deletedNodeCount++;
|
|
1084
1191
|
const nodeType = this.runtime.getNodeType(nodeId);
|
|
1085
1192
|
if (nodeType === GCNodeType.DataStore) {
|
|
1086
|
-
sweepPhaseStats.
|
|
1193
|
+
sweepPhaseStats.deletedDataStoreCount++;
|
|
1087
1194
|
} else if (nodeType === GCNodeType.Blob) {
|
|
1088
|
-
sweepPhaseStats.
|
|
1195
|
+
sweepPhaseStats.deletedAttachmentBlobCount++;
|
|
1089
1196
|
}
|
|
1090
1197
|
}
|
|
1091
1198
|
return sweepPhaseStats;
|
package/src/gc/gcConfigs.ts
CHANGED
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
MonitoringContext,
|
|
8
|
+
UsageError,
|
|
9
|
+
validatePrecondition,
|
|
10
|
+
} from "@fluidframework/telemetry-utils";
|
|
7
11
|
import { IContainerRuntimeMetadata } from "../summary";
|
|
8
12
|
import {
|
|
9
13
|
nextGCVersion,
|
|
@@ -11,9 +15,7 @@ import {
|
|
|
11
15
|
defaultSessionExpiryDurationMs,
|
|
12
16
|
disableTombstoneKey,
|
|
13
17
|
GCFeatureMatrix,
|
|
14
|
-
gcSweepGenerationOptionName,
|
|
15
18
|
gcTestModeKey,
|
|
16
|
-
gcTombstoneGenerationOptionName,
|
|
17
19
|
GCVersion,
|
|
18
20
|
gcVersionUpgradeToV4Key,
|
|
19
21
|
IGarbageCollectorConfigs,
|
|
@@ -26,9 +28,11 @@ import {
|
|
|
26
28
|
stableGCVersion,
|
|
27
29
|
throwOnTombstoneLoadOverrideKey,
|
|
28
30
|
throwOnTombstoneUsageKey,
|
|
29
|
-
|
|
31
|
+
gcDisableThrowOnTombstoneLoadOptionName,
|
|
32
|
+
defaultSweepGracePeriodMs,
|
|
33
|
+
gcGenerationOptionName,
|
|
30
34
|
} from "./gcDefinitions";
|
|
31
|
-
import { getGCVersion, shouldAllowGcSweep
|
|
35
|
+
import { getGCVersion, shouldAllowGcSweep } from "./gcHelpers";
|
|
32
36
|
|
|
33
37
|
/**
|
|
34
38
|
* Generates configurations for the Garbage Collector that it uses to determine what to run and how.
|
|
@@ -71,14 +75,6 @@ export function generateGCConfigs(
|
|
|
71
75
|
createParams.metadata?.sweepTimeoutMs ?? computeSweepTimeout(sessionExpiryTimeoutMs); // Backfill old documents that didn't persist this
|
|
72
76
|
persistedGcFeatureMatrix = createParams.metadata?.gcFeatureMatrix;
|
|
73
77
|
} else {
|
|
74
|
-
const tombstoneGeneration = createParams.gcOptions[gcTombstoneGenerationOptionName];
|
|
75
|
-
const sweepGeneration = createParams.gcOptions[gcSweepGenerationOptionName];
|
|
76
|
-
|
|
77
|
-
// Sweep should not be enabled (via sweepGeneration value) without enabling GC mark phase.
|
|
78
|
-
if (sweepGeneration !== undefined && createParams.gcOptions.gcAllowed === false) {
|
|
79
|
-
throw new UsageError("GC sweep phase cannot be enabled without enabling GC mark phase");
|
|
80
|
-
}
|
|
81
|
-
|
|
82
78
|
// This Test Override only applies for new containers
|
|
83
79
|
const testOverrideSweepTimeoutMs = mc.config.getNumber(
|
|
84
80
|
"Fluid.GarbageCollection.TestOverride.SweepTimeoutMs",
|
|
@@ -95,18 +91,18 @@ export function generateGCConfigs(
|
|
|
95
91
|
}
|
|
96
92
|
sweepTimeoutMs = testOverrideSweepTimeoutMs ?? computeSweepTimeout(sessionExpiryTimeoutMs);
|
|
97
93
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
sweepGeneration,
|
|
102
|
-
};
|
|
94
|
+
const gcGeneration = createParams.gcOptions[gcGenerationOptionName];
|
|
95
|
+
if (gcGeneration !== undefined) {
|
|
96
|
+
persistedGcFeatureMatrix = { gcGeneration };
|
|
103
97
|
}
|
|
104
98
|
}
|
|
105
99
|
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
100
|
+
// The persisted GC generation must indicate Sweep is allowed for this document,
|
|
101
|
+
// according to the GC Generation option provided this session.
|
|
102
|
+
// Note that if no generation option is provided, Sweep is allowed for any document.
|
|
103
|
+
const sweepAllowed = shouldAllowGcSweep(
|
|
104
|
+
persistedGcFeatureMatrix ?? {} /* featureMatrix */,
|
|
105
|
+
createParams.gcOptions[gcGenerationOptionName] /* currentGeneration */,
|
|
110
106
|
);
|
|
111
107
|
|
|
112
108
|
// If version upgrade is not enabled, fall back to the stable GC version.
|
|
@@ -123,27 +119,30 @@ export function generateGCConfigs(
|
|
|
123
119
|
* Whether GC should run or not. The following conditions have to be met to run sweep:
|
|
124
120
|
* 1. GC should be enabled for this container.
|
|
125
121
|
* 2. GC should not be disabled via disableGC GC option.
|
|
126
|
-
* 3. The current GC version should be greater
|
|
127
|
-
*
|
|
122
|
+
* 3. The current GC version should be greater or equal to the GC version in the base snapshot.
|
|
123
|
+
*
|
|
124
|
+
* These conditions can be overridden via the RunGC feature flag.
|
|
128
125
|
*/
|
|
129
126
|
const shouldRunGC =
|
|
130
127
|
mc.config.getBoolean(runGCKey) ??
|
|
131
128
|
(gcEnabled && !createParams.gcOptions.disableGC && isGCVersionUpToDate);
|
|
132
129
|
|
|
133
130
|
/**
|
|
134
|
-
* Whether sweep should run or not.
|
|
131
|
+
* Whether sweep should run or not. This refers to whether Tombstones should fail on load and whether
|
|
132
|
+
* sweep-ready nodes should be deleted.
|
|
135
133
|
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* feature flag.
|
|
134
|
+
* Assuming overall GC is enabled and sweepTimeout is provided, the following conditions have to be met to run sweep:
|
|
135
|
+
*
|
|
136
|
+
* 1. Sweep should be enabled for this container.
|
|
137
|
+
* 2. Sweep should be enabled for this session.
|
|
138
|
+
*
|
|
139
|
+
* These conditions can be overridden via the RunSweep feature flag.
|
|
142
140
|
*/
|
|
143
141
|
const shouldRunSweep =
|
|
144
|
-
shouldRunGC
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
!shouldRunGC || sweepTimeoutMs === undefined
|
|
143
|
+
? false
|
|
144
|
+
: mc.config.getBoolean(runSweepKey) ??
|
|
145
|
+
(sweepAllowed && createParams.gcOptions.enableGCSweep === true);
|
|
147
146
|
|
|
148
147
|
// Override inactive timeout if test config or gc options to override it is set.
|
|
149
148
|
const inactiveTimeoutMs =
|
|
@@ -159,46 +158,45 @@ export function generateGCConfigs(
|
|
|
159
158
|
// Whether we are running in test mode. In this mode, unreferenced nodes are immediately deleted.
|
|
160
159
|
const testMode =
|
|
161
160
|
mc.config.getBoolean(gcTestModeKey) ?? createParams.gcOptions.runGCInTestMode === true;
|
|
162
|
-
// Whether we are running in tombstone mode.
|
|
163
|
-
//
|
|
164
|
-
const tombstoneMode =
|
|
161
|
+
// Whether we are running in tombstone mode. If disabled, tombstone data will not be written to or read from snapshots,
|
|
162
|
+
// and objects will not be marked as tombstoned even if they pass to the "TombstoneReady" state during the session.
|
|
163
|
+
const tombstoneMode = mc.config.getBoolean(disableTombstoneKey) !== true;
|
|
165
164
|
const runFullGC = createParams.gcOptions.runFullGC;
|
|
166
165
|
|
|
166
|
+
const sweepGracePeriodMs =
|
|
167
|
+
createParams.gcOptions.sweepGracePeriodMs ?? defaultSweepGracePeriodMs;
|
|
168
|
+
validatePrecondition(sweepGracePeriodMs >= 0, "sweepGracePeriodMs must be non-negative", {
|
|
169
|
+
sweepGracePeriodMs,
|
|
170
|
+
});
|
|
171
|
+
|
|
167
172
|
const throwOnInactiveLoad: boolean | undefined = createParams.gcOptions.throwOnInactiveLoad;
|
|
168
|
-
const tombstoneEnforcementAllowed = shouldAllowGcTombstoneEnforcement(
|
|
169
|
-
createParams.metadata?.gcFeatureMatrix?.tombstoneGeneration /* persisted */,
|
|
170
|
-
createParams.gcOptions[gcTombstoneGenerationOptionName] /* current */,
|
|
171
|
-
);
|
|
172
173
|
|
|
173
174
|
const throwOnTombstoneLoadConfig =
|
|
174
175
|
mc.config.getBoolean(throwOnTombstoneLoadOverrideKey) ??
|
|
175
|
-
createParams.gcOptions[
|
|
176
|
-
false;
|
|
176
|
+
createParams.gcOptions[gcDisableThrowOnTombstoneLoadOptionName] !== true;
|
|
177
177
|
const throwOnTombstoneLoad =
|
|
178
|
-
throwOnTombstoneLoadConfig &&
|
|
179
|
-
tombstoneEnforcementAllowed &&
|
|
180
|
-
!createParams.isSummarizerClient;
|
|
178
|
+
throwOnTombstoneLoadConfig && sweepAllowed && !createParams.isSummarizerClient;
|
|
181
179
|
const throwOnTombstoneUsage =
|
|
182
180
|
mc.config.getBoolean(throwOnTombstoneUsageKey) === true &&
|
|
183
|
-
|
|
181
|
+
sweepAllowed &&
|
|
184
182
|
!createParams.isSummarizerClient;
|
|
185
183
|
|
|
186
184
|
return {
|
|
187
|
-
gcEnabled,
|
|
188
|
-
sweepEnabled,
|
|
189
|
-
shouldRunGC,
|
|
190
|
-
shouldRunSweep,
|
|
185
|
+
gcEnabled, // For this document
|
|
186
|
+
sweepEnabled: sweepAllowed, // For this document (based on current GC Generation option)
|
|
187
|
+
shouldRunGC, // For this session
|
|
188
|
+
shouldRunSweep, // For this session
|
|
191
189
|
runFullGC,
|
|
192
190
|
testMode,
|
|
193
191
|
tombstoneMode,
|
|
194
192
|
sessionExpiryTimeoutMs,
|
|
195
193
|
sweepTimeoutMs,
|
|
194
|
+
sweepGracePeriodMs,
|
|
196
195
|
inactiveTimeoutMs,
|
|
197
196
|
persistedGcFeatureMatrix,
|
|
198
197
|
gcVersionInBaseSnapshot,
|
|
199
198
|
gcVersionInEffect,
|
|
200
199
|
throwOnInactiveLoad,
|
|
201
|
-
tombstoneEnforcementAllowed,
|
|
202
200
|
throwOnTombstoneLoad,
|
|
203
201
|
throwOnTombstoneUsage,
|
|
204
202
|
};
|