@fluidframework/container-runtime 2.0.0-internal.3.4.1 → 2.0.0-internal.3.4.3

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.
@@ -2,11 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { assert } from "@fluidframework/common-utils";
6
- import { gcTreeKey, } from "@fluidframework/runtime-definitions";
7
5
  import { packagePathToTelemetryProperty } from "@fluidframework/runtime-utils";
8
- import { getSummaryForDatastores } from "../dataStores";
9
- import { dataStoreAttributesBlobName, } from "../summary";
10
6
  import { disableTombstoneKey, runSweepKey, throwOnTombstoneLoadKey, throwOnTombstoneUsageKey, } from "./gcDefinitions";
11
7
  export function getGCVersion(metadata) {
12
8
  var _a;
@@ -94,50 +90,4 @@ export function generateSortedGCState(gcState) {
94
90
  }
95
91
  return sortedGCState;
96
92
  }
97
- /**
98
- * This is for back-compat only - Before GC data was written at the root of the summary tree, individual GC blobs were
99
- * written at data store's snapshot tree. This function consolidates them into the new IGarbageCollectionState format.
100
- */
101
- export async function getSnapshotDataFromOldSnapshotFormat(oldSnapshot, metadata, readAndParseBlob) {
102
- var _a;
103
- // Add a node for the root node that is not present in older snapshot format.
104
- const gcState = {
105
- gcNodes: { "/": { outboundRoutes: [] } },
106
- };
107
- const dataStoreSnapshotTree = getSummaryForDatastores(oldSnapshot, metadata);
108
- assert(dataStoreSnapshotTree !== undefined, 0x2a8 /* "Expected data store snapshot tree in base snapshot" */);
109
- for (const [dsId, dsSnapshotTree] of Object.entries(dataStoreSnapshotTree.trees)) {
110
- const blobId = dsSnapshotTree.blobs[gcTreeKey];
111
- if (blobId === undefined) {
112
- continue;
113
- }
114
- const gcSummaryDetails = await readAndParseBlob(blobId);
115
- // If there are no nodes for this data store, skip it.
116
- if (((_a = gcSummaryDetails.gcData) === null || _a === void 0 ? void 0 : _a.gcNodes) === undefined) {
117
- continue;
118
- }
119
- const dsRootId = `/${dsId}`;
120
- // Since we used to write GC data at data store level, we won't have an entry for the root ("/").
121
- // Construct that entry by adding root data store ids to its outbound routes.
122
- const initialSnapshotDetails = await readAndParseBlob(dsSnapshotTree.blobs[dataStoreAttributesBlobName]);
123
- if (initialSnapshotDetails.isRootDataStore) {
124
- gcState.gcNodes["/"].outboundRoutes.push(dsRootId);
125
- }
126
- for (const [id, outboundRoutes] of Object.entries(gcSummaryDetails.gcData.gcNodes)) {
127
- // Prefix the data store id to the GC node ids to make them relative to the root from being
128
- // relative to the data store. Similar to how its done in DataStore::getGCData.
129
- const rootId = id === "/" ? dsRootId : `${dsRootId}${id}`;
130
- gcState.gcNodes[rootId] = {
131
- outboundRoutes: Array.from(outboundRoutes),
132
- };
133
- }
134
- assert(gcState.gcNodes[dsRootId] !== undefined, 0x2a9 /* GC nodes for data store not in GC blob */);
135
- gcState.gcNodes[dsRootId].unreferencedTimestampMs = gcSummaryDetails.unrefTimestamp;
136
- }
137
- // If there is only one node (root node just added above), either GC is disabled or we are loading from
138
- // the first summary generated by detached container. In both cases, GC was not run - return undefined.
139
- return Object.keys(gcState.gcNodes).length === 1
140
- ? undefined
141
- : { gcState, tombstones: undefined, deletedNodes: undefined };
142
- }
143
93
  //# sourceMappingURL=gcHelpers.js.map
@@ -1 +1 @@
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\tGCFeatureMatrix,\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 * Indicates whether Tombstone Enforcement is allowed for this document based on the current/persisted\n * TombstoneGeneration values\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 Tombstone (Failing on Tombstone load/usage) 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 *\n * If no generation is provided at runtime, this defaults to return true to maintain expected default behavior\n *\n * @param persistedGeneration - The persisted tombstoneGeneration value\n * @param currentGeneration - The current app-provided tombstoneGeneration value\n * @returns true if GC Tombstone enforcement (Fail on Tombstone load/usage) should be allowed for this document\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 * Indicates whether Sweep is allowed for this document based on the GC Feature Matrix and current SweepGeneration\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 Sweep would cause legitimate data loss, the container author may increment the generation value for Sweep\n * such that containers created with a different value will not be subjected to GC Sweep.\n *\n * If no generation is provided, Sweep will be disabled.\n * Passing 0 is a special case: Sweep will be enabled for any document with gcSweepGeneration OR gcTombstoneGeneration as 0.\n *\n * @param persistedGenerations - The persisted sweep/tombstone generations from the GC Feature Matrix\n * @param currentGeneration - The current app-provided sweepGeneration value\n * @returns true if GC Sweep should be allowed for this document\n */\nexport function shouldAllowGcSweep(\n\tpersistedGenerations: Pick<GCFeatureMatrix, \"sweepGeneration\" | \"tombstoneGeneration\">,\n\tcurrentGeneration: number | undefined,\n): boolean {\n\t// If no Generation value is provided for this session, default to false\n\tif (currentGeneration === undefined) {\n\t\treturn false;\n\t}\n\n\t// 0 is a special case: It matches both SweepGeneration and TombstoneGeneration\n\t// This is an optimistic measure to maximize coverage of GC Sweep if no bumps to TombstoneGeneration are needed before enabling Sweep.\n\tif (currentGeneration === 0) {\n\t\treturn (\n\t\t\tpersistedGenerations.sweepGeneration === 0 ||\n\t\t\tpersistedGenerations.tombstoneGeneration === 0\n\t\t);\n\t}\n\n\treturn persistedGenerations.sweepGeneration === 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"]}
1
+ {"version":3,"file":"gcHelpers.js","sourceRoot":"","sources":["../../src/gc/gcHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAE/E,OAAO,EACN,mBAAmB,EAInB,WAAW,EACX,uBAAuB,EACvB,wBAAwB,GACxB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,UAAU,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;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CACzC,EAAqB,EACrB,KAGC,EACD,WAA0C,EAC1C,KAAe;IAEf,KAAK,CAAC,GAAG,GAAG,8BAA8B,CAAC,WAAW,CAAC,CAAC;IACxD,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;QACrC,gBAAgB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC;QAC3D,qBAAqB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,wBAAwB,CAAC;QACrE,oBAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,uBAAuB,CAAC;KACnE,CAAC,CAAC;IACH,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,eAAe,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC;KAClD,CAAC,CAAC;IAEH,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,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;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kBAAkB,CACjC,oBAAsF,EACtF,iBAAqC;IAErC,wEAAwE;IACxE,IAAI,iBAAiB,KAAK,SAAS,EAAE;QACpC,OAAO,KAAK,CAAC;KACb;IAED,+EAA+E;IAC/E,sIAAsI;IACtI,IAAI,iBAAiB,KAAK,CAAC,EAAE;QAC5B,OAAO,CACN,oBAAoB,CAAC,eAAe,KAAK,CAAC;YAC1C,oBAAoB,CAAC,mBAAmB,KAAK,CAAC,CAC9C,CAAC;KACF;IAED,OAAO,oBAAoB,CAAC,eAAe,KAAK,iBAAiB,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,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","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\tGCFeatureMatrix,\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 * Indicates whether Tombstone Enforcement is allowed for this document based on the current/persisted\n * TombstoneGeneration values\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 Tombstone (Failing on Tombstone load/usage) 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 *\n * If no generation is provided at runtime, this defaults to return true to maintain expected default behavior\n *\n * @param persistedGeneration - The persisted tombstoneGeneration value\n * @param currentGeneration - The current app-provided tombstoneGeneration value\n * @returns true if GC Tombstone enforcement (Fail on Tombstone load/usage) should be allowed for this document\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 * Indicates whether Sweep is allowed for this document based on the GC Feature Matrix and current SweepGeneration\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 Sweep would cause legitimate data loss, the container author may increment the generation value for Sweep\n * such that containers created with a different value will not be subjected to GC Sweep.\n *\n * If no generation is provided, Sweep will be disabled.\n * Passing 0 is a special case: Sweep will be enabled for any document with gcSweepGeneration OR gcTombstoneGeneration as 0.\n *\n * @param persistedGenerations - The persisted sweep/tombstone generations from the GC Feature Matrix\n * @param currentGeneration - The current app-provided sweepGeneration value\n * @returns true if GC Sweep should be allowed for this document\n */\nexport function shouldAllowGcSweep(\n\tpersistedGenerations: Pick<GCFeatureMatrix, \"sweepGeneration\" | \"tombstoneGeneration\">,\n\tcurrentGeneration: number | undefined,\n): boolean {\n\t// If no Generation value is provided for this session, default to false\n\tif (currentGeneration === undefined) {\n\t\treturn false;\n\t}\n\n\t// 0 is a special case: It matches both SweepGeneration and TombstoneGeneration\n\t// This is an optimistic measure to maximize coverage of GC Sweep if no bumps to TombstoneGeneration are needed before enabling Sweep.\n\tif (currentGeneration === 0) {\n\t\treturn (\n\t\t\tpersistedGenerations.sweepGeneration === 0 ||\n\t\t\tpersistedGenerations.tombstoneGeneration === 0\n\t\t);\n\t}\n\n\treturn persistedGenerations.sweepGeneration === 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"]}
package/lib/gc/index.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  export { GarbageCollector } from "./garbageCollection";
6
6
  export { currentGCVersion, defaultInactiveTimeoutMs, defaultSessionExpiryDurationMs, disableSweepLogKey, GCNodeType, gcTestModeKey, gcTombstoneGenerationOptionName, gcSweepGenerationOptionName, GCFeatureMatrix, GCVersion, gcVersionUpgradeToV2Key, IGarbageCollectionRuntime, // Deprecated
7
7
  IGarbageCollector, IGarbageCollectorConfigs, IGarbageCollectorCreateParams, IGCMetadata, IGCRuntimeOptions, IGCStats, oneDayMs, runGCKey, runSessionExpiryKey, runSweepKey, stableGCVersion, sweepAttachmentBlobsKey, sweepDatastoresKey, throwOnTombstoneLoadKey, throwOnTombstoneUsageKey, UnreferencedState, } from "./gcDefinitions";
8
- export { getSnapshotDataFromOldSnapshotFormat, sendGCUnexpectedUsageEvent, shouldAllowGcTombstoneEnforcement, shouldAllowGcSweep, } from "./gcHelpers";
8
+ export { sendGCUnexpectedUsageEvent, shouldAllowGcTombstoneEnforcement, shouldAllowGcSweep, } from "./gcHelpers";
9
9
  export { GCSummaryStateTracker } from "./gcSummaryStateTracker";
10
10
  export { skipClosureForXDaysKey, closuresMapLocalStorageKey, SweepReadyUsageDetectionHandler, } from "./gcSweepReadyUsageDetection";
11
11
  export { UnreferencedStateTracker } from "./gcUnreferencedStateTracker";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,8BAA8B,EAC9B,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,+BAA+B,EAC/B,2BAA2B,EAC3B,eAAe,EACf,SAAS,EACT,uBAAuB,EACvB,yBAAyB,EAAE,aAAa;AACxC,iBAAiB,EACjB,wBAAwB,EACxB,6BAA6B,EAC7B,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,oCAAoC,EACpC,0BAA0B,EAC1B,iCAAiC,EACjC,kBAAkB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACN,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,GAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,8BAA8B,EAC9B,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,+BAA+B,EAC/B,2BAA2B,EAC3B,eAAe,EACf,SAAS,EACT,uBAAuB,EACvB,yBAAyB,EAAE,aAAa;AACxC,iBAAiB,EACjB,wBAAwB,EACxB,6BAA6B,EAC7B,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,0BAA0B,EAC1B,iCAAiC,EACjC,kBAAkB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACN,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,GAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC"}
package/lib/gc/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export { GarbageCollector } from "./garbageCollection";
6
6
  export { currentGCVersion, defaultInactiveTimeoutMs, defaultSessionExpiryDurationMs, disableSweepLogKey, GCNodeType, gcTestModeKey, gcTombstoneGenerationOptionName, gcSweepGenerationOptionName, gcVersionUpgradeToV2Key, oneDayMs, runGCKey, runSessionExpiryKey, runSweepKey, stableGCVersion, sweepAttachmentBlobsKey, sweepDatastoresKey, throwOnTombstoneLoadKey, throwOnTombstoneUsageKey, UnreferencedState, } from "./gcDefinitions";
7
- export { getSnapshotDataFromOldSnapshotFormat, sendGCUnexpectedUsageEvent, shouldAllowGcTombstoneEnforcement, shouldAllowGcSweep, } from "./gcHelpers";
7
+ export { sendGCUnexpectedUsageEvent, shouldAllowGcTombstoneEnforcement, shouldAllowGcSweep, } from "./gcHelpers";
8
8
  export { GCSummaryStateTracker } from "./gcSummaryStateTracker";
9
9
  export { skipClosureForXDaysKey, closuresMapLocalStorageKey, SweepReadyUsageDetectionHandler, } from "./gcSweepReadyUsageDetection";
10
10
  export { UnreferencedStateTracker } from "./gcUnreferencedStateTracker";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,8BAA8B,EAC9B,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,+BAA+B,EAC/B,2BAA2B,EAG3B,uBAAuB,EAQvB,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,oCAAoC,EACpC,0BAA0B,EAC1B,iCAAiC,EACjC,kBAAkB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACN,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,GAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { GarbageCollector } from \"./garbageCollection\";\nexport {\n\tcurrentGCVersion,\n\tdefaultInactiveTimeoutMs,\n\tdefaultSessionExpiryDurationMs,\n\tdisableSweepLogKey,\n\tGCNodeType,\n\tgcTestModeKey,\n\tgcTombstoneGenerationOptionName,\n\tgcSweepGenerationOptionName,\n\tGCFeatureMatrix,\n\tGCVersion,\n\tgcVersionUpgradeToV2Key,\n\tIGarbageCollectionRuntime, // Deprecated\n\tIGarbageCollector,\n\tIGarbageCollectorConfigs,\n\tIGarbageCollectorCreateParams,\n\tIGCMetadata,\n\tIGCRuntimeOptions,\n\tIGCStats,\n\toneDayMs,\n\trunGCKey,\n\trunSessionExpiryKey,\n\trunSweepKey,\n\tstableGCVersion,\n\tsweepAttachmentBlobsKey,\n\tsweepDatastoresKey,\n\tthrowOnTombstoneLoadKey,\n\tthrowOnTombstoneUsageKey,\n\tUnreferencedState,\n} from \"./gcDefinitions\";\nexport {\n\tgetSnapshotDataFromOldSnapshotFormat,\n\tsendGCUnexpectedUsageEvent,\n\tshouldAllowGcTombstoneEnforcement,\n\tshouldAllowGcSweep,\n} from \"./gcHelpers\";\nexport { GCSummaryStateTracker } from \"./gcSummaryStateTracker\";\nexport {\n\tskipClosureForXDaysKey,\n\tclosuresMapLocalStorageKey,\n\tSweepReadyUsageDetectionHandler,\n} from \"./gcSweepReadyUsageDetection\";\nexport { UnreferencedStateTracker } from \"./gcUnreferencedStateTracker\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,8BAA8B,EAC9B,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,+BAA+B,EAC/B,2BAA2B,EAG3B,uBAAuB,EAQvB,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,0BAA0B,EAC1B,iCAAiC,EACjC,kBAAkB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACN,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,GAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { GarbageCollector } from \"./garbageCollection\";\nexport {\n\tcurrentGCVersion,\n\tdefaultInactiveTimeoutMs,\n\tdefaultSessionExpiryDurationMs,\n\tdisableSweepLogKey,\n\tGCNodeType,\n\tgcTestModeKey,\n\tgcTombstoneGenerationOptionName,\n\tgcSweepGenerationOptionName,\n\tGCFeatureMatrix,\n\tGCVersion,\n\tgcVersionUpgradeToV2Key,\n\tIGarbageCollectionRuntime, // Deprecated\n\tIGarbageCollector,\n\tIGarbageCollectorConfigs,\n\tIGarbageCollectorCreateParams,\n\tIGCMetadata,\n\tIGCRuntimeOptions,\n\tIGCStats,\n\toneDayMs,\n\trunGCKey,\n\trunSessionExpiryKey,\n\trunSweepKey,\n\tstableGCVersion,\n\tsweepAttachmentBlobsKey,\n\tsweepDatastoresKey,\n\tthrowOnTombstoneLoadKey,\n\tthrowOnTombstoneUsageKey,\n\tUnreferencedState,\n} from \"./gcDefinitions\";\nexport {\n\tsendGCUnexpectedUsageEvent,\n\tshouldAllowGcTombstoneEnforcement,\n\tshouldAllowGcSweep,\n} from \"./gcHelpers\";\nexport { GCSummaryStateTracker } from \"./gcSummaryStateTracker\";\nexport {\n\tskipClosureForXDaysKey,\n\tclosuresMapLocalStorageKey,\n\tSweepReadyUsageDetectionHandler,\n} from \"./gcSweepReadyUsageDetection\";\nexport { UnreferencedStateTracker } from \"./gcUnreferencedStateTracker\";\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/container-runtime";
8
- export declare const pkgVersion = "2.0.0-internal.3.4.1";
8
+ export declare const pkgVersion = "2.0.0-internal.3.4.3";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/container-runtime";
8
- export const pkgVersion = "2.0.0-internal.3.4.1";
8
+ export const pkgVersion = "2.0.0-internal.3.4.3";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,mCAAmC,CAAC;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-internal.3.4.1\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,mCAAmC,CAAC;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-internal.3.4.3\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-runtime",
3
- "version": "2.0.0-internal.3.4.1",
3
+ "version": "2.0.0-internal.3.4.3",
4
4
  "description": "Fluid container runtime",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -37,19 +37,19 @@
37
37
  "dependencies": {
38
38
  "@fluidframework/common-definitions": "^0.20.1",
39
39
  "@fluidframework/common-utils": "^1.1.1",
40
- "@fluidframework/container-definitions": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
41
- "@fluidframework/container-runtime-definitions": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
42
- "@fluidframework/container-utils": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
43
- "@fluidframework/core-interfaces": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
44
- "@fluidframework/datastore": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
45
- "@fluidframework/driver-definitions": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
46
- "@fluidframework/driver-utils": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
47
- "@fluidframework/garbage-collector": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
40
+ "@fluidframework/container-definitions": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
41
+ "@fluidframework/container-runtime-definitions": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
42
+ "@fluidframework/container-utils": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
43
+ "@fluidframework/core-interfaces": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
44
+ "@fluidframework/datastore": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
45
+ "@fluidframework/driver-definitions": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
46
+ "@fluidframework/driver-utils": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
47
+ "@fluidframework/garbage-collector": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
48
48
  "@fluidframework/protocol-base": "^0.1038.4000",
49
49
  "@fluidframework/protocol-definitions": "^1.1.0",
50
- "@fluidframework/runtime-definitions": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
51
- "@fluidframework/runtime-utils": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
52
- "@fluidframework/telemetry-utils": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
50
+ "@fluidframework/runtime-definitions": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
51
+ "@fluidframework/runtime-utils": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
52
+ "@fluidframework/telemetry-utils": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
53
53
  "double-ended-queue": "^2.1.0-0",
54
54
  "events": "^3.1.0",
55
55
  "lz4js": "^0.2.0",
@@ -61,8 +61,8 @@
61
61
  "@fluidframework/build-tools": "^0.13.0",
62
62
  "@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-internal.3.2.0",
63
63
  "@fluidframework/eslint-config-fluid": "^2.0.0",
64
- "@fluidframework/mocha-test-setup": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
65
- "@fluidframework/test-runtime-utils": ">=2.0.0-internal.3.4.1 <2.0.0-internal.4.0.0",
64
+ "@fluidframework/mocha-test-setup": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
65
+ "@fluidframework/test-runtime-utils": ">=2.0.0-internal.3.4.3 <2.0.0-internal.4.0.0",
66
66
  "@microsoft/api-extractor": "^7.34.4",
67
67
  "@types/double-ended-queue": "^2.1.0",
68
68
  "@types/events": "^3.0.0",
@@ -52,9 +52,8 @@ import {
52
52
  IGCMetadata,
53
53
  IGarbageCollectorConfigs,
54
54
  } from "./gcDefinitions";
55
- import { getSnapshotDataFromOldSnapshotFormat, sendGCUnexpectedUsageEvent } from "./gcHelpers";
55
+ import { sendGCUnexpectedUsageEvent } from "./gcHelpers";
56
56
  import { GCSummaryStateTracker } from "./gcSummaryStateTracker";
57
- import { SweepReadyUsageDetectionHandler } from "./gcSweepReadyUsageDetection";
58
57
  import { UnreferencedStateTracker } from "./gcUnreferencedStateTracker";
59
58
 
60
59
  /** The event that is logged when unreferenced node is used after a certain time. */
@@ -156,9 +155,6 @@ export class GarbageCollector implements IGarbageCollector {
156
155
  return this.summaryStateTracker.doesSummaryStateNeedReset;
157
156
  }
158
157
 
159
- /** Handler to respond to when a SweepReady object is used */
160
- private readonly sweepReadyUsageHandler: SweepReadyUsageDetectionHandler;
161
-
162
158
  protected constructor(createParams: IGarbageCollectorCreateParams) {
163
159
  this.runtime = createParams.runtime;
164
160
  this.isSummarizerClient = createParams.isSummarizerClient;
@@ -176,12 +172,6 @@ export class GarbageCollector implements IGarbageCollector {
176
172
  }),
177
173
  );
178
174
 
179
- this.sweepReadyUsageHandler = new SweepReadyUsageDetectionHandler(
180
- createParams.getContainerDiagnosticId(),
181
- this.mc,
182
- this.runtime.closeFn,
183
- );
184
-
185
175
  this.configs = generateGCConfigs(this.mc, createParams);
186
176
 
187
177
  // If session expiry is enabled, we need to close the container when the session expiry timeout expires.
@@ -220,12 +210,9 @@ export class GarbageCollector implements IGarbageCollector {
220
210
  return getGCDataFromSnapshot(gcSnapshotTree, readAndParseBlob);
221
211
  }
222
212
 
223
- // back-compat - Older documents will have the GC blobs in each data store's snapshot tree.
224
- return getSnapshotDataFromOldSnapshotFormat(
225
- baseSnapshot,
226
- createParams.metadata,
227
- readAndParseBlob,
228
- );
213
+ // back-compat - Older documents get their gc data reset for simplicity as there are few of them
214
+ // incremental gc summary will not work with older gc data as well
215
+ return undefined;
229
216
  } catch (error) {
230
217
  const dpe = DataProcessingError.wrapIfUnrecognized(
231
218
  error,
@@ -1203,16 +1190,6 @@ export class GarbageCollector implements IGarbageCollector {
1203
1190
  this.mc.logger.sendErrorEvent(event);
1204
1191
  }
1205
1192
  }
1206
-
1207
- // If SweepReady Usage Detection is enabled, the handler may close the interactive container.
1208
- // Once Sweep is fully implemented, this will be removed since the objects will be gone
1209
- // and errors will arise elsewhere in the runtime
1210
- if (state === UnreferencedState.SweepReady) {
1211
- this.sweepReadyUsageHandler.usageDetectedInInteractiveClient({
1212
- ...propsToLog,
1213
- usageType,
1214
- });
1215
- }
1216
1193
  }
1217
1194
  }
1218
1195
 
@@ -4,23 +4,12 @@
4
4
  */
5
5
 
6
6
  import { ITelemetryGenericEvent } from "@fluidframework/common-definitions";
7
- import { assert } from "@fluidframework/common-utils";
8
- import { ISnapshotTree } from "@fluidframework/protocol-definitions";
9
7
  import {
10
- gcTreeKey,
11
8
  IGarbageCollectionNodeData,
12
- IGarbageCollectionSnapshotData,
13
9
  IGarbageCollectionState,
14
- IGarbageCollectionSummaryDetailsLegacy,
15
10
  } from "@fluidframework/runtime-definitions";
16
- import { packagePathToTelemetryProperty, ReadAndParseBlob } from "@fluidframework/runtime-utils";
11
+ import { packagePathToTelemetryProperty } from "@fluidframework/runtime-utils";
17
12
  import { MonitoringContext } from "@fluidframework/telemetry-utils";
18
- import { getSummaryForDatastores } from "../dataStores";
19
- import {
20
- dataStoreAttributesBlobName,
21
- IContainerRuntimeMetadata,
22
- ReadFluidDataStoreAttributes,
23
- } from "../summary";
24
13
  import {
25
14
  disableTombstoneKey,
26
15
  GCFeatureMatrix,
@@ -139,66 +128,3 @@ export function generateSortedGCState(gcState: IGarbageCollectionState): IGarbag
139
128
  }
140
129
  return sortedGCState;
141
130
  }
142
-
143
- /**
144
- * This is for back-compat only - Before GC data was written at the root of the summary tree, individual GC blobs were
145
- * written at data store's snapshot tree. This function consolidates them into the new IGarbageCollectionState format.
146
- */
147
- export async function getSnapshotDataFromOldSnapshotFormat(
148
- oldSnapshot: ISnapshotTree,
149
- metadata: IContainerRuntimeMetadata | undefined,
150
- readAndParseBlob: ReadAndParseBlob,
151
- ): Promise<IGarbageCollectionSnapshotData | undefined> {
152
- // Add a node for the root node that is not present in older snapshot format.
153
- const gcState: IGarbageCollectionState = {
154
- gcNodes: { "/": { outboundRoutes: [] } },
155
- };
156
- const dataStoreSnapshotTree = getSummaryForDatastores(oldSnapshot, metadata);
157
- assert(
158
- dataStoreSnapshotTree !== undefined,
159
- 0x2a8 /* "Expected data store snapshot tree in base snapshot" */,
160
- );
161
- for (const [dsId, dsSnapshotTree] of Object.entries(dataStoreSnapshotTree.trees)) {
162
- const blobId = dsSnapshotTree.blobs[gcTreeKey];
163
- if (blobId === undefined) {
164
- continue;
165
- }
166
-
167
- const gcSummaryDetails = await readAndParseBlob<IGarbageCollectionSummaryDetailsLegacy>(
168
- blobId,
169
- );
170
- // If there are no nodes for this data store, skip it.
171
- if (gcSummaryDetails.gcData?.gcNodes === undefined) {
172
- continue;
173
- }
174
-
175
- const dsRootId = `/${dsId}`;
176
- // Since we used to write GC data at data store level, we won't have an entry for the root ("/").
177
- // Construct that entry by adding root data store ids to its outbound routes.
178
- const initialSnapshotDetails = await readAndParseBlob<ReadFluidDataStoreAttributes>(
179
- dsSnapshotTree.blobs[dataStoreAttributesBlobName],
180
- );
181
- if (initialSnapshotDetails.isRootDataStore) {
182
- gcState.gcNodes["/"].outboundRoutes.push(dsRootId);
183
- }
184
-
185
- for (const [id, outboundRoutes] of Object.entries(gcSummaryDetails.gcData.gcNodes)) {
186
- // Prefix the data store id to the GC node ids to make them relative to the root from being
187
- // relative to the data store. Similar to how its done in DataStore::getGCData.
188
- const rootId = id === "/" ? dsRootId : `${dsRootId}${id}`;
189
- gcState.gcNodes[rootId] = {
190
- outboundRoutes: Array.from(outboundRoutes),
191
- };
192
- }
193
- assert(
194
- gcState.gcNodes[dsRootId] !== undefined,
195
- 0x2a9 /* GC nodes for data store not in GC blob */,
196
- );
197
- gcState.gcNodes[dsRootId].unreferencedTimestampMs = gcSummaryDetails.unrefTimestamp;
198
- }
199
- // If there is only one node (root node just added above), either GC is disabled or we are loading from
200
- // the first summary generated by detached container. In both cases, GC was not run - return undefined.
201
- return Object.keys(gcState.gcNodes).length === 1
202
- ? undefined
203
- : { gcState, tombstones: undefined, deletedNodes: undefined };
204
- }
package/src/gc/index.ts CHANGED
@@ -35,7 +35,6 @@ export {
35
35
  UnreferencedState,
36
36
  } from "./gcDefinitions";
37
37
  export {
38
- getSnapshotDataFromOldSnapshotFormat,
39
38
  sendGCUnexpectedUsageEvent,
40
39
  shouldAllowGcTombstoneEnforcement,
41
40
  shouldAllowGcSweep,
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.0.0-internal.3.4.1";
9
+ export const pkgVersion = "2.0.0-internal.3.4.3";