@fluidframework/container-runtime 2.0.0-dev.7.4.0.217884 → 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 +22 -18
- package/dist/blobManager.d.ts +3 -3
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js.map +1 -1
- package/dist/container-runtime-alpha.d.ts +42 -21
- 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 +51 -38
- package/dist/containerRuntime.d.ts +9 -7
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +42 -22
- 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 +88 -35
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +25 -15
- 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/lib/blobManager.d.ts +3 -3
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js.map +1 -1
- package/lib/container-runtime-alpha.d.ts +42 -21
- 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 +51 -38
- package/lib/containerRuntime.d.ts +9 -7
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +44 -24
- 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 +88 -35
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +24 -14
- 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/package.json +18 -15
- package/src/blobManager.ts +4 -4
- package/src/containerRuntime.ts +56 -30
- 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 +103 -41
- 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/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
|
@@ -6,6 +6,7 @@ import { IRequest } from "@fluidframework/core-interfaces";
|
|
|
6
6
|
import { IGarbageCollectionDetailsBase, ISummarizeResult, ITelemetryContext } from "@fluidframework/runtime-definitions";
|
|
7
7
|
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
8
8
|
import { RuntimeHeaderData } from "../containerRuntime";
|
|
9
|
+
import { ContainerRuntimeGCMessage } from "../messageTypes";
|
|
9
10
|
import { IRefreshSummaryResult } from "../summary";
|
|
10
11
|
import { IGarbageCollector, IGarbageCollectorCreateParams, IGCStats, IGCMetadata } from "./gcDefinitions";
|
|
11
12
|
/**
|
|
@@ -61,6 +62,7 @@ export declare class GarbageCollector implements IGarbageCollector {
|
|
|
61
62
|
private readonly getLastSummaryTimestampMs;
|
|
62
63
|
/** Returns true if connection is active, i.e. it's "write" connection and the runtime is connected. */
|
|
63
64
|
private readonly activeConnection;
|
|
65
|
+
private readonly submitMessage;
|
|
64
66
|
get summaryStateNeedsReset(): boolean;
|
|
65
67
|
/** Returns the count of data stores whose GC state updated since the last summary. */
|
|
66
68
|
get updatedDSCountSinceLastSummary(): number;
|
|
@@ -81,7 +83,7 @@ export declare class GarbageCollector implements IGarbageCollector {
|
|
|
81
83
|
private updateStateFromSnapshotData;
|
|
82
84
|
/**
|
|
83
85
|
* Called when the connection state of the runtime changes, i.e., it connects or disconnects. GC subscribes to this
|
|
84
|
-
* to initialize the base state for non-summarizer clients so that they can track inactive / sweep
|
|
86
|
+
* to initialize the base state for non-summarizer clients so that they can track inactive / sweep-ready nodes.
|
|
85
87
|
* @param connected - Whether the runtime connected / disconnected.
|
|
86
88
|
* @param clientId - The clientId of this runtime.
|
|
87
89
|
*/
|
|
@@ -105,10 +107,15 @@ export declare class GarbageCollector implements IGarbageCollector {
|
|
|
105
107
|
}, telemetryContext?: ITelemetryContext): Promise<IGCStats | undefined>;
|
|
106
108
|
/**
|
|
107
109
|
* Runs garbage collection. It does the following:
|
|
110
|
+
*
|
|
108
111
|
* 1. It generates / analyzes the runtime's reference graph.
|
|
112
|
+
*
|
|
109
113
|
* 2. Generates mark phase stats.
|
|
114
|
+
*
|
|
110
115
|
* 3. Runs Mark phase.
|
|
116
|
+
*
|
|
111
117
|
* 4. Runs Sweep phase.
|
|
118
|
+
*
|
|
112
119
|
* 5. Generates sweep phase stats.
|
|
113
120
|
*/
|
|
114
121
|
private runGC;
|
|
@@ -124,19 +131,19 @@ export declare class GarbageCollector implements IGarbageCollector {
|
|
|
124
131
|
* @param gcResult - The result of the GC run on the gcData.
|
|
125
132
|
* @param allReferencedNodeIds - Nodes referenced in this GC run + referenced between previous and current GC run.
|
|
126
133
|
* @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
|
|
127
|
-
* @returns
|
|
134
|
+
* @returns The sets of tombstone-ready and sweep-ready nodes, i.e., nodes that ready to be tombstoned or deleted.
|
|
128
135
|
*/
|
|
129
136
|
private runMarkPhase;
|
|
130
137
|
/**
|
|
131
138
|
* Runs the GC Sweep phase. It does the following:
|
|
132
|
-
*
|
|
133
|
-
*
|
|
139
|
+
*
|
|
140
|
+
* 1. Marks tombstone-ready nodes as tombstones.
|
|
141
|
+
*
|
|
142
|
+
* 2. Sends a sweep op to delete nodes that are sweep-ready. Once the op is ack'd, these nodes will be deleted.
|
|
134
143
|
*
|
|
135
144
|
* @param gcResult - The result of the GC run on the gcData.
|
|
136
|
-
* @param
|
|
137
|
-
* @param
|
|
138
|
-
* @param logger - The logger to be used to log any telemetry.
|
|
139
|
-
* @returns A list of nodes that have been deleted.
|
|
145
|
+
* @param tombstoneReadyNodes - List of nodes that are tombstone-ready.
|
|
146
|
+
* @param sweepReadyNodes - List of nodes that are sweep-ready.
|
|
140
147
|
*/
|
|
141
148
|
private runSweepPhase;
|
|
142
149
|
/**
|
|
@@ -166,6 +173,18 @@ export declare class GarbageCollector implements IGarbageCollector {
|
|
|
166
173
|
* Called to refresh the latest summary state. This happens when either a pending summary is acked.
|
|
167
174
|
*/
|
|
168
175
|
refreshLatestSummary(result: IRefreshSummaryResult): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Process a GC message.
|
|
178
|
+
* @param message - The GC message from the container runtime.
|
|
179
|
+
* @param local - Whether it was send by this client.
|
|
180
|
+
*/
|
|
181
|
+
processMessage(message: ContainerRuntimeGCMessage, local: boolean): void;
|
|
182
|
+
/**
|
|
183
|
+
* Delete nodes that are sweep-ready. Call the runtime to delete these nodes and clear the unreferenced state
|
|
184
|
+
* tracking for nodes that are actually deleted by the runtime.
|
|
185
|
+
* @param sweepReadyNodeIds - The ids of nodes that are ready to be deleted.
|
|
186
|
+
*/
|
|
187
|
+
private deleteSweepReadyNodes;
|
|
169
188
|
/**
|
|
170
189
|
* Called when a node with the given id is updated. If the node is inactive or tombstoned, this will log an error
|
|
171
190
|
* or throw an error if failing on incorrect usage is configured.
|
|
@@ -199,8 +218,8 @@ export declare class GarbageCollector implements IGarbageCollector {
|
|
|
199
218
|
private getMarkPhaseStats;
|
|
200
219
|
/**
|
|
201
220
|
* Generates the stats of a garbage collection sweep phase run.
|
|
202
|
-
* @param
|
|
203
|
-
* @param
|
|
221
|
+
* @param deletedNodes - The nodes that have been deleted until this run.
|
|
222
|
+
* @param sweepReadyNodes - The nodes that are sweep-ready in this GC run.
|
|
204
223
|
* @param markPhaseStats - The stats of the mark phase run.
|
|
205
224
|
* @returns the stats of the sweep phase run.
|
|
206
225
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../../src/gc/garbageCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC3D,OAAO,EAGN,6BAA6B,EAC7B,gBAAgB,EAChB,iBAAiB,EACjB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EAIN,mBAAmB,EAGnB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../../src/gc/garbageCollection.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,9 +8,10 @@ import { createResponseError, responseToException } from "@fluidframework/runtim
|
|
|
8
8
|
import { createChildLogger, createChildMonitoringContext, DataProcessingError, PerformanceEvent, } from "@fluidframework/telemetry-utils";
|
|
9
9
|
import { InactiveResponseHeaderKey, TombstoneResponseHeaderKey, } from "../containerRuntime";
|
|
10
10
|
import { ClientSessionExpiredError } from "../error";
|
|
11
|
+
import { ContainerMessageType } from "../messageTypes";
|
|
11
12
|
import { generateGCConfigs } from "./gcConfigs";
|
|
12
|
-
import { GCNodeType, UnreferencedState, } from "./gcDefinitions";
|
|
13
|
-
import { cloneGCData, concatGarbageCollectionData, getGCDataFromSnapshot } from "./gcHelpers";
|
|
13
|
+
import { GCNodeType, UnreferencedState, GarbageCollectionMessageType, } from "./gcDefinitions";
|
|
14
|
+
import { cloneGCData, compatBehaviorAllowsGCMessageType, concatGarbageCollectionData, getGCDataFromSnapshot, } from "./gcHelpers";
|
|
14
15
|
import { runGarbageCollection } from "./gcReferenceGraphAlgorithm";
|
|
15
16
|
import { GCSummaryStateTracker } from "./gcSummaryStateTracker";
|
|
16
17
|
import { UnreferencedStateTracker } from "./gcUnreferencedStateTracker";
|
|
@@ -46,7 +47,7 @@ export class GarbageCollector {
|
|
|
46
47
|
}
|
|
47
48
|
/** If false, loading or using a Tombstoned object should merely log, not fail */
|
|
48
49
|
get tombstoneEnforcementAllowed() {
|
|
49
|
-
return this.configs.
|
|
50
|
+
return this.configs.sweepEnabled;
|
|
50
51
|
}
|
|
51
52
|
/** If true, throw an error when a tombstone data store is retrieved */
|
|
52
53
|
get throwOnTombstoneLoad() {
|
|
@@ -80,6 +81,7 @@ export class GarbageCollector {
|
|
|
80
81
|
this.getNodePackagePath = createParams.getNodePackagePath;
|
|
81
82
|
this.getLastSummaryTimestampMs = createParams.getLastSummaryTimestampMs;
|
|
82
83
|
this.activeConnection = createParams.activeConnection;
|
|
84
|
+
this.submitMessage = createParams.submitMessage;
|
|
83
85
|
const baseSnapshot = createParams.baseSnapshot;
|
|
84
86
|
const readAndParseBlob = createParams.readAndParseBlob;
|
|
85
87
|
this.mc = createChildMonitoringContext({
|
|
@@ -141,7 +143,7 @@ export class GarbageCollector {
|
|
|
141
143
|
/**
|
|
142
144
|
* Set up the initializer which initializes the GC state from the data in base snapshot. This is done when
|
|
143
145
|
* connected in write mode or when GC runs the first time. It sets up all unreferenced nodes from the base
|
|
144
|
-
* GC state and updates their inactive or sweep
|
|
146
|
+
* GC state and updates their inactive or sweep-ready state.
|
|
145
147
|
*/
|
|
146
148
|
this.initializeGCStateFromBaseSnapshotP = new LazyPromise(async () => {
|
|
147
149
|
/**
|
|
@@ -291,7 +293,7 @@ export class GarbageCollector {
|
|
|
291
293
|
const gcNodes = {};
|
|
292
294
|
for (const [nodeId, nodeData] of Object.entries(snapshotData.gcState.gcNodes)) {
|
|
293
295
|
if (nodeData.unreferencedTimestampMs !== undefined) {
|
|
294
|
-
this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(nodeData.unreferencedTimestampMs, this.configs.inactiveTimeoutMs, currentReferenceTimestampMs, this.configs.sweepTimeoutMs));
|
|
296
|
+
this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(nodeData.unreferencedTimestampMs, this.configs.inactiveTimeoutMs, currentReferenceTimestampMs, this.configs.sweepTimeoutMs, this.configs.sweepGracePeriodMs));
|
|
295
297
|
}
|
|
296
298
|
gcNodes[nodeId] = Array.from(nodeData.outboundRoutes);
|
|
297
299
|
}
|
|
@@ -299,7 +301,7 @@ export class GarbageCollector {
|
|
|
299
301
|
}
|
|
300
302
|
/**
|
|
301
303
|
* Called when the connection state of the runtime changes, i.e., it connects or disconnects. GC subscribes to this
|
|
302
|
-
* to initialize the base state for non-summarizer clients so that they can track inactive / sweep
|
|
304
|
+
* to initialize the base state for non-summarizer clients so that they can track inactive / sweep-ready nodes.
|
|
303
305
|
* @param connected - Whether the runtime connected / disconnected.
|
|
304
306
|
* @param clientId - The clientId of this runtime.
|
|
305
307
|
*/
|
|
@@ -315,7 +317,7 @@ export class GarbageCollector {
|
|
|
315
317
|
* the receiving summarizer client.
|
|
316
318
|
*
|
|
317
319
|
* Ideally, this initialization should only be done for summarizer client. However, we are currently rolling out
|
|
318
|
-
* sweep in phases and we want to track when inactive and sweep
|
|
320
|
+
* sweep in phases and we want to track when inactive and sweep-ready objects are used in any client.
|
|
319
321
|
*/
|
|
320
322
|
if (this.activeConnection() && this.configs.shouldRunGC) {
|
|
321
323
|
this.initializeGCStateFromBaseSnapshotP.catch((error) => { });
|
|
@@ -392,10 +394,15 @@ export class GarbageCollector {
|
|
|
392
394
|
}
|
|
393
395
|
/**
|
|
394
396
|
* Runs garbage collection. It does the following:
|
|
397
|
+
*
|
|
395
398
|
* 1. It generates / analyzes the runtime's reference graph.
|
|
399
|
+
*
|
|
396
400
|
* 2. Generates mark phase stats.
|
|
401
|
+
*
|
|
397
402
|
* 3. Runs Mark phase.
|
|
403
|
+
*
|
|
398
404
|
* 4. Runs Sweep phase.
|
|
405
|
+
*
|
|
399
406
|
* 5. Generates sweep phase stats.
|
|
400
407
|
*/
|
|
401
408
|
async runGC(fullGC, currentReferenceTimestampMs, logger) {
|
|
@@ -410,14 +417,15 @@ export class GarbageCollector {
|
|
|
410
417
|
// This is done before running mark phase because we need the previous GC state before it is updated.
|
|
411
418
|
const markPhaseStats = this.getMarkPhaseStats(gcResult);
|
|
412
419
|
// 3. Run the Mark phase.
|
|
413
|
-
// It will mark nodes as referenced / unreferenced and return
|
|
414
|
-
const sweepReadyNodeIds = this.runMarkPhase(gcResult, allReferencedNodeIds, currentReferenceTimestampMs);
|
|
420
|
+
// It will mark nodes as referenced / unreferenced and return lists of tombstone-ready and sweep-ready nodes.
|
|
421
|
+
const { tombstoneReadyNodeIds, sweepReadyNodeIds } = this.runMarkPhase(gcResult, allReferencedNodeIds, currentReferenceTimestampMs);
|
|
415
422
|
// 4. Run the Sweep phase.
|
|
416
|
-
// It will
|
|
417
|
-
|
|
418
|
-
this.
|
|
423
|
+
// It will tombstone any tombstone-ready nodes, and initiate the deletion of sweep-ready nodes by sending a
|
|
424
|
+
// sweep op. All clients, including this one, will delete these nodes once it processes the op.
|
|
425
|
+
this.runSweepPhase(gcResult, tombstoneReadyNodeIds, sweepReadyNodeIds);
|
|
426
|
+
this.gcDataFromLastRun = cloneGCData(gcData);
|
|
419
427
|
// 5. Get the sweep phase stats.
|
|
420
|
-
const sweepPhaseStats = this.getSweepPhaseStats(this.
|
|
428
|
+
const sweepPhaseStats = this.getSweepPhaseStats(this.deletedNodes, sweepReadyNodeIds, markPhaseStats);
|
|
421
429
|
return { ...markPhaseStats, ...sweepPhaseStats };
|
|
422
430
|
}
|
|
423
431
|
/**
|
|
@@ -432,7 +440,7 @@ export class GarbageCollector {
|
|
|
432
440
|
* @param gcResult - The result of the GC run on the gcData.
|
|
433
441
|
* @param allReferencedNodeIds - Nodes referenced in this GC run + referenced between previous and current GC run.
|
|
434
442
|
* @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
|
|
435
|
-
* @returns
|
|
443
|
+
* @returns The sets of tombstone-ready and sweep-ready nodes, i.e., nodes that ready to be tombstoned or deleted.
|
|
436
444
|
*/
|
|
437
445
|
runMarkPhase(gcResult, allReferencedNodeIds, currentReferenceTimestampMs) {
|
|
438
446
|
// 1. Marks all referenced nodes by clearing their unreferenced tracker, if any.
|
|
@@ -446,17 +454,21 @@ export class GarbageCollector {
|
|
|
446
454
|
}
|
|
447
455
|
}
|
|
448
456
|
// 2. Mark unreferenced nodes in this run by starting unreferenced tracking for them.
|
|
457
|
+
const tombstoneReadyNodeIds = new Set();
|
|
449
458
|
const sweepReadyNodeIds = new Set();
|
|
450
459
|
for (const nodeId of gcResult.deletedNodeIds) {
|
|
451
460
|
const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
|
|
452
461
|
if (nodeStateTracker === undefined) {
|
|
453
|
-
this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(currentReferenceTimestampMs, this.configs.inactiveTimeoutMs, currentReferenceTimestampMs, this.configs.sweepTimeoutMs));
|
|
462
|
+
this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(currentReferenceTimestampMs, this.configs.inactiveTimeoutMs, currentReferenceTimestampMs, this.configs.sweepTimeoutMs, this.configs.sweepGracePeriodMs));
|
|
454
463
|
}
|
|
455
464
|
else {
|
|
456
465
|
// If a node was already unreferenced, update its tracking information. Since the current reference time
|
|
457
466
|
// is from the ops seen, this will ensure that we keep updating unreferenced state as time moves forward.
|
|
458
467
|
nodeStateTracker.updateTracking(currentReferenceTimestampMs);
|
|
459
|
-
// If a node is sweep
|
|
468
|
+
// If a node is tombstone or sweep-ready, store it so it can be returned.
|
|
469
|
+
if (nodeStateTracker.state === UnreferencedState.TombstoneReady) {
|
|
470
|
+
tombstoneReadyNodeIds.add(nodeId);
|
|
471
|
+
}
|
|
460
472
|
if (nodeStateTracker.state === UnreferencedState.SweepReady) {
|
|
461
473
|
sweepReadyNodeIds.add(nodeId);
|
|
462
474
|
}
|
|
@@ -464,62 +476,72 @@ export class GarbageCollector {
|
|
|
464
476
|
}
|
|
465
477
|
// 3. Call the runtime to update referenced nodes in this run.
|
|
466
478
|
this.runtime.updateUsedRoutes(gcResult.referencedNodeIds);
|
|
467
|
-
return sweepReadyNodeIds;
|
|
479
|
+
return { tombstoneReadyNodeIds, sweepReadyNodeIds };
|
|
468
480
|
}
|
|
469
481
|
/**
|
|
470
482
|
* Runs the GC Sweep phase. It does the following:
|
|
471
|
-
*
|
|
472
|
-
*
|
|
483
|
+
*
|
|
484
|
+
* 1. Marks tombstone-ready nodes as tombstones.
|
|
485
|
+
*
|
|
486
|
+
* 2. Sends a sweep op to delete nodes that are sweep-ready. Once the op is ack'd, these nodes will be deleted.
|
|
473
487
|
*
|
|
474
488
|
* @param gcResult - The result of the GC run on the gcData.
|
|
475
|
-
* @param
|
|
476
|
-
* @param
|
|
477
|
-
* @param logger - The logger to be used to log any telemetry.
|
|
478
|
-
* @returns A list of nodes that have been deleted.
|
|
489
|
+
* @param tombstoneReadyNodes - List of nodes that are tombstone-ready.
|
|
490
|
+
* @param sweepReadyNodes - List of nodes that are sweep-ready.
|
|
479
491
|
*/
|
|
480
|
-
runSweepPhase(gcResult, sweepReadyNodes) {
|
|
492
|
+
runSweepPhase(gcResult, tombstoneReadyNodes, sweepReadyNodes) {
|
|
481
493
|
/**
|
|
482
|
-
*
|
|
483
|
-
* Test mode - Unreferenced nodes are immediately deleted without waiting for them to be sweep ready.
|
|
484
|
-
* Tombstone mode - Sweep ready modes are marked as tombstones instead of being deleted.
|
|
485
|
-
* Sweep mode - Sweep ready modes are deleted.
|
|
494
|
+
* Under "Test Mode", unreferenced nodes are immediately deleted without waiting for them to be sweep-ready.
|
|
486
495
|
*
|
|
487
|
-
*
|
|
488
|
-
*
|
|
496
|
+
* Otherwise, depending on how long it's been since the node was unreferenced, it will either be
|
|
497
|
+
* marked as Tombstone, or deleted by Sweep.
|
|
489
498
|
*/
|
|
490
499
|
if (this.configs.testMode) {
|
|
491
500
|
// If we are running in GC test mode, unreferenced nodes (gcResult.deletedNodeIds) are deleted.
|
|
492
501
|
this.runtime.updateUnusedRoutes(gcResult.deletedNodeIds);
|
|
493
|
-
return
|
|
502
|
+
return;
|
|
494
503
|
}
|
|
504
|
+
// If sweep is disabled, we'll tombstone both tombstone-ready and sweep-ready nodes.
|
|
505
|
+
// This is important because a container may never load during a node's Sweep Grace Period,
|
|
506
|
+
// so that node would directly become sweep-ready skipping over tombstone-ready state,
|
|
507
|
+
// but should be Tombstoned since Sweep is disabled.
|
|
508
|
+
const { nodesToTombstone, nodesToDelete } = this.configs.shouldRunSweep
|
|
509
|
+
? {
|
|
510
|
+
nodesToTombstone: [...tombstoneReadyNodes],
|
|
511
|
+
nodesToDelete: [...sweepReadyNodes],
|
|
512
|
+
}
|
|
513
|
+
: {
|
|
514
|
+
nodesToTombstone: [...tombstoneReadyNodes, ...sweepReadyNodes],
|
|
515
|
+
nodesToDelete: [],
|
|
516
|
+
};
|
|
495
517
|
if (this.configs.tombstoneMode) {
|
|
496
|
-
this.tombstones =
|
|
497
|
-
// If we are running in GC tombstone mode, update tombstoned routes.
|
|
498
|
-
// involving access to "deleted" data without actually deleting the data from summaries.
|
|
518
|
+
this.tombstones = nodesToTombstone;
|
|
519
|
+
// If we are running in GC tombstone mode, update tombstoned routes.
|
|
499
520
|
this.runtime.updateTombstonedRoutes(this.tombstones);
|
|
500
|
-
return [];
|
|
501
521
|
}
|
|
502
|
-
if (
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
522
|
+
if (this.configs.shouldRunSweep && nodesToDelete.length > 0) {
|
|
523
|
+
// Do not send DDS node ids in the GC op. This is an optimization to reduce its size. Since GC applies to
|
|
524
|
+
// to data store only, all its DDSes are deleted along with it. The DDS ids will be retrieved from the
|
|
525
|
+
// local state when processing the op.
|
|
526
|
+
const sweepReadyDSAndBlobs = nodesToDelete.filter((nodeId) => {
|
|
527
|
+
const nodeType = this.runtime.getNodeType(nodeId);
|
|
528
|
+
return nodeType === GCNodeType.DataStore || nodeType === GCNodeType.Blob;
|
|
529
|
+
});
|
|
530
|
+
const contents = {
|
|
531
|
+
type: GarbageCollectionMessageType.Sweep,
|
|
532
|
+
deletedNodeIds: sweepReadyDSAndBlobs,
|
|
533
|
+
};
|
|
534
|
+
// Its fine for older clients to ignore this op because it doesn't have any functional impact. This op
|
|
535
|
+
// is an optimization to ensure that all clients are in sync when it comes to deleted nodes to prevent their
|
|
536
|
+
// accidental usage. The clients will sync without the delete op too but it may take longer.
|
|
537
|
+
const containerGCMessage = {
|
|
538
|
+
type: ContainerMessageType.GC,
|
|
539
|
+
contents,
|
|
540
|
+
compatDetails: { behavior: "Ignore" },
|
|
541
|
+
};
|
|
542
|
+
this.submitMessage(containerGCMessage);
|
|
543
|
+
return;
|
|
521
544
|
}
|
|
522
|
-
return deletedNodeIds;
|
|
523
545
|
}
|
|
524
546
|
/**
|
|
525
547
|
* Since GC runs periodically, the GC data that is generated only tells us the state of the world at that point in
|
|
@@ -629,6 +651,65 @@ export class GarbageCollector {
|
|
|
629
651
|
async refreshLatestSummary(result) {
|
|
630
652
|
return this.summaryStateTracker.refreshLatestSummary(result);
|
|
631
653
|
}
|
|
654
|
+
/**
|
|
655
|
+
* Process a GC message.
|
|
656
|
+
* @param message - The GC message from the container runtime.
|
|
657
|
+
* @param local - Whether it was send by this client.
|
|
658
|
+
*/
|
|
659
|
+
processMessage(message, local) {
|
|
660
|
+
switch (message.contents.type) {
|
|
661
|
+
case "Sweep": {
|
|
662
|
+
// Delete the nodes whose ids are present in the contents.
|
|
663
|
+
this.deleteSweepReadyNodes(message.contents.deletedNodeIds);
|
|
664
|
+
break;
|
|
665
|
+
}
|
|
666
|
+
default: {
|
|
667
|
+
if (!compatBehaviorAllowsGCMessageType(message.contents.type, message.compatDetails?.behavior)) {
|
|
668
|
+
const error = DataProcessingError.create(`Garbage collection message of unknown type ${message.contents.type}`, "processMessage");
|
|
669
|
+
throw error;
|
|
670
|
+
}
|
|
671
|
+
break;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Delete nodes that are sweep-ready. Call the runtime to delete these nodes and clear the unreferenced state
|
|
677
|
+
* tracking for nodes that are actually deleted by the runtime.
|
|
678
|
+
* @param sweepReadyNodeIds - The ids of nodes that are ready to be deleted.
|
|
679
|
+
*/
|
|
680
|
+
deleteSweepReadyNodes(sweepReadyNodeIds) {
|
|
681
|
+
// Use a set for lookup because its much faster than array or map.
|
|
682
|
+
const sweepReadyNodesSet = new Set(sweepReadyNodeIds);
|
|
683
|
+
// The ids in the sweep-ready nodes do not contain DDS node ids. This is an optimization to reduce the size
|
|
684
|
+
// of the GC op. Since GC applies to data store only, all its DDSes are deleted along with it. So, get the
|
|
685
|
+
// DDS nodes ID from the unreferenced nodes state.
|
|
686
|
+
const allSweepReadyNodeIds = Array.from(sweepReadyNodeIds);
|
|
687
|
+
for (const [id] of this.unreferencedNodesState) {
|
|
688
|
+
// Ignore data store nodes since they would already be in the list.
|
|
689
|
+
const pathParts = id.split("/");
|
|
690
|
+
if (pathParts.length <= 2) {
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
// Get the data store id part. Note that this may include blobs but that's okay since the part would just
|
|
694
|
+
// be "_blobs" and it won't be found.
|
|
695
|
+
const dsId = `/${pathParts[1]}`;
|
|
696
|
+
if (sweepReadyNodesSet.has(dsId)) {
|
|
697
|
+
allSweepReadyNodeIds.push(id);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
const deletedNodeIds = this.runtime.deleteSweepReadyNodes(allSweepReadyNodeIds);
|
|
701
|
+
// Clear unreferenced state tracking for deleted nodes.
|
|
702
|
+
for (const nodeId of deletedNodeIds) {
|
|
703
|
+
const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
|
|
704
|
+
if (nodeStateTracker !== undefined) {
|
|
705
|
+
// Stop tracking so as to clear out any running timers.
|
|
706
|
+
nodeStateTracker.stopTracking();
|
|
707
|
+
// Delete the node as we don't need to track it any more.
|
|
708
|
+
this.unreferencedNodesState.delete(nodeId);
|
|
709
|
+
}
|
|
710
|
+
this.deletedNodes.add(nodeId);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
632
713
|
/**
|
|
633
714
|
* Called when a node with the given id is updated. If the node is inactive or tombstoned, this will log an error
|
|
634
715
|
* or throw an error if failing on incorrect usage is configured.
|
|
@@ -774,12 +855,12 @@ export class GarbageCollector {
|
|
|
774
855
|
}
|
|
775
856
|
/**
|
|
776
857
|
* Generates the stats of a garbage collection sweep phase run.
|
|
777
|
-
* @param
|
|
778
|
-
* @param
|
|
858
|
+
* @param deletedNodes - The nodes that have been deleted until this run.
|
|
859
|
+
* @param sweepReadyNodes - The nodes that are sweep-ready in this GC run.
|
|
779
860
|
* @param markPhaseStats - The stats of the mark phase run.
|
|
780
861
|
* @returns the stats of the sweep phase run.
|
|
781
862
|
*/
|
|
782
|
-
getSweepPhaseStats(
|
|
863
|
+
getSweepPhaseStats(deletedNodes, sweepReadyNodes, markPhaseStats) {
|
|
783
864
|
// Initialize the life time node counts to the mark phase node counts. If sweep is not enabled,
|
|
784
865
|
// these will be the life time node count for this container.
|
|
785
866
|
const sweepPhaseStats = {
|
|
@@ -790,7 +871,7 @@ export class GarbageCollector {
|
|
|
790
871
|
deletedDataStoreCount: 0,
|
|
791
872
|
deletedAttachmentBlobCount: 0,
|
|
792
873
|
};
|
|
793
|
-
for (const nodeId of
|
|
874
|
+
for (const nodeId of deletedNodes) {
|
|
794
875
|
sweepPhaseStats.deletedNodeCount++;
|
|
795
876
|
const nodeType = this.runtime.getNodeType(nodeId);
|
|
796
877
|
if (nodeType === GCNodeType.DataStore) {
|
|
@@ -800,24 +881,25 @@ export class GarbageCollector {
|
|
|
800
881
|
sweepPhaseStats.deletedAttachmentBlobCount++;
|
|
801
882
|
}
|
|
802
883
|
}
|
|
803
|
-
if (!this.configs.shouldRunSweep) {
|
|
804
|
-
return sweepPhaseStats;
|
|
805
|
-
}
|
|
806
884
|
// If sweep is enabled, the counts from the mark phase stats do not include nodes that have been
|
|
807
|
-
// deleted in previous runs.
|
|
885
|
+
// deleted in previous runs. So, add the deleted node counts to life time stats.
|
|
808
886
|
sweepPhaseStats.lifetimeNodeCount += sweepPhaseStats.deletedNodeCount;
|
|
809
887
|
sweepPhaseStats.lifetimeDataStoreCount += sweepPhaseStats.deletedDataStoreCount;
|
|
810
888
|
sweepPhaseStats.lifetimeAttachmentBlobCount += sweepPhaseStats.deletedAttachmentBlobCount;
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
889
|
+
if (this.configs.shouldRunSweep) {
|
|
890
|
+
return sweepPhaseStats;
|
|
891
|
+
}
|
|
892
|
+
// If sweep is not enabled, the current sweep-ready node stats should be added to deleted stats since this
|
|
893
|
+
// is the final state the node will be in.
|
|
894
|
+
// If sweep is enabled, this will happen in the run after the GC op round trips back.
|
|
895
|
+
for (const nodeId of sweepReadyNodes) {
|
|
896
|
+
sweepPhaseStats.deletedNodeCount++;
|
|
815
897
|
const nodeType = this.runtime.getNodeType(nodeId);
|
|
816
898
|
if (nodeType === GCNodeType.DataStore) {
|
|
817
|
-
sweepPhaseStats.
|
|
899
|
+
sweepPhaseStats.deletedDataStoreCount++;
|
|
818
900
|
}
|
|
819
901
|
else if (nodeType === GCNodeType.Blob) {
|
|
820
|
-
sweepPhaseStats.
|
|
902
|
+
sweepPhaseStats.deletedAttachmentBlobCount++;
|
|
821
903
|
}
|
|
822
904
|
}
|
|
823
905
|
return sweepPhaseStats;
|