@fluidframework/container-runtime 2.0.0-internal.3.2.1 → 2.0.0-internal.3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/containerRuntime.d.ts +32 -53
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +55 -21
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +8 -3
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts +19 -0
- package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -0
- package/dist/deltaManagerSummarizerProxy.js +40 -0
- package/dist/deltaManagerSummarizerProxy.js.map +1 -0
- package/dist/gc/garbageCollection.d.ts +2 -33
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +36 -181
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts +22 -0
- package/dist/gc/gcConfigs.d.ts.map +1 -0
- package/dist/gc/gcConfigs.js +138 -0
- package/dist/gc/gcConfigs.js.map +1 -0
- package/dist/gc/gcDefinitions.d.ts +101 -3
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +8 -3
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +12 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +55 -1
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +1 -2
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +28 -37
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/index.d.ts +3 -2
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +2 -1
- package/dist/gc/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +9 -0
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +19 -2
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +2 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +24 -10
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +4 -0
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +42 -4
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +14 -2
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +35 -18
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +29 -21
- 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/storageServiceWithAttachBlobs.d.ts +17 -0
- package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -0
- package/dist/storageServiceWithAttachBlobs.js +32 -0
- package/dist/storageServiceWithAttachBlobs.js.map +1 -0
- package/dist/summary/runWhileConnectedCoordinator.d.ts +3 -2
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js +5 -4
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +2 -0
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/lib/containerRuntime.d.ts +32 -53
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +56 -22
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +9 -4
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaManagerSummarizerProxy.d.ts +19 -0
- package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -0
- package/lib/deltaManagerSummarizerProxy.js +36 -0
- package/lib/deltaManagerSummarizerProxy.js.map +1 -0
- package/lib/gc/garbageCollection.d.ts +2 -33
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +39 -184
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts +22 -0
- package/lib/gc/gcConfigs.d.ts.map +1 -0
- package/lib/gc/gcConfigs.js +134 -0
- package/lib/gc/gcConfigs.js.map +1 -0
- package/lib/gc/gcDefinitions.d.ts +101 -3
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +7 -2
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +12 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +53 -0
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +1 -2
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +28 -37
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/index.d.ts +3 -2
- 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 +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +9 -0
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +17 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +25 -11
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +4 -0
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +42 -4
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +14 -2
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +35 -18
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +30 -22
- 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/storageServiceWithAttachBlobs.d.ts +17 -0
- package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -0
- package/lib/storageServiceWithAttachBlobs.js +28 -0
- package/lib/storageServiceWithAttachBlobs.js.map +1 -0
- package/lib/summary/runWhileConnectedCoordinator.d.ts +3 -2
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js +5 -4
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +2 -0
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/package.json +20 -31
- package/src/containerRuntime.ts +92 -76
- package/src/dataStores.ts +9 -4
- package/src/deltaManagerSummarizerProxy.ts +46 -0
- package/src/gc/garbageCollection.ts +50 -290
- package/src/gc/gcConfigs.ts +177 -0
- package/src/gc/gcDefinitions.ts +110 -4
- package/src/gc/gcHelpers.ts +78 -1
- package/src/gc/gcSummaryStateTracker.ts +35 -42
- package/src/gc/index.ts +8 -2
- package/src/index.ts +1 -2
- package/src/opLifecycle/README.md +2 -2
- package/src/opLifecycle/batchManager.ts +19 -1
- package/src/opLifecycle/index.ts +1 -1
- package/src/opLifecycle/opCompressor.ts +31 -12
- package/src/opLifecycle/opDecompressor.ts +49 -5
- package/src/opLifecycle/opSplitter.ts +44 -20
- package/src/opLifecycle/outbox.ts +36 -22
- package/src/packageVersion.ts +1 -1
- package/src/storageServiceWithAttachBlobs.ts +38 -0
- package/src/summary/runWhileConnectedCoordinator.ts +7 -7
- package/src/summary/summarizerTypes.ts +2 -0
|
@@ -8,7 +8,6 @@ import { ISnapshotTree } from "@fluidframework/protocol-definitions";
|
|
|
8
8
|
import { IGarbageCollectionData, IGarbageCollectionDetailsBase, ISummarizeResult, ITelemetryContext } from "@fluidframework/runtime-definitions";
|
|
9
9
|
import { ReadAndParseBlob, RefreshSummaryResult } from "@fluidframework/runtime-utils";
|
|
10
10
|
import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
11
|
-
import { IGCRuntimeOptions } from "../containerRuntime";
|
|
12
11
|
import { IContainerRuntimeMetadata, ICreateContainerMetadata } from "../summary";
|
|
13
12
|
export declare type GCVersion = number;
|
|
14
13
|
/** The stable version of garbage collection in production. */
|
|
@@ -21,7 +20,6 @@ export declare const runGCKey = "Fluid.GarbageCollection.RunGC";
|
|
|
21
20
|
export declare const runSweepKey = "Fluid.GarbageCollection.RunSweep";
|
|
22
21
|
export declare const gcTestModeKey = "Fluid.GarbageCollection.GCTestMode";
|
|
23
22
|
export declare const runSessionExpiryKey = "Fluid.GarbageCollection.RunSessionExpiry";
|
|
24
|
-
export declare const trackGCStateKey = "Fluid.GarbageCollection.TrackGCState";
|
|
25
23
|
export declare const disableSweepLogKey = "Fluid.GarbageCollection.DisableSweepLog";
|
|
26
24
|
export declare const disableTombstoneKey = "Fluid.GarbageCollection.DisableTombstone";
|
|
27
25
|
export declare const throwOnTombstoneLoadKey = "Fluid.GarbageCollection.ThrowOnTombstoneLoad";
|
|
@@ -30,6 +28,13 @@ export declare const gcVersionUpgradeToV2Key = "Fluid.GarbageCollection.GCVersio
|
|
|
30
28
|
export declare const sweepDatastoresKey = "Fluid.GarbageCollection.Test.SweepDataStores";
|
|
31
29
|
export declare const sweepAttachmentBlobsKey = "Fluid.GarbageCollection.Test.SweepAttachmentBlobs";
|
|
32
30
|
export declare const oneDayMs: number;
|
|
31
|
+
/**
|
|
32
|
+
* The maximum snapshot cache expiry in the driver. This is used to calculate the sweep timeout.
|
|
33
|
+
* Sweep timeout = session expiry timeout + snapshot cache expiry timeout + a buffer.
|
|
34
|
+
* The snapshot cache expiry timeout cannot be known precisely but the upper bound is 5 days, i.e., any snapshot
|
|
35
|
+
* in cache will be invalidated before 5 days.
|
|
36
|
+
*/
|
|
37
|
+
export declare const maxSnapshotCacheExpiryMs: number;
|
|
33
38
|
export declare const defaultInactiveTimeoutMs: number;
|
|
34
39
|
export declare const defaultSessionExpiryDurationMs: number;
|
|
35
40
|
/** @see IGCMetadata.gcFeatureMatrix */
|
|
@@ -102,7 +107,10 @@ export declare const GCNodeType: {
|
|
|
102
107
|
Other: string;
|
|
103
108
|
};
|
|
104
109
|
export declare type GCNodeType = typeof GCNodeType[keyof typeof GCNodeType];
|
|
105
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* @deprecated - Was only to be used internally anyway, no replacement provided.
|
|
112
|
+
* Defines the APIs for the runtime object to be passed to the garbage collector.
|
|
113
|
+
*/
|
|
106
114
|
export interface IGarbageCollectionRuntime {
|
|
107
115
|
/** Before GC runs, called to notify the runtime to update any pending GC state. */
|
|
108
116
|
updateStateBeforeGC(): Promise<void>;
|
|
@@ -176,6 +184,96 @@ export interface IGarbageCollectorCreateParams {
|
|
|
176
184
|
readonly activeConnection: () => boolean;
|
|
177
185
|
readonly getContainerDiagnosticId: () => string;
|
|
178
186
|
}
|
|
187
|
+
export interface IGCRuntimeOptions {
|
|
188
|
+
/**
|
|
189
|
+
* Flag that if true, will enable running garbage collection (GC) for a new container.
|
|
190
|
+
*
|
|
191
|
+
* GC has mark phase and sweep phase. In mark phase, unreferenced objects are identified
|
|
192
|
+
* and marked as such in the summary. This option enables the mark phase.
|
|
193
|
+
* In sweep phase, unreferenced objects are eventually deleted from the container if they meet certain conditions.
|
|
194
|
+
* Sweep phase can be enabled via the "sweepAllowed" option.
|
|
195
|
+
*
|
|
196
|
+
* Note: This setting is persisted in the container's summary and cannot be changed.
|
|
197
|
+
*/
|
|
198
|
+
gcAllowed?: boolean;
|
|
199
|
+
/**
|
|
200
|
+
* Flag that if true, enables GC's sweep phase for a new container.
|
|
201
|
+
*
|
|
202
|
+
* This will allow GC to eventually delete unreferenced objects from the container.
|
|
203
|
+
* This flag should only be set to true if "gcAllowed" is true.
|
|
204
|
+
*
|
|
205
|
+
* Note: This setting is persisted in the container's summary and cannot be changed.
|
|
206
|
+
*/
|
|
207
|
+
sweepAllowed?: boolean;
|
|
208
|
+
/**
|
|
209
|
+
* Flag that if true, will disable garbage collection for the session.
|
|
210
|
+
* Can be used to disable running GC on containers where it is allowed via the gcAllowed option.
|
|
211
|
+
*/
|
|
212
|
+
disableGC?: boolean;
|
|
213
|
+
/**
|
|
214
|
+
* Flag that will bypass optimizations and generate GC data for all nodes irrespective of whether a node
|
|
215
|
+
* changed or not.
|
|
216
|
+
*/
|
|
217
|
+
runFullGC?: boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Maximum session duration for a new container. If not present, a default value will be used.
|
|
220
|
+
*
|
|
221
|
+
* Note: This setting is persisted in the container's summary and cannot be changed.
|
|
222
|
+
*/
|
|
223
|
+
sessionExpiryTimeoutMs?: number;
|
|
224
|
+
/**
|
|
225
|
+
* Allows additional GC options to be passed.
|
|
226
|
+
*/
|
|
227
|
+
[key: string]: any;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* The configurations for Garbage Collector that determines what runs and how.
|
|
231
|
+
*/
|
|
232
|
+
export interface IGarbageCollectorConfigs {
|
|
233
|
+
/**
|
|
234
|
+
* Tracks if GC is enabled for this document. This is specified during document creation and doesn't change
|
|
235
|
+
* throughout its lifetime.
|
|
236
|
+
*/
|
|
237
|
+
readonly gcEnabled: boolean;
|
|
238
|
+
/**
|
|
239
|
+
* Tracks if sweep phase is enabled for this document. This is specified during document creation and doesn't change
|
|
240
|
+
* throughout its lifetime.
|
|
241
|
+
*/
|
|
242
|
+
readonly sweepEnabled: boolean;
|
|
243
|
+
/**
|
|
244
|
+
* Tracks if GC should run or not. Even if GC is enabled for a document (see gcEnabled), it can be explicitly
|
|
245
|
+
* disabled via runtime options or feature flags.
|
|
246
|
+
*/
|
|
247
|
+
readonly shouldRunGC: boolean;
|
|
248
|
+
/**
|
|
249
|
+
* Tracks if sweep phase should run or not. Even if the sweep phase is enabled for a document (see sweepEnabled), it
|
|
250
|
+
* can be explicitly disabled via feature flags. It also won't run if session expiry is not enabled.
|
|
251
|
+
*/
|
|
252
|
+
readonly shouldRunSweep: boolean;
|
|
253
|
+
/**
|
|
254
|
+
* If true, bypass optimizations and generate GC data for all nodes irrespective of whether a node changed or not.
|
|
255
|
+
*/
|
|
256
|
+
readonly runFullGC: boolean | undefined;
|
|
257
|
+
/** The time in ms to expire a session for a client for gc. */
|
|
258
|
+
readonly sessionExpiryTimeoutMs: number | undefined;
|
|
259
|
+
/** The time after which an unreferenced node is ready to be swept. */
|
|
260
|
+
readonly sweepTimeoutMs: number | undefined;
|
|
261
|
+
/** The time after which an unreferenced node is inactive. */
|
|
262
|
+
readonly inactiveTimeoutMs: number;
|
|
263
|
+
/** Tracks whether GC should run in test mode. In this mode, unreferenced objects are deleted immediately. */
|
|
264
|
+
readonly testMode: boolean;
|
|
265
|
+
/**
|
|
266
|
+
* Tracks whether GC should run in tombstone mode. In this mode, sweep ready objects are marked as tombstones.
|
|
267
|
+
* In interactive (non-summarizer) clients, tombstone objects behave as if they are deleted, i.e., access to them
|
|
268
|
+
* is not allowed. However, these objects can be accessed after referencing them first. It is used as a staging
|
|
269
|
+
* step for sweep where accidental sweep ready objects can be recovered.
|
|
270
|
+
*/
|
|
271
|
+
readonly tombstoneMode: boolean;
|
|
272
|
+
/** @see GCFeatureMatrix. */
|
|
273
|
+
readonly persistedGcFeatureMatrix: GCFeatureMatrix | undefined;
|
|
274
|
+
/** The version of GC in the base snapshot. */
|
|
275
|
+
readonly gcVersionInBaseSnapshot: GCVersion | undefined;
|
|
276
|
+
}
|
|
179
277
|
/** The state of node that is unreferenced. */
|
|
180
278
|
export declare const UnreferencedState: {
|
|
181
279
|
/** The node is active, i.e., it can become referenced again. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcDefinitions.d.ts","sourceRoot":"","sources":["../../src/gc/gcDefinitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EACN,sBAAsB,EACtB,6BAA6B,EAC7B,gBAAgB,EAChB,iBAAiB,EACjB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"gcDefinitions.d.ts","sourceRoot":"","sources":["../../src/gc/gcDefinitions.ts"],"names":[],"mappings":"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"}
|
package/dist/gc/gcDefinitions.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.UnreferencedState = exports.GCNodeType = exports.defaultSessionExpiryDurationMs = exports.defaultInactiveTimeoutMs = exports.oneDayMs = exports.sweepAttachmentBlobsKey = exports.sweepDatastoresKey = exports.gcVersionUpgradeToV2Key = exports.throwOnTombstoneUsageKey = exports.throwOnTombstoneLoadKey = exports.disableTombstoneKey = exports.disableSweepLogKey = exports.
|
|
7
|
+
exports.UnreferencedState = exports.GCNodeType = exports.defaultSessionExpiryDurationMs = exports.defaultInactiveTimeoutMs = exports.maxSnapshotCacheExpiryMs = exports.oneDayMs = exports.sweepAttachmentBlobsKey = exports.sweepDatastoresKey = exports.gcVersionUpgradeToV2Key = exports.throwOnTombstoneUsageKey = exports.throwOnTombstoneLoadKey = exports.disableTombstoneKey = exports.disableSweepLogKey = exports.runSessionExpiryKey = exports.gcTestModeKey = exports.runSweepKey = exports.runGCKey = exports.gcTombstoneGenerationOptionName = exports.currentGCVersion = exports.stableGCVersion = void 0;
|
|
8
8
|
/** The stable version of garbage collection in production. */
|
|
9
9
|
exports.stableGCVersion = 1;
|
|
10
10
|
/** The current version of garbage collection. */
|
|
@@ -19,8 +19,6 @@ exports.runSweepKey = "Fluid.GarbageCollection.RunSweep";
|
|
|
19
19
|
exports.gcTestModeKey = "Fluid.GarbageCollection.GCTestMode";
|
|
20
20
|
// Feature gate key to expire a session after a set period of time.
|
|
21
21
|
exports.runSessionExpiryKey = "Fluid.GarbageCollection.RunSessionExpiry";
|
|
22
|
-
// Feature gate key to write the gc blob as a handle if the data is the same.
|
|
23
|
-
exports.trackGCStateKey = "Fluid.GarbageCollection.TrackGCState";
|
|
24
22
|
// Feature gate key to turn GC sweep log off.
|
|
25
23
|
exports.disableSweepLogKey = "Fluid.GarbageCollection.DisableSweepLog";
|
|
26
24
|
// Feature gate key to disable the tombstone feature, i.e., tombstone information is not read / written into summary.
|
|
@@ -38,6 +36,13 @@ exports.sweepDatastoresKey = "Fluid.GarbageCollection.Test.SweepDataStores";
|
|
|
38
36
|
exports.sweepAttachmentBlobsKey = "Fluid.GarbageCollection.Test.SweepAttachmentBlobs";
|
|
39
37
|
// One day in milliseconds.
|
|
40
38
|
exports.oneDayMs = 1 * 24 * 60 * 60 * 1000;
|
|
39
|
+
/**
|
|
40
|
+
* The maximum snapshot cache expiry in the driver. This is used to calculate the sweep timeout.
|
|
41
|
+
* Sweep timeout = session expiry timeout + snapshot cache expiry timeout + a buffer.
|
|
42
|
+
* The snapshot cache expiry timeout cannot be known precisely but the upper bound is 5 days, i.e., any snapshot
|
|
43
|
+
* in cache will be invalidated before 5 days.
|
|
44
|
+
*/
|
|
45
|
+
exports.maxSnapshotCacheExpiryMs = 5 * exports.oneDayMs;
|
|
41
46
|
exports.defaultInactiveTimeoutMs = 7 * exports.oneDayMs; // 7 days
|
|
42
47
|
exports.defaultSessionExpiryDurationMs = 30 * exports.oneDayMs; // 30 days
|
|
43
48
|
/** The types of GC nodes in the GC reference graph. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcDefinitions.js","sourceRoot":"","sources":["../../src/gc/gcDefinitions.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAkBH,8DAA8D;AACjD,QAAA,eAAe,GAAc,CAAC,CAAC;AAC5C,iDAAiD;AACpC,QAAA,gBAAgB,GAAc,CAAC,CAAC;AAE7C,kJAAkJ;AACrI,QAAA,+BAA+B,GAAG,uBAAuB,CAAC;AAEvE,wCAAwC;AAC3B,QAAA,QAAQ,GAAG,+BAA+B,CAAC;AACxD,8CAA8C;AACjC,QAAA,WAAW,GAAG,kCAAkC,CAAC;AAC9D,kDAAkD;AACrC,QAAA,aAAa,GAAG,oCAAoC,CAAC;AAClE,mEAAmE;AACtD,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,6EAA6E;AAChE,QAAA,eAAe,GAAG,sCAAsC,CAAC;AACtE,6CAA6C;AAChC,QAAA,kBAAkB,GAAG,yCAAyC,CAAC;AAC5E,qHAAqH;AACxG,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,wFAAwF;AAC3E,QAAA,uBAAuB,GAAG,8CAA8C,CAAC;AACtF,0GAA0G;AAC7F,QAAA,wBAAwB,GAAG,+CAA+C,CAAC;AACxF,6CAA6C;AAChC,QAAA,uBAAuB,GAAG,8CAA8C,CAAC;AACtF,kDAAkD;AAClD,yEAAyE;AAC5D,QAAA,kBAAkB,GAAG,8CAA8C,CAAC;AACjF,wDAAwD;AAC3C,QAAA,uBAAuB,GAAG,mDAAmD,CAAC;AAE3F,2BAA2B;AACd,QAAA,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnC,QAAA,wBAAwB,GAAG,CAAC,GAAG,gBAAQ,CAAC,CAAC,SAAS;AAClD,QAAA,8BAA8B,GAAG,EAAE,GAAG,gBAAQ,CAAC,CAAC,UAAU;AAoEvE,uDAAuD;AAC1C,QAAA,UAAU,GAAG;IACzB,kCAAkC;IAClC,SAAS,EAAE,WAAW;IACtB,8DAA8D;IAC9D,YAAY,EAAE,cAAc;IAC5B,6EAA6E;IAC7E,IAAI,EAAE,MAAM;IACZ,+DAA+D;IAC/D,KAAK,EAAE,OAAO;CACd,CAAC;AAiGF,8CAA8C;AACjC,QAAA,iBAAiB,GAAG;IAChC,gEAAgE;IAChE,MAAM,EAAE,QAAQ;IAChB,mEAAmE;IACnE,QAAQ,EAAE,UAAU;IACpB,0DAA0D;IAC1D,UAAU,EAAE,YAAY;CACf,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { IRequestHeader } from \"@fluidframework/core-interfaces\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tIGarbageCollectionData,\n\tIGarbageCollectionDetailsBase,\n\tISummarizeResult,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { ReadAndParseBlob, RefreshSummaryResult } from \"@fluidframework/runtime-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { IGCRuntimeOptions } from \"../containerRuntime\";\nimport { IContainerRuntimeMetadata, ICreateContainerMetadata } from \"../summary\";\n\nexport type GCVersion = number;\n\n/** The stable version of garbage collection in production. */\nexport const stableGCVersion: GCVersion = 1;\n/** The current version of garbage collection. */\nexport const currentGCVersion: GCVersion = 2;\n\n/** This undocumented GC Option (on ContainerRuntime Options) allows an app to disable enforcing GC on old documents by incrementing this value */\nexport const gcTombstoneGenerationOptionName = \"gcTombstoneGeneration\";\n\n// Feature gate key to turn GC on / off.\nexport const runGCKey = \"Fluid.GarbageCollection.RunGC\";\n// Feature gate key to turn GC sweep on / off.\nexport const runSweepKey = \"Fluid.GarbageCollection.RunSweep\";\n// Feature gate key to turn GC test mode on / off.\nexport const gcTestModeKey = \"Fluid.GarbageCollection.GCTestMode\";\n// Feature gate key to expire a session after a set period of time.\nexport const runSessionExpiryKey = \"Fluid.GarbageCollection.RunSessionExpiry\";\n// Feature gate key to write the gc blob as a handle if the data is the same.\nexport const trackGCStateKey = \"Fluid.GarbageCollection.TrackGCState\";\n// Feature gate key to turn GC sweep log off.\nexport const disableSweepLogKey = \"Fluid.GarbageCollection.DisableSweepLog\";\n// Feature gate key to disable the tombstone feature, i.e., tombstone information is not read / written into summary.\nexport const disableTombstoneKey = \"Fluid.GarbageCollection.DisableTombstone\";\n// Feature gate to enable throwing an error when tombstone object is loaded (requested).\nexport const throwOnTombstoneLoadKey = \"Fluid.GarbageCollection.ThrowOnTombstoneLoad\";\n// Feature gate to enable throwing an error when tombstone object is used (e.g. outgoing or incoming ops).\nexport const throwOnTombstoneUsageKey = \"Fluid.GarbageCollection.ThrowOnTombstoneUsage\";\n// Feature gate to enable GC version upgrade.\nexport const gcVersionUpgradeToV2Key = \"Fluid.GarbageCollection.GCVersionUpgradeToV2\";\n// Feature gate to enable GC sweep for datastores.\n// TODO: Remove Test from the flag when we are confident to turn on sweep\nexport const sweepDatastoresKey = \"Fluid.GarbageCollection.Test.SweepDataStores\";\n// Feature gate to enable GC sweep for attachment blobs.\nexport const sweepAttachmentBlobsKey = \"Fluid.GarbageCollection.Test.SweepAttachmentBlobs\";\n\n// One day in milliseconds.\nexport const oneDayMs = 1 * 24 * 60 * 60 * 1000;\n\nexport const defaultInactiveTimeoutMs = 7 * oneDayMs; // 7 days\nexport const defaultSessionExpiryDurationMs = 30 * oneDayMs; // 30 days\n\n/** @see IGCMetadata.gcFeatureMatrix */\nexport interface GCFeatureMatrix {\n\t/**\n\t * The Tombstone Generation value in effect when this file was created.\n\t * Gives a way for an app to disqualify old files from GC Tombstone enforcement\n\t * Provided via Container Runtime Options\n\t */\n\ttombstoneGeneration?: number;\n}\n\nexport interface IGCMetadata {\n\t/**\n\t * The version of the GC code that was run to generate the GC data that is written in the summary.\n\t * If the persisted value doesn't match the current value in the code, saved GC data will be discarded and regenerated from scratch.\n\t * Also, used to determine whether GC is enabled for this container or not:\n\t * - A value of 0 or undefined means GC is disabled.\n\t * - A value greater than 0 means GC is enabled.\n\t */\n\treadonly gcFeature?: GCVersion;\n\n\t/**\n\t * A collection of different numerical \"Generations\" for different features,\n\t * used to determine feature availability over time.\n\t * This info may come from multiple sources (FF code, config service, app via Container Runtime Options),\n\t * and pertains to aspects of the document that may be fixed for its lifetime.\n\t *\n\t * For each dimension, if the persisted value doesn't match the currently provided value,\n\t * then this file does not support the corresponding feature as currently implemented.\n\t *\n\t * Guidance is that if no value is provided at runtime, it should result in the current default behavior.\n\t */\n\treadonly gcFeatureMatrix?: GCFeatureMatrix;\n\t/**\n\t * Tells whether the GC sweep phase is enabled for this container.\n\t * - True means sweep phase is enabled.\n\t * - False means sweep phase is disabled. If GC is disabled as per gcFeature, sweep is also disabled.\n\t */\n\treadonly sweepEnabled?: boolean;\n\t/** If this is present, the session for this container will expire after this time and the container will close */\n\treadonly sessionExpiryTimeoutMs?: number;\n\t/** How long to wait after an object is unreferenced before deleting it via GC Sweep */\n\treadonly sweepTimeoutMs?: number;\n}\n\n/** The statistics of the system state after a garbage collection run. */\nexport interface IGCStats {\n\t/** The number of nodes in the container. */\n\tnodeCount: number;\n\t/** The number of data stores in the container. */\n\tdataStoreCount: number;\n\t/** The number of attachment blobs in the container. */\n\tattachmentBlobCount: number;\n\t/** The number of unreferenced nodes in the container. */\n\tunrefNodeCount: number;\n\t/** The number of unreferenced data stores in the container. */\n\tunrefDataStoreCount: number;\n\t/** The number of unreferenced attachment blobs in the container. */\n\tunrefAttachmentBlobCount: number;\n\t/** The number of nodes whose reference state updated since last GC run. */\n\tupdatedNodeCount: number;\n\t/** The number of data stores whose reference state updated since last GC run. */\n\tupdatedDataStoreCount: number;\n\t/** The number of attachment blobs whose reference state updated since last GC run. */\n\tupdatedAttachmentBlobCount: number;\n}\n\n/** The types of GC nodes in the GC reference graph. */\nexport const GCNodeType = {\n\t// Nodes that are for data stores.\n\tDataStore: \"DataStore\",\n\t// Nodes that are within a data store. For example, DDS nodes.\n\tSubDataStore: \"SubDataStore\",\n\t// Nodes that are for attachment blobs, i.e., blobs uploaded via BlobManager.\n\tBlob: \"Blob\",\n\t// Nodes that are neither of the above. For example, root node.\n\tOther: \"Other\",\n};\nexport type GCNodeType = typeof GCNodeType[keyof typeof GCNodeType];\n\n/** Defines the APIs for the runtime object to be passed to the garbage collector. */\nexport interface IGarbageCollectionRuntime {\n\t/** Before GC runs, called to notify the runtime to update any pending GC state. */\n\tupdateStateBeforeGC(): Promise<void>;\n\t/** Returns the garbage collection data of the runtime. */\n\tgetGCData(fullGC?: boolean): Promise<IGarbageCollectionData>;\n\t/** After GC has run, called to notify the runtime of routes that are used in it. */\n\tupdateUsedRoutes(usedRoutes: string[]): void;\n\t/** After GC has run, called to notify the runtime of routes that are unused in it. */\n\tupdateUnusedRoutes(unusedRoutes: string[]): void;\n\t/**\n\t * After GC has run and identified nodes that are sweep ready, called to delete the sweep ready nodes. The runtime\n\t * should return the routes of nodes that were deleted.\n\t * @param sweepReadyRoutes - The routes of nodes that are sweep ready and should be deleted.\n\t */\n\tdeleteSweepReadyNodes(sweepReadyRoutes: string[]): string[];\n\t/** Called to notify the runtime of routes that are tombstones. */\n\tupdateTombstonedRoutes(tombstoneRoutes: string[]): void;\n\t/** Returns a referenced timestamp to be used to track unreferenced nodes. */\n\tgetCurrentReferenceTimestampMs(): number | undefined;\n\t/** Returns the type of the GC node. */\n\tgetNodeType(nodePath: string): GCNodeType;\n\t/** Called when the runtime should close because of an error. */\n\tcloseFn: (error?: ICriticalContainerError) => void;\n\t/** If false, loading or using a Tombstoned object should merely log, not fail */\n\tgcTombstoneEnforcementAllowed: boolean;\n}\n\n/** Defines the contract for the garbage collector. */\nexport interface IGarbageCollector {\n\t/** Tells whether GC should run or not. */\n\treadonly shouldRunGC: boolean;\n\t/** Tells whether the GC state in summary needs to be reset in the next summary. */\n\treadonly summaryStateNeedsReset: boolean;\n\t/** Initialize the state from the base snapshot after its creation. */\n\tinitializeBaseState(): Promise<void>;\n\t/** Run garbage collection and update the reference / used state of the system. */\n\tcollectGarbage(\n\t\toptions: {\n\t\t\tlogger?: ITelemetryLogger;\n\t\t\trunSweep?: boolean;\n\t\t\tfullGC?: boolean;\n\t\t},\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<IGCStats | undefined>;\n\t/** Summarizes the GC data and returns it as a summary tree. */\n\tsummarize(\n\t\tfullTree: boolean,\n\t\ttrackState: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): ISummarizeResult | undefined;\n\t/** Returns the garbage collector specific metadata to be written into the summary. */\n\tgetMetadata(): IGCMetadata;\n\t/** Returns the GC details generated from the base snapshot. */\n\tgetBaseGCDetails(): Promise<IGarbageCollectionDetailsBase>;\n\t/** Called when the latest summary of the system has been refreshed. */\n\trefreshLatestSummary(\n\t\tproposalHandle: string | undefined,\n\t\tresult: RefreshSummaryResult,\n\t\treadAndParseBlob: ReadAndParseBlob,\n\t): Promise<void>;\n\t/** Called when a node is updated. Used to detect and log when an inactive node is changed or loaded. */\n\tnodeUpdated(\n\t\tnodePath: string,\n\t\treason: \"Loaded\" | \"Changed\",\n\t\ttimestampMs?: number,\n\t\tpackagePath?: readonly string[],\n\t\trequestHeaders?: IRequestHeader,\n\t): void;\n\t/** Called when a reference is added to a node. Used to identify nodes that were referenced between summaries. */\n\taddedOutboundReference(fromNodePath: string, toNodePath: string): void;\n\t/** Returns true if this node has been deleted by GC during sweep phase. */\n\tisNodeDeleted(nodePath: string): boolean;\n\tsetConnectionState(connected: boolean, clientId?: string): void;\n\tdispose(): void;\n}\n\n/** Parameters necessary for creating a GarbageCollector. */\nexport interface IGarbageCollectorCreateParams {\n\treadonly runtime: IGarbageCollectionRuntime;\n\treadonly gcOptions: IGCRuntimeOptions;\n\treadonly baseLogger: ITelemetryLogger;\n\treadonly existing: boolean;\n\treadonly metadata: IContainerRuntimeMetadata | undefined;\n\treadonly createContainerMetadata: ICreateContainerMetadata;\n\treadonly baseSnapshot: ISnapshotTree | undefined;\n\treadonly isSummarizerClient: boolean;\n\treadonly getNodePackagePath: (nodePath: string) => Promise<readonly string[] | undefined>;\n\treadonly getLastSummaryTimestampMs: () => number | undefined;\n\treadonly readAndParseBlob: ReadAndParseBlob;\n\treadonly activeConnection: () => boolean;\n\treadonly getContainerDiagnosticId: () => string;\n}\n\n/** The state of node that is unreferenced. */\nexport const UnreferencedState = {\n\t/** The node is active, i.e., it can become referenced again. */\n\tActive: \"Active\",\n\t/** The node is inactive, i.e., it should not become referenced. */\n\tInactive: \"Inactive\",\n\t/** The node is ready to be deleted by the sweep phase. */\n\tSweepReady: \"SweepReady\",\n} as const;\nexport type UnreferencedState = typeof UnreferencedState[keyof typeof UnreferencedState];\n"]}
|
|
1
|
+
{"version":3,"file":"gcDefinitions.js","sourceRoot":"","sources":["../../src/gc/gcDefinitions.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAiBH,8DAA8D;AACjD,QAAA,eAAe,GAAc,CAAC,CAAC;AAC5C,iDAAiD;AACpC,QAAA,gBAAgB,GAAc,CAAC,CAAC;AAE7C,kJAAkJ;AACrI,QAAA,+BAA+B,GAAG,uBAAuB,CAAC;AAEvE,wCAAwC;AAC3B,QAAA,QAAQ,GAAG,+BAA+B,CAAC;AACxD,8CAA8C;AACjC,QAAA,WAAW,GAAG,kCAAkC,CAAC;AAC9D,kDAAkD;AACrC,QAAA,aAAa,GAAG,oCAAoC,CAAC;AAClE,mEAAmE;AACtD,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,6CAA6C;AAChC,QAAA,kBAAkB,GAAG,yCAAyC,CAAC;AAC5E,qHAAqH;AACxG,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,wFAAwF;AAC3E,QAAA,uBAAuB,GAAG,8CAA8C,CAAC;AACtF,0GAA0G;AAC7F,QAAA,wBAAwB,GAAG,+CAA+C,CAAC;AACxF,6CAA6C;AAChC,QAAA,uBAAuB,GAAG,8CAA8C,CAAC;AACtF,kDAAkD;AAClD,yEAAyE;AAC5D,QAAA,kBAAkB,GAAG,8CAA8C,CAAC;AACjF,wDAAwD;AAC3C,QAAA,uBAAuB,GAAG,mDAAmD,CAAC;AAE3F,2BAA2B;AACd,QAAA,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhD;;;;;GAKG;AACU,QAAA,wBAAwB,GAAG,CAAC,GAAG,gBAAQ,CAAC;AAExC,QAAA,wBAAwB,GAAG,CAAC,GAAG,gBAAQ,CAAC,CAAC,SAAS;AAClD,QAAA,8BAA8B,GAAG,EAAE,GAAG,gBAAQ,CAAC,CAAC,UAAU;AAoEvE,uDAAuD;AAC1C,QAAA,UAAU,GAAG;IACzB,kCAAkC;IAClC,SAAS,EAAE,WAAW;IACtB,8DAA8D;IAC9D,YAAY,EAAE,cAAc;IAC5B,6EAA6E;IAC7E,IAAI,EAAE,MAAM;IACZ,+DAA+D;IAC/D,KAAK,EAAE,OAAO;CACd,CAAC;AAsMF,8CAA8C;AACjC,QAAA,iBAAiB,GAAG;IAChC,gEAAgE;IAChE,MAAM,EAAE,QAAQ;IAChB,mEAAmE;IACnE,QAAQ,EAAE,UAAU;IACpB,0DAA0D;IAC1D,UAAU,EAAE,YAAY;CACf,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { IRequestHeader } from \"@fluidframework/core-interfaces\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tIGarbageCollectionData,\n\tIGarbageCollectionDetailsBase,\n\tISummarizeResult,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { ReadAndParseBlob, RefreshSummaryResult } from \"@fluidframework/runtime-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { IContainerRuntimeMetadata, ICreateContainerMetadata } from \"../summary\";\n\nexport type GCVersion = number;\n\n/** The stable version of garbage collection in production. */\nexport const stableGCVersion: GCVersion = 1;\n/** The current version of garbage collection. */\nexport const currentGCVersion: GCVersion = 2;\n\n/** This undocumented GC Option (on ContainerRuntime Options) allows an app to disable enforcing GC on old documents by incrementing this value */\nexport const gcTombstoneGenerationOptionName = \"gcTombstoneGeneration\";\n\n// Feature gate key to turn GC on / off.\nexport const runGCKey = \"Fluid.GarbageCollection.RunGC\";\n// Feature gate key to turn GC sweep on / off.\nexport const runSweepKey = \"Fluid.GarbageCollection.RunSweep\";\n// Feature gate key to turn GC test mode on / off.\nexport const gcTestModeKey = \"Fluid.GarbageCollection.GCTestMode\";\n// Feature gate key to expire a session after a set period of time.\nexport const runSessionExpiryKey = \"Fluid.GarbageCollection.RunSessionExpiry\";\n// Feature gate key to turn GC sweep log off.\nexport const disableSweepLogKey = \"Fluid.GarbageCollection.DisableSweepLog\";\n// Feature gate key to disable the tombstone feature, i.e., tombstone information is not read / written into summary.\nexport const disableTombstoneKey = \"Fluid.GarbageCollection.DisableTombstone\";\n// Feature gate to enable throwing an error when tombstone object is loaded (requested).\nexport const throwOnTombstoneLoadKey = \"Fluid.GarbageCollection.ThrowOnTombstoneLoad\";\n// Feature gate to enable throwing an error when tombstone object is used (e.g. outgoing or incoming ops).\nexport const throwOnTombstoneUsageKey = \"Fluid.GarbageCollection.ThrowOnTombstoneUsage\";\n// Feature gate to enable GC version upgrade.\nexport const gcVersionUpgradeToV2Key = \"Fluid.GarbageCollection.GCVersionUpgradeToV2\";\n// Feature gate to enable GC sweep for datastores.\n// TODO: Remove Test from the flag when we are confident to turn on sweep\nexport const sweepDatastoresKey = \"Fluid.GarbageCollection.Test.SweepDataStores\";\n// Feature gate to enable GC sweep for attachment blobs.\nexport const sweepAttachmentBlobsKey = \"Fluid.GarbageCollection.Test.SweepAttachmentBlobs\";\n\n// One day in milliseconds.\nexport const oneDayMs = 1 * 24 * 60 * 60 * 1000;\n\n/**\n * The maximum snapshot cache expiry in the driver. This is used to calculate the sweep timeout.\n * Sweep timeout = session expiry timeout + snapshot cache expiry timeout + a buffer.\n * The snapshot cache expiry timeout cannot be known precisely but the upper bound is 5 days, i.e., any snapshot\n * in cache will be invalidated before 5 days.\n */\nexport const maxSnapshotCacheExpiryMs = 5 * oneDayMs;\n\nexport const defaultInactiveTimeoutMs = 7 * oneDayMs; // 7 days\nexport const defaultSessionExpiryDurationMs = 30 * oneDayMs; // 30 days\n\n/** @see IGCMetadata.gcFeatureMatrix */\nexport interface GCFeatureMatrix {\n\t/**\n\t * The Tombstone Generation value in effect when this file was created.\n\t * Gives a way for an app to disqualify old files from GC Tombstone enforcement\n\t * Provided via Container Runtime Options\n\t */\n\ttombstoneGeneration?: number;\n}\n\nexport interface IGCMetadata {\n\t/**\n\t * The version of the GC code that was run to generate the GC data that is written in the summary.\n\t * If the persisted value doesn't match the current value in the code, saved GC data will be discarded and regenerated from scratch.\n\t * Also, used to determine whether GC is enabled for this container or not:\n\t * - A value of 0 or undefined means GC is disabled.\n\t * - A value greater than 0 means GC is enabled.\n\t */\n\treadonly gcFeature?: GCVersion;\n\n\t/**\n\t * A collection of different numerical \"Generations\" for different features,\n\t * used to determine feature availability over time.\n\t * This info may come from multiple sources (FF code, config service, app via Container Runtime Options),\n\t * and pertains to aspects of the document that may be fixed for its lifetime.\n\t *\n\t * For each dimension, if the persisted value doesn't match the currently provided value,\n\t * then this file does not support the corresponding feature as currently implemented.\n\t *\n\t * Guidance is that if no value is provided at runtime, it should result in the current default behavior.\n\t */\n\treadonly gcFeatureMatrix?: GCFeatureMatrix;\n\t/**\n\t * Tells whether the GC sweep phase is enabled for this container.\n\t * - True means sweep phase is enabled.\n\t * - False means sweep phase is disabled. If GC is disabled as per gcFeature, sweep is also disabled.\n\t */\n\treadonly sweepEnabled?: boolean;\n\t/** If this is present, the session for this container will expire after this time and the container will close */\n\treadonly sessionExpiryTimeoutMs?: number;\n\t/** How long to wait after an object is unreferenced before deleting it via GC Sweep */\n\treadonly sweepTimeoutMs?: number;\n}\n\n/** The statistics of the system state after a garbage collection run. */\nexport interface IGCStats {\n\t/** The number of nodes in the container. */\n\tnodeCount: number;\n\t/** The number of data stores in the container. */\n\tdataStoreCount: number;\n\t/** The number of attachment blobs in the container. */\n\tattachmentBlobCount: number;\n\t/** The number of unreferenced nodes in the container. */\n\tunrefNodeCount: number;\n\t/** The number of unreferenced data stores in the container. */\n\tunrefDataStoreCount: number;\n\t/** The number of unreferenced attachment blobs in the container. */\n\tunrefAttachmentBlobCount: number;\n\t/** The number of nodes whose reference state updated since last GC run. */\n\tupdatedNodeCount: number;\n\t/** The number of data stores whose reference state updated since last GC run. */\n\tupdatedDataStoreCount: number;\n\t/** The number of attachment blobs whose reference state updated since last GC run. */\n\tupdatedAttachmentBlobCount: number;\n}\n\n/** The types of GC nodes in the GC reference graph. */\nexport const GCNodeType = {\n\t// Nodes that are for data stores.\n\tDataStore: \"DataStore\",\n\t// Nodes that are within a data store. For example, DDS nodes.\n\tSubDataStore: \"SubDataStore\",\n\t// Nodes that are for attachment blobs, i.e., blobs uploaded via BlobManager.\n\tBlob: \"Blob\",\n\t// Nodes that are neither of the above. For example, root node.\n\tOther: \"Other\",\n};\nexport type GCNodeType = typeof GCNodeType[keyof typeof GCNodeType];\n\n// NOTE: Once this is removed from the package exports in the next major, the deprecation tag can be removed as well\n/**\n * @deprecated - Was only to be used internally anyway, no replacement provided.\n * Defines the APIs for the runtime object to be passed to the garbage collector.\n */\nexport interface IGarbageCollectionRuntime {\n\t/** Before GC runs, called to notify the runtime to update any pending GC state. */\n\tupdateStateBeforeGC(): Promise<void>;\n\t/** Returns the garbage collection data of the runtime. */\n\tgetGCData(fullGC?: boolean): Promise<IGarbageCollectionData>;\n\t/** After GC has run, called to notify the runtime of routes that are used in it. */\n\tupdateUsedRoutes(usedRoutes: string[]): void;\n\t/** After GC has run, called to notify the runtime of routes that are unused in it. */\n\tupdateUnusedRoutes(unusedRoutes: string[]): void;\n\t/**\n\t * After GC has run and identified nodes that are sweep ready, called to delete the sweep ready nodes. The runtime\n\t * should return the routes of nodes that were deleted.\n\t * @param sweepReadyRoutes - The routes of nodes that are sweep ready and should be deleted.\n\t */\n\tdeleteSweepReadyNodes(sweepReadyRoutes: string[]): string[];\n\t/** Called to notify the runtime of routes that are tombstones. */\n\tupdateTombstonedRoutes(tombstoneRoutes: string[]): void;\n\t/** Returns a referenced timestamp to be used to track unreferenced nodes. */\n\tgetCurrentReferenceTimestampMs(): number | undefined;\n\t/** Returns the type of the GC node. */\n\tgetNodeType(nodePath: string): GCNodeType;\n\t/** Called when the runtime should close because of an error. */\n\tcloseFn: (error?: ICriticalContainerError) => void;\n\t/** If false, loading or using a Tombstoned object should merely log, not fail */\n\tgcTombstoneEnforcementAllowed: boolean;\n}\n\n/** Defines the contract for the garbage collector. */\nexport interface IGarbageCollector {\n\t/** Tells whether GC should run or not. */\n\treadonly shouldRunGC: boolean;\n\t/** Tells whether the GC state in summary needs to be reset in the next summary. */\n\treadonly summaryStateNeedsReset: boolean;\n\t/** Initialize the state from the base snapshot after its creation. */\n\tinitializeBaseState(): Promise<void>;\n\t/** Run garbage collection and update the reference / used state of the system. */\n\tcollectGarbage(\n\t\toptions: {\n\t\t\tlogger?: ITelemetryLogger;\n\t\t\trunSweep?: boolean;\n\t\t\tfullGC?: boolean;\n\t\t},\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<IGCStats | undefined>;\n\t/** Summarizes the GC data and returns it as a summary tree. */\n\tsummarize(\n\t\tfullTree: boolean,\n\t\ttrackState: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): ISummarizeResult | undefined;\n\t/** Returns the garbage collector specific metadata to be written into the summary. */\n\tgetMetadata(): IGCMetadata;\n\t/** Returns the GC details generated from the base snapshot. */\n\tgetBaseGCDetails(): Promise<IGarbageCollectionDetailsBase>;\n\t/** Called when the latest summary of the system has been refreshed. */\n\trefreshLatestSummary(\n\t\tproposalHandle: string | undefined,\n\t\tresult: RefreshSummaryResult,\n\t\treadAndParseBlob: ReadAndParseBlob,\n\t): Promise<void>;\n\t/** Called when a node is updated. Used to detect and log when an inactive node is changed or loaded. */\n\tnodeUpdated(\n\t\tnodePath: string,\n\t\treason: \"Loaded\" | \"Changed\",\n\t\ttimestampMs?: number,\n\t\tpackagePath?: readonly string[],\n\t\trequestHeaders?: IRequestHeader,\n\t): void;\n\t/** Called when a reference is added to a node. Used to identify nodes that were referenced between summaries. */\n\taddedOutboundReference(fromNodePath: string, toNodePath: string): void;\n\t/** Returns true if this node has been deleted by GC during sweep phase. */\n\tisNodeDeleted(nodePath: string): boolean;\n\tsetConnectionState(connected: boolean, clientId?: string): void;\n\tdispose(): void;\n}\n\n/** Parameters necessary for creating a GarbageCollector. */\nexport interface IGarbageCollectorCreateParams {\n\treadonly runtime: IGarbageCollectionRuntime;\n\treadonly gcOptions: IGCRuntimeOptions;\n\treadonly baseLogger: ITelemetryLogger;\n\treadonly existing: boolean;\n\treadonly metadata: IContainerRuntimeMetadata | undefined;\n\treadonly createContainerMetadata: ICreateContainerMetadata;\n\treadonly baseSnapshot: ISnapshotTree | undefined;\n\treadonly isSummarizerClient: boolean;\n\treadonly getNodePackagePath: (nodePath: string) => Promise<readonly string[] | undefined>;\n\treadonly getLastSummaryTimestampMs: () => number | undefined;\n\treadonly readAndParseBlob: ReadAndParseBlob;\n\treadonly activeConnection: () => boolean;\n\treadonly getContainerDiagnosticId: () => string;\n}\n\nexport interface IGCRuntimeOptions {\n\t/**\n\t * Flag that if true, will enable running garbage collection (GC) for a new container.\n\t *\n\t * GC has mark phase and sweep phase. In mark phase, unreferenced objects are identified\n\t * and marked as such in the summary. This option enables the mark phase.\n\t * In sweep phase, unreferenced objects are eventually deleted from the container if they meet certain conditions.\n\t * Sweep phase can be enabled via the \"sweepAllowed\" option.\n\t *\n\t * Note: This setting is persisted in the container's summary and cannot be changed.\n\t */\n\tgcAllowed?: boolean;\n\n\t/**\n\t * Flag that if true, enables GC's sweep phase for a new container.\n\t *\n\t * This will allow GC to eventually delete unreferenced objects from the container.\n\t * This flag should only be set to true if \"gcAllowed\" is true.\n\t *\n\t * Note: This setting is persisted in the container's summary and cannot be changed.\n\t */\n\tsweepAllowed?: boolean;\n\n\t/**\n\t * Flag that if true, will disable garbage collection for the session.\n\t * Can be used to disable running GC on containers where it is allowed via the gcAllowed option.\n\t */\n\tdisableGC?: boolean;\n\n\t/**\n\t * Flag that will bypass optimizations and generate GC data for all nodes irrespective of whether a node\n\t * changed or not.\n\t */\n\trunFullGC?: boolean;\n\n\t/**\n\t * Maximum session duration for a new container. If not present, a default value will be used.\n\t *\n\t * Note: This setting is persisted in the container's summary and cannot be changed.\n\t */\n\tsessionExpiryTimeoutMs?: number;\n\n\t/**\n\t * Allows additional GC options to be passed.\n\t */\n\t[key: string]: any;\n}\n\n/**\n * The configurations for Garbage Collector that determines what runs and how.\n */\nexport interface IGarbageCollectorConfigs {\n\t/**\n\t * Tracks if GC is enabled for this document. This is specified during document creation and doesn't change\n\t * throughout its lifetime.\n\t */\n\treadonly gcEnabled: boolean;\n\t/**\n\t * Tracks if sweep phase is enabled for this document. This is specified during document creation and doesn't change\n\t * throughout its lifetime.\n\t */\n\treadonly sweepEnabled: boolean;\n\t/**\n\t * Tracks if GC should run or not. Even if GC is enabled for a document (see gcEnabled), it can be explicitly\n\t * disabled via runtime options or feature flags.\n\t */\n\treadonly shouldRunGC: boolean;\n\t/**\n\t * Tracks if sweep phase should run or not. Even if the sweep phase is enabled for a document (see sweepEnabled), it\n\t * can be explicitly disabled via feature flags. It also won't run if session expiry is not enabled.\n\t */\n\treadonly shouldRunSweep: boolean;\n\t/**\n\t * If true, bypass optimizations and generate GC data for all nodes irrespective of whether a node changed or not.\n\t */\n\treadonly runFullGC: boolean | undefined;\n\t/** The time in ms to expire a session for a client for gc. */\n\treadonly sessionExpiryTimeoutMs: number | undefined;\n\t/** The time after which an unreferenced node is ready to be swept. */\n\treadonly sweepTimeoutMs: number | undefined;\n\t/** The time after which an unreferenced node is inactive. */\n\treadonly inactiveTimeoutMs: number;\n\t/** Tracks whether GC should run in test mode. In this mode, unreferenced objects are deleted immediately. */\n\treadonly testMode: boolean;\n\t/**\n\t * Tracks whether GC should run in tombstone mode. In this mode, sweep ready objects are marked as tombstones.\n\t * In interactive (non-summarizer) clients, tombstone objects behave as if they are deleted, i.e., access to them\n\t * is not allowed. However, these objects can be accessed after referencing them first. It is used as a staging\n\t * step for sweep where accidental sweep ready objects can be recovered.\n\t */\n\treadonly tombstoneMode: boolean;\n\t/** @see GCFeatureMatrix. */\n\treadonly persistedGcFeatureMatrix: GCFeatureMatrix | undefined;\n\t/** The version of GC in the base snapshot. */\n\treadonly gcVersionInBaseSnapshot: GCVersion | undefined;\n}\n\n/** The state of node that is unreferenced. */\nexport const UnreferencedState = {\n\t/** The node is active, i.e., it can become referenced again. */\n\tActive: \"Active\",\n\t/** The node is inactive, i.e., it should not become referenced. */\n\tInactive: \"Inactive\",\n\t/** The node is ready to be deleted by the sweep phase. */\n\tSweepReady: \"SweepReady\",\n} as const;\nexport type UnreferencedState = typeof UnreferencedState[keyof typeof UnreferencedState];\n"]}
|
package/dist/gc/gcHelpers.d.ts
CHANGED
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { ITelemetryGenericEvent } from "@fluidframework/common-definitions";
|
|
6
|
-
import {
|
|
6
|
+
import { ISnapshotTree } from "@fluidframework/protocol-definitions";
|
|
7
|
+
import { IGarbageCollectionSnapshotData, IGarbageCollectionState } from "@fluidframework/runtime-definitions";
|
|
8
|
+
import { ReadAndParseBlob } from "@fluidframework/runtime-utils";
|
|
7
9
|
import { MonitoringContext } from "@fluidframework/telemetry-utils";
|
|
10
|
+
import { IContainerRuntimeMetadata } from "../summary";
|
|
8
11
|
import { GCVersion, IGCMetadata } from "./gcDefinitions";
|
|
9
12
|
export declare function getGCVersion(metadata?: IGCMetadata): GCVersion;
|
|
10
13
|
/**
|
|
@@ -26,5 +29,13 @@ export declare function sendGCUnexpectedUsageEvent(mc: MonitoringContext, event:
|
|
|
26
29
|
* @returns true if GC Enforcement (Fail on Tombstone load/usage) should be allowed
|
|
27
30
|
*/
|
|
28
31
|
export declare function shouldAllowGcTombstoneEnforcement(persistedGeneration: number | undefined, currentGeneration: number | undefined): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Sorts the given GC state as per the id of the GC nodes. It also sorts the outbound routes array of each node.
|
|
34
|
+
*/
|
|
29
35
|
export declare function generateSortedGCState(gcState: IGarbageCollectionState): IGarbageCollectionState;
|
|
36
|
+
/**
|
|
37
|
+
* This is for back-compat only - Before GC data was written at the root of the summary tree, individual GC blobs were
|
|
38
|
+
* written at data store's snapshot tree. This function consolidates them into the new IGarbageCollectionState format.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getSnapshotDataFromOldSnapshotFormat(oldSnapshot: ISnapshotTree, metadata: IContainerRuntimeMetadata | undefined, readAndParseBlob: ReadAndParseBlob): Promise<IGarbageCollectionSnapshotData | undefined>;
|
|
30
41
|
//# sourceMappingURL=gcHelpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcHelpers.d.ts","sourceRoot":"","sources":["../../src/gc/gcHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"gcHelpers.d.ts","sourceRoot":"","sources":["../../src/gc/gcHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAE5E,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAGN,8BAA8B,EAC9B,uBAAuB,EAEvB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAkC,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,OAAO,EAEN,yBAAyB,EAEzB,MAAM,YAAY,CAAC;AACpB,OAAO,EAEN,SAAS,EACT,WAAW,EAIX,MAAM,iBAAiB,CAAC;AAEzB,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,SAAS,CAM9D;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACzC,EAAE,EAAE,iBAAiB,EACrB,KAAK,EAAE,sBAAsB,GAAG;IAC/B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,6BAA6B,EAAE,OAAO,GAAG,SAAS,CAAC;CACnD,EACD,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAC1C,KAAK,CAAC,EAAE,OAAO,QAaf;AAED;;;;;;;;;GASG;AACH,wBAAgB,iCAAiC,CAChD,mBAAmB,EAAE,MAAM,GAAG,SAAS,EACvC,iBAAiB,EAAE,MAAM,GAAG,SAAS,GACnC,OAAO,CAMT;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,uBAAuB,GAAG,uBAAuB,CAS/F;AAED;;;GAGG;AACH,wBAAsB,oCAAoC,CACzD,WAAW,EAAE,aAAa,EAC1B,QAAQ,EAAE,yBAAyB,GAAG,SAAS,EAC/C,gBAAgB,EAAE,gBAAgB,GAChC,OAAO,CAAC,8BAA8B,GAAG,SAAS,CAAC,CAqDrD"}
|
package/dist/gc/gcHelpers.js
CHANGED
|
@@ -4,8 +4,12 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.generateSortedGCState = exports.shouldAllowGcTombstoneEnforcement = exports.sendGCUnexpectedUsageEvent = exports.getGCVersion = void 0;
|
|
7
|
+
exports.getSnapshotDataFromOldSnapshotFormat = exports.generateSortedGCState = exports.shouldAllowGcTombstoneEnforcement = exports.sendGCUnexpectedUsageEvent = exports.getGCVersion = void 0;
|
|
8
|
+
const common_utils_1 = require("@fluidframework/common-utils");
|
|
9
|
+
const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
|
|
8
10
|
const runtime_utils_1 = require("@fluidframework/runtime-utils");
|
|
11
|
+
const dataStores_1 = require("../dataStores");
|
|
12
|
+
const summary_1 = require("../summary");
|
|
9
13
|
const gcDefinitions_1 = require("./gcDefinitions");
|
|
10
14
|
function getGCVersion(metadata) {
|
|
11
15
|
var _a;
|
|
@@ -51,6 +55,9 @@ function shouldAllowGcTombstoneEnforcement(persistedGeneration, currentGeneratio
|
|
|
51
55
|
return persistedGeneration === currentGeneration;
|
|
52
56
|
}
|
|
53
57
|
exports.shouldAllowGcTombstoneEnforcement = shouldAllowGcTombstoneEnforcement;
|
|
58
|
+
/**
|
|
59
|
+
* Sorts the given GC state as per the id of the GC nodes. It also sorts the outbound routes array of each node.
|
|
60
|
+
*/
|
|
54
61
|
function generateSortedGCState(gcState) {
|
|
55
62
|
const sortableArray = Object.entries(gcState.gcNodes);
|
|
56
63
|
sortableArray.sort(([a], [b]) => a.localeCompare(b));
|
|
@@ -62,4 +69,51 @@ function generateSortedGCState(gcState) {
|
|
|
62
69
|
return sortedGCState;
|
|
63
70
|
}
|
|
64
71
|
exports.generateSortedGCState = generateSortedGCState;
|
|
72
|
+
/**
|
|
73
|
+
* This is for back-compat only - Before GC data was written at the root of the summary tree, individual GC blobs were
|
|
74
|
+
* written at data store's snapshot tree. This function consolidates them into the new IGarbageCollectionState format.
|
|
75
|
+
*/
|
|
76
|
+
async function getSnapshotDataFromOldSnapshotFormat(oldSnapshot, metadata, readAndParseBlob) {
|
|
77
|
+
var _a;
|
|
78
|
+
// Add a node for the root node that is not present in older snapshot format.
|
|
79
|
+
const gcState = {
|
|
80
|
+
gcNodes: { "/": { outboundRoutes: [] } },
|
|
81
|
+
};
|
|
82
|
+
const dataStoreSnapshotTree = (0, dataStores_1.getSummaryForDatastores)(oldSnapshot, metadata);
|
|
83
|
+
(0, common_utils_1.assert)(dataStoreSnapshotTree !== undefined, 0x2a8 /* "Expected data store snapshot tree in base snapshot" */);
|
|
84
|
+
for (const [dsId, dsSnapshotTree] of Object.entries(dataStoreSnapshotTree.trees)) {
|
|
85
|
+
const blobId = dsSnapshotTree.blobs[runtime_definitions_1.gcTreeKey];
|
|
86
|
+
if (blobId === undefined) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const gcSummaryDetails = await readAndParseBlob(blobId);
|
|
90
|
+
// If there are no nodes for this data store, skip it.
|
|
91
|
+
if (((_a = gcSummaryDetails.gcData) === null || _a === void 0 ? void 0 : _a.gcNodes) === undefined) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const dsRootId = `/${dsId}`;
|
|
95
|
+
// Since we used to write GC data at data store level, we won't have an entry for the root ("/").
|
|
96
|
+
// Construct that entry by adding root data store ids to its outbound routes.
|
|
97
|
+
const initialSnapshotDetails = await readAndParseBlob(dsSnapshotTree.blobs[summary_1.dataStoreAttributesBlobName]);
|
|
98
|
+
if (initialSnapshotDetails.isRootDataStore) {
|
|
99
|
+
gcState.gcNodes["/"].outboundRoutes.push(dsRootId);
|
|
100
|
+
}
|
|
101
|
+
for (const [id, outboundRoutes] of Object.entries(gcSummaryDetails.gcData.gcNodes)) {
|
|
102
|
+
// Prefix the data store id to the GC node ids to make them relative to the root from being
|
|
103
|
+
// relative to the data store. Similar to how its done in DataStore::getGCData.
|
|
104
|
+
const rootId = id === "/" ? dsRootId : `${dsRootId}${id}`;
|
|
105
|
+
gcState.gcNodes[rootId] = {
|
|
106
|
+
outboundRoutes: Array.from(outboundRoutes),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
(0, common_utils_1.assert)(gcState.gcNodes[dsRootId] !== undefined, 0x2a9 /* GC nodes for data store not in GC blob */);
|
|
110
|
+
gcState.gcNodes[dsRootId].unreferencedTimestampMs = gcSummaryDetails.unrefTimestamp;
|
|
111
|
+
}
|
|
112
|
+
// If there is only one node (root node just added above), either GC is disabled or we are loading from
|
|
113
|
+
// the first summary generated by detached container. In both cases, GC was not run - return undefined.
|
|
114
|
+
return Object.keys(gcState.gcNodes).length === 1
|
|
115
|
+
? undefined
|
|
116
|
+
: { gcState, tombstones: undefined, deletedNodes: undefined };
|
|
117
|
+
}
|
|
118
|
+
exports.getSnapshotDataFromOldSnapshotFormat = getSnapshotDataFromOldSnapshotFormat;
|
|
65
119
|
//# sourceMappingURL=gcHelpers.js.map
|
package/dist/gc/gcHelpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcHelpers.js","sourceRoot":"","sources":["../../src/gc/gcHelpers.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAOH,iEAA+E;AAE/E,mDAOyB;AAEzB,SAAgB,YAAY,CAAC,QAAsB;;IAClD,IAAI,CAAC,QAAQ,EAAE;QACd,0CAA0C;QAC1C,OAAO,CAAC,CAAC;KACT;IACD,OAAO,MAAA,QAAQ,CAAC,SAAS,mCAAI,CAAC,CAAC;AAChC,CAAC;AAND,oCAMC;AAED;;;GAGG;AACH,SAAgB,0BAA0B,CACzC,EAAqB,EACrB,KAGC,EACD,WAA0C,EAC1C,KAAe;IAEf,KAAK,CAAC,GAAG,GAAG,IAAA,8CAA8B,EAAC,WAAW,CAAC,CAAC;IACxD,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;QACrC,gBAAgB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,mCAAmB,CAAC;QAC3D,qBAAqB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,wCAAwB,CAAC;QACrE,oBAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,uCAAuB,CAAC;KACnE,CAAC,CAAC;IACH,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,eAAe,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,2BAAW,CAAC;KAClD,CAAC,CAAC;IAEH,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AApBD,gEAoBC;AAED;;;;;;;;;GASG;AACH,SAAgB,iCAAiC,CAChD,mBAAuC,EACvC,iBAAqC;IAErC,+HAA+H;IAC/H,IAAI,iBAAiB,KAAK,SAAS,EAAE;QACpC,OAAO,IAAI,CAAC;KACZ;IACD,OAAO,mBAAmB,KAAK,iBAAiB,CAAC;AAClD,CAAC;AATD,8EASC;AAED,SAAgB,qBAAqB,CAAC,OAAgC;IACrE,MAAM,aAAa,GAA2C,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9F,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,aAAa,GAA4B,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC/D,KAAK,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,aAAa,EAAE;QAC/C,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/B,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;KACzC;IACD,OAAO,aAAa,CAAC;AACtB,CAAC;AATD,sDASC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryGenericEvent } from \"@fluidframework/common-definitions\";\nimport {\n\tIGarbageCollectionNodeData,\n\tIGarbageCollectionState,\n} from \"@fluidframework/runtime-definitions\";\nimport { packagePathToTelemetryProperty } from \"@fluidframework/runtime-utils\";\nimport { MonitoringContext } from \"@fluidframework/telemetry-utils\";\nimport {\n\tdisableTombstoneKey,\n\tGCVersion,\n\tIGCMetadata,\n\trunSweepKey,\n\tthrowOnTombstoneLoadKey,\n\tthrowOnTombstoneUsageKey,\n} from \"./gcDefinitions\";\n\nexport function getGCVersion(metadata?: IGCMetadata): GCVersion {\n\tif (!metadata) {\n\t\t// Force to 0/disallowed in prior versions\n\t\treturn 0;\n\t}\n\treturn metadata.gcFeature ?? 0;\n}\n\n/**\n * Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a\n * tombstoned or deleted object is loaded.\n */\nexport function sendGCUnexpectedUsageEvent(\n\tmc: MonitoringContext,\n\tevent: ITelemetryGenericEvent & {\n\t\tcategory: \"error\" | \"generic\";\n\t\tgcTombstoneEnforcementAllowed: boolean | undefined;\n\t},\n\tpackagePath: readonly string[] | undefined,\n\terror?: unknown,\n) {\n\tevent.pkg = packagePathToTelemetryProperty(packagePath);\n\tevent.tombstoneFlags = JSON.stringify({\n\t\tDisableTombstone: mc.config.getBoolean(disableTombstoneKey),\n\t\tThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),\n\t\tThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadKey),\n\t});\n\tevent.sweepFlags = JSON.stringify({\n\t\tEnableSweepFlag: mc.config.getBoolean(runSweepKey),\n\t});\n\n\tmc.logger.sendTelemetryEvent(event, error);\n}\n\n/**\n * In order to protect old documents that were created at a time when known bugs exist that violate GC's invariants\n * such that enforcing GC (Fail on Tombstone load/usage, GC Sweep) would cause legitimate data loss,\n * the container author may increment the generation value for Tombstone such that containers created\n * with a different value will not be subjected to GC enforcement.\n * If no generation is provided at runtime, this defaults to return true to maintain expected default behavior\n * @param persistedGeneration - The persisted feature support value\n * @param currentGeneration - The current app-provided feature support value\n * @returns true if GC Enforcement (Fail on Tombstone load/usage) should be allowed\n */\nexport function shouldAllowGcTombstoneEnforcement(\n\tpersistedGeneration: number | undefined,\n\tcurrentGeneration: number | undefined,\n): boolean {\n\t// If no Generation value is provided for this session, then we should default to letting Tombstone feature behave as intended.\n\tif (currentGeneration === undefined) {\n\t\treturn true;\n\t}\n\treturn persistedGeneration === currentGeneration;\n}\n\nexport function generateSortedGCState(gcState: IGarbageCollectionState): IGarbageCollectionState {\n\tconst sortableArray: [string, IGarbageCollectionNodeData][] = Object.entries(gcState.gcNodes);\n\tsortableArray.sort(([a], [b]) => a.localeCompare(b));\n\tconst sortedGCState: IGarbageCollectionState = { gcNodes: {} };\n\tfor (const [nodeId, nodeData] of sortableArray) {\n\t\tnodeData.outboundRoutes.sort();\n\t\tsortedGCState.gcNodes[nodeId] = nodeData;\n\t}\n\treturn sortedGCState;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"gcHelpers.js","sourceRoot":"","sources":["../../src/gc/gcHelpers.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryGenericEvent } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tgcTreeKey,\n\tIGarbageCollectionNodeData,\n\tIGarbageCollectionSnapshotData,\n\tIGarbageCollectionState,\n\tIGarbageCollectionSummaryDetailsLegacy,\n} from \"@fluidframework/runtime-definitions\";\nimport { packagePathToTelemetryProperty, ReadAndParseBlob } from \"@fluidframework/runtime-utils\";\nimport { MonitoringContext } from \"@fluidframework/telemetry-utils\";\nimport { getSummaryForDatastores } from \"../dataStores\";\nimport {\n\tdataStoreAttributesBlobName,\n\tIContainerRuntimeMetadata,\n\tReadFluidDataStoreAttributes,\n} from \"../summary\";\nimport {\n\tdisableTombstoneKey,\n\tGCVersion,\n\tIGCMetadata,\n\trunSweepKey,\n\tthrowOnTombstoneLoadKey,\n\tthrowOnTombstoneUsageKey,\n} from \"./gcDefinitions\";\n\nexport function getGCVersion(metadata?: IGCMetadata): GCVersion {\n\tif (!metadata) {\n\t\t// Force to 0/disallowed in prior versions\n\t\treturn 0;\n\t}\n\treturn metadata.gcFeature ?? 0;\n}\n\n/**\n * Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a\n * tombstoned or deleted object is loaded.\n */\nexport function sendGCUnexpectedUsageEvent(\n\tmc: MonitoringContext,\n\tevent: ITelemetryGenericEvent & {\n\t\tcategory: \"error\" | \"generic\";\n\t\tgcTombstoneEnforcementAllowed: boolean | undefined;\n\t},\n\tpackagePath: readonly string[] | undefined,\n\terror?: unknown,\n) {\n\tevent.pkg = packagePathToTelemetryProperty(packagePath);\n\tevent.tombstoneFlags = JSON.stringify({\n\t\tDisableTombstone: mc.config.getBoolean(disableTombstoneKey),\n\t\tThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),\n\t\tThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadKey),\n\t});\n\tevent.sweepFlags = JSON.stringify({\n\t\tEnableSweepFlag: mc.config.getBoolean(runSweepKey),\n\t});\n\n\tmc.logger.sendTelemetryEvent(event, error);\n}\n\n/**\n * In order to protect old documents that were created at a time when known bugs exist that violate GC's invariants\n * such that enforcing GC (Fail on Tombstone load/usage, GC Sweep) would cause legitimate data loss,\n * the container author may increment the generation value for Tombstone such that containers created\n * with a different value will not be subjected to GC enforcement.\n * If no generation is provided at runtime, this defaults to return true to maintain expected default behavior\n * @param persistedGeneration - The persisted feature support value\n * @param currentGeneration - The current app-provided feature support value\n * @returns true if GC Enforcement (Fail on Tombstone load/usage) should be allowed\n */\nexport function shouldAllowGcTombstoneEnforcement(\n\tpersistedGeneration: number | undefined,\n\tcurrentGeneration: number | undefined,\n): boolean {\n\t// If no Generation value is provided for this session, then we should default to letting Tombstone feature behave as intended.\n\tif (currentGeneration === undefined) {\n\t\treturn true;\n\t}\n\treturn persistedGeneration === currentGeneration;\n}\n\n/**\n * Sorts the given GC state as per the id of the GC nodes. It also sorts the outbound routes array of each node.\n */\nexport function generateSortedGCState(gcState: IGarbageCollectionState): IGarbageCollectionState {\n\tconst sortableArray: [string, IGarbageCollectionNodeData][] = Object.entries(gcState.gcNodes);\n\tsortableArray.sort(([a], [b]) => a.localeCompare(b));\n\tconst sortedGCState: IGarbageCollectionState = { gcNodes: {} };\n\tfor (const [nodeId, nodeData] of sortableArray) {\n\t\tnodeData.outboundRoutes.sort();\n\t\tsortedGCState.gcNodes[nodeId] = nodeData;\n\t}\n\treturn sortedGCState;\n}\n\n/**\n * This is for back-compat only - Before GC data was written at the root of the summary tree, individual GC blobs were\n * written at data store's snapshot tree. This function consolidates them into the new IGarbageCollectionState format.\n */\nexport async function getSnapshotDataFromOldSnapshotFormat(\n\toldSnapshot: ISnapshotTree,\n\tmetadata: IContainerRuntimeMetadata | undefined,\n\treadAndParseBlob: ReadAndParseBlob,\n): Promise<IGarbageCollectionSnapshotData | undefined> {\n\t// Add a node for the root node that is not present in older snapshot format.\n\tconst gcState: IGarbageCollectionState = {\n\t\tgcNodes: { \"/\": { outboundRoutes: [] } },\n\t};\n\tconst dataStoreSnapshotTree = getSummaryForDatastores(oldSnapshot, metadata);\n\tassert(\n\t\tdataStoreSnapshotTree !== undefined,\n\t\t0x2a8 /* \"Expected data store snapshot tree in base snapshot\" */,\n\t);\n\tfor (const [dsId, dsSnapshotTree] of Object.entries(dataStoreSnapshotTree.trees)) {\n\t\tconst blobId = dsSnapshotTree.blobs[gcTreeKey];\n\t\tif (blobId === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst gcSummaryDetails = await readAndParseBlob<IGarbageCollectionSummaryDetailsLegacy>(\n\t\t\tblobId,\n\t\t);\n\t\t// If there are no nodes for this data store, skip it.\n\t\tif (gcSummaryDetails.gcData?.gcNodes === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst dsRootId = `/${dsId}`;\n\t\t// Since we used to write GC data at data store level, we won't have an entry for the root (\"/\").\n\t\t// Construct that entry by adding root data store ids to its outbound routes.\n\t\tconst initialSnapshotDetails = await readAndParseBlob<ReadFluidDataStoreAttributes>(\n\t\t\tdsSnapshotTree.blobs[dataStoreAttributesBlobName],\n\t\t);\n\t\tif (initialSnapshotDetails.isRootDataStore) {\n\t\t\tgcState.gcNodes[\"/\"].outboundRoutes.push(dsRootId);\n\t\t}\n\n\t\tfor (const [id, outboundRoutes] of Object.entries(gcSummaryDetails.gcData.gcNodes)) {\n\t\t\t// Prefix the data store id to the GC node ids to make them relative to the root from being\n\t\t\t// relative to the data store. Similar to how its done in DataStore::getGCData.\n\t\t\tconst rootId = id === \"/\" ? dsRootId : `${dsRootId}${id}`;\n\t\t\tgcState.gcNodes[rootId] = {\n\t\t\t\toutboundRoutes: Array.from(outboundRoutes),\n\t\t\t};\n\t\t}\n\t\tassert(\n\t\t\tgcState.gcNodes[dsRootId] !== undefined,\n\t\t\t0x2a9 /* GC nodes for data store not in GC blob */,\n\t\t);\n\t\tgcState.gcNodes[dsRootId].unreferencedTimestampMs = gcSummaryDetails.unrefTimestamp;\n\t}\n\t// If there is only one node (root node just added above), either GC is disabled or we are loading from\n\t// the first summary generated by detached container. In both cases, GC was not run - return undefined.\n\treturn Object.keys(gcState.gcNodes).length === 1\n\t\t? undefined\n\t\t: { gcState, tombstones: undefined, deletedNodes: undefined };\n}\n"]}
|
|
@@ -14,7 +14,6 @@ import { GCVersion } from "./gcDefinitions";
|
|
|
14
14
|
*/
|
|
15
15
|
export declare class GCSummaryStateTracker {
|
|
16
16
|
private readonly shouldRunGC;
|
|
17
|
-
private readonly trackGCState;
|
|
18
17
|
private readonly tombstoneMode;
|
|
19
18
|
private readonly mc;
|
|
20
19
|
readonly currentGCVersion: GCVersion;
|
|
@@ -22,7 +21,7 @@ export declare class GCSummaryStateTracker {
|
|
|
22
21
|
private latestSummaryData;
|
|
23
22
|
private pendingSummaryData;
|
|
24
23
|
private wasGCRunInLatestSummary;
|
|
25
|
-
constructor(shouldRunGC: boolean,
|
|
24
|
+
constructor(shouldRunGC: boolean, tombstoneMode: boolean, mc: MonitoringContext, wasGCRunInBaseSnapshot: boolean, gcVersionInBaseSnapshot: GCVersion | undefined);
|
|
26
25
|
/**
|
|
27
26
|
* Tells whether the GC state needs to be reset. This can happen under 3 conditions:
|
|
28
27
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcSummaryStateTracker.d.ts","sourceRoot":"","sources":["../../src/gc/gcSummaryStateTracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAKN,8BAA8B,EAC9B,uBAAuB,EACvB,gBAAgB,EAEhB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAEN,gBAAgB,EAChB,oBAAoB,EAEpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,OAAO,EAEN,SAAS,EAGT,MAAM,iBAAiB,CAAC;AAYzB;;;;;GAKG;AACH,qBAAa,qBAAqB;IAgBhC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"gcSummaryStateTracker.d.ts","sourceRoot":"","sources":["../../src/gc/gcSummaryStateTracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAKN,8BAA8B,EAC9B,uBAAuB,EACvB,gBAAgB,EAEhB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAEN,gBAAgB,EAChB,oBAAoB,EAEpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,OAAO,EAEN,SAAS,EAGT,MAAM,iBAAiB,CAAC;AAYzB;;;;;GAKG;AACH,qBAAa,qBAAqB;IAgBhC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,EAAE;IAjBpB,SAAgB,gBAAgB,EAAE,SAAS,CAAC;IAE5C,OAAO,CAAC,sBAAsB,CAAY;IAG1C,OAAO,CAAC,iBAAiB,CAAqC;IAE9D,OAAO,CAAC,kBAAkB,CAAqC;IAG/D,OAAO,CAAC,uBAAuB,CAAU;gBAIvB,WAAW,EAAE,OAAO,EAEpB,aAAa,EAAE,OAAO,EACtB,EAAE,EAAE,iBAAiB,EAEtC,sBAAsB,EAAE,OAAO,EAE/B,uBAAuB,EAAE,SAAS,GAAG,SAAS;IAa/C;;;;;;;;;;;;;OAaG;IACI,oBAAoB,IAAI,OAAO;IAItC;;;;;;;;;;;;;;OAcG;IACI,yBAAyB,IAAI,OAAO;IAO3C;;;;;OAKG;IACI,SAAS,CACf,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,uBAAuB,EAChC,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,EACzB,UAAU,EAAE,MAAM,EAAE,GAClB,gBAAgB,GAAG,SAAS;IAgE/B;;;;;;;;;OASG;IACH,OAAO,CAAC,kBAAkB;IAsD1B;;;OAGG;IACU,oBAAoB,CAChC,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,MAAM,EAAE,oBAAoB,EAC5B,gBAAgB,EAAE,gBAAgB,GAChC,OAAO,CAAC,8BAA8B,GAAG,SAAS,CAAC;IAyCtD;;;OAGG;IACI,2BAA2B,CAAC,cAAc,EAAE,8BAA8B,GAAG,SAAS;CAc7F"}
|
|
@@ -22,8 +22,6 @@ class GCSummaryStateTracker {
|
|
|
22
22
|
constructor(
|
|
23
23
|
// Tells whether GC should run or not.
|
|
24
24
|
shouldRunGC,
|
|
25
|
-
// Tells whether GC state should be tracked across summaries or not.
|
|
26
|
-
trackGCState,
|
|
27
25
|
// Tells whether tombstone mode is enabled or not.
|
|
28
26
|
tombstoneMode, mc,
|
|
29
27
|
// Tells whether GC was run in the base snapshot this container loaded from.
|
|
@@ -31,7 +29,6 @@ class GCSummaryStateTracker {
|
|
|
31
29
|
// The GC version in the base snapshot this container loaded from.
|
|
32
30
|
gcVersionInBaseSnapshot) {
|
|
33
31
|
this.shouldRunGC = shouldRunGC;
|
|
34
|
-
this.trackGCState = trackGCState;
|
|
35
32
|
this.tombstoneMode = tombstoneMode;
|
|
36
33
|
this.mc = mc;
|
|
37
34
|
this.wasGCRunInLatestSummary = wasGCRunInBaseSnapshot;
|
|
@@ -106,30 +103,28 @@ class GCSummaryStateTracker {
|
|
|
106
103
|
* Otherwise, write the GC summary tree. In the tree, for each of these that changed, write a summary blob and
|
|
107
104
|
* for each of these that did not change, write a summary handle.
|
|
108
105
|
*/
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
// If some state changed, build a GC summary tree.
|
|
131
|
-
return this.buildGCSummaryTree(serializedGCState, serializedTombstones, serializedDeletedNodes, true /* trackState */);
|
|
106
|
+
this.pendingSummaryData = {
|
|
107
|
+
serializedGCState,
|
|
108
|
+
serializedTombstones,
|
|
109
|
+
serializedDeletedNodes,
|
|
110
|
+
};
|
|
111
|
+
if (trackState && !fullTree && this.latestSummaryData !== undefined) {
|
|
112
|
+
// If nothing changed since last summary, send a summary handle for the entire GC data.
|
|
113
|
+
if (this.latestSummaryData.serializedGCState === serializedGCState &&
|
|
114
|
+
this.latestSummaryData.serializedTombstones === serializedTombstones) {
|
|
115
|
+
const stats = (0, runtime_utils_1.mergeStats)();
|
|
116
|
+
stats.handleNodeCount++;
|
|
117
|
+
return {
|
|
118
|
+
summary: {
|
|
119
|
+
type: protocol_definitions_1.SummaryType.Handle,
|
|
120
|
+
handle: `/${runtime_definitions_1.gcTreeKey}`,
|
|
121
|
+
handleType: protocol_definitions_1.SummaryType.Tree,
|
|
122
|
+
},
|
|
123
|
+
stats,
|
|
124
|
+
};
|
|
132
125
|
}
|
|
126
|
+
// If some state changed, build a GC summary tree.
|
|
127
|
+
return this.buildGCSummaryTree(serializedGCState, serializedTombstones, serializedDeletedNodes, true /* trackState */);
|
|
133
128
|
}
|
|
134
129
|
// If not tracking GC state, build a GC summary tree without any summary handles.
|
|
135
130
|
return this.buildGCSummaryTree(serializedGCState, serializedTombstones, serializedDeletedNodes, false /* trackState */);
|
|
@@ -199,10 +194,8 @@ class GCSummaryStateTracker {
|
|
|
199
194
|
// Update latest state from pending.
|
|
200
195
|
if (result.wasSummaryTracked) {
|
|
201
196
|
this.latestSummaryGCVersion = this.currentGCVersion;
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
this.pendingSummaryData = undefined;
|
|
205
|
-
}
|
|
197
|
+
this.latestSummaryData = this.pendingSummaryData;
|
|
198
|
+
this.pendingSummaryData = undefined;
|
|
206
199
|
return undefined;
|
|
207
200
|
}
|
|
208
201
|
// If the summary was not tracked by this client, the state should be updated from the downloaded snapshot.
|
|
@@ -233,13 +226,11 @@ class GCSummaryStateTracker {
|
|
|
233
226
|
return;
|
|
234
227
|
}
|
|
235
228
|
// If tracking state across summaries, update latest summary data from the snapshot's GC data.
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
};
|
|
242
|
-
}
|
|
229
|
+
this.latestSummaryData = {
|
|
230
|
+
serializedGCState: JSON.stringify((0, gcHelpers_1.generateSortedGCState)(gcSnapshotData.gcState)),
|
|
231
|
+
serializedTombstones: JSON.stringify(gcSnapshotData.tombstones),
|
|
232
|
+
serializedDeletedNodes: JSON.stringify(gcSnapshotData.deletedNodes),
|
|
233
|
+
};
|
|
243
234
|
}
|
|
244
235
|
}
|
|
245
236
|
exports.GCSummaryStateTracker = GCSummaryStateTracker;
|