@fluidframework/container-runtime 2.1.0-276985 → 2.1.0-281041

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.
Files changed (196) hide show
  1. package/README.md +71 -18
  2. package/api-extractor/api-extractor.current.json +5 -0
  3. package/api-extractor/api-extractor.legacy.json +1 -1
  4. package/api-extractor.json +1 -1
  5. package/api-report/container-runtime.legacy.public.api.md +9 -0
  6. package/container-runtime.test-files.tar +0 -0
  7. package/dist/blobManager/blobManager.d.ts +10 -0
  8. package/dist/blobManager/blobManager.d.ts.map +1 -1
  9. package/dist/blobManager/blobManager.js +19 -0
  10. package/dist/blobManager/blobManager.js.map +1 -1
  11. package/dist/channelCollection.d.ts +1 -1
  12. package/dist/channelCollection.d.ts.map +1 -1
  13. package/dist/channelCollection.js +40 -8
  14. package/dist/channelCollection.js.map +1 -1
  15. package/dist/containerRuntime.d.ts +14 -5
  16. package/dist/containerRuntime.d.ts.map +1 -1
  17. package/dist/containerRuntime.js +142 -98
  18. package/dist/containerRuntime.js.map +1 -1
  19. package/dist/dataStoreContext.d.ts +4 -0
  20. package/dist/dataStoreContext.d.ts.map +1 -1
  21. package/dist/dataStoreContext.js +9 -3
  22. package/dist/dataStoreContext.js.map +1 -1
  23. package/dist/gc/garbageCollection.d.ts +1 -1
  24. package/dist/gc/garbageCollection.d.ts.map +1 -1
  25. package/dist/gc/garbageCollection.js +14 -8
  26. package/dist/gc/garbageCollection.js.map +1 -1
  27. package/dist/gc/gcDefinitions.d.ts +4 -2
  28. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  29. package/dist/gc/gcDefinitions.js.map +1 -1
  30. package/dist/gc/gcHelpers.d.ts.map +1 -1
  31. package/dist/gc/gcHelpers.js +12 -0
  32. package/dist/gc/gcHelpers.js.map +1 -1
  33. package/dist/gc/gcTelemetry.d.ts +3 -2
  34. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  35. package/dist/gc/gcTelemetry.js +6 -6
  36. package/dist/gc/gcTelemetry.js.map +1 -1
  37. package/dist/legacy.d.ts +1 -1
  38. package/dist/metadata.d.ts +7 -1
  39. package/dist/metadata.d.ts.map +1 -1
  40. package/dist/metadata.js +6 -0
  41. package/dist/metadata.js.map +1 -1
  42. package/dist/opLifecycle/batchManager.d.ts +8 -1
  43. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  44. package/dist/opLifecycle/batchManager.js +37 -16
  45. package/dist/opLifecycle/batchManager.js.map +1 -1
  46. package/dist/opLifecycle/definitions.d.ts +1 -1
  47. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  48. package/dist/opLifecycle/definitions.js.map +1 -1
  49. package/dist/opLifecycle/index.d.ts +1 -1
  50. package/dist/opLifecycle/index.d.ts.map +1 -1
  51. package/dist/opLifecycle/index.js +2 -1
  52. package/dist/opLifecycle/index.js.map +1 -1
  53. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  54. package/dist/opLifecycle/opCompressor.js +12 -8
  55. package/dist/opLifecycle/opCompressor.js.map +1 -1
  56. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  57. package/dist/opLifecycle/opGroupingManager.js +14 -11
  58. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  59. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  60. package/dist/opLifecycle/opSplitter.js +11 -6
  61. package/dist/opLifecycle/opSplitter.js.map +1 -1
  62. package/dist/opLifecycle/outbox.d.ts +22 -6
  63. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  64. package/dist/opLifecycle/outbox.js +43 -21
  65. package/dist/opLifecycle/outbox.js.map +1 -1
  66. package/dist/opLifecycle/remoteMessageProcessor.d.ts +6 -6
  67. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  68. package/dist/opLifecycle/remoteMessageProcessor.js +18 -6
  69. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  70. package/dist/packageVersion.d.ts +1 -1
  71. package/dist/packageVersion.js +1 -1
  72. package/dist/packageVersion.js.map +1 -1
  73. package/dist/pendingStateManager.d.ts +37 -13
  74. package/dist/pendingStateManager.d.ts.map +1 -1
  75. package/dist/pendingStateManager.js +95 -45
  76. package/dist/pendingStateManager.js.map +1 -1
  77. package/dist/public.d.ts +1 -1
  78. package/dist/scheduleManager.js +4 -0
  79. package/dist/scheduleManager.js.map +1 -1
  80. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  81. package/dist/summary/summarizerNode/summarizerNodeUtils.js +2 -0
  82. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  83. package/dist/summary/summaryFormat.d.ts.map +1 -1
  84. package/dist/summary/summaryFormat.js +4 -1
  85. package/dist/summary/summaryFormat.js.map +1 -1
  86. package/internal.d.ts +1 -1
  87. package/legacy.d.ts +1 -1
  88. package/lib/blobManager/blobManager.d.ts +10 -0
  89. package/lib/blobManager/blobManager.d.ts.map +1 -1
  90. package/lib/blobManager/blobManager.js +19 -0
  91. package/lib/blobManager/blobManager.js.map +1 -1
  92. package/lib/channelCollection.d.ts +1 -1
  93. package/lib/channelCollection.d.ts.map +1 -1
  94. package/lib/channelCollection.js +40 -8
  95. package/lib/channelCollection.js.map +1 -1
  96. package/lib/containerRuntime.d.ts +14 -5
  97. package/lib/containerRuntime.d.ts.map +1 -1
  98. package/lib/containerRuntime.js +142 -98
  99. package/lib/containerRuntime.js.map +1 -1
  100. package/lib/dataStoreContext.d.ts +4 -0
  101. package/lib/dataStoreContext.d.ts.map +1 -1
  102. package/lib/dataStoreContext.js +10 -4
  103. package/lib/dataStoreContext.js.map +1 -1
  104. package/lib/gc/garbageCollection.d.ts +1 -1
  105. package/lib/gc/garbageCollection.d.ts.map +1 -1
  106. package/lib/gc/garbageCollection.js +14 -8
  107. package/lib/gc/garbageCollection.js.map +1 -1
  108. package/lib/gc/gcDefinitions.d.ts +4 -2
  109. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  110. package/lib/gc/gcDefinitions.js.map +1 -1
  111. package/lib/gc/gcHelpers.d.ts.map +1 -1
  112. package/lib/gc/gcHelpers.js +12 -0
  113. package/lib/gc/gcHelpers.js.map +1 -1
  114. package/lib/gc/gcTelemetry.d.ts +3 -2
  115. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  116. package/lib/gc/gcTelemetry.js +6 -6
  117. package/lib/gc/gcTelemetry.js.map +1 -1
  118. package/lib/legacy.d.ts +1 -1
  119. package/lib/metadata.d.ts +7 -1
  120. package/lib/metadata.d.ts.map +1 -1
  121. package/lib/metadata.js +4 -1
  122. package/lib/metadata.js.map +1 -1
  123. package/lib/opLifecycle/batchManager.d.ts +8 -1
  124. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  125. package/lib/opLifecycle/batchManager.js +35 -15
  126. package/lib/opLifecycle/batchManager.js.map +1 -1
  127. package/lib/opLifecycle/definitions.d.ts +1 -1
  128. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  129. package/lib/opLifecycle/definitions.js.map +1 -1
  130. package/lib/opLifecycle/index.d.ts +1 -1
  131. package/lib/opLifecycle/index.d.ts.map +1 -1
  132. package/lib/opLifecycle/index.js +1 -1
  133. package/lib/opLifecycle/index.js.map +1 -1
  134. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  135. package/lib/opLifecycle/opCompressor.js +12 -8
  136. package/lib/opLifecycle/opCompressor.js.map +1 -1
  137. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  138. package/lib/opLifecycle/opGroupingManager.js +14 -11
  139. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  140. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  141. package/lib/opLifecycle/opSplitter.js +11 -6
  142. package/lib/opLifecycle/opSplitter.js.map +1 -1
  143. package/lib/opLifecycle/outbox.d.ts +22 -6
  144. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  145. package/lib/opLifecycle/outbox.js +44 -22
  146. package/lib/opLifecycle/outbox.js.map +1 -1
  147. package/lib/opLifecycle/remoteMessageProcessor.d.ts +6 -6
  148. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  149. package/lib/opLifecycle/remoteMessageProcessor.js +18 -6
  150. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  151. package/lib/packageVersion.d.ts +1 -1
  152. package/lib/packageVersion.js +1 -1
  153. package/lib/packageVersion.js.map +1 -1
  154. package/lib/pendingStateManager.d.ts +37 -13
  155. package/lib/pendingStateManager.d.ts.map +1 -1
  156. package/lib/pendingStateManager.js +95 -45
  157. package/lib/pendingStateManager.js.map +1 -1
  158. package/lib/public.d.ts +1 -1
  159. package/lib/scheduleManager.js +4 -0
  160. package/lib/scheduleManager.js.map +1 -1
  161. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  162. package/lib/summary/summarizerNode/summarizerNodeUtils.js +2 -0
  163. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  164. package/lib/summary/summaryFormat.d.ts.map +1 -1
  165. package/lib/summary/summaryFormat.js +4 -1
  166. package/lib/summary/summaryFormat.js.map +1 -1
  167. package/package.json +45 -30
  168. package/src/blobManager/blobManager.ts +19 -0
  169. package/src/channelCollection.ts +48 -11
  170. package/src/containerRuntime.ts +190 -132
  171. package/src/dataStoreContext.ts +22 -4
  172. package/src/gc/garbageCollection.ts +15 -10
  173. package/src/gc/gcDefinitions.ts +7 -2
  174. package/src/gc/gcHelpers.ts +18 -6
  175. package/src/gc/gcTelemetry.ts +20 -8
  176. package/src/metadata.ts +11 -1
  177. package/src/opLifecycle/README.md +0 -8
  178. package/src/opLifecycle/batchManager.ts +46 -16
  179. package/src/opLifecycle/definitions.ts +1 -1
  180. package/src/opLifecycle/index.ts +8 -1
  181. package/src/opLifecycle/opCompressor.ts +12 -8
  182. package/src/opLifecycle/opGroupingManager.ts +14 -11
  183. package/src/opLifecycle/opSplitter.ts +10 -6
  184. package/src/opLifecycle/outbox.ts +64 -26
  185. package/src/opLifecycle/remoteMessageProcessor.ts +24 -8
  186. package/src/packageVersion.ts +1 -1
  187. package/src/pendingStateManager.ts +173 -74
  188. package/src/scheduleManager.ts +6 -2
  189. package/src/summary/README.md +81 -0
  190. package/src/summary/summarizerNode/summarizerNodeUtils.ts +3 -1
  191. package/src/summary/summaryFormat.ts +3 -1
  192. package/src/summary/summaryFormats.md +69 -8
  193. package/tsconfig.json +0 -1
  194. package/src/summary/images/appTree.png +0 -0
  195. package/src/summary/images/protocolAndAppTree.png +0 -0
  196. package/src/summary/images/summaryTree.png +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"garbageCollection.js","sourceRoot":"","sources":["../../src/gc/garbageCollection.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 { IRequest } from \"@fluidframework/core-interfaces\";\nimport { assert, LazyPromise, Timer } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIGarbageCollectionDetailsBase,\n\tISummarizeResult,\n\tgcTreeKey,\n\ttype IGarbageCollectionData,\n\ttype ITelemetryContext,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\tcreateResponseError,\n\tresponseToException,\n} from \"@fluidframework/runtime-utils/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tDataProcessingError,\n\tMonitoringContext,\n\tPerformanceEvent,\n\tcreateChildLogger,\n\tcreateChildMonitoringContext,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { blobManagerBasePath } from \"../blobManager/index.js\";\nimport { InactiveResponseHeaderKey, TombstoneResponseHeaderKey } from \"../containerRuntime.js\";\nimport { ClientSessionExpiredError } from \"../error.js\";\nimport { ContainerMessageType, ContainerRuntimeGCMessage } from \"../messageTypes.js\";\nimport { IRefreshSummaryResult } from \"../summary/index.js\";\n\nimport { generateGCConfigs } from \"./gcConfigs.js\";\nimport {\n\tGCNodeType,\n\tGarbageCollectionMessage,\n\tGarbageCollectionMessageType,\n\tIGCMetadata,\n\tIGCResult,\n\tIGCStats,\n\tIGarbageCollectionRuntime,\n\tIGarbageCollector,\n\tIGarbageCollectorConfigs,\n\tIGarbageCollectorCreateParams,\n\tIMarkPhaseStats,\n\tISweepPhaseStats,\n\tUnreferencedState,\n\tdisableAutoRecoveryKey,\n\ttype IGCNodeUpdatedProps,\n} from \"./gcDefinitions.js\";\nimport {\n\tcloneGCData,\n\tcompatBehaviorAllowsGCMessageType,\n\tconcatGarbageCollectionData,\n\tdataStoreNodePathOnly,\n\tgetGCDataFromSnapshot,\n\turlToGCNodePath,\n} from \"./gcHelpers.js\";\nimport { runGarbageCollection } from \"./gcReferenceGraphAlgorithm.js\";\nimport {\n\tIGarbageCollectionSnapshotData,\n\tIGarbageCollectionState,\n} from \"./gcSummaryDefinitions.js\";\nimport { GCSummaryStateTracker } from \"./gcSummaryStateTracker.js\";\nimport { GCTelemetryTracker } from \"./gcTelemetry.js\";\nimport {\n\tUnreferencedStateTracker,\n\tUnreferencedStateTrackerMap,\n} from \"./gcUnreferencedStateTracker.js\";\n\n/**\n * The garbage collector for the container runtime. It consolidates the garbage collection functionality and maintains\n * its state across summaries.\n *\n * Node - represented as nodeId, it's a node on the GC graph\n *\n * Outbound Route - a path from one node to another node, think `nodeA` -\\> `nodeB`\n *\n * Graph - all nodes with their respective routes\n *\n * ```\n *\t\t\t GC Graph\n *\n *\t\t\t Node\n *\t\tNodeId = \"datastore1\"\n *\t\t /\t\t\t \\\\\n *\tOutboundRoute OutboundRoute\n *\t\t /\t\t\t\t \\\\\n *\t Node\t\t\t Node\n * NodeId = \"dds1\"\t NodeId = \"dds2\"\n * ```\n */\nexport class GarbageCollector implements IGarbageCollector {\n\tpublic static create(createParams: IGarbageCollectorCreateParams): IGarbageCollector {\n\t\treturn new GarbageCollector(createParams);\n\t}\n\n\tprivate readonly mc: MonitoringContext;\n\n\tprivate readonly configs: IGarbageCollectorConfigs;\n\n\tpublic get shouldRunGC(): boolean {\n\t\treturn this.configs.gcEnabled;\n\t}\n\n\tpublic readonly sessionExpiryTimerStarted: number | undefined;\n\t// Keeps track of the GC state from the last run.\n\tprivate gcDataFromLastRun: IGarbageCollectionData | undefined;\n\t// Keeps a list of references (edges in the GC graph) between GC runs. Each entry has a node id and a list of\n\t// outbound routes from that node.\n\tprivate readonly newReferencesSinceLastRun: Map<string, string[]> = new Map();\n\t// A list of nodes that have been tombstoned.\n\tprivate tombstones: string[] = [];\n\t// A list of nodes that have been deleted during sweep phase.\n\tprivate deletedNodes: Set<string> = new Set();\n\n\t// Promise when resolved returns the GC data data in the base snapshot.\n\tprivate readonly baseSnapshotDataP: Promise<IGarbageCollectionSnapshotData | undefined>;\n\t// Promise when resolved initializes the GC state from the data in the base snapshot.\n\tprivate readonly initializeGCStateFromBaseSnapshotP: Promise<void>;\n\t// The GC details generated from the base snapshot.\n\tprivate readonly baseGCDetailsP: Promise<IGarbageCollectionDetailsBase>;\n\n\t/**\n\t * Map of node ids to their unreferenced state tracker\n\t * NOTE: The set of keys in this map is considered as the set of unreferenced nodes\n\t * as of the last GC run. So in between runs, nothing should be added or removed.\n\t */\n\tprivate readonly unreferencedNodesState: UnreferencedStateTrackerMap =\n\t\tnew UnreferencedStateTrackerMap();\n\n\t// The Timer responsible for closing the container when the session has expired\n\tprivate sessionExpiryTimer: Timer | undefined;\n\n\t// The number of times GC has successfully completed on this instance of GarbageCollector.\n\tprivate completedRuns = 0;\n\n\tprivate readonly runtime: IGarbageCollectionRuntime;\n\tprivate readonly isSummarizerClient: boolean;\n\n\tprivate readonly summaryStateTracker: GCSummaryStateTracker;\n\tprivate readonly telemetryTracker: GCTelemetryTracker;\n\n\t/** If false, loading or using a Tombstoned object should merely log, not fail */\n\tpublic get tombstoneEnforcementAllowed(): boolean {\n\t\treturn this.configs.sweepEnabled;\n\t}\n\t/** If true, throw an error when a tombstone data store is retrieved */\n\tpublic get throwOnTombstoneLoad(): boolean {\n\t\treturn this.configs.throwOnTombstoneLoad;\n\t}\n\t/** If true, throw an error when a tombstone data store is used */\n\tpublic get throwOnTombstoneUsage(): boolean {\n\t\treturn this.configs.throwOnTombstoneUsage;\n\t}\n\n\t/** For a given node path, returns the node's package path. */\n\tprivate readonly getNodePackagePath: (\n\t\tnodePath: string,\n\t) => Promise<readonly string[] | undefined>;\n\t/** Returns the timestamp of the last summary generated for this container. */\n\tprivate readonly getLastSummaryTimestampMs: () => number | undefined;\n\n\tprivate readonly submitMessage: (message: ContainerRuntimeGCMessage) => void;\n\n\t/** Returns the count of data stores whose GC state updated since the last summary. */\n\tpublic get updatedDSCountSinceLastSummary(): number {\n\t\treturn this.summaryStateTracker.updatedDSCountSinceLastSummary;\n\t}\n\n\tprotected constructor(createParams: IGarbageCollectorCreateParams) {\n\t\tthis.runtime = createParams.runtime;\n\t\tthis.isSummarizerClient = createParams.isSummarizerClient;\n\t\tthis.getNodePackagePath = createParams.getNodePackagePath;\n\t\tthis.getLastSummaryTimestampMs = createParams.getLastSummaryTimestampMs;\n\t\tthis.submitMessage = createParams.submitMessage;\n\n\t\tconst baseSnapshot = createParams.baseSnapshot;\n\t\tconst readAndParseBlob = createParams.readAndParseBlob;\n\t\tconst pendingSessionExpiryTimerStarted = createParams.sessionExpiryTimerStarted;\n\n\t\tthis.mc = createChildMonitoringContext({\n\t\t\tlogger: createParams.baseLogger,\n\t\t\tnamespace: \"GarbageCollector\",\n\t\t\tproperties: {\n\t\t\t\tall: { completedGCRuns: () => this.completedRuns },\n\t\t\t},\n\t\t});\n\n\t\tthis.configs = generateGCConfigs(this.mc, createParams);\n\n\t\t// If session expiry is enabled, we need to close the container when the session expiry timeout expires.\n\t\tif (this.configs.sessionExpiryTimeoutMs !== undefined) {\n\t\t\t// If Test Override config is set, override Session Expiry timeout.\n\t\t\tconst overrideSessionExpiryTimeoutMs = this.mc.config.getNumber(\n\t\t\t\t\"Fluid.GarbageCollection.TestOverride.SessionExpiryMs\",\n\t\t\t);\n\t\t\tlet timeoutMs = this.configs.sessionExpiryTimeoutMs;\n\n\t\t\tif (pendingSessionExpiryTimerStarted) {\n\t\t\t\t// NOTE: This assumes the client clock hasn't been tampered with since the original session\n\t\t\t\tconst timeLapsedSincePendingTimer = Date.now() - pendingSessionExpiryTimerStarted;\n\t\t\t\ttimeoutMs -= timeLapsedSincePendingTimer;\n\t\t\t}\n\t\t\ttimeoutMs = overrideSessionExpiryTimeoutMs ?? timeoutMs;\n\t\t\tif (timeoutMs <= 0) {\n\t\t\t\tthis.runtime.closeFn(\n\t\t\t\t\tnew ClientSessionExpiredError(`Client session expired.`, timeoutMs),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.sessionExpiryTimer = new Timer(timeoutMs, () => {\n\t\t\t\tthis.runtime.closeFn(\n\t\t\t\t\tnew ClientSessionExpiredError(`Client session expired.`, timeoutMs),\n\t\t\t\t);\n\t\t\t});\n\t\t\tthis.sessionExpiryTimer.start();\n\t\t\tthis.sessionExpiryTimerStarted = Date.now();\n\t\t}\n\n\t\tthis.summaryStateTracker = new GCSummaryStateTracker(this.configs);\n\n\t\tthis.telemetryTracker = new GCTelemetryTracker(\n\t\t\tthis.mc,\n\t\t\tthis.configs,\n\t\t\tthis.isSummarizerClient,\n\t\t\tcreateParams.createContainerMetadata,\n\t\t\t(nodeId: string) => this.runtime.getNodeType(nodeId),\n\t\t\t(nodeId: string) => this.unreferencedNodesState.get(nodeId),\n\t\t\tthis.getNodePackagePath,\n\t\t);\n\n\t\t// Get the GC data from the base snapshot. Use LazyPromise because we only want to do this once since it\n\t\t// it involves fetching blobs from storage which is expensive.\n\t\tthis.baseSnapshotDataP = new LazyPromise<IGarbageCollectionSnapshotData | undefined>(\n\t\t\tasync () => {\n\t\t\t\tif (baseSnapshot === undefined) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\t// For newer documents, GC data should be present in the GC tree in the root of the snapshot.\n\t\t\t\t\tconst gcSnapshotTree = baseSnapshot.trees[gcTreeKey];\n\t\t\t\t\tif (gcSnapshotTree === undefined) {\n\t\t\t\t\t\t// back-compat - Older documents get their gc data reset for simplicity as there are few of them\n\t\t\t\t\t\t// incremental gc summary will not work with older gc data as well\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst snapshotData = await getGCDataFromSnapshot(gcSnapshotTree, readAndParseBlob);\n\n\t\t\t\t\t// If the GC version in base snapshot does not match the GC version currently in effect, the GC data\n\t\t\t\t\t// in the snapshot cannot be interpreted correctly. Set everything to undefined except for\n\t\t\t\t\t// deletedNodes because irrespective of GC versions, these nodes have been deleted and cannot be\n\t\t\t\t\t// brought back. The deletedNodes info is needed to identify when these nodes are used.\n\t\t\t\t\tif (this.configs.gcVersionInEffect !== this.configs.gcVersionInBaseSnapshot) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tgcState: undefined,\n\t\t\t\t\t\t\ttombstones: undefined,\n\t\t\t\t\t\t\tdeletedNodes: snapshotData.deletedNodes,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\treturn snapshotData;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst dpe = DataProcessingError.wrapIfUnrecognized(error, \"FailedToInitializeGC\");\n\t\t\t\t\tdpe.addTelemetryProperties({\n\t\t\t\t\t\tgcConfigs: JSON.stringify(this.configs),\n\t\t\t\t\t});\n\t\t\t\t\tthrow dpe;\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\t/**\n\t\t * Set up the initializer which initializes the GC state from the data in base snapshot. It sets up GC data\n\t\t * from the base GC state and starts tracking the state of unreferenced nodes.\n\t\t *\n\t\t * Must only be called if there is a current reference timestamp.\n\t\t */\n\t\tthis.initializeGCStateFromBaseSnapshotP = new LazyPromise<void>(async () => {\n\t\t\tconst currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();\n\t\t\tassert(\n\t\t\t\tcurrentReferenceTimestampMs !== undefined,\n\t\t\t\t0x8a4 /* Trying to initialize GC state without current timestamp */,\n\t\t\t);\n\n\t\t\t/**\n\t\t\t * The base snapshot data will not be present if the container is loaded from:\n\t\t\t * 1. The first summary created by the detached container.\n\t\t\t * 2. A summary that was generated with GC disabled.\n\t\t\t * 3. A summary that was generated before GC even existed.\n\t\t\t */\n\t\t\tconst baseSnapshotData = await this.baseSnapshotDataP;\n\t\t\tthis.summaryStateTracker.initializeBaseState(baseSnapshotData);\n\n\t\t\tif (baseSnapshotData?.gcState === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Update unreferenced state tracking as per the GC state in the snapshot data and update gcDataFromLastRun\n\t\t\t// to the GC data from the snapshot data.\n\t\t\tconst gcNodes: { [id: string]: string[] } = {};\n\t\t\tfor (const [nodeId, nodeData] of Object.entries(baseSnapshotData.gcState.gcNodes)) {\n\t\t\t\tif (nodeData.unreferencedTimestampMs !== undefined) {\n\t\t\t\t\tthis.unreferencedNodesState.set(\n\t\t\t\t\t\tnodeId,\n\t\t\t\t\t\tnew UnreferencedStateTracker(\n\t\t\t\t\t\t\tnodeData.unreferencedTimestampMs,\n\t\t\t\t\t\t\tthis.configs.inactiveTimeoutMs,\n\t\t\t\t\t\t\tcurrentReferenceTimestampMs,\n\t\t\t\t\t\t\tthis.configs.tombstoneTimeoutMs,\n\t\t\t\t\t\t\tthis.configs.sweepGracePeriodMs,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tgcNodes[nodeId] = Array.from(nodeData.outboundRoutes);\n\t\t\t}\n\t\t\tthis.gcDataFromLastRun = { gcNodes };\n\t\t});\n\n\t\t// Get the GC details from the GC state in the base summary. This is returned in getBaseGCDetails which is\n\t\t// used to initialize the GC state of all the nodes in the container.\n\t\tthis.baseGCDetailsP = new LazyPromise<IGarbageCollectionDetailsBase>(async () => {\n\t\t\tconst baseSnapshotData = await this.baseSnapshotDataP;\n\t\t\tif (baseSnapshotData?.gcState === undefined) {\n\t\t\t\treturn {};\n\t\t\t}\n\n\t\t\t// Note that the base GC details are returned even if GC is disabled. This is to handle the special scenario\n\t\t\t// where GC is disabled but GC state exists in base snapshot. In this scenario, the nodes which get the GC\n\t\t\t// state will re-summarize to reset any GC specific state in their summaries (like unreferenced flag).\n\n\t\t\tconst gcNodes: { [id: string]: string[] } = {};\n\t\t\tfor (const [nodeId, nodeData] of Object.entries(baseSnapshotData.gcState.gcNodes)) {\n\t\t\t\tgcNodes[nodeId] = Array.from(nodeData.outboundRoutes);\n\t\t\t}\n\t\t\t// Run GC on the nodes in the base summary to get the routes used in each node in the container.\n\t\t\t// This is an optimization for space (vs performance) wherein we don't need to store the used routes of\n\t\t\t// each node in the summary.\n\t\t\tconst usedRoutes = runGarbageCollection(gcNodes, [\"/\"]).referencedNodeIds;\n\n\t\t\treturn { gcData: { gcNodes }, usedRoutes };\n\t\t});\n\n\t\t// Log all the GC options and the state determined by the garbage collector.\n\t\t// This is useful even for interactive clients since they track unreferenced nodes and log errors.\n\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\teventName: \"GarbageCollectorLoaded\",\n\t\t\tgcConfigs: JSON.stringify(this.configs),\n\t\t\tgcOptions: JSON.stringify(createParams.gcOptions),\n\t\t\t...createParams.createContainerMetadata,\n\t\t});\n\t}\n\n\t/**\n\t * Called during container initialization. Initializes the tombstone and deleted nodes state from the base snapshot.\n\t * Also, initializes the GC state including unreferenced nodes tracking if a current reference timestamp exists.\n\t * Note that if there is any GC state in the base snapshot, then there will definitely be a reference timestamp\n\t * to work with - The GC state would have been generated using a timestamp which is part of the snapshot.\n\t */\n\tpublic async initializeBaseState(): Promise<void> {\n\t\tconst baseSnapshotData = await this.baseSnapshotDataP;\n\t\t/**\n\t\t * The base snapshot data will not be present if the container is loaded from:\n\t\t * 1. The first summary created by the detached container.\n\t\t * 2. A summary that was generated with GC disabled.\n\t\t * 3. A summary that was generated before GC even existed.\n\t\t */\n\t\tif (baseSnapshotData === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize the deleted nodes from the snapshot. This is done irrespective of whether GC / sweep is enabled\n\t\t// to identify deleted nodes' usage.\n\t\tif (baseSnapshotData.deletedNodes !== undefined) {\n\t\t\tthis.deletedNodes = new Set(baseSnapshotData.deletedNodes);\n\t\t}\n\n\t\t// If running in tombstone mode, initialize the tombstone state from the snapshot. Also, notify the runtime of\n\t\t// tombstone routes.\n\t\tif (this.configs.tombstoneMode && baseSnapshotData.tombstones !== undefined) {\n\t\t\t// Create a copy since we are writing from a source we don't control\n\t\t\tthis.tombstones = Array.from(baseSnapshotData.tombstones);\n\t\t\tthis.runtime.updateTombstonedRoutes(this.tombstones);\n\t\t}\n\n\t\tawait this.initializeOrUpdateGCState();\n\t}\n\n\t/**\n\t * Initialize the GC state if not already initialized. If GC state is already initialized, update the unreferenced\n\t * state tracking as per the current reference timestamp.\n\t */\n\tprivate async initializeOrUpdateGCState() {\n\t\tconst currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();\n\t\tif (currentReferenceTimestampMs === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst initialized = this.gcDataFromLastRun !== undefined;\n\t\tawait PerformanceEvent.timedExecAsync(\n\t\t\tthis.mc.logger,\n\t\t\t{\n\t\t\t\teventName: \"InitializeOrUpdateGCState\",\n\t\t\t\tdetails: { initialized, unrefNodeCount: this.unreferencedNodesState.size },\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\t// If the GC state hasn't been initialized yet, initialize it and return.\n\t\t\t\tif (!initialized) {\n\t\t\t\t\tawait this.initializeGCStateFromBaseSnapshotP;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// If the GC state has been initialized, update the tracking of unreferenced nodes as per the current\n\t\t\t\t// reference timestamp.\n\t\t\t\tfor (const [, nodeStateTracker] of this.unreferencedNodesState) {\n\t\t\t\t\tnodeStateTracker.updateTracking(currentReferenceTimestampMs);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Called when the connection state of the runtime changes, i.e., it connects or disconnects. GC subscribes to this\n\t * to initialize or update the unreference state tracking.\n\t * @param connected - Whether the runtime connected / disconnected.\n\t * @param clientId - The clientId of this runtime.\n\t */\n\tpublic setConnectionState(connected: boolean, clientId?: string | undefined): void {\n\t\t/**\n\t\t * When the client connects (or reconnects), attempt to initialize or update the GC state. This will keep\n\t\t * the unreferenced state tracking updated as per the reference timestamp at the time of connection.\n\t\t *\n\t\t * During GC initialization and during connections in read mode, it is possible that either no ops are\n\t\t * processed or only trailing ops are processed. This means that the GC state is not initialized or initialized\n\t\t * with an older reference timestamp. So, doing this on every connection will keep the unreferenced state\n\t\t * tracking up-to-date.\n\t\t */\n\t\tif (connected && this.shouldRunGC) {\n\t\t\tthis.initializeOrUpdateGCState().catch((error) => {\n\t\t\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GCInitializationOrUpdateFailed\",\n\t\t\t\t\t\tgcConfigs: JSON.stringify(this.configs),\n\t\t\t\t\t\tclientId,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Returns a the GC details generated from the base summary. This is used to initialize the GC state of the nodes\n\t * in the container.\n\t */\n\tpublic async getBaseGCDetails(): Promise<IGarbageCollectionDetailsBase> {\n\t\treturn this.baseGCDetailsP;\n\t}\n\n\t/**\n\t * Runs garbage collection and updates the reference / used state of the nodes in the container.\n\t * @returns stats of the GC run or undefined if GC did not run.\n\t */\n\tpublic async collectGarbage(\n\t\toptions: {\n\t\t\t/** Logger to use for logging GC events */\n\t\t\tlogger?: ITelemetryLoggerExt;\n\t\t\t/** True to run GC sweep phase after the mark phase */\n\t\t\trunSweep?: boolean;\n\t\t\t/** True to generate full GC data */\n\t\t\tfullGC?: boolean;\n\t\t},\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<IGCStats | undefined> {\n\t\tconst fullGC =\n\t\t\toptions.fullGC ??\n\t\t\t(this.configs.runFullGC === true ||\n\t\t\t\tthis.summaryStateTracker.autoRecovery.fullGCRequested());\n\n\t\t// Add the options that are used to run GC to the telemetry context.\n\t\ttelemetryContext?.setMultiple(\"fluid_GC\", \"Options\", {\n\t\t\tfullGC,\n\t\t\trunSweep: options.runSweep,\n\t\t});\n\n\t\tconst logger = createChildLogger({\n\t\t\tlogger: options.logger ?? this.mc.logger,\n\t\t\tproperties: {\n\t\t\t\tall: { completedGCRuns: this.completedRuns, fullGC },\n\t\t\t},\n\t\t});\n\n\t\t/**\n\t\t * If there is no current reference timestamp, skip running GC. We need the current timestamp to track\n\t\t * how long objects have been unreferenced and if they should be deleted.\n\t\t *\n\t\t * Note that the only scenario where GC is called and there is no reference timestamp is when no ops have ever\n\t\t * been processed for this container and it is in read mode. In this scenario, there is no point in running GC\n\t\t * anyway because references in the container do not change without any ops, i.e., there is nothing to collect.\n\t\t */\n\t\tconst currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();\n\t\tif (currentReferenceTimestampMs === undefined) {\n\t\t\t// Log an event so we can evaluate how often we run into this scenario.\n\t\t\tlogger.sendErrorEvent({\n\t\t\t\teventName: \"CollectGarbageCalledWithoutTimestamp\",\n\t\t\t\tgcConfigs: JSON.stringify(this.configs),\n\t\t\t});\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\tlogger,\n\t\t\t{ eventName: \"GarbageCollection\" },\n\t\t\tasync (event) => {\n\t\t\t\t/** Pre-GC steps */\n\t\t\t\t// Ensure that state has been initialized from the base snapshot data.\n\t\t\t\tawait this.initializeGCStateFromBaseSnapshotP;\n\n\t\t\t\t/** GC step */\n\t\t\t\tconst gcStats = await this.runGC(fullGC, currentReferenceTimestampMs, logger);\n\t\t\t\tevent.end({\n\t\t\t\t\t...gcStats,\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\ttimestamp: currentReferenceTimestampMs,\n\t\t\t\t\t\tsweep: this.configs.shouldRunSweep,\n\t\t\t\t\t\ttombstone: this.configs.throwOnTombstoneLoad,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\t/** Post-GC steps */\n\t\t\t\t// Log pending unreferenced events such as a node being used after inactive. This is done after GC runs and\n\t\t\t\t// updates its state so that we don't send false positives based on intermediate state. For example, we may get\n\t\t\t\t// reference to an unreferenced node from another unreferenced node which means the node wasn't revived.\n\t\t\t\tawait this.telemetryTracker.logPendingEvents(logger);\n\t\t\t\t// Update the state of summary state tracker from this run's stats.\n\t\t\t\tthis.summaryStateTracker.updateStateFromGCRunStats(gcStats);\n\t\t\t\tthis.newReferencesSinceLastRun.clear();\n\t\t\t\tthis.completedRuns++;\n\n\t\t\t\treturn gcStats;\n\t\t\t},\n\t\t\t{ end: true, cancel: \"error\" },\n\t\t);\n\t}\n\n\t/**\n\t * Runs garbage collection. It does the following:\n\t *\n\t * 1. It generates / analyzes the runtime's reference graph.\n\t *\n\t * 2. Generates mark phase stats.\n\t *\n\t * 3. Runs Mark phase.\n\t *\n\t * 4. Runs Sweep phase.\n\t *\n\t * 5. Generates sweep phase stats.\n\t */\n\tprivate async runGC(\n\t\tfullGC: boolean,\n\t\tcurrentReferenceTimestampMs: number,\n\t\tlogger: ITelemetryLoggerExt,\n\t): Promise<IGCStats> {\n\t\t// 1. Generate / analyze the runtime's reference graph.\n\t\t// Get the reference graph (gcData) and run GC algorithm to get referenced / unreferenced nodes.\n\t\tconst gcData = await this.runtime.getGCData(fullGC);\n\t\tconst gcResult = runGarbageCollection(gcData.gcNodes, [\"/\"]);\n\t\t// Get all referenced nodes - References in this run + references between the previous and current runs.\n\t\tconst allReferencedNodeIds =\n\t\t\tthis.findAllNodesReferencedBetweenGCs(gcData, this.gcDataFromLastRun, logger) ??\n\t\t\tgcResult.referencedNodeIds;\n\n\t\t// 2. Get the mark phase stats based on the previous / current GC state.\n\t\t// This is done before running mark phase because we need the previous GC state before it is updated.\n\t\tconst markPhaseStats = this.getMarkPhaseStats(gcResult);\n\n\t\t// 3. Run the Mark phase.\n\t\t// It will mark nodes as referenced / unreferenced and return lists of tombstone-ready and sweep-ready nodes.\n\t\tconst { tombstoneReadyNodeIds, sweepReadyNodeIds } = this.runMarkPhase(\n\t\t\tgcResult,\n\t\t\tallReferencedNodeIds,\n\t\t\tcurrentReferenceTimestampMs,\n\t\t);\n\n\t\t// 4. Run the Sweep phase.\n\t\t// It will initiate the deletion (sending the GC Sweep op) of any sweep-ready nodes that are\n\t\t// allowed to be deleted per config, and tombstone the rest along with the tombstone-ready nodes.\n\t\t// Note that no nodes will be deleted until the GC Sweep op is processed.\n\t\tthis.runSweepPhase(gcResult, tombstoneReadyNodeIds, sweepReadyNodeIds);\n\n\t\tthis.gcDataFromLastRun = cloneGCData(gcData);\n\n\t\t// 5. Get the sweep phase stats.\n\t\tconst sweepPhaseStats = this.getSweepPhaseStats(\n\t\t\tthis.deletedNodes,\n\t\t\tsweepReadyNodeIds,\n\t\t\tmarkPhaseStats,\n\t\t);\n\n\t\treturn { ...markPhaseStats, ...sweepPhaseStats };\n\t}\n\n\t/**\n\t * Runs the GC Mark phase. It does the following:\n\t *\n\t * 1. Marks all referenced nodes in this run by clearing tracking for them.\n\t *\n\t * 2. Marks unreferenced nodes in this run by starting tracking for them.\n\t *\n\t * 3. Calls the runtime to update nodes that were marked referenced.\n\t *\n\t * @param gcResult - The result of the GC run on the gcData.\n\t * @param allReferencedNodeIds - Nodes referenced in this GC run + referenced between previous and current GC run.\n\t * @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.\n\t * @returns The sets of tombstone-ready and sweep-ready nodes, i.e., nodes that ready to be tombstoned or deleted.\n\t */\n\tprivate runMarkPhase(\n\t\tgcResult: IGCResult,\n\t\tallReferencedNodeIds: string[],\n\t\tcurrentReferenceTimestampMs: number,\n\t): { tombstoneReadyNodeIds: Set<string>; sweepReadyNodeIds: Set<string> } {\n\t\t// 1. Marks all referenced nodes by clearing their unreferenced tracker, if any.\n\t\tfor (const nodeId of allReferencedNodeIds) {\n\t\t\tthis.unreferencedNodesState.delete(nodeId);\n\t\t}\n\n\t\t// 2. Mark unreferenced nodes in this run by starting or updating unreferenced tracking for them.\n\t\tconst tombstoneReadyNodeIds: Set<string> = new Set();\n\t\tconst sweepReadyNodeIds: Set<string> = new Set();\n\t\tfor (const nodeId of gcResult.deletedNodeIds) {\n\t\t\tconst nodeStateTracker = this.unreferencedNodesState.get(nodeId);\n\t\t\tif (nodeStateTracker === undefined) {\n\t\t\t\tthis.unreferencedNodesState.set(\n\t\t\t\t\tnodeId,\n\t\t\t\t\tnew UnreferencedStateTracker(\n\t\t\t\t\t\tcurrentReferenceTimestampMs,\n\t\t\t\t\t\tthis.configs.inactiveTimeoutMs,\n\t\t\t\t\t\tcurrentReferenceTimestampMs,\n\t\t\t\t\t\tthis.configs.tombstoneTimeoutMs,\n\t\t\t\t\t\tthis.configs.sweepGracePeriodMs,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// If a node was already unreferenced, update its tracking information. Since the current reference time\n\t\t\t\t// is from the ops seen, this will ensure that we keep updating unreferenced state as time moves forward.\n\t\t\t\tnodeStateTracker.updateTracking(currentReferenceTimestampMs);\n\n\t\t\t\t// If a node is tombstone or sweep-ready, store it so it can be returned.\n\t\t\t\tif (nodeStateTracker.state === UnreferencedState.TombstoneReady) {\n\t\t\t\t\ttombstoneReadyNodeIds.add(nodeId);\n\t\t\t\t}\n\t\t\t\tif (nodeStateTracker.state === UnreferencedState.SweepReady) {\n\t\t\t\t\tsweepReadyNodeIds.add(nodeId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 3. Call the runtime to update referenced nodes in this run.\n\t\tthis.runtime.updateUsedRoutes(gcResult.referencedNodeIds);\n\n\t\treturn { tombstoneReadyNodeIds, sweepReadyNodeIds };\n\t}\n\n\t/**\n\t * Runs the GC Sweep phase. It does the following:\n\t *\n\t * 1. Marks tombstone-ready nodes as tombstones.\n\t *\n\t * 2. Sends a sweep op to delete nodes that are sweep-ready. Once the op is ack'd, these nodes will be deleted.\n\t *\n\t * @param gcResult - The result of the GC run on the gcData.\n\t * @param tombstoneReadyNodes - List of nodes that are tombstone-ready.\n\t * @param sweepReadyNodes - List of nodes that are sweep-ready.\n\t */\n\tprivate runSweepPhase(\n\t\tgcResult: IGCResult,\n\t\ttombstoneReadyNodes: Set<string>,\n\t\tsweepReadyNodes: Set<string>,\n\t) {\n\t\t/**\n\t\t * Under \"Test Mode\", unreferenced nodes are immediately deleted without waiting for them to be sweep-ready.\n\t\t *\n\t\t * Otherwise, depending on how long it's been since the node was unreferenced, it will either be\n\t\t * marked as Tombstone, or deleted by Sweep.\n\t\t */\n\n\t\tif (this.configs.testMode) {\n\t\t\t// If we are running in GC test mode, unreferenced nodes (gcResult.deletedNodeIds) are deleted immediately.\n\t\t\tthis.runtime.deleteSweepReadyNodes(gcResult.deletedNodeIds);\n\t\t\treturn;\n\t\t}\n\n\t\t// We'll build up the lists of nodes to be either Tombstoned or Deleted\n\t\t// based on the configuration and the nodes' current state.\n\t\t// We must Tombstone any sweep-ready node that Sweep won't run for.\n\t\t// This is important because a container may never load during a node's Sweep Grace Period,\n\t\t// so that node would directly become sweep-ready skipping over tombstone-ready state,\n\t\t// but should be Tombstoned since Sweep is disabled.\n\t\tconst { nodesToTombstone, nodesToDelete } = {\n\t\t\tnodesToTombstone: [...tombstoneReadyNodes],\n\t\t\tnodesToDelete: [] as string[],\n\t\t};\n\t\tswitch (this.configs.shouldRunSweep) {\n\t\t\tcase \"YES\":\n\t\t\t\tnodesToDelete.push(...sweepReadyNodes);\n\t\t\t\tbreak;\n\t\t\tcase \"ONLY_BLOBS\":\n\t\t\t\tsweepReadyNodes.forEach((nodeId) => {\n\t\t\t\t\tconst nodeType = this.runtime.getNodeType(nodeId);\n\t\t\t\t\tif (nodeType === GCNodeType.Blob) {\n\t\t\t\t\t\tnodesToDelete.push(nodeId);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnodesToTombstone.push(nodeId);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tdefault: // case \"NO\":\n\t\t\t\tnodesToTombstone.push(...sweepReadyNodes);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (this.configs.tombstoneMode) {\n\t\t\tthis.tombstones = nodesToTombstone;\n\t\t\t// If we are running in GC tombstone mode, update tombstoned routes.\n\t\t\tthis.runtime.updateTombstonedRoutes(this.tombstones);\n\t\t}\n\n\t\tif (nodesToDelete.length > 0) {\n\t\t\t// Do not send DDS node ids in the GC op. This is an optimization to reduce its size. Since GC applies to\n\t\t\t// to data store only, all its DDSes are deleted along with it. The DDS ids will be retrieved from the\n\t\t\t// local state when processing the op.\n\t\t\tconst sweepReadyDSAndBlobs = nodesToDelete.filter((nodeId) => {\n\t\t\t\tconst nodeType = this.runtime.getNodeType(nodeId);\n\t\t\t\treturn nodeType === GCNodeType.DataStore || nodeType === GCNodeType.Blob;\n\t\t\t});\n\t\t\tconst contents: GarbageCollectionMessage = {\n\t\t\t\ttype: GarbageCollectionMessageType.Sweep,\n\t\t\t\tdeletedNodeIds: sweepReadyDSAndBlobs,\n\t\t\t};\n\n\t\t\t// Its fine for older clients to ignore this op because it doesn't have any functional impact. This op\n\t\t\t// is an optimization to ensure that all clients are in sync when it comes to deleted nodes to prevent their\n\t\t\t// accidental usage. The clients will sync without the delete op too but it may take longer.\n\t\t\tconst containerGCMessage: ContainerRuntimeGCMessage = {\n\t\t\t\ttype: ContainerMessageType.GC,\n\t\t\t\tcontents,\n\t\t\t\tcompatDetails: { behavior: \"Ignore\" }, // DEPRECATED: For temporary back compat only\n\t\t\t};\n\t\t\tthis.submitMessage(containerGCMessage);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/**\n\t * Since GC runs periodically, the GC data that is generated only tells us the state of the world at that point in\n\t * time. There can be nodes that were referenced in between two runs and their unreferenced state needs to be\n\t * updated. For example, in the following scenarios not updating the unreferenced timestamp can lead to deletion of\n\t * these objects while there can be in-memory referenced to it:\n\t * 1. A node transitions from `unreferenced -> referenced -> unreferenced` between two runs. When the reference is\n\t * added, the object may have been accessed and in-memory reference to it added.\n\t * 2. A reference is added from one unreferenced node to one or more unreferenced nodes. Even though the node[s] were\n\t * unreferenced, they could have been accessed and in-memory reference to them added.\n\t *\n\t * This function identifies nodes that were referenced since the last run.\n\t * If these nodes are currently unreferenced, they will be assigned new unreferenced state by the current run.\n\t *\n\t * @returns A list of all nodes referenced from the last local summary until now.\n\t */\n\tprivate findAllNodesReferencedBetweenGCs(\n\t\tcurrentGCData: IGarbageCollectionData,\n\t\tpreviousGCData: IGarbageCollectionData | undefined,\n\t\tlogger: ITelemetryLoggerExt,\n\t): string[] | undefined {\n\t\t// If we haven't run GC before there is nothing to do.\n\t\t// No previousGCData, means nothing is unreferenced, and there are no reference state trackers to clear\n\t\tif (previousGCData === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t/**\n\t\t * If there are references that were not explicitly notified to GC, log an error because this should never happen.\n\t\t * If it does, this may result in the unreferenced timestamps of these nodes not updated when they were referenced.\n\t\t */\n\t\tthis.telemetryTracker.logIfMissingExplicitReferences(\n\t\t\tcurrentGCData,\n\t\t\tpreviousGCData,\n\t\t\tthis.newReferencesSinceLastRun,\n\t\t\tlogger,\n\t\t);\n\n\t\t// No references were added since the last run so we don't have to update reference states of any unreferenced\n\t\t// nodes. There is no in between state at this point.\n\t\tif (this.newReferencesSinceLastRun.size === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t/**\n\t\t * Generate a super set of the GC data that contains the nodes and edges from last run, plus any new node and\n\t\t * edges that have been added since then. To do this, combine the GC data from the last run and the current\n\t\t * run, and then add the references since last run.\n\t\t *\n\t\t * Note on why we need to combine the data from previous run, current run and all references in between -\n\t\t * 1. We need data from last run because some of its references may have been deleted since then. If those\n\t\t * references added new outbound references before they were deleted, we need to detect them.\n\t\t *\n\t\t * 2. We need new outbound references since last run because some of them may have been deleted later. If those\n\t\t * references added new outbound references before they were deleted, we need to detect them.\n\t\t *\n\t\t * 3. We need data from the current run because currently we may not detect when DDSes are referenced:\n\t\t * - We don't require DDSes handles to be stored in a referenced DDS.\n\t\t * - A new data store may have \"root\" DDSes already created and we don't detect them today.\n\t\t */\n\t\tconst gcDataSuperSet = concatGarbageCollectionData(previousGCData, currentGCData);\n\t\tconst newOutboundRoutesSinceLastRun: string[] = [];\n\t\tthis.newReferencesSinceLastRun.forEach(\n\t\t\t(outboundRoutes: string[], sourceNodeId: string) => {\n\t\t\t\tif (gcDataSuperSet.gcNodes[sourceNodeId] === undefined) {\n\t\t\t\t\tgcDataSuperSet.gcNodes[sourceNodeId] = outboundRoutes;\n\t\t\t\t} else {\n\t\t\t\t\tgcDataSuperSet.gcNodes[sourceNodeId].push(...outboundRoutes);\n\t\t\t\t}\n\t\t\t\tnewOutboundRoutesSinceLastRun.push(...outboundRoutes);\n\t\t\t},\n\t\t);\n\n\t\t/**\n\t\t * Run GC on the above reference graph starting with root and all new outbound routes. This will generate a\n\t\t * list of all nodes that could have been referenced since the last run. If any of these nodes are unreferenced,\n\t\t * unreferenced, stop tracking them and remove from unreferenced list.\n\t\t * Note that some of these nodes may be unreferenced now and if so, the current run will mark them as\n\t\t * unreferenced and add unreferenced state.\n\t\t */\n\t\tconst gcResult = runGarbageCollection(gcDataSuperSet.gcNodes, [\n\t\t\t\"/\",\n\t\t\t...newOutboundRoutesSinceLastRun,\n\t\t]);\n\t\treturn gcResult.referencedNodeIds;\n\t}\n\n\t/**\n\t * Summarizes the GC data and returns it as a summary tree.\n\t * We current write the entire GC state in a single blob. This can be modified later to write multiple\n\t * blobs. All the blob keys should start with `gcBlobPrefix`.\n\t */\n\tpublic summarize(\n\t\tfullTree: boolean,\n\t\ttrackState: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): ISummarizeResult | undefined {\n\t\tif (!this.shouldRunGC || this.gcDataFromLastRun === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst gcState: IGarbageCollectionState = { gcNodes: {} };\n\t\tfor (const [nodeId, outboundRoutes] of Object.entries(this.gcDataFromLastRun.gcNodes)) {\n\t\t\tgcState.gcNodes[nodeId] = {\n\t\t\t\toutboundRoutes,\n\t\t\t\tunreferencedTimestampMs:\n\t\t\t\t\tthis.unreferencedNodesState.get(nodeId)?.unreferencedTimestampMs,\n\t\t\t};\n\t\t}\n\n\t\treturn this.summaryStateTracker.summarize(\n\t\t\ttrackState && !fullTree,\n\t\t\tgcState,\n\t\t\tthis.deletedNodes,\n\t\t\tthis.tombstones,\n\t\t);\n\t}\n\n\tpublic getMetadata(): IGCMetadata {\n\t\treturn {\n\t\t\t/**\n\t\t\t * If GC is enabled, the GC data is written using the GC version in effect and that is the gcFeature that goes\n\t\t\t * into the metadata blob. If GC is disabled, the gcFeature is 0.\n\t\t\t */\n\t\t\tgcFeature: this.configs.gcEnabled ? this.configs.gcVersionInEffect : 0,\n\t\t\tgcFeatureMatrix: this.configs.persistedGcFeatureMatrix,\n\t\t\tsessionExpiryTimeoutMs: this.configs.sessionExpiryTimeoutMs,\n\t\t\tsweepEnabled: false, // DEPRECATED - to be removed\n\t\t\ttombstoneTimeoutMs: this.configs.tombstoneTimeoutMs,\n\t\t};\n\t}\n\n\t/**\n\t * Called to refresh the latest summary state. This happens when either a pending summary is acked.\n\t */\n\tpublic async refreshLatestSummary(result: IRefreshSummaryResult): Promise<void> {\n\t\treturn this.summaryStateTracker.refreshLatestSummary(result);\n\t}\n\n\t/**\n\t * Process a GC message.\n\t * @param message - The GC message from the container runtime.\n\t * @param messageTimestampMs - The timestamp of the message.\n\t * @param local - Whether it was send by this client.\n\t */\n\tpublic processMessage(\n\t\tmessage: ContainerRuntimeGCMessage,\n\t\tmessageTimestampMs: number,\n\t\tlocal: boolean,\n\t) {\n\t\tconst gcMessageType = message.contents.type;\n\t\tswitch (gcMessageType) {\n\t\t\tcase GarbageCollectionMessageType.Sweep: {\n\t\t\t\t// Delete the nodes whose ids are present in the contents.\n\t\t\t\tthis.deleteSweepReadyNodes(message.contents.deletedNodeIds);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase GarbageCollectionMessageType.TombstoneLoaded: {\n\t\t\t\tif (\n\t\t\t\t\t!this.configs.tombstoneAutorecoveryEnabled ||\n\t\t\t\t\tthis.mc.config.getBoolean(disableAutoRecoveryKey) === true\n\t\t\t\t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Mark the node as referenced to ensure it isn't Swept\n\t\t\t\tconst tombstonedNodePath = message.contents.nodePath;\n\t\t\t\tthis.addedOutboundReference(\n\t\t\t\t\t\"/\",\n\t\t\t\t\ttombstonedNodePath,\n\t\t\t\t\tmessageTimestampMs,\n\t\t\t\t\ttrue /* autorecovery */,\n\t\t\t\t);\n\n\t\t\t\t// In case the cause of the TombstoneLoaded event is incorrect GC Data (i.e. the object is actually reachable),\n\t\t\t\t// do fullGC on the next run to get a chance to repair (in the likely case the bug is not deterministic)\n\t\t\t\tthis.summaryStateTracker.autoRecovery.requestFullGCOnNextRun();\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tif (\n\t\t\t\t\t!compatBehaviorAllowsGCMessageType(gcMessageType, message.compatDetails?.behavior)\n\t\t\t\t) {\n\t\t\t\t\tconst error = DataProcessingError.create(\n\t\t\t\t\t\t`Garbage collection message of unknown type ${gcMessageType}`,\n\t\t\t\t\t\t\"processMessage\",\n\t\t\t\t\t);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Delete nodes that are sweep-ready. Call the runtime to delete these nodes and clear the unreferenced state\n\t * tracking for nodes that are actually deleted by the runtime.\n\t *\n\t * Note that this doesn't check any configuration around whether Sweep is enabled.\n\t * That happens before the op is submitted, and from that point, any client should execute the delete.\n\t *\n\t * @param sweepReadyNodeIds - The ids of nodes that are ready to be deleted.\n\t */\n\tprivate deleteSweepReadyNodes(sweepReadyNodeIds: readonly string[]) {\n\t\t// Use a set for lookup because its much faster than array or map.\n\t\tconst sweepReadyNodesSet: Set<string> = new Set(sweepReadyNodeIds);\n\n\t\t// The ids in the sweep-ready nodes do not contain DDS node ids. This is an optimization to reduce the size\n\t\t// of the GC op. Since GC applies to data store only, all its DDSes are deleted along with it. So, get the\n\t\t// DDS nodes ID from the unreferenced nodes state.\n\t\tconst allSweepReadyNodeIds = Array.from(sweepReadyNodeIds);\n\t\tfor (const [id] of this.unreferencedNodesState) {\n\t\t\t// Ignore data store nodes since they would already be in the list.\n\t\t\tconst pathParts = id.split(\"/\");\n\t\t\tif (pathParts.length <= 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Get the data store id part. Note that this may include blobs but that's okay since the part would just\n\t\t\t// be \"_blobs\" and it won't be found.\n\t\t\tconst dsId = `/${pathParts[1]}`;\n\t\t\tif (sweepReadyNodesSet.has(dsId)) {\n\t\t\t\tallSweepReadyNodeIds.push(id);\n\t\t\t}\n\t\t}\n\t\tconst deletedNodeIds = this.runtime.deleteSweepReadyNodes(allSweepReadyNodeIds);\n\n\t\t// Clear unreferenced state tracking for deleted nodes.\n\t\tfor (const nodeId of deletedNodeIds) {\n\t\t\t// Usually we avoid modifying the set of unreferencedNodesState keys in between GC runs,\n\t\t\t// but this is ok since this node won't exist at all in the next GC run.\n\t\t\tthis.unreferencedNodesState.delete(nodeId);\n\t\t\tthis.deletedNodes.add(nodeId);\n\t\t}\n\t}\n\n\t/**\n\t * Called when a node with the given id is updated. If the node is inactive or tombstoned, this will log an error\n\t * or throw an error if failing on incorrect usage is configured.\n\t * @param IGCNodeUpdatedProps - Details about the node and how it was updated\n\t */\n\tpublic nodeUpdated({\n\t\tnode,\n\t\treason,\n\t\ttimestampMs,\n\t\tpackagePath,\n\t\trequest,\n\t\theaderData,\n\t}: IGCNodeUpdatedProps) {\n\t\t// If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip\n\t\t// logging as nothing interesting would have happened worth logging.\n\t\tif (!this.shouldRunGC || timestampMs === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\t// trackedId will be either DataStore or Blob ID (not sub-DataStore ID, since some of those are unrecognized by GC)\n\t\tconst trackedId = node.path;\n\t\tconst isTombstoned = this.tombstones.includes(trackedId);\n\t\tconst isInactive = this.unreferencedNodesState.get(trackedId)?.state === \"Inactive\";\n\n\t\tconst fullPath = request !== undefined ? urlToGCNodePath(request.url) : trackedId;\n\n\t\t// This will log if appropriate\n\t\tthis.telemetryTracker.nodeUsed(trackedId, {\n\t\t\tid: fullPath,\n\t\t\tusageType: reason,\n\t\t\tcurrentReferenceTimestampMs: timestampMs,\n\t\t\tpackagePath,\n\t\t\tcompletedGCRuns: this.completedRuns,\n\t\t\tisTombstoned,\n\t\t\tlastSummaryTime: this.getLastSummaryTimestampMs(),\n\t\t\theaders: headerData,\n\t\t\trequestUrl: request?.url,\n\t\t\trequestHeaders: JSON.stringify(request?.headers),\n\t\t});\n\n\t\t// Any time we log a Tombstone Loaded error (via Telemetry Tracker),\n\t\t// we want to also trigger autorecovery to avoid the object being deleted\n\t\t// Note: We don't need to trigger on \"Changed\" because any change will cause the object\n\t\t// to be loaded by the Summarizer, and auto-recovery will be triggered then.\n\t\tif (isTombstoned && reason === \"Loaded\") {\n\t\t\t// Note that when a DataStore and its DDS are all loaded, each will trigger AutoRecovery for itself.\n\t\t\tthis.triggerAutoRecovery(fullPath);\n\t\t}\n\n\t\tconst nodeType = this.runtime.getNodeType(fullPath);\n\n\t\t// Unless this is a Loaded event for a Blob or DataStore, we're done after telemetry tracking\n\t\tconst loadedBlobOrDataStore =\n\t\t\treason === \"Loaded\" &&\n\t\t\t(nodeType === GCNodeType.Blob || nodeType === GCNodeType.DataStore);\n\t\tif (!loadedBlobOrDataStore) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst errorRequest: IRequest = request ?? { url: fullPath };\n\t\tif (isTombstoned && this.throwOnTombstoneLoad && headerData?.allowTombstone !== true) {\n\t\t\t// The requested data store is removed by gc. Create a 404 gc response exception.\n\t\t\tthrow responseToException(\n\t\t\t\tcreateResponseError(404, `${nodeType} was tombstoned`, errorRequest, {\n\t\t\t\t\t[TombstoneResponseHeaderKey]: true,\n\t\t\t\t}),\n\t\t\t\terrorRequest,\n\t\t\t);\n\t\t}\n\n\t\t// If the object is inactive and inactive enforcement is configured, throw an error.\n\t\tif (isInactive) {\n\t\t\tconst shouldThrowOnInactiveLoad =\n\t\t\t\t!this.isSummarizerClient &&\n\t\t\t\tthis.configs.throwOnInactiveLoad === true &&\n\t\t\t\theaderData?.allowInactive !== true;\n\t\t\tif (shouldThrowOnInactiveLoad) {\n\t\t\t\tthrow responseToException(\n\t\t\t\t\tcreateResponseError(404, `${nodeType} is inactive`, errorRequest, {\n\t\t\t\t\t\t[InactiveResponseHeaderKey]: true,\n\t\t\t\t\t}),\n\t\t\t\t\terrorRequest,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The given node should have its unreferenced state reset in the next GC,\n\t * even if the true GC graph shows it is unreferenced. This will\n\t * prevent it from being deleted by Sweep (after the Grace Period).\n\t *\n\t * Submit a GC op indicating that the Tombstone with the given path has been loaded.\n\t * Broadcasting this information in the op stream allows the Summarizer to reset unreferenced state\n\t * before runnint GC next.\n\t */\n\tprivate triggerAutoRecovery(nodePath: string) {\n\t\tif (\n\t\t\t!this.configs.tombstoneAutorecoveryEnabled ||\n\t\t\tthis.mc.config.getBoolean(disableAutoRecoveryKey) === true\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Use compat behavior \"Ignore\" since this is an optimization to opportunistically protect\n\t\t// objects from deletion, so it's fine for older clients to ignore this op.\n\t\tconst containerGCMessage: ContainerRuntimeGCMessage = {\n\t\t\ttype: ContainerMessageType.GC,\n\t\t\tcontents: {\n\t\t\t\ttype: GarbageCollectionMessageType.TombstoneLoaded,\n\t\t\t\tnodePath,\n\t\t\t},\n\t\t\tcompatDetails: { behavior: \"Ignore\" }, // DEPRECATED: For temporary back compat only\n\t\t};\n\t\tthis.submitMessage(containerGCMessage);\n\t}\n\n\t/**\n\t * Called when an outbound reference is added to a node. This is used to identify all nodes that have been\n\t * referenced between summaries so that their unreferenced timestamp can be reset.\n\t *\n\t * @param fromNodePath - The node from which the reference is added.\n\t * @param toNodePath - The node to which the reference is added.\n\t * @param timestampMs - The timestamp of the message that added the reference.\n\t * @param autorecovery - This reference is added artificially, for autorecovery. Used for logging.\n\t */\n\tpublic addedOutboundReference(\n\t\tfromNodePath: string,\n\t\ttoNodePath: string,\n\t\ttimestampMs: number,\n\t\tautorecovery?: true,\n\t) {\n\t\tif (!this.shouldRunGC) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!toNodePath.startsWith(\"/\")) {\n\t\t\t// A long time ago we stored handles with relatives paths. We don't expect to see these cases though\n\t\t\t// because GC was enabled only after we made the switch to always using absolute paths.\n\t\t\tthis.mc.logger.sendErrorEvent({\n\t\t\t\teventName: \"InvalidRelativeOutboundRoute\",\n\t\t\t\t...tagCodeArtifacts({ fromId: fromNodePath, id: toNodePath }),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tassert(fromNodePath.startsWith(\"/\"), 0x8a5 /* fromNodePath must be an absolute path */);\n\n\t\tconst outboundRoutes = this.newReferencesSinceLastRun.get(fromNodePath) ?? [];\n\t\toutboundRoutes.push(toNodePath);\n\t\tthis.newReferencesSinceLastRun.set(fromNodePath, outboundRoutes);\n\n\t\t// GC won't recognize some subDataStore paths that we encounter (e.g. a path suited for a custom request handler)\n\t\t// So for subDataStore paths we need to check the parent dataStore for current tombstone/inactive status.\n\t\tconst trackedId =\n\t\t\tthis.runtime.getNodeType(toNodePath) === \"SubDataStore\"\n\t\t\t\t? dataStoreNodePathOnly(toNodePath)\n\t\t\t\t: toNodePath;\n\t\tthis.telemetryTracker.nodeUsed(trackedId, {\n\t\t\tid: toNodePath,\n\t\t\tfromId: fromNodePath,\n\t\t\tusageType: \"Revived\",\n\t\t\tcurrentReferenceTimestampMs: timestampMs,\n\t\t\tpackagePath: undefined,\n\t\t\tcompletedGCRuns: this.completedRuns,\n\t\t\tisTombstoned: this.tombstones.includes(trackedId),\n\t\t\tlastSummaryTime: this.getLastSummaryTimestampMs(),\n\t\t\tautorecovery,\n\t\t});\n\n\t\t// This node is referenced - Clear its unreferenced state if present\n\t\t// But don't delete the node id from the map yet.\n\t\t// When generating GC stats, the set of nodes in here is used as the baseline for\n\t\t// what was unreferenced in the last GC run.\n\t\t// NOTE: We use toNodePath not trackedId even though it may be an unrecognized subDataStore route (hence no-op),\n\t\t// because a reference to such a path is not sufficient to consider the DataStore referenced.\n\t\tthis.unreferencedNodesState.get(toNodePath)?.stopTracking();\n\t}\n\n\t/**\n\t * Returns whether a node with the given path has been deleted or not. This can be used by the runtime to identify\n\t * cases where objects are used after they are deleted and throw / log errors accordingly.\n\t */\n\tpublic isNodeDeleted(nodePath: string): boolean {\n\t\treturn this.deletedNodes.has(nodePath);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.sessionExpiryTimer?.clear();\n\t\tthis.sessionExpiryTimer = undefined;\n\t}\n\n\t/**\n\t * Generates the stats of a garbage collection mark phase run.\n\t * @param gcResult - The result of the current GC run.\n\t * @returns the stats of the mark phase run.\n\t */\n\tprivate getMarkPhaseStats(gcResult: IGCResult): IMarkPhaseStats {\n\t\tconst markPhaseStats: IMarkPhaseStats = {\n\t\t\tnodeCount: 0,\n\t\t\tdataStoreCount: 0,\n\t\t\tattachmentBlobCount: 0,\n\t\t\tunrefNodeCount: 0,\n\t\t\tunrefDataStoreCount: 0,\n\t\t\tunrefAttachmentBlobCount: 0,\n\t\t\tupdatedNodeCount: 0,\n\t\t\tupdatedDataStoreCount: 0,\n\t\t\tupdatedAttachmentBlobCount: 0,\n\t\t};\n\n\t\tconst updateNodeStats = (nodeId: string, isReferenced: boolean) => {\n\t\t\tmarkPhaseStats.nodeCount++;\n\t\t\t// If there is no previous GC data, every node's state is generated and is considered as updated.\n\t\t\t// Otherwise, find out if any node went from referenced to unreferenced or vice-versa.\n\t\t\tconst wasNotReferenced = this.unreferencedNodesState.has(nodeId);\n\t\t\tconst stateUpdated =\n\t\t\t\tthis.gcDataFromLastRun === undefined || wasNotReferenced === isReferenced;\n\t\t\tif (stateUpdated) {\n\t\t\t\tmarkPhaseStats.updatedNodeCount++;\n\t\t\t}\n\t\t\tif (!isReferenced) {\n\t\t\t\tmarkPhaseStats.unrefNodeCount++;\n\t\t\t}\n\n\t\t\tif (this.runtime.getNodeType(nodeId) === GCNodeType.DataStore) {\n\t\t\t\tmarkPhaseStats.dataStoreCount++;\n\t\t\t\tif (stateUpdated) {\n\t\t\t\t\tmarkPhaseStats.updatedDataStoreCount++;\n\t\t\t\t}\n\t\t\t\tif (!isReferenced) {\n\t\t\t\t\tmarkPhaseStats.unrefDataStoreCount++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.runtime.getNodeType(nodeId) === GCNodeType.Blob) {\n\t\t\t\tmarkPhaseStats.attachmentBlobCount++;\n\t\t\t\tif (stateUpdated) {\n\t\t\t\t\tmarkPhaseStats.updatedAttachmentBlobCount++;\n\t\t\t\t}\n\t\t\t\tif (!isReferenced) {\n\t\t\t\t\tmarkPhaseStats.unrefAttachmentBlobCount++;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tfor (const nodeId of gcResult.referencedNodeIds) {\n\t\t\tupdateNodeStats(nodeId, true /* referenced */);\n\t\t}\n\n\t\tfor (const nodeId of gcResult.deletedNodeIds) {\n\t\t\tupdateNodeStats(nodeId, false /* referenced */);\n\t\t}\n\n\t\treturn markPhaseStats;\n\t}\n\n\t/**\n\t * Generates the stats of a garbage collection sweep phase run.\n\t * @param deletedNodes - The nodes that have already been deleted even before this run.\n\t * @param sweepReadyNodes - The nodes that are sweep-ready in this GC run. These will be deleted but are not deleted yet,\n\t * due to either sweep not being enabled or the Sweep Op needing to roundtrip before the delete is executed.\n\t * @param markPhaseStats - The stats of the mark phase run.\n\t * @returns the stats of the sweep phase run.\n\t */\n\tprivate getSweepPhaseStats(\n\t\tdeletedNodes: Set<string>,\n\t\tsweepReadyNodes: Set<string>,\n\t\tmarkPhaseStats: IMarkPhaseStats,\n\t): ISweepPhaseStats {\n\t\t// Initialize the life time node counts to the mark phase node counts. If sweep is not enabled,\n\t\t// these will be the life time node count for this container.\n\t\tconst sweepPhaseStats: ISweepPhaseStats = {\n\t\t\tlifetimeNodeCount: markPhaseStats.nodeCount,\n\t\t\tlifetimeDataStoreCount: markPhaseStats.dataStoreCount,\n\t\t\tlifetimeAttachmentBlobCount: markPhaseStats.attachmentBlobCount,\n\t\t\tdeletedNodeCount: 0,\n\t\t\tdeletedDataStoreCount: 0,\n\t\t\tdeletedAttachmentBlobCount: 0,\n\t\t};\n\n\t\t// The runtime can't reliably identify the type of deleted nodes. So, get the type here. This should\n\t\t// be good enough because the only types that participate in GC today are data stores, DDSes and blobs.\n\t\tconst getDeletedNodeType = (nodeId: string): GCNodeType => {\n\t\t\tconst pathParts = nodeId.split(\"/\");\n\t\t\tif (pathParts[1] === blobManagerBasePath) {\n\t\t\t\treturn GCNodeType.Blob;\n\t\t\t}\n\t\t\tif (pathParts.length === 2) {\n\t\t\t\treturn GCNodeType.DataStore;\n\t\t\t}\n\t\t\tif (pathParts.length === 3) {\n\t\t\t\treturn GCNodeType.SubDataStore;\n\t\t\t}\n\t\t\treturn GCNodeType.Other;\n\t\t};\n\n\t\tfor (const nodeId of deletedNodes) {\n\t\t\tsweepPhaseStats.deletedNodeCount++;\n\t\t\tconst nodeType = getDeletedNodeType(nodeId);\n\t\t\tif (nodeType === GCNodeType.DataStore) {\n\t\t\t\tsweepPhaseStats.deletedDataStoreCount++;\n\t\t\t} else if (nodeType === GCNodeType.Blob) {\n\t\t\t\tsweepPhaseStats.deletedAttachmentBlobCount++;\n\t\t\t}\n\t\t}\n\n\t\t// The counts from the mark phase stats do not include nodes that were\n\t\t// deleted in previous runs. So, add the deleted node counts to life time stats.\n\t\tsweepPhaseStats.lifetimeNodeCount += sweepPhaseStats.deletedNodeCount;\n\t\tsweepPhaseStats.lifetimeDataStoreCount += sweepPhaseStats.deletedDataStoreCount;\n\t\tsweepPhaseStats.lifetimeAttachmentBlobCount += sweepPhaseStats.deletedAttachmentBlobCount;\n\n\t\t// These stats are used to estimate the impact of GC in terms of how much garbage is/will be cleaned up.\n\t\t// So we include the current sweep-ready node stats since these nodes will be deleted eventually.\n\t\t// - If sweep is enabled, this will happen in the run after the GC op round trips back\n\t\t// (they'll be in deletedNodes that time).\n\t\t// - If sweep is not enabled, we still want to include these nodes since they\n\t\t// _will be_ deleted once it is enabled.\n\t\tfor (const nodeId of sweepReadyNodes) {\n\t\t\tsweepPhaseStats.deletedNodeCount++;\n\t\t\tconst nodeType = this.runtime.getNodeType(nodeId);\n\t\t\tif (nodeType === GCNodeType.DataStore) {\n\t\t\t\tsweepPhaseStats.deletedDataStoreCount++;\n\t\t\t} else if (nodeType === GCNodeType.Blob) {\n\t\t\t\tsweepPhaseStats.deletedAttachmentBlobCount++;\n\t\t\t}\n\t\t}\n\n\t\treturn sweepPhaseStats;\n\t}\n}\n"]}
1
+ {"version":3,"file":"garbageCollection.js","sourceRoot":"","sources":["../../src/gc/garbageCollection.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 { IRequest } from \"@fluidframework/core-interfaces\";\nimport { assert, LazyPromise, Timer } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIGarbageCollectionDetailsBase,\n\tISummarizeResult,\n\tgcTreeKey,\n\ttype IGarbageCollectionData,\n\ttype ITelemetryContext,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\tcreateResponseError,\n\tresponseToException,\n} from \"@fluidframework/runtime-utils/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tDataProcessingError,\n\tMonitoringContext,\n\tPerformanceEvent,\n\tcreateChildLogger,\n\tcreateChildMonitoringContext,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { blobManagerBasePath } from \"../blobManager/index.js\";\nimport { InactiveResponseHeaderKey, TombstoneResponseHeaderKey } from \"../containerRuntime.js\";\nimport { ClientSessionExpiredError } from \"../error.js\";\nimport { ContainerMessageType, ContainerRuntimeGCMessage } from \"../messageTypes.js\";\nimport { IRefreshSummaryResult } from \"../summary/index.js\";\n\nimport { generateGCConfigs } from \"./gcConfigs.js\";\nimport {\n\tGCNodeType,\n\tGarbageCollectionMessage,\n\tGarbageCollectionMessageType,\n\tIGCMetadata,\n\tIGCResult,\n\tIGCStats,\n\tIGarbageCollectionRuntime,\n\tIGarbageCollector,\n\tIGarbageCollectorConfigs,\n\tIGarbageCollectorCreateParams,\n\tIMarkPhaseStats,\n\tISweepPhaseStats,\n\tUnreferencedState,\n\tdisableAutoRecoveryKey,\n\ttype IGCNodeUpdatedProps,\n} from \"./gcDefinitions.js\";\nimport {\n\tcloneGCData,\n\tcompatBehaviorAllowsGCMessageType,\n\tconcatGarbageCollectionData,\n\tdataStoreNodePathOnly,\n\tgetGCDataFromSnapshot,\n\turlToGCNodePath,\n} from \"./gcHelpers.js\";\nimport { runGarbageCollection } from \"./gcReferenceGraphAlgorithm.js\";\nimport {\n\tIGarbageCollectionSnapshotData,\n\tIGarbageCollectionState,\n} from \"./gcSummaryDefinitions.js\";\nimport { GCSummaryStateTracker } from \"./gcSummaryStateTracker.js\";\nimport { GCTelemetryTracker } from \"./gcTelemetry.js\";\nimport {\n\tUnreferencedStateTracker,\n\tUnreferencedStateTrackerMap,\n} from \"./gcUnreferencedStateTracker.js\";\n\n/**\n * The garbage collector for the container runtime. It consolidates the garbage collection functionality and maintains\n * its state across summaries.\n *\n * Node - represented as nodeId, it's a node on the GC graph\n *\n * Outbound Route - a path from one node to another node, think `nodeA` -\\> `nodeB`\n *\n * Graph - all nodes with their respective routes\n *\n * ```\n *\t\t\t GC Graph\n *\n *\t\t\t Node\n *\t\tNodeId = \"datastore1\"\n *\t\t /\t\t\t \\\\\n *\tOutboundRoute OutboundRoute\n *\t\t /\t\t\t\t \\\\\n *\t Node\t\t\t Node\n * NodeId = \"dds1\"\t NodeId = \"dds2\"\n * ```\n */\nexport class GarbageCollector implements IGarbageCollector {\n\tpublic static create(createParams: IGarbageCollectorCreateParams): IGarbageCollector {\n\t\treturn new GarbageCollector(createParams);\n\t}\n\n\tprivate readonly mc: MonitoringContext;\n\n\tprivate readonly configs: IGarbageCollectorConfigs;\n\n\tpublic get shouldRunGC(): boolean {\n\t\treturn this.configs.gcEnabled;\n\t}\n\n\tpublic readonly sessionExpiryTimerStarted: number | undefined;\n\t// Keeps track of the GC state from the last run.\n\tprivate gcDataFromLastRun: IGarbageCollectionData | undefined;\n\t// Keeps a list of references (edges in the GC graph) between GC runs. Each entry has a node id and a list of\n\t// outbound routes from that node.\n\tprivate readonly newReferencesSinceLastRun: Map<string, string[]> = new Map();\n\t// A list of nodes that have been tombstoned.\n\tprivate tombstones: string[] = [];\n\t// A list of nodes that have been deleted during sweep phase.\n\tprivate deletedNodes: Set<string> = new Set();\n\n\t// Promise when resolved returns the GC data data in the base snapshot.\n\tprivate readonly baseSnapshotDataP: Promise<IGarbageCollectionSnapshotData | undefined>;\n\t// Promise when resolved initializes the GC state from the data in the base snapshot.\n\tprivate readonly initializeGCStateFromBaseSnapshotP: Promise<void>;\n\t// The GC details generated from the base snapshot.\n\tprivate readonly baseGCDetailsP: Promise<IGarbageCollectionDetailsBase>;\n\n\t/**\n\t * Map of node ids to their unreferenced state tracker\n\t * NOTE: The set of keys in this map is considered as the set of unreferenced nodes\n\t * as of the last GC run. So in between runs, nothing should be added or removed.\n\t */\n\tprivate readonly unreferencedNodesState: UnreferencedStateTrackerMap =\n\t\tnew UnreferencedStateTrackerMap();\n\n\t// The Timer responsible for closing the container when the session has expired\n\tprivate sessionExpiryTimer: Timer | undefined;\n\n\t// The number of times GC has successfully completed on this instance of GarbageCollector.\n\tprivate completedRuns = 0;\n\n\tprivate readonly runtime: IGarbageCollectionRuntime;\n\tprivate readonly isSummarizerClient: boolean;\n\n\tprivate readonly summaryStateTracker: GCSummaryStateTracker;\n\tprivate readonly telemetryTracker: GCTelemetryTracker;\n\n\t/** If false, loading or using a Tombstoned object should merely log, not fail */\n\tpublic get tombstoneEnforcementAllowed(): boolean {\n\t\treturn this.configs.sweepEnabled;\n\t}\n\t/** If true, throw an error when a tombstone data store is retrieved */\n\tpublic get throwOnTombstoneLoad(): boolean {\n\t\treturn this.configs.throwOnTombstoneLoad;\n\t}\n\t/** If true, throw an error when a tombstone data store is used */\n\tpublic get throwOnTombstoneUsage(): boolean {\n\t\treturn this.configs.throwOnTombstoneUsage;\n\t}\n\n\t/** For a given node path, returns the node's package path. */\n\tprivate readonly getNodePackagePath: (\n\t\tnodePath: string,\n\t) => Promise<readonly string[] | undefined>;\n\t/** Returns the timestamp of the last summary generated for this container. */\n\tprivate readonly getLastSummaryTimestampMs: () => number | undefined;\n\n\tprivate readonly submitMessage: (message: ContainerRuntimeGCMessage) => void;\n\n\t/** Returns the count of data stores whose GC state updated since the last summary. */\n\tpublic get updatedDSCountSinceLastSummary(): number {\n\t\treturn this.summaryStateTracker.updatedDSCountSinceLastSummary;\n\t}\n\n\tprotected constructor(createParams: IGarbageCollectorCreateParams) {\n\t\tthis.runtime = createParams.runtime;\n\t\tthis.isSummarizerClient = createParams.isSummarizerClient;\n\t\tthis.getNodePackagePath = createParams.getNodePackagePath;\n\t\tthis.getLastSummaryTimestampMs = createParams.getLastSummaryTimestampMs;\n\t\tthis.submitMessage = createParams.submitMessage;\n\n\t\tconst baseSnapshot = createParams.baseSnapshot;\n\t\tconst readAndParseBlob = createParams.readAndParseBlob;\n\t\tconst pendingSessionExpiryTimerStarted = createParams.sessionExpiryTimerStarted;\n\n\t\tthis.mc = createChildMonitoringContext({\n\t\t\tlogger: createParams.baseLogger,\n\t\t\tnamespace: \"GarbageCollector\",\n\t\t\tproperties: {\n\t\t\t\tall: { completedGCRuns: () => this.completedRuns },\n\t\t\t},\n\t\t});\n\n\t\tthis.configs = generateGCConfigs(this.mc, createParams);\n\n\t\t// If session expiry is enabled, we need to close the container when the session expiry timeout expires.\n\t\tif (this.configs.sessionExpiryTimeoutMs !== undefined) {\n\t\t\t// If Test Override config is set, override Session Expiry timeout.\n\t\t\tconst overrideSessionExpiryTimeoutMs = this.mc.config.getNumber(\n\t\t\t\t\"Fluid.GarbageCollection.TestOverride.SessionExpiryMs\",\n\t\t\t);\n\t\t\tlet timeoutMs = this.configs.sessionExpiryTimeoutMs;\n\n\t\t\tif (pendingSessionExpiryTimerStarted) {\n\t\t\t\t// NOTE: This assumes the client clock hasn't been tampered with since the original session\n\t\t\t\tconst timeLapsedSincePendingTimer = Date.now() - pendingSessionExpiryTimerStarted;\n\t\t\t\ttimeoutMs -= timeLapsedSincePendingTimer;\n\t\t\t}\n\t\t\ttimeoutMs = overrideSessionExpiryTimeoutMs ?? timeoutMs;\n\t\t\tif (timeoutMs <= 0) {\n\t\t\t\tthis.runtime.closeFn(\n\t\t\t\t\tnew ClientSessionExpiredError(`Client session expired.`, timeoutMs),\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.sessionExpiryTimer = new Timer(timeoutMs, () => {\n\t\t\t\tthis.runtime.closeFn(\n\t\t\t\t\tnew ClientSessionExpiredError(`Client session expired.`, timeoutMs),\n\t\t\t\t);\n\t\t\t});\n\t\t\tthis.sessionExpiryTimer.start();\n\t\t\tthis.sessionExpiryTimerStarted = Date.now();\n\t\t}\n\n\t\tthis.summaryStateTracker = new GCSummaryStateTracker(this.configs);\n\n\t\tthis.telemetryTracker = new GCTelemetryTracker(\n\t\t\tthis.mc,\n\t\t\tthis.configs,\n\t\t\tthis.isSummarizerClient,\n\t\t\tcreateParams.createContainerMetadata,\n\t\t\t(nodeId: string) => this.runtime.getNodeType(nodeId),\n\t\t\t(nodeId: string) => this.unreferencedNodesState.get(nodeId),\n\t\t\tthis.getNodePackagePath,\n\t\t);\n\n\t\t// Get the GC data from the base snapshot. Use LazyPromise because we only want to do this once since it\n\t\t// it involves fetching blobs from storage which is expensive.\n\t\tthis.baseSnapshotDataP = new LazyPromise<IGarbageCollectionSnapshotData | undefined>(\n\t\t\tasync () => {\n\t\t\t\tif (baseSnapshot === undefined) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\t// For newer documents, GC data should be present in the GC tree in the root of the snapshot.\n\t\t\t\t\tconst gcSnapshotTree = baseSnapshot.trees[gcTreeKey];\n\t\t\t\t\tif (gcSnapshotTree === undefined) {\n\t\t\t\t\t\t// back-compat - Older documents get their gc data reset for simplicity as there are few of them\n\t\t\t\t\t\t// incremental gc summary will not work with older gc data as well\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst snapshotData = await getGCDataFromSnapshot(gcSnapshotTree, readAndParseBlob);\n\n\t\t\t\t\t// If the GC version in base snapshot does not match the GC version currently in effect, the GC data\n\t\t\t\t\t// in the snapshot cannot be interpreted correctly. Set everything to undefined except for\n\t\t\t\t\t// deletedNodes because irrespective of GC versions, these nodes have been deleted and cannot be\n\t\t\t\t\t// brought back. The deletedNodes info is needed to identify when these nodes are used.\n\t\t\t\t\tif (this.configs.gcVersionInEffect !== this.configs.gcVersionInBaseSnapshot) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tgcState: undefined,\n\t\t\t\t\t\t\ttombstones: undefined,\n\t\t\t\t\t\t\tdeletedNodes: snapshotData.deletedNodes,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\treturn snapshotData;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst dpe = DataProcessingError.wrapIfUnrecognized(error, \"FailedToInitializeGC\");\n\t\t\t\t\tdpe.addTelemetryProperties({\n\t\t\t\t\t\tgcConfigs: JSON.stringify(this.configs),\n\t\t\t\t\t});\n\t\t\t\t\tthrow dpe;\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\t/**\n\t\t * Set up the initializer which initializes the GC state from the data in base snapshot. It sets up GC data\n\t\t * from the base GC state and starts tracking the state of unreferenced nodes.\n\t\t *\n\t\t * Must only be called if there is a current reference timestamp.\n\t\t */\n\t\tthis.initializeGCStateFromBaseSnapshotP = new LazyPromise<void>(async () => {\n\t\t\tconst currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();\n\t\t\tassert(\n\t\t\t\tcurrentReferenceTimestampMs !== undefined,\n\t\t\t\t0x8a4 /* Trying to initialize GC state without current timestamp */,\n\t\t\t);\n\n\t\t\t/**\n\t\t\t * The base snapshot data will not be present if the container is loaded from:\n\t\t\t * 1. The first summary created by the detached container.\n\t\t\t * 2. A summary that was generated with GC disabled.\n\t\t\t * 3. A summary that was generated before GC even existed.\n\t\t\t */\n\t\t\tconst baseSnapshotData = await this.baseSnapshotDataP;\n\t\t\tthis.summaryStateTracker.initializeBaseState(baseSnapshotData);\n\n\t\t\tif (baseSnapshotData?.gcState === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Update unreferenced state tracking as per the GC state in the snapshot data and update gcDataFromLastRun\n\t\t\t// to the GC data from the snapshot data.\n\t\t\tconst gcNodes: { [id: string]: string[] } = {};\n\t\t\tfor (const [nodeId, nodeData] of Object.entries(baseSnapshotData.gcState.gcNodes)) {\n\t\t\t\tif (nodeData.unreferencedTimestampMs !== undefined) {\n\t\t\t\t\tthis.unreferencedNodesState.set(\n\t\t\t\t\t\tnodeId,\n\t\t\t\t\t\tnew UnreferencedStateTracker(\n\t\t\t\t\t\t\tnodeData.unreferencedTimestampMs,\n\t\t\t\t\t\t\tthis.configs.inactiveTimeoutMs,\n\t\t\t\t\t\t\tcurrentReferenceTimestampMs,\n\t\t\t\t\t\t\tthis.configs.tombstoneTimeoutMs,\n\t\t\t\t\t\t\tthis.configs.sweepGracePeriodMs,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tgcNodes[nodeId] = Array.from(nodeData.outboundRoutes);\n\t\t\t}\n\t\t\tthis.gcDataFromLastRun = { gcNodes };\n\t\t});\n\n\t\t// Get the GC details from the GC state in the base summary. This is returned in getBaseGCDetails which is\n\t\t// used to initialize the GC state of all the nodes in the container.\n\t\tthis.baseGCDetailsP = new LazyPromise<IGarbageCollectionDetailsBase>(async () => {\n\t\t\tconst baseSnapshotData = await this.baseSnapshotDataP;\n\t\t\tif (baseSnapshotData?.gcState === undefined) {\n\t\t\t\treturn {};\n\t\t\t}\n\n\t\t\t// Note that the base GC details are returned even if GC is disabled. This is to handle the special scenario\n\t\t\t// where GC is disabled but GC state exists in base snapshot. In this scenario, the nodes which get the GC\n\t\t\t// state will re-summarize to reset any GC specific state in their summaries (like unreferenced flag).\n\n\t\t\tconst gcNodes: { [id: string]: string[] } = {};\n\t\t\tfor (const [nodeId, nodeData] of Object.entries(baseSnapshotData.gcState.gcNodes)) {\n\t\t\t\tgcNodes[nodeId] = Array.from(nodeData.outboundRoutes);\n\t\t\t}\n\t\t\t// Run GC on the nodes in the base summary to get the routes used in each node in the container.\n\t\t\t// This is an optimization for space (vs performance) wherein we don't need to store the used routes of\n\t\t\t// each node in the summary.\n\t\t\tconst usedRoutes = runGarbageCollection(gcNodes, [\"/\"]).referencedNodeIds;\n\n\t\t\treturn { gcData: { gcNodes }, usedRoutes };\n\t\t});\n\n\t\t// Log all the GC options and the state determined by the garbage collector.\n\t\t// This is useful even for interactive clients since they track unreferenced nodes and log errors.\n\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\teventName: \"GarbageCollectorLoaded\",\n\t\t\tgcConfigs: JSON.stringify(this.configs),\n\t\t\tgcOptions: JSON.stringify(createParams.gcOptions),\n\t\t\t...createParams.createContainerMetadata,\n\t\t});\n\t}\n\n\t/**\n\t * Called during container initialization. Initializes the tombstone and deleted nodes state from the base snapshot.\n\t * Also, initializes the GC state including unreferenced nodes tracking if a current reference timestamp exists.\n\t * Note that if there is any GC state in the base snapshot, then there will definitely be a reference timestamp\n\t * to work with - The GC state would have been generated using a timestamp which is part of the snapshot.\n\t */\n\tpublic async initializeBaseState(): Promise<void> {\n\t\tconst baseSnapshotData = await this.baseSnapshotDataP;\n\t\t/**\n\t\t * The base snapshot data will not be present if the container is loaded from:\n\t\t * 1. The first summary created by the detached container.\n\t\t * 2. A summary that was generated with GC disabled.\n\t\t * 3. A summary that was generated before GC even existed.\n\t\t */\n\t\tif (baseSnapshotData === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize the deleted nodes from the snapshot. This is done irrespective of whether GC / sweep is enabled\n\t\t// to identify deleted nodes' usage.\n\t\tif (baseSnapshotData.deletedNodes !== undefined) {\n\t\t\tthis.deletedNodes = new Set(baseSnapshotData.deletedNodes);\n\t\t}\n\n\t\t// If running in tombstone mode, initialize the tombstone state from the snapshot. Also, notify the runtime of\n\t\t// tombstone routes.\n\t\tif (this.configs.tombstoneMode && baseSnapshotData.tombstones !== undefined) {\n\t\t\t// Create a copy since we are writing from a source we don't control\n\t\t\tthis.tombstones = Array.from(baseSnapshotData.tombstones);\n\t\t\tthis.runtime.updateTombstonedRoutes(this.tombstones);\n\t\t}\n\n\t\tawait this.initializeOrUpdateGCState();\n\t}\n\n\t/**\n\t * Initialize the GC state if not already initialized. If GC state is already initialized, update the unreferenced\n\t * state tracking as per the current reference timestamp.\n\t */\n\tprivate async initializeOrUpdateGCState() {\n\t\tconst currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();\n\t\tif (currentReferenceTimestampMs === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst initialized = this.gcDataFromLastRun !== undefined;\n\t\tawait PerformanceEvent.timedExecAsync(\n\t\t\tthis.mc.logger,\n\t\t\t{\n\t\t\t\teventName: \"InitializeOrUpdateGCState\",\n\t\t\t},\n\t\t\tasync (event) => {\n\t\t\t\t// If the GC state hasn't been initialized yet, initialize it and return.\n\t\t\t\tif (!initialized) {\n\t\t\t\t\tawait this.initializeGCStateFromBaseSnapshotP;\n\t\t\t\t} else {\n\t\t\t\t\t// If the GC state has been initialized, update the tracking of unreferenced nodes as per the current\n\t\t\t\t\t// reference timestamp.\n\t\t\t\t\tfor (const [, nodeStateTracker] of this.unreferencedNodesState) {\n\t\t\t\t\t\tnodeStateTracker.updateTracking(currentReferenceTimestampMs);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tevent.end({\n\t\t\t\t\tdetails: { initialized, unrefNodeCount: this.unreferencedNodesState.size },\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Called when the connection state of the runtime changes, i.e., it connects or disconnects. GC subscribes to this\n\t * to initialize or update the unreference state tracking.\n\t * @param connected - Whether the runtime connected / disconnected.\n\t * @param clientId - The clientId of this runtime.\n\t */\n\tpublic setConnectionState(connected: boolean, clientId?: string | undefined): void {\n\t\t/**\n\t\t * When the client connects (or reconnects), attempt to initialize or update the GC state. This will keep\n\t\t * the unreferenced state tracking updated as per the reference timestamp at the time of connection.\n\t\t *\n\t\t * During GC initialization and during connections in read mode, it is possible that either no ops are\n\t\t * processed or only trailing ops are processed. This means that the GC state is not initialized or initialized\n\t\t * with an older reference timestamp. So, doing this on every connection will keep the unreferenced state\n\t\t * tracking up-to-date.\n\t\t */\n\t\tif (connected && this.shouldRunGC) {\n\t\t\tthis.initializeOrUpdateGCState().catch((error) => {\n\t\t\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GCInitializationOrUpdateFailed\",\n\t\t\t\t\t\tgcConfigs: JSON.stringify(this.configs),\n\t\t\t\t\t\tclientId,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Returns a the GC details generated from the base summary. This is used to initialize the GC state of the nodes\n\t * in the container.\n\t */\n\tpublic async getBaseGCDetails(): Promise<IGarbageCollectionDetailsBase> {\n\t\treturn this.baseGCDetailsP;\n\t}\n\n\t/**\n\t * Runs garbage collection and updates the reference / used state of the nodes in the container.\n\t * @returns stats of the GC run or undefined if GC did not run.\n\t */\n\tpublic async collectGarbage(\n\t\toptions: {\n\t\t\t/** Logger to use for logging GC events */\n\t\t\tlogger?: ITelemetryLoggerExt;\n\t\t\t/** True to run GC sweep phase after the mark phase */\n\t\t\trunSweep?: boolean;\n\t\t\t/** True to generate full GC data */\n\t\t\tfullGC?: boolean;\n\t\t},\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<IGCStats | undefined> {\n\t\tconst fullGC =\n\t\t\toptions.fullGC ??\n\t\t\t(this.configs.runFullGC === true ||\n\t\t\t\tthis.summaryStateTracker.autoRecovery.fullGCRequested());\n\n\t\t// Add the options that are used to run GC to the telemetry context.\n\t\ttelemetryContext?.setMultiple(\"fluid_GC\", \"Options\", {\n\t\t\tfullGC,\n\t\t\trunSweep: options.runSweep,\n\t\t});\n\n\t\tconst logger = createChildLogger({\n\t\t\tlogger: options.logger ?? this.mc.logger,\n\t\t\tproperties: {\n\t\t\t\tall: { completedGCRuns: this.completedRuns, fullGC },\n\t\t\t},\n\t\t});\n\n\t\t/**\n\t\t * If there is no current reference timestamp, skip running GC. We need the current timestamp to track\n\t\t * how long objects have been unreferenced and if they should be deleted.\n\t\t *\n\t\t * Note that the only scenario where GC is called and there is no reference timestamp is when no ops have ever\n\t\t * been processed for this container and it is in read mode. In this scenario, there is no point in running GC\n\t\t * anyway because references in the container do not change without any ops, i.e., there is nothing to collect.\n\t\t */\n\t\tconst currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();\n\t\tif (currentReferenceTimestampMs === undefined) {\n\t\t\t// Log an event so we can evaluate how often we run into this scenario.\n\t\t\tlogger.sendErrorEvent({\n\t\t\t\teventName: \"CollectGarbageCalledWithoutTimestamp\",\n\t\t\t\tgcConfigs: JSON.stringify(this.configs),\n\t\t\t});\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\tlogger,\n\t\t\t{ eventName: \"GarbageCollection\" },\n\t\t\tasync (event) => {\n\t\t\t\t/** Pre-GC steps */\n\t\t\t\t// Ensure that state has been initialized from the base snapshot data.\n\t\t\t\tawait this.initializeGCStateFromBaseSnapshotP;\n\n\t\t\t\t/** GC step */\n\t\t\t\tconst gcStats = await this.runGC(fullGC, currentReferenceTimestampMs, logger);\n\t\t\t\tevent.end({\n\t\t\t\t\t...gcStats,\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\ttimestamp: currentReferenceTimestampMs,\n\t\t\t\t\t\tsweep: this.configs.shouldRunSweep,\n\t\t\t\t\t\ttombstone: this.configs.throwOnTombstoneLoad,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\t/** Post-GC steps */\n\t\t\t\t// Log pending unreferenced events such as a node being used after inactive. This is done after GC runs and\n\t\t\t\t// updates its state so that we don't send false positives based on intermediate state. For example, we may get\n\t\t\t\t// reference to an unreferenced node from another unreferenced node which means the node wasn't revived.\n\t\t\t\tawait this.telemetryTracker.logPendingEvents(logger);\n\t\t\t\t// Update the state of summary state tracker from this run's stats.\n\t\t\t\tthis.summaryStateTracker.updateStateFromGCRunStats(gcStats);\n\t\t\t\tthis.newReferencesSinceLastRun.clear();\n\t\t\t\tthis.completedRuns++;\n\n\t\t\t\treturn gcStats;\n\t\t\t},\n\t\t\t{ end: true, cancel: \"error\" },\n\t\t);\n\t}\n\n\t/**\n\t * Runs garbage collection. It does the following:\n\t *\n\t * 1. It generates / analyzes the runtime's reference graph.\n\t *\n\t * 2. Generates mark phase stats.\n\t *\n\t * 3. Runs Mark phase.\n\t *\n\t * 4. Runs Sweep phase.\n\t *\n\t * 5. Generates sweep phase stats.\n\t */\n\tprivate async runGC(\n\t\tfullGC: boolean,\n\t\tcurrentReferenceTimestampMs: number,\n\t\tlogger: ITelemetryLoggerExt,\n\t): Promise<IGCStats> {\n\t\t// 1. Generate / analyze the runtime's reference graph.\n\t\t// Get the reference graph (gcData) and run GC algorithm to get referenced / unreferenced nodes.\n\t\tconst gcData = await this.runtime.getGCData(fullGC);\n\t\tconst gcResult = runGarbageCollection(gcData.gcNodes, [\"/\"]);\n\t\t// Get all referenced nodes - References in this run + references between the previous and current runs.\n\t\tconst allReferencedNodeIds =\n\t\t\tthis.findAllNodesReferencedBetweenGCs(gcData, this.gcDataFromLastRun, logger) ??\n\t\t\tgcResult.referencedNodeIds;\n\n\t\t// 2. Get the mark phase stats based on the previous / current GC state.\n\t\t// This is done before running mark phase because we need the previous GC state before it is updated.\n\t\tconst markPhaseStats = this.getMarkPhaseStats(gcResult);\n\n\t\t// 3. Run the Mark phase.\n\t\t// It will mark nodes as referenced / unreferenced and return lists of tombstone-ready and sweep-ready nodes.\n\t\tconst { tombstoneReadyNodeIds, sweepReadyNodeIds } = this.runMarkPhase(\n\t\t\tgcResult,\n\t\t\tallReferencedNodeIds,\n\t\t\tcurrentReferenceTimestampMs,\n\t\t);\n\n\t\t// 4. Run the Sweep phase.\n\t\t// It will initiate the deletion (sending the GC Sweep op) of any sweep-ready nodes that are\n\t\t// allowed to be deleted per config, and tombstone the rest along with the tombstone-ready nodes.\n\t\t// Note that no nodes will be deleted until the GC Sweep op is processed.\n\t\tthis.runSweepPhase(gcResult, tombstoneReadyNodeIds, sweepReadyNodeIds);\n\n\t\tthis.gcDataFromLastRun = cloneGCData(gcData);\n\n\t\t// 5. Get the sweep phase stats.\n\t\tconst sweepPhaseStats = this.getSweepPhaseStats(\n\t\t\tthis.deletedNodes,\n\t\t\tsweepReadyNodeIds,\n\t\t\tmarkPhaseStats,\n\t\t);\n\n\t\treturn { ...markPhaseStats, ...sweepPhaseStats };\n\t}\n\n\t/**\n\t * Runs the GC Mark phase. It does the following:\n\t *\n\t * 1. Marks all referenced nodes in this run by clearing tracking for them.\n\t *\n\t * 2. Marks unreferenced nodes in this run by starting tracking for them.\n\t *\n\t * 3. Calls the runtime to update nodes that were marked referenced.\n\t *\n\t * @param gcResult - The result of the GC run on the gcData.\n\t * @param allReferencedNodeIds - Nodes referenced in this GC run + referenced between previous and current GC run.\n\t * @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.\n\t * @returns The sets of tombstone-ready and sweep-ready nodes, i.e., nodes that ready to be tombstoned or deleted.\n\t */\n\tprivate runMarkPhase(\n\t\tgcResult: IGCResult,\n\t\tallReferencedNodeIds: string[],\n\t\tcurrentReferenceTimestampMs: number,\n\t): { tombstoneReadyNodeIds: Set<string>; sweepReadyNodeIds: Set<string> } {\n\t\t// 1. Marks all referenced nodes by clearing their unreferenced tracker, if any.\n\t\tfor (const nodeId of allReferencedNodeIds) {\n\t\t\tthis.unreferencedNodesState.delete(nodeId);\n\t\t}\n\n\t\t// 2. Mark unreferenced nodes in this run by starting or updating unreferenced tracking for them.\n\t\tconst tombstoneReadyNodeIds: Set<string> = new Set();\n\t\tconst sweepReadyNodeIds: Set<string> = new Set();\n\t\tfor (const nodeId of gcResult.deletedNodeIds) {\n\t\t\tconst nodeStateTracker = this.unreferencedNodesState.get(nodeId);\n\t\t\tif (nodeStateTracker === undefined) {\n\t\t\t\tthis.unreferencedNodesState.set(\n\t\t\t\t\tnodeId,\n\t\t\t\t\tnew UnreferencedStateTracker(\n\t\t\t\t\t\tcurrentReferenceTimestampMs,\n\t\t\t\t\t\tthis.configs.inactiveTimeoutMs,\n\t\t\t\t\t\tcurrentReferenceTimestampMs,\n\t\t\t\t\t\tthis.configs.tombstoneTimeoutMs,\n\t\t\t\t\t\tthis.configs.sweepGracePeriodMs,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// If a node was already unreferenced, update its tracking information. Since the current reference time\n\t\t\t\t// is from the ops seen, this will ensure that we keep updating unreferenced state as time moves forward.\n\t\t\t\tnodeStateTracker.updateTracking(currentReferenceTimestampMs);\n\n\t\t\t\t// If a node is tombstone or sweep-ready, store it so it can be returned.\n\t\t\t\tif (nodeStateTracker.state === UnreferencedState.TombstoneReady) {\n\t\t\t\t\ttombstoneReadyNodeIds.add(nodeId);\n\t\t\t\t}\n\t\t\t\tif (nodeStateTracker.state === UnreferencedState.SweepReady) {\n\t\t\t\t\tsweepReadyNodeIds.add(nodeId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 3. Call the runtime to update referenced nodes in this run.\n\t\tthis.runtime.updateUsedRoutes(gcResult.referencedNodeIds);\n\n\t\treturn { tombstoneReadyNodeIds, sweepReadyNodeIds };\n\t}\n\n\t/**\n\t * Runs the GC Sweep phase. It does the following:\n\t *\n\t * 1. Marks tombstone-ready nodes as tombstones.\n\t *\n\t * 2. Sends a sweep op to delete nodes that are sweep-ready. Once the op is ack'd, these nodes will be deleted.\n\t *\n\t * @param gcResult - The result of the GC run on the gcData.\n\t * @param tombstoneReadyNodes - List of nodes that are tombstone-ready.\n\t * @param sweepReadyNodes - List of nodes that are sweep-ready.\n\t */\n\tprivate runSweepPhase(\n\t\tgcResult: IGCResult,\n\t\ttombstoneReadyNodes: Set<string>,\n\t\tsweepReadyNodes: Set<string>,\n\t) {\n\t\t/**\n\t\t * Under \"Test Mode\", unreferenced nodes are immediately deleted without waiting for them to be sweep-ready.\n\t\t *\n\t\t * Otherwise, depending on how long it's been since the node was unreferenced, it will either be\n\t\t * marked as Tombstone, or deleted by Sweep.\n\t\t */\n\n\t\tif (this.configs.testMode) {\n\t\t\t// If we are running in GC test mode, unreferenced nodes (gcResult.deletedNodeIds) are deleted immediately.\n\t\t\tthis.runtime.deleteSweepReadyNodes(gcResult.deletedNodeIds);\n\t\t\treturn;\n\t\t}\n\n\t\t// We'll build up the lists of nodes to be either Tombstoned or Deleted\n\t\t// based on the configuration and the nodes' current state.\n\t\t// We must Tombstone any sweep-ready node that Sweep won't run for.\n\t\t// This is important because a container may never load during a node's Sweep Grace Period,\n\t\t// so that node would directly become sweep-ready skipping over tombstone-ready state,\n\t\t// but should be Tombstoned since Sweep is disabled.\n\t\tconst { nodesToTombstone, nodesToDelete } = {\n\t\t\tnodesToTombstone: [...tombstoneReadyNodes],\n\t\t\tnodesToDelete: [] as string[],\n\t\t};\n\t\tswitch (this.configs.shouldRunSweep) {\n\t\t\tcase \"YES\":\n\t\t\t\tnodesToDelete.push(...sweepReadyNodes);\n\t\t\t\tbreak;\n\t\t\tcase \"ONLY_BLOBS\":\n\t\t\t\tsweepReadyNodes.forEach((nodeId) => {\n\t\t\t\t\tconst nodeType = this.runtime.getNodeType(nodeId);\n\t\t\t\t\tif (nodeType === GCNodeType.Blob) {\n\t\t\t\t\t\tnodesToDelete.push(nodeId);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnodesToTombstone.push(nodeId);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tdefault: // case \"NO\":\n\t\t\t\tnodesToTombstone.push(...sweepReadyNodes);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (this.configs.tombstoneMode) {\n\t\t\tthis.tombstones = nodesToTombstone;\n\t\t\t// If we are running in GC tombstone mode, update tombstoned routes.\n\t\t\tthis.runtime.updateTombstonedRoutes(this.tombstones);\n\t\t}\n\n\t\tif (nodesToDelete.length > 0) {\n\t\t\t// Do not send DDS node ids in the GC op. This is an optimization to reduce its size. Since GC applies to\n\t\t\t// to data store only, all its DDSes are deleted along with it. The DDS ids will be retrieved from the\n\t\t\t// local state when processing the op.\n\t\t\tconst sweepReadyDSAndBlobs = nodesToDelete.filter((nodeId) => {\n\t\t\t\tconst nodeType = this.runtime.getNodeType(nodeId);\n\t\t\t\treturn nodeType === GCNodeType.DataStore || nodeType === GCNodeType.Blob;\n\t\t\t});\n\t\t\tconst contents: GarbageCollectionMessage = {\n\t\t\t\ttype: GarbageCollectionMessageType.Sweep,\n\t\t\t\tdeletedNodeIds: sweepReadyDSAndBlobs,\n\t\t\t};\n\n\t\t\t// Its fine for older clients to ignore this op because it doesn't have any functional impact. This op\n\t\t\t// is an optimization to ensure that all clients are in sync when it comes to deleted nodes to prevent their\n\t\t\t// accidental usage. The clients will sync without the delete op too but it may take longer.\n\t\t\tconst containerGCMessage: ContainerRuntimeGCMessage = {\n\t\t\t\ttype: ContainerMessageType.GC,\n\t\t\t\tcontents,\n\t\t\t\tcompatDetails: { behavior: \"Ignore\" }, // DEPRECATED: For temporary back compat only\n\t\t\t};\n\t\t\tthis.submitMessage(containerGCMessage);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/**\n\t * Since GC runs periodically, the GC data that is generated only tells us the state of the world at that point in\n\t * time. There can be nodes that were referenced in between two runs and their unreferenced state needs to be\n\t * updated. For example, in the following scenarios not updating the unreferenced timestamp can lead to deletion of\n\t * these objects while there can be in-memory referenced to it:\n\t * 1. A node transitions from `unreferenced -> referenced -> unreferenced` between two runs. When the reference is\n\t * added, the object may have been accessed and in-memory reference to it added.\n\t * 2. A reference is added from one unreferenced node to one or more unreferenced nodes. Even though the node[s] were\n\t * unreferenced, they could have been accessed and in-memory reference to them added.\n\t *\n\t * This function identifies nodes that were referenced since the last run.\n\t * If these nodes are currently unreferenced, they will be assigned new unreferenced state by the current run.\n\t *\n\t * @returns A list of all nodes referenced from the last local summary until now.\n\t */\n\tprivate findAllNodesReferencedBetweenGCs(\n\t\tcurrentGCData: IGarbageCollectionData,\n\t\tpreviousGCData: IGarbageCollectionData | undefined,\n\t\tlogger: ITelemetryLoggerExt,\n\t): string[] | undefined {\n\t\t// If we haven't run GC before there is nothing to do.\n\t\t// No previousGCData, means nothing is unreferenced, and there are no reference state trackers to clear\n\t\tif (previousGCData === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t/**\n\t\t * If there are references that were not explicitly notified to GC, log an error because this should never happen.\n\t\t * If it does, this may result in the unreferenced timestamps of these nodes not updated when they were referenced.\n\t\t */\n\t\tthis.telemetryTracker.logIfMissingExplicitReferences(\n\t\t\tcurrentGCData,\n\t\t\tpreviousGCData,\n\t\t\tthis.newReferencesSinceLastRun,\n\t\t\tlogger,\n\t\t);\n\n\t\t// No references were added since the last run so we don't have to update reference states of any unreferenced\n\t\t// nodes. There is no in between state at this point.\n\t\tif (this.newReferencesSinceLastRun.size === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t/**\n\t\t * Generate a super set of the GC data that contains the nodes and edges from last run, plus any new node and\n\t\t * edges that have been added since then. To do this, combine the GC data from the last run and the current\n\t\t * run, and then add the references since last run.\n\t\t *\n\t\t * Note on why we need to combine the data from previous run, current run and all references in between -\n\t\t * 1. We need data from last run because some of its references may have been deleted since then. If those\n\t\t * references added new outbound references before they were deleted, we need to detect them.\n\t\t *\n\t\t * 2. We need new outbound references since last run because some of them may have been deleted later. If those\n\t\t * references added new outbound references before they were deleted, we need to detect them.\n\t\t *\n\t\t * 3. We need data from the current run because currently we may not detect when DDSes are referenced:\n\t\t * - We don't require DDSes handles to be stored in a referenced DDS.\n\t\t * - A new data store may have \"root\" DDSes already created and we don't detect them today.\n\t\t */\n\t\tconst gcDataSuperSet = concatGarbageCollectionData(previousGCData, currentGCData);\n\t\tconst newOutboundRoutesSinceLastRun: string[] = [];\n\t\tthis.newReferencesSinceLastRun.forEach(\n\t\t\t(outboundRoutes: string[], sourceNodeId: string) => {\n\t\t\t\tif (gcDataSuperSet.gcNodes[sourceNodeId] === undefined) {\n\t\t\t\t\tgcDataSuperSet.gcNodes[sourceNodeId] = outboundRoutes;\n\t\t\t\t} else {\n\t\t\t\t\t// Non null asserting here because we are checking if it is undefined above.\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tgcDataSuperSet.gcNodes[sourceNodeId]!.push(...outboundRoutes);\n\t\t\t\t}\n\t\t\t\tnewOutboundRoutesSinceLastRun.push(...outboundRoutes);\n\t\t\t},\n\t\t);\n\n\t\t/**\n\t\t * Run GC on the above reference graph starting with root and all new outbound routes. This will generate a\n\t\t * list of all nodes that could have been referenced since the last run. If any of these nodes are unreferenced,\n\t\t * unreferenced, stop tracking them and remove from unreferenced list.\n\t\t * Note that some of these nodes may be unreferenced now and if so, the current run will mark them as\n\t\t * unreferenced and add unreferenced state.\n\t\t */\n\t\tconst gcResult = runGarbageCollection(gcDataSuperSet.gcNodes, [\n\t\t\t\"/\",\n\t\t\t...newOutboundRoutesSinceLastRun,\n\t\t]);\n\t\treturn gcResult.referencedNodeIds;\n\t}\n\n\t/**\n\t * Summarizes the GC data and returns it as a summary tree.\n\t * We current write the entire GC state in a single blob. This can be modified later to write multiple\n\t * blobs. All the blob keys should start with `gcBlobPrefix`.\n\t */\n\tpublic summarize(\n\t\tfullTree: boolean,\n\t\ttrackState: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): ISummarizeResult | undefined {\n\t\tif (!this.shouldRunGC || this.gcDataFromLastRun === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst gcState: IGarbageCollectionState = { gcNodes: {} };\n\t\tfor (const [nodeId, outboundRoutes] of Object.entries(this.gcDataFromLastRun.gcNodes)) {\n\t\t\tgcState.gcNodes[nodeId] = {\n\t\t\t\toutboundRoutes,\n\t\t\t\tunreferencedTimestampMs:\n\t\t\t\t\tthis.unreferencedNodesState.get(nodeId)?.unreferencedTimestampMs,\n\t\t\t};\n\t\t}\n\n\t\treturn this.summaryStateTracker.summarize(\n\t\t\ttrackState && !fullTree,\n\t\t\tgcState,\n\t\t\tthis.deletedNodes,\n\t\t\tthis.tombstones,\n\t\t);\n\t}\n\n\tpublic getMetadata(): IGCMetadata {\n\t\treturn {\n\t\t\t/**\n\t\t\t * If GC is enabled, the GC data is written using the GC version in effect and that is the gcFeature that goes\n\t\t\t * into the metadata blob. If GC is disabled, the gcFeature is 0.\n\t\t\t */\n\t\t\tgcFeature: this.configs.gcEnabled ? this.configs.gcVersionInEffect : 0,\n\t\t\tgcFeatureMatrix: this.configs.persistedGcFeatureMatrix,\n\t\t\tsessionExpiryTimeoutMs: this.configs.sessionExpiryTimeoutMs,\n\t\t\tsweepEnabled: false, // DEPRECATED - to be removed\n\t\t\ttombstoneTimeoutMs: this.configs.tombstoneTimeoutMs,\n\t\t};\n\t}\n\n\t/**\n\t * Called to refresh the latest summary state. This happens when either a pending summary is acked.\n\t */\n\tpublic async refreshLatestSummary(result: IRefreshSummaryResult): Promise<void> {\n\t\treturn this.summaryStateTracker.refreshLatestSummary(result);\n\t}\n\n\t/**\n\t * Process a GC message.\n\t * @param message - The GC message from the container runtime.\n\t * @param messageTimestampMs - The timestamp of the message.\n\t * @param local - Whether it was send by this client.\n\t */\n\tpublic processMessage(\n\t\tmessage: ContainerRuntimeGCMessage,\n\t\tmessageTimestampMs: number,\n\t\tlocal: boolean,\n\t) {\n\t\tconst gcMessageType = message.contents.type;\n\t\tswitch (gcMessageType) {\n\t\t\tcase GarbageCollectionMessageType.Sweep: {\n\t\t\t\t// Delete the nodes whose ids are present in the contents.\n\t\t\t\tthis.deleteSweepReadyNodes(message.contents.deletedNodeIds);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase GarbageCollectionMessageType.TombstoneLoaded: {\n\t\t\t\tif (\n\t\t\t\t\t!this.configs.tombstoneAutorecoveryEnabled ||\n\t\t\t\t\tthis.mc.config.getBoolean(disableAutoRecoveryKey) === true\n\t\t\t\t) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Mark the node as referenced to ensure it isn't Swept\n\t\t\t\tconst tombstonedNodePath = message.contents.nodePath;\n\t\t\t\tthis.addedOutboundReference(\n\t\t\t\t\t\"/\",\n\t\t\t\t\ttombstonedNodePath,\n\t\t\t\t\tmessageTimestampMs,\n\t\t\t\t\ttrue /* autorecovery */,\n\t\t\t\t);\n\n\t\t\t\t// In case the cause of the TombstoneLoaded event is incorrect GC Data (i.e. the object is actually reachable),\n\t\t\t\t// do fullGC on the next run to get a chance to repair (in the likely case the bug is not deterministic)\n\t\t\t\tthis.summaryStateTracker.autoRecovery.requestFullGCOnNextRun();\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tif (\n\t\t\t\t\t!compatBehaviorAllowsGCMessageType(gcMessageType, message.compatDetails?.behavior)\n\t\t\t\t) {\n\t\t\t\t\tconst error = DataProcessingError.create(\n\t\t\t\t\t\t`Garbage collection message of unknown type ${gcMessageType}`,\n\t\t\t\t\t\t\"processMessage\",\n\t\t\t\t\t);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Delete nodes that are sweep-ready. Call the runtime to delete these nodes and clear the unreferenced state\n\t * tracking for nodes that are actually deleted by the runtime.\n\t *\n\t * Note that this doesn't check any configuration around whether Sweep is enabled.\n\t * That happens before the op is submitted, and from that point, any client should execute the delete.\n\t *\n\t * @param sweepReadyNodeIds - The ids of nodes that are ready to be deleted.\n\t */\n\tprivate deleteSweepReadyNodes(sweepReadyNodeIds: readonly string[]) {\n\t\t// Use a set for lookup because its much faster than array or map.\n\t\tconst sweepReadyNodesSet: Set<string> = new Set(sweepReadyNodeIds);\n\n\t\t// The ids in the sweep-ready nodes do not contain DDS node ids. This is an optimization to reduce the size\n\t\t// of the GC op. Since GC applies to data store only, all its DDSes are deleted along with it. So, get the\n\t\t// DDS nodes ID from the unreferenced nodes state.\n\t\tconst allSweepReadyNodeIds = Array.from(sweepReadyNodeIds);\n\t\tfor (const [id] of this.unreferencedNodesState) {\n\t\t\t// Ignore data store nodes since they would already be in the list.\n\t\t\tconst pathParts = id.split(\"/\");\n\t\t\tif (pathParts.length <= 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Get the data store id part. Note that this may include blobs but that's okay since the part would just\n\t\t\t// be \"_blobs\" and it won't be found.\n\t\t\tconst dsId = `/${pathParts[1]}`;\n\t\t\tif (sweepReadyNodesSet.has(dsId)) {\n\t\t\t\tallSweepReadyNodeIds.push(id);\n\t\t\t}\n\t\t}\n\t\tconst deletedNodeIds = this.runtime.deleteSweepReadyNodes(allSweepReadyNodeIds);\n\n\t\t// Clear unreferenced state tracking for deleted nodes.\n\t\tfor (const nodeId of deletedNodeIds) {\n\t\t\t// Usually we avoid modifying the set of unreferencedNodesState keys in between GC runs,\n\t\t\t// but this is ok since this node won't exist at all in the next GC run.\n\t\t\tthis.unreferencedNodesState.delete(nodeId);\n\t\t\tthis.deletedNodes.add(nodeId);\n\t\t}\n\t}\n\n\t/**\n\t * Called when a node with the given id is updated. If the node is inactive or tombstoned, this will log an error\n\t * or throw an error if failing on incorrect usage is configured.\n\t * @param IGCNodeUpdatedProps - Details about the node and how it was updated\n\t */\n\tpublic nodeUpdated({\n\t\tnode,\n\t\treason,\n\t\ttimestampMs,\n\t\tpackagePath,\n\t\trequest,\n\t\theaderData,\n\t\tadditionalProps,\n\t}: IGCNodeUpdatedProps) {\n\t\t// If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip\n\t\t// logging as nothing interesting would have happened worth logging.\n\t\tif (!this.shouldRunGC || timestampMs === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\t// trackedId will be either DataStore or Blob ID (not sub-DataStore ID, since some of those are unrecognized by GC)\n\t\tconst trackedId = node.path;\n\t\tconst isTombstoned = this.tombstones.includes(trackedId);\n\t\tconst isInactive = this.unreferencedNodesState.get(trackedId)?.state === \"Inactive\";\n\n\t\tconst fullPath = request !== undefined ? urlToGCNodePath(request.url) : trackedId;\n\n\t\t// This will log if appropriate\n\t\tthis.telemetryTracker.nodeUsed(trackedId, {\n\t\t\tid: fullPath,\n\t\t\tusageType: reason,\n\t\t\tcurrentReferenceTimestampMs: timestampMs,\n\t\t\tpackagePath,\n\t\t\tcompletedGCRuns: this.completedRuns,\n\t\t\tisTombstoned,\n\t\t\tlastSummaryTime: this.getLastSummaryTimestampMs(),\n\t\t\theaders: headerData,\n\t\t\trequestUrl: request?.url,\n\t\t\trequestHeaders: JSON.stringify(request?.headers),\n\t\t\tadditionalProps,\n\t\t});\n\n\t\t// Any time we log a Tombstone Loaded error (via Telemetry Tracker),\n\t\t// we want to also trigger autorecovery to avoid the object being deleted\n\t\t// Note: We don't need to trigger on \"Changed\" because any change will cause the object\n\t\t// to be loaded by the Summarizer, and auto-recovery will be triggered then.\n\t\tif (isTombstoned && reason === \"Loaded\") {\n\t\t\t// Note that when a DataStore and its DDS are all loaded, each will trigger AutoRecovery for itself.\n\t\t\tthis.triggerAutoRecovery(fullPath);\n\t\t}\n\n\t\tconst nodeType = this.runtime.getNodeType(fullPath);\n\n\t\t// Unless this is a Loaded event for a Blob or DataStore, we're done after telemetry tracking\n\t\tconst loadedBlobOrDataStore =\n\t\t\treason === \"Loaded\" &&\n\t\t\t(nodeType === GCNodeType.Blob || nodeType === GCNodeType.DataStore);\n\t\tif (!loadedBlobOrDataStore) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst errorRequest: IRequest = request ?? { url: fullPath };\n\t\tif (isTombstoned && this.throwOnTombstoneLoad && headerData?.allowTombstone !== true) {\n\t\t\t// The requested data store is removed by gc. Create a 404 gc response exception.\n\t\t\tthrow responseToException(\n\t\t\t\tcreateResponseError(404, `${nodeType} was tombstoned`, errorRequest, {\n\t\t\t\t\t[TombstoneResponseHeaderKey]: true,\n\t\t\t\t}),\n\t\t\t\terrorRequest,\n\t\t\t);\n\t\t}\n\n\t\t// If the object is inactive and inactive enforcement is configured, throw an error.\n\t\tif (isInactive) {\n\t\t\tconst shouldThrowOnInactiveLoad =\n\t\t\t\t!this.isSummarizerClient &&\n\t\t\t\tthis.configs.throwOnInactiveLoad === true &&\n\t\t\t\theaderData?.allowInactive !== true;\n\t\t\tif (shouldThrowOnInactiveLoad) {\n\t\t\t\tthrow responseToException(\n\t\t\t\t\tcreateResponseError(404, `${nodeType} is inactive`, errorRequest, {\n\t\t\t\t\t\t[InactiveResponseHeaderKey]: true,\n\t\t\t\t\t}),\n\t\t\t\t\terrorRequest,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The given node should have its unreferenced state reset in the next GC,\n\t * even if the true GC graph shows it is unreferenced. This will\n\t * prevent it from being deleted by Sweep (after the Grace Period).\n\t *\n\t * Submit a GC op indicating that the Tombstone with the given path has been loaded.\n\t * Broadcasting this information in the op stream allows the Summarizer to reset unreferenced state\n\t * before runnint GC next.\n\t */\n\tprivate triggerAutoRecovery(nodePath: string) {\n\t\tif (\n\t\t\t!this.configs.tombstoneAutorecoveryEnabled ||\n\t\t\tthis.mc.config.getBoolean(disableAutoRecoveryKey) === true\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Use compat behavior \"Ignore\" since this is an optimization to opportunistically protect\n\t\t// objects from deletion, so it's fine for older clients to ignore this op.\n\t\tconst containerGCMessage: ContainerRuntimeGCMessage = {\n\t\t\ttype: ContainerMessageType.GC,\n\t\t\tcontents: {\n\t\t\t\ttype: GarbageCollectionMessageType.TombstoneLoaded,\n\t\t\t\tnodePath,\n\t\t\t},\n\t\t\tcompatDetails: { behavior: \"Ignore\" }, // DEPRECATED: For temporary back compat only\n\t\t};\n\t\tthis.submitMessage(containerGCMessage);\n\t}\n\n\t/**\n\t * Called when an outbound reference is added to a node. This is used to identify all nodes that have been\n\t * referenced between summaries so that their unreferenced timestamp can be reset.\n\t *\n\t * @param fromNodePath - The node from which the reference is added.\n\t * @param toNodePath - The node to which the reference is added.\n\t * @param timestampMs - The timestamp of the message that added the reference.\n\t * @param autorecovery - This reference is added artificially, for autorecovery. Used for logging.\n\t */\n\tpublic addedOutboundReference(\n\t\tfromNodePath: string,\n\t\ttoNodePath: string,\n\t\ttimestampMs: number,\n\t\tautorecovery?: true,\n\t) {\n\t\tif (!this.shouldRunGC) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!toNodePath.startsWith(\"/\")) {\n\t\t\t// A long time ago we stored handles with relatives paths. We don't expect to see these cases though\n\t\t\t// because GC was enabled only after we made the switch to always using absolute paths.\n\t\t\tthis.mc.logger.sendErrorEvent({\n\t\t\t\teventName: \"InvalidRelativeOutboundRoute\",\n\t\t\t\t...tagCodeArtifacts({ fromId: fromNodePath, id: toNodePath }),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tassert(fromNodePath.startsWith(\"/\"), 0x8a5 /* fromNodePath must be an absolute path */);\n\n\t\tconst outboundRoutes = this.newReferencesSinceLastRun.get(fromNodePath) ?? [];\n\t\toutboundRoutes.push(toNodePath);\n\t\tthis.newReferencesSinceLastRun.set(fromNodePath, outboundRoutes);\n\n\t\t// GC won't recognize some subDataStore paths that we encounter (e.g. a path suited for a custom request handler)\n\t\t// So for subDataStore paths we need to check the parent dataStore for current tombstone/inactive status.\n\t\tconst trackedId =\n\t\t\tthis.runtime.getNodeType(toNodePath) === \"SubDataStore\"\n\t\t\t\t? dataStoreNodePathOnly(toNodePath)\n\t\t\t\t: toNodePath;\n\t\tthis.telemetryTracker.nodeUsed(trackedId, {\n\t\t\tid: toNodePath,\n\t\t\tfromId: fromNodePath,\n\t\t\tusageType: \"Revived\",\n\t\t\tcurrentReferenceTimestampMs: timestampMs,\n\t\t\tpackagePath: undefined,\n\t\t\tcompletedGCRuns: this.completedRuns,\n\t\t\tisTombstoned: this.tombstones.includes(trackedId),\n\t\t\tlastSummaryTime: this.getLastSummaryTimestampMs(),\n\t\t\tautorecovery,\n\t\t});\n\n\t\t// This node is referenced - Clear its unreferenced state if present\n\t\t// But don't delete the node id from the map yet.\n\t\t// When generating GC stats, the set of nodes in here is used as the baseline for\n\t\t// what was unreferenced in the last GC run.\n\t\t// NOTE: We use toNodePath not trackedId even though it may be an unrecognized subDataStore route (hence no-op),\n\t\t// because a reference to such a path is not sufficient to consider the DataStore referenced.\n\t\tthis.unreferencedNodesState.get(toNodePath)?.stopTracking();\n\t}\n\n\t/**\n\t * Returns whether a node with the given path has been deleted or not. This can be used by the runtime to identify\n\t * cases where objects are used after they are deleted and throw / log errors accordingly.\n\t */\n\tpublic isNodeDeleted(nodePath: string): boolean {\n\t\treturn this.deletedNodes.has(nodePath);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.sessionExpiryTimer?.clear();\n\t\tthis.sessionExpiryTimer = undefined;\n\t}\n\n\t/**\n\t * Generates the stats of a garbage collection mark phase run.\n\t * @param gcResult - The result of the current GC run.\n\t * @returns the stats of the mark phase run.\n\t */\n\tprivate getMarkPhaseStats(gcResult: IGCResult): IMarkPhaseStats {\n\t\tconst markPhaseStats: IMarkPhaseStats = {\n\t\t\tnodeCount: 0,\n\t\t\tdataStoreCount: 0,\n\t\t\tattachmentBlobCount: 0,\n\t\t\tunrefNodeCount: 0,\n\t\t\tunrefDataStoreCount: 0,\n\t\t\tunrefAttachmentBlobCount: 0,\n\t\t\tupdatedNodeCount: 0,\n\t\t\tupdatedDataStoreCount: 0,\n\t\t\tupdatedAttachmentBlobCount: 0,\n\t\t};\n\n\t\tconst updateNodeStats = (nodeId: string, isReferenced: boolean) => {\n\t\t\tmarkPhaseStats.nodeCount++;\n\t\t\t// If there is no previous GC data, every node's state is generated and is considered as updated.\n\t\t\t// Otherwise, find out if any node went from referenced to unreferenced or vice-versa.\n\t\t\tconst wasNotReferenced = this.unreferencedNodesState.has(nodeId);\n\t\t\tconst stateUpdated =\n\t\t\t\tthis.gcDataFromLastRun === undefined || wasNotReferenced === isReferenced;\n\t\t\tif (stateUpdated) {\n\t\t\t\tmarkPhaseStats.updatedNodeCount++;\n\t\t\t}\n\t\t\tif (!isReferenced) {\n\t\t\t\tmarkPhaseStats.unrefNodeCount++;\n\t\t\t}\n\n\t\t\tif (this.runtime.getNodeType(nodeId) === GCNodeType.DataStore) {\n\t\t\t\tmarkPhaseStats.dataStoreCount++;\n\t\t\t\tif (stateUpdated) {\n\t\t\t\t\tmarkPhaseStats.updatedDataStoreCount++;\n\t\t\t\t}\n\t\t\t\tif (!isReferenced) {\n\t\t\t\t\tmarkPhaseStats.unrefDataStoreCount++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.runtime.getNodeType(nodeId) === GCNodeType.Blob) {\n\t\t\t\tmarkPhaseStats.attachmentBlobCount++;\n\t\t\t\tif (stateUpdated) {\n\t\t\t\t\tmarkPhaseStats.updatedAttachmentBlobCount++;\n\t\t\t\t}\n\t\t\t\tif (!isReferenced) {\n\t\t\t\t\tmarkPhaseStats.unrefAttachmentBlobCount++;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tfor (const nodeId of gcResult.referencedNodeIds) {\n\t\t\tupdateNodeStats(nodeId, true /* referenced */);\n\t\t}\n\n\t\tfor (const nodeId of gcResult.deletedNodeIds) {\n\t\t\tupdateNodeStats(nodeId, false /* referenced */);\n\t\t}\n\n\t\treturn markPhaseStats;\n\t}\n\n\t/**\n\t * Generates the stats of a garbage collection sweep phase run.\n\t * @param deletedNodes - The nodes that have already been deleted even before this run.\n\t * @param sweepReadyNodes - The nodes that are sweep-ready in this GC run. These will be deleted but are not deleted yet,\n\t * due to either sweep not being enabled or the Sweep Op needing to roundtrip before the delete is executed.\n\t * @param markPhaseStats - The stats of the mark phase run.\n\t * @returns the stats of the sweep phase run.\n\t */\n\tprivate getSweepPhaseStats(\n\t\tdeletedNodes: Set<string>,\n\t\tsweepReadyNodes: Set<string>,\n\t\tmarkPhaseStats: IMarkPhaseStats,\n\t): ISweepPhaseStats {\n\t\t// Initialize the life time node counts to the mark phase node counts. If sweep is not enabled,\n\t\t// these will be the life time node count for this container.\n\t\tconst sweepPhaseStats: ISweepPhaseStats = {\n\t\t\tlifetimeNodeCount: markPhaseStats.nodeCount,\n\t\t\tlifetimeDataStoreCount: markPhaseStats.dataStoreCount,\n\t\t\tlifetimeAttachmentBlobCount: markPhaseStats.attachmentBlobCount,\n\t\t\tdeletedNodeCount: 0,\n\t\t\tdeletedDataStoreCount: 0,\n\t\t\tdeletedAttachmentBlobCount: 0,\n\t\t};\n\n\t\t// The runtime can't reliably identify the type of deleted nodes. So, get the type here. This should\n\t\t// be good enough because the only types that participate in GC today are data stores, DDSes and blobs.\n\t\tconst getDeletedNodeType = (nodeId: string): GCNodeType => {\n\t\t\tconst pathParts = nodeId.split(\"/\");\n\t\t\tif (pathParts[1] === blobManagerBasePath) {\n\t\t\t\treturn GCNodeType.Blob;\n\t\t\t}\n\t\t\tif (pathParts.length === 2) {\n\t\t\t\treturn GCNodeType.DataStore;\n\t\t\t}\n\t\t\tif (pathParts.length === 3) {\n\t\t\t\treturn GCNodeType.SubDataStore;\n\t\t\t}\n\t\t\treturn GCNodeType.Other;\n\t\t};\n\n\t\tfor (const nodeId of deletedNodes) {\n\t\t\tsweepPhaseStats.deletedNodeCount++;\n\t\t\tconst nodeType = getDeletedNodeType(nodeId);\n\t\t\tif (nodeType === GCNodeType.DataStore) {\n\t\t\t\tsweepPhaseStats.deletedDataStoreCount++;\n\t\t\t} else if (nodeType === GCNodeType.Blob) {\n\t\t\t\tsweepPhaseStats.deletedAttachmentBlobCount++;\n\t\t\t}\n\t\t}\n\n\t\t// The counts from the mark phase stats do not include nodes that were\n\t\t// deleted in previous runs. So, add the deleted node counts to life time stats.\n\t\tsweepPhaseStats.lifetimeNodeCount += sweepPhaseStats.deletedNodeCount;\n\t\tsweepPhaseStats.lifetimeDataStoreCount += sweepPhaseStats.deletedDataStoreCount;\n\t\tsweepPhaseStats.lifetimeAttachmentBlobCount += sweepPhaseStats.deletedAttachmentBlobCount;\n\n\t\t// These stats are used to estimate the impact of GC in terms of how much garbage is/will be cleaned up.\n\t\t// So we include the current sweep-ready node stats since these nodes will be deleted eventually.\n\t\t// - If sweep is enabled, this will happen in the run after the GC op round trips back\n\t\t// (they'll be in deletedNodes that time).\n\t\t// - If sweep is not enabled, we still want to include these nodes since they\n\t\t// _will be_ deleted once it is enabled.\n\t\tfor (const nodeId of sweepReadyNodes) {\n\t\t\tsweepPhaseStats.deletedNodeCount++;\n\t\t\tconst nodeType = this.runtime.getNodeType(nodeId);\n\t\t\tif (nodeType === GCNodeType.DataStore) {\n\t\t\t\tsweepPhaseStats.deletedDataStoreCount++;\n\t\t\t} else if (nodeType === GCNodeType.Blob) {\n\t\t\t\tsweepPhaseStats.deletedAttachmentBlobCount++;\n\t\t\t}\n\t\t}\n\n\t\treturn sweepPhaseStats;\n\t}\n}\n"]}
@@ -7,7 +7,7 @@ import { IRequest } from "@fluidframework/core-interfaces";
7
7
  import { ISnapshotTree } from "@fluidframework/driver-definitions/internal";
8
8
  import { ITelemetryContext, IGarbageCollectionData, IGarbageCollectionDetailsBase, ISummarizeResult } from "@fluidframework/runtime-definitions/internal";
9
9
  import { ReadAndParseBlob } from "@fluidframework/runtime-utils/internal";
10
- import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
10
+ import { ITelemetryLoggerExt, type ITelemetryPropertiesExt } from "@fluidframework/telemetry-utils/internal";
11
11
  import { RuntimeHeaderData } from "../containerRuntime.js";
12
12
  import { ContainerRuntimeGCMessage } from "../messageTypes.js";
13
13
  import { IContainerRuntimeMetadata, ICreateContainerMetadata, IRefreshSummaryResult } from "../summary/index.js";
@@ -339,7 +339,7 @@ export interface IGCNodeUpdatedProps {
339
339
  path: string;
340
340
  };
341
341
  /** Whether the node (or a subpath) was loaded or changed. */
342
- reason: "Loaded" | "Changed";
342
+ reason: "Loaded" | "Changed" | "Realized";
343
343
  /**
344
344
  * The op-based timestamp when the node changed. If the update is from receiving an op, this should
345
345
  * be the timestamp of the op. If not, this should be the timestamp of the last op processed.
@@ -351,6 +351,8 @@ export interface IGCNodeUpdatedProps {
351
351
  request?: IRequest;
352
352
  /** If the node was loaded via request path, the header data. May be modified from the original request */
353
353
  headerData?: RuntimeHeaderData;
354
+ /** Any other properties to be logged. */
355
+ additionalProps?: ITelemetryPropertiesExt;
354
356
  }
355
357
  /** Parameters necessary for creating a GarbageCollector. */
356
358
  export interface IGarbageCollectorCreateParams {
@@ -1 +1 @@
1
- {"version":3,"file":"gcDefinitions.d.ts","sourceRoot":"","sources":["../../src/gc/gcDefinitions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gcDefinitions.d.ts","sourceRoot":"","sources":["../../src/gc/gcDefinitions.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"gcDefinitions.js","sourceRoot":"","sources":["../../src/gc/gcDefinitions.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA4BH,4CAA4C;AAC/B,QAAA,eAAe,GAAc,CAAC,CAAC;AAC5C,0GAA0G;AAC7F,QAAA,aAAa,GAAc,CAAC,CAAC;AAE1C;;;;;GAKG;AACU,QAAA,uCAAuC,GAAG,+BAA+B,CAAC;AAEvF;;;GAGG;AACU,QAAA,iCAAiC,GAAG,uBAAuB,CAAC;AAEzE;;;;;;;;;;GAUG;AACU,QAAA,sBAAsB,GAAG,cAAc,CAAC;AAErD,gDAAgD;AACnC,QAAA,aAAa,GAAG,oCAAoC,CAAC;AAClE,mFAAmF;AACtE,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,mHAAmH;AACtG,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,4FAA4F;AAC/E,QAAA,+BAA+B,GAC3C,sDAAsD,CAAC;AACxD,4GAA4G;AAC/F,QAAA,wBAAwB,GAAG,+CAA+C,CAAC;AACxF,+CAA+C;AAClC,QAAA,uBAAuB,GAAG,8CAA8C,CAAC;AACtF,mFAAmF;AACtE,QAAA,wBAAwB,GAAG,+CAA+C,CAAC;AACxF,yHAAyH;AAC5G,QAAA,sBAAsB,GAAG,6CAA6C,CAAC;AAEpF,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;AAC1D,QAAA,yBAAyB,GAAG,CAAC,GAAG,gBAAQ,CAAC,CAAC,QAAQ;AA6I/D;;;;GAIG;AACU,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;CACL,CAAC;AAQX;;;GAGG;AACU,QAAA,4BAA4B,GAAG;IAC3C,0DAA0D;IAC1D,KAAK,EAAE,OAAO;IACd,oEAAoE;IACpE,eAAe,EAAE,iBAAiB;CACzB,CAAC;AA0QX,8CAA8C;AACjC,QAAA,iBAAiB,GAAG;IAChC,gEAAgE;IAChE,MAAM,EAAE,QAAQ;IAChB,mEAAmE;IACnE,QAAQ,EAAE,UAAU;IACpB,yCAAyC;IACzC,cAAc,EAAE,gBAAgB;IAChC,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 { IRequest } from \"@fluidframework/core-interfaces\";\nimport { ISnapshotTree } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tITelemetryContext,\n\tIGarbageCollectionData,\n\tIGarbageCollectionDetailsBase,\n\tISummarizeResult,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { ReadAndParseBlob } from \"@fluidframework/runtime-utils/internal\";\nimport { ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { RuntimeHeaderData } from \"../containerRuntime.js\";\nimport { ContainerRuntimeGCMessage } from \"../messageTypes.js\";\nimport {\n\tIContainerRuntimeMetadata,\n\tICreateContainerMetadata,\n\tIRefreshSummaryResult,\n} from \"../summary/index.js\";\n\n/**\n * @legacy\n * @alpha\n */\nexport type GCVersion = number;\n\n/** The stable/default version of GC Data */\nexport const stableGCVersion: GCVersion = 3;\n/** The next version of GC Data, to bump to in case we need to regenerate all GC Data across all files. */\nexport const nextGCVersion: GCVersion = 4;\n\n/**\n * This undocumented GC Option (on ContainerRuntime Options) allows an app to disable throwing an error when tombstone\n * object is loaded (requested), merely logging a message instead.\n *\n * By default, attempting to load a Tombstoned object will result in an error.\n */\nexport const gcDisableThrowOnTombstoneLoadOptionName = \"gcDisableThrowOnTombstoneLoad\";\n\n/**\n * This undocumented GC Option (on ContainerRuntime Options) allows an app to enable Sweep for blobs only.\n * Only applies if enableGCSweep option is set to true.\n */\nexport const gcDisableDataStoreSweepOptionName = \"disableDataStoreSweep\";\n\n/**\n * This undocumented GC Option (on ContainerRuntime Options) allows configuring which documents can have Sweep enabled.\n * This provides a way to disable both Tombstone Enforcement and Sweep.\n *\n * If unset, Tombstone Enforcement + Sweep will operate as otherwise configured.\n * Otherwise, the Sweep Phase will be disabled for documents where persisted value doesn't match what is passed into this session.\n * This provides a way to disallow Sweep for old documents that may be too difficult for an app to repair,\n * in case a bug is found that violates GC's assumptions.\n *\n * @see GCFeatureMatrix (gcGeneration)\n */\nexport const gcGenerationOptionName = \"gcGeneration\";\n\n/** Config key to turn GC test mode on / off. */\nexport const gcTestModeKey = \"Fluid.GarbageCollection.GCTestMode\";\n/** Config key to expire a session after a set period of time. Defaults to true. */\nexport const runSessionExpiryKey = \"Fluid.GarbageCollection.RunSessionExpiry\";\n/** Config key to disable the tombstone feature, i.e., tombstone information is not read / written into summary. */\nexport const disableTombstoneKey = \"Fluid.GarbageCollection.DisableTombstone\";\n/** Config key to override throwing an error when tombstone object is loaded (requested). */\nexport const throwOnTombstoneLoadOverrideKey =\n\t\"Fluid.GarbageCollection.ThrowOnTombstoneLoadOverride\";\n/** Config key to enable throwing an error when tombstone object is used (e.g. outgoing or incoming ops). */\nexport const throwOnTombstoneUsageKey = \"Fluid.GarbageCollection.ThrowOnTombstoneUsage\";\n/** Config key to enable GC version upgrade. */\nexport const gcVersionUpgradeToV4Key = \"Fluid.GarbageCollection.GCVersionUpgradeToV4\";\n/** Config key to disable GC sweep for datastores. They'll merely be Tombstoned. */\nexport const disableDatastoreSweepKey = \"Fluid.GarbageCollection.DisableDataStoreSweep\";\n/** Config key to disable auto-recovery mechanism that protects Tombstones that are loaded from being swept (use true) */\nexport const disableAutoRecoveryKey = \"Fluid.GarbageCollection.DisableAutoRecovery\";\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 tombstone timeout.\n * Tombstone 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\nexport const defaultSweepGracePeriodMs = 1 * oneDayMs; // 1 day\n\n/**\n * @see IGCMetadata.gcFeatureMatrix and @see gcGenerationOptionName\n * @legacy\n * @alpha\n */\nexport type GCFeatureMatrix =\n\t| {\n\t\t\t/**\n\t\t\t * The GC Generation value in effect when this file was created.\n\t\t\t * Gives a way for an app to disqualify old files from GC Sweep.\n\t\t\t * Provided via Container Runtime Options.\n\t\t\t */\n\t\t\tgcGeneration?: number;\n\t\t\t/** Deprecated property from legacy type. Will not be set concurrently with gcGeneration */\n\t\t\ttombstoneGeneration?: undefined;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * The Tombstone Generation value in effect when this file was created.\n\t\t\t * Legacy - new containers would get gcGeneration instead (if anything)\n\t\t\t */\n\t\t\ttombstoneGeneration: number;\n\t };\n\n/**\n * Deprecated properties formerly included in @see IGCMetadata.\n * These may be found in old snapshots, so we need to support them for backwards compatibility.\n */\nexport interface IGCMetadata_Deprecated {\n\t/**\n\t * How long to wait after an object is unreferenced before deleting it via GC Sweep\n\t *\n\t * @deprecated Replaced by @see IGCMetadata.tombstoneTimeoutMs\n\t */\n\treadonly sweepTimeoutMs?: number;\n}\n\n/**\n * GC-specific metadata to be written into the summary.\n *\n * @legacy\n * @alpha\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\t * @deprecated use GCFeatureMatrix.gcGeneration instead. @see GCFeatureMatrix.gcGeneration\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/**\n\t * How long to wait after an object is unreferenced before it becomes a Tombstone.\n\t *\n\t * After this point, there's a grace period before the object is deleted.\n\t * @see IGCRuntimeOptions.sweepGracePeriodMs\n\t *\n\t * So the full sweep timeout in a session is tombstoneTimeoutMs + sweepGracePeriodMs.\n\t */\n\treadonly tombstoneTimeoutMs?: number;\n}\n\n/**\n * The statistics of the system state after a garbage collection mark phase run.\n * @legacy\n * @alpha\n */\nexport interface IMarkPhaseStats {\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/**\n * The statistics of the system state after a garbage collection sweep phase run.\n * @legacy\n * @alpha\n */\nexport interface ISweepPhaseStats {\n\t/** The number of nodes in the lifetime of the container. */\n\tlifetimeNodeCount: number;\n\t/** The number of data stores in the lifetime of the container. */\n\tlifetimeDataStoreCount: number;\n\t/** The number of attachment blobs in the lifetime of the container. */\n\tlifetimeAttachmentBlobCount: number;\n\t/** The number of deleted nodes in the container. */\n\tdeletedNodeCount: number;\n\t/** The number of deleted data stores in the container. */\n\tdeletedDataStoreCount: number;\n\t/** The number of deleted attachment blobs in the container. */\n\tdeletedAttachmentBlobCount: number;\n}\n\n/**\n * The statistics of the system state after a garbage collection run.\n * @legacy\n * @alpha\n */\nexport interface IGCStats extends IMarkPhaseStats, ISweepPhaseStats {}\n\n/**\n * The types of GC nodes in the GC reference graph.\n * @legacy\n * @alpha\n */\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} as const;\n\n/**\n * @legacy\n * @alpha\n */\nexport type GCNodeType = (typeof GCNodeType)[keyof typeof GCNodeType];\n\n/**\n * The type of a garbage collection message.\n * @internal\n */\nexport const GarbageCollectionMessageType = {\n\t/** Message sent directing GC to delete the given nodes */\n\tSweep: \"Sweep\",\n\t/** Message sent notifying GC that a Tombstoned object was Loaded */\n\tTombstoneLoaded: \"TombstoneLoaded\",\n} as const;\n\n/**\n * @internal\n */\nexport type GarbageCollectionMessageType =\n\t(typeof GarbageCollectionMessageType)[keyof typeof GarbageCollectionMessageType];\n\n/**\n * The garbage collection sweep message.\n * @internal\n */\nexport interface ISweepMessage {\n\t/** @see GarbageCollectionMessageType.Sweep */\n\ttype: typeof GarbageCollectionMessageType.Sweep;\n\t/** The ids of nodes that are deleted. */\n\tdeletedNodeIds: string[];\n}\n\n/**\n * The GC TombstoneLoaded message.\n * @internal\n */\nexport interface ITombstoneLoadedMessage {\n\t/** @see GarbageCollectionMessageType.TombstoneLoaded */\n\ttype: typeof GarbageCollectionMessageType.TombstoneLoaded;\n\t/** The id of Tombstoned node that was loaded. */\n\tnodePath: string;\n}\n\n/**\n * Type for a message to be used for sending / received garbage collection messages.\n * @internal\n */\nexport type GarbageCollectionMessage = ISweepMessage | ITombstoneLoadedMessage;\n\n/**\n * Defines the APIs for the runtime object to be passed to the garbage collector.\n */\nexport interface IGarbageCollectionRuntime {\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: readonly 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: readonly string[]): readonly string[];\n\t/** Called to notify the runtime of routes that are tombstones. */\n\tupdateTombstonedRoutes(tombstoneRoutes: readonly 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}\n\n/** Defines the contract for the garbage collector. */\nexport interface IGarbageCollector {\n\t/**\n\t * Tells the time at which session expiry timer started in a previous container.\n\t * This is only set when loading from a stashed container and will be equal to the\n\t * original container's local client time when it was loaded (and started the session expiry timer).\n\t */\n\treadonly sessionExpiryTimerStarted: number | undefined;\n\t/** Tells whether GC should run or not. */\n\treadonly shouldRunGC: boolean;\n\t/** The count of data stores whose GC state updated since the last summary. */\n\treadonly updatedDSCountSinceLastSummary: number;\n\t/** Tells whether tombstone feature is enabled and enforced. */\n\treadonly tombstoneEnforcementAllowed: boolean;\n\t/** Tells whether loading a tombstone object should fail or merely log. */\n\treadonly throwOnTombstoneLoad: boolean;\n\t/** Tells whether using a tombstone object should fail or merely log. */\n\treadonly throwOnTombstoneUsage: 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?: ITelemetryLoggerExt;\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(result: IRefreshSummaryResult): Promise<void>;\n\t/**\n\t * Called when a node with the given path is updated. If the node is inactive or tombstoned, this will log an error\n\t * or throw an error if failing on incorrect usage is configured.\n\t */\n\tnodeUpdated(props: IGCNodeUpdatedProps): void;\n\t/** Called when a reference is added to a node. Used to identify nodes that were referenced between summaries. */\n\taddedOutboundReference(\n\t\tfromNodePath: string,\n\t\ttoNodePath: string,\n\t\ttimestampMs: number,\n\t\tautorecovery?: true,\n\t): void;\n\t/** Called to process a garbage collection message. */\n\tprocessMessage(\n\t\tmessage: ContainerRuntimeGCMessage,\n\t\tmessageTimestampMs: number,\n\t\tlocal: boolean,\n\t): 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/**\n * Info needed by GC when notified that a node was updated (loaded or changed)\n * @internal\n */\nexport interface IGCNodeUpdatedProps {\n\t/** Type and path of the updated node */\n\tnode: { type: (typeof GCNodeType)[\"DataStore\" | \"Blob\"]; path: string };\n\t/** Whether the node (or a subpath) was loaded or changed. */\n\treason: \"Loaded\" | \"Changed\";\n\t/**\n\t * The op-based timestamp when the node changed. If the update is from receiving an op, this should\n\t * be the timestamp of the op. If not, this should be the timestamp of the last op processed.\n\t */\n\ttimestampMs: number | undefined;\n\t/** The package path of the node. This may not be available if the node hasn't been loaded yet */\n\tpackagePath?: readonly string[];\n\t/** The original request for loads to preserve it in telemetry */\n\trequest?: IRequest;\n\t/** If the node was loaded via request path, the header data. May be modified from the original request */\n\theaderData?: RuntimeHeaderData;\n}\n\n/** Parameters necessary for creating a GarbageCollector. */\nexport interface IGarbageCollectorCreateParams {\n\treadonly runtime: IGarbageCollectionRuntime;\n\treadonly gcOptions: IGCRuntimeOptions;\n\treadonly baseLogger: ITelemetryLoggerExt;\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 submitMessage: (message: ContainerRuntimeGCMessage) => void;\n\treadonly sessionExpiryTimerStarted?: number | undefined;\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface IGCRuntimeOptions {\n\t/**\n\t * Flag that if true, will enable the full Sweep Phase of garbage collection for this session,\n\t * where Tombstoned objects are permanently deleted from the container.\n\t *\n\t * IMPORTANT: This only applies if this document is allowed to run Sweep Phase.\n\t *\n\t * Current default behavior is for Sweep Phase not to delete Tombstoned objects,\n\t * but merely to prevent them from being loaded.\n\t */\n\tenableGCSweep?: true;\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 * Delay between when Tombstone should run and when the object should be deleted.\n\t * This grace period gives a chance to intervene to recover if needed, before Sweep deletes the object.\n\t * If not present, a default (non-zero) value will be used.\n\t */\n\tsweepGracePeriodMs?: 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. GC may not be enabled for old documents created pre-GC.\n\t */\n\treadonly gcEnabled: boolean;\n\t/**\n\t * Tracks if sweep phase is allowed 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/** Is Tombstone AutoRecovery enabled? Useful for preventing the GC \"TombstoneLoaded\" op, for compatibility reasons */\n\treadonly tombstoneAutorecoveryEnabled: boolean;\n\t/**\n\t * Tracks if sweep phase should run or not, or if it should run only for attachment blobs.\n\t * Even if the sweep phase is allowed for a document (see sweepEnabled), it may be disabled or partially enabled\n\t * for the session, depending on a variety of other configurations present.\n\t */\n\treadonly shouldRunSweep: \"YES\" | \"ONLY_BLOBS\" | \"NO\";\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 can be Tombstoned - i.e. GC knows it can't be referenced again (revived). */\n\treadonly tombstoneTimeoutMs: number | undefined;\n\t/**\n\t * The delay between tombstone and sweep. Not persisted, so concurrent sessions may use different values.\n\t * Sweep is implemented in an eventually-consistent way so this is acceptable.\n\t */\n\treadonly sweepGracePeriodMs: number;\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, objects are marked as tombstones as a step along the\n\t * way before they are fully deleted.\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 \"warning\"\n\t * step before sweep, where objects wrongly marked as unreferenced 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\t/** The current version of GC data in the running code */\n\treadonly gcVersionInEffect: GCVersion;\n\t/** It is easier for users to diagnose InactiveObject usage if we throw on load, which this option enables */\n\treadonly throwOnInactiveLoad: boolean | undefined;\n\t/** If true, throw an error when a tombstone data store is retrieved */\n\treadonly throwOnTombstoneLoad: boolean;\n\t/** If true, throw an error when a tombstone data store is used. */\n\treadonly throwOnTombstoneUsage: boolean;\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 tombstoned */\n\tTombstoneReady: \"TombstoneReady\",\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\n/**\n * Represents the result of a GC run.\n */\nexport interface IGCResult {\n\t/** The ids of nodes that are referenced in the referenced graph */\n\treferencedNodeIds: string[];\n\t/** The ids of nodes that are not-referenced or deleted in the referenced graph */\n\tdeletedNodeIds: string[];\n}\n"]}
1
+ {"version":3,"file":"gcDefinitions.js","sourceRoot":"","sources":["../../src/gc/gcDefinitions.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA+BH,4CAA4C;AAC/B,QAAA,eAAe,GAAc,CAAC,CAAC;AAC5C,0GAA0G;AAC7F,QAAA,aAAa,GAAc,CAAC,CAAC;AAE1C;;;;;GAKG;AACU,QAAA,uCAAuC,GAAG,+BAA+B,CAAC;AAEvF;;;GAGG;AACU,QAAA,iCAAiC,GAAG,uBAAuB,CAAC;AAEzE;;;;;;;;;;GAUG;AACU,QAAA,sBAAsB,GAAG,cAAc,CAAC;AAErD,gDAAgD;AACnC,QAAA,aAAa,GAAG,oCAAoC,CAAC;AAClE,mFAAmF;AACtE,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,mHAAmH;AACtG,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,4FAA4F;AAC/E,QAAA,+BAA+B,GAC3C,sDAAsD,CAAC;AACxD,4GAA4G;AAC/F,QAAA,wBAAwB,GAAG,+CAA+C,CAAC;AACxF,+CAA+C;AAClC,QAAA,uBAAuB,GAAG,8CAA8C,CAAC;AACtF,mFAAmF;AACtE,QAAA,wBAAwB,GAAG,+CAA+C,CAAC;AACxF,yHAAyH;AAC5G,QAAA,sBAAsB,GAAG,6CAA6C,CAAC;AAEpF,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;AAC1D,QAAA,yBAAyB,GAAG,CAAC,GAAG,gBAAQ,CAAC,CAAC,QAAQ;AA6I/D;;;;GAIG;AACU,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;CACL,CAAC;AAQX;;;GAGG;AACU,QAAA,4BAA4B,GAAG;IAC3C,0DAA0D;IAC1D,KAAK,EAAE,OAAO;IACd,oEAAoE;IACpE,eAAe,EAAE,iBAAiB;CACzB,CAAC;AA4QX,8CAA8C;AACjC,QAAA,iBAAiB,GAAG;IAChC,gEAAgE;IAChE,MAAM,EAAE,QAAQ;IAChB,mEAAmE;IACnE,QAAQ,EAAE,UAAU;IACpB,yCAAyC;IACzC,cAAc,EAAE,gBAAgB;IAChC,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 { IRequest } from \"@fluidframework/core-interfaces\";\nimport { ISnapshotTree } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tITelemetryContext,\n\tIGarbageCollectionData,\n\tIGarbageCollectionDetailsBase,\n\tISummarizeResult,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { ReadAndParseBlob } from \"@fluidframework/runtime-utils/internal\";\nimport {\n\tITelemetryLoggerExt,\n\ttype ITelemetryPropertiesExt,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { RuntimeHeaderData } from \"../containerRuntime.js\";\nimport { ContainerRuntimeGCMessage } from \"../messageTypes.js\";\nimport {\n\tIContainerRuntimeMetadata,\n\tICreateContainerMetadata,\n\tIRefreshSummaryResult,\n} from \"../summary/index.js\";\n\n/**\n * @legacy\n * @alpha\n */\nexport type GCVersion = number;\n\n/** The stable/default version of GC Data */\nexport const stableGCVersion: GCVersion = 3;\n/** The next version of GC Data, to bump to in case we need to regenerate all GC Data across all files. */\nexport const nextGCVersion: GCVersion = 4;\n\n/**\n * This undocumented GC Option (on ContainerRuntime Options) allows an app to disable throwing an error when tombstone\n * object is loaded (requested), merely logging a message instead.\n *\n * By default, attempting to load a Tombstoned object will result in an error.\n */\nexport const gcDisableThrowOnTombstoneLoadOptionName = \"gcDisableThrowOnTombstoneLoad\";\n\n/**\n * This undocumented GC Option (on ContainerRuntime Options) allows an app to enable Sweep for blobs only.\n * Only applies if enableGCSweep option is set to true.\n */\nexport const gcDisableDataStoreSweepOptionName = \"disableDataStoreSweep\";\n\n/**\n * This undocumented GC Option (on ContainerRuntime Options) allows configuring which documents can have Sweep enabled.\n * This provides a way to disable both Tombstone Enforcement and Sweep.\n *\n * If unset, Tombstone Enforcement + Sweep will operate as otherwise configured.\n * Otherwise, the Sweep Phase will be disabled for documents where persisted value doesn't match what is passed into this session.\n * This provides a way to disallow Sweep for old documents that may be too difficult for an app to repair,\n * in case a bug is found that violates GC's assumptions.\n *\n * @see GCFeatureMatrix (gcGeneration)\n */\nexport const gcGenerationOptionName = \"gcGeneration\";\n\n/** Config key to turn GC test mode on / off. */\nexport const gcTestModeKey = \"Fluid.GarbageCollection.GCTestMode\";\n/** Config key to expire a session after a set period of time. Defaults to true. */\nexport const runSessionExpiryKey = \"Fluid.GarbageCollection.RunSessionExpiry\";\n/** Config key to disable the tombstone feature, i.e., tombstone information is not read / written into summary. */\nexport const disableTombstoneKey = \"Fluid.GarbageCollection.DisableTombstone\";\n/** Config key to override throwing an error when tombstone object is loaded (requested). */\nexport const throwOnTombstoneLoadOverrideKey =\n\t\"Fluid.GarbageCollection.ThrowOnTombstoneLoadOverride\";\n/** Config key to enable throwing an error when tombstone object is used (e.g. outgoing or incoming ops). */\nexport const throwOnTombstoneUsageKey = \"Fluid.GarbageCollection.ThrowOnTombstoneUsage\";\n/** Config key to enable GC version upgrade. */\nexport const gcVersionUpgradeToV4Key = \"Fluid.GarbageCollection.GCVersionUpgradeToV4\";\n/** Config key to disable GC sweep for datastores. They'll merely be Tombstoned. */\nexport const disableDatastoreSweepKey = \"Fluid.GarbageCollection.DisableDataStoreSweep\";\n/** Config key to disable auto-recovery mechanism that protects Tombstones that are loaded from being swept (use true) */\nexport const disableAutoRecoveryKey = \"Fluid.GarbageCollection.DisableAutoRecovery\";\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 tombstone timeout.\n * Tombstone 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\nexport const defaultSweepGracePeriodMs = 1 * oneDayMs; // 1 day\n\n/**\n * @see IGCMetadata.gcFeatureMatrix and @see gcGenerationOptionName\n * @legacy\n * @alpha\n */\nexport type GCFeatureMatrix =\n\t| {\n\t\t\t/**\n\t\t\t * The GC Generation value in effect when this file was created.\n\t\t\t * Gives a way for an app to disqualify old files from GC Sweep.\n\t\t\t * Provided via Container Runtime Options.\n\t\t\t */\n\t\t\tgcGeneration?: number;\n\t\t\t/** Deprecated property from legacy type. Will not be set concurrently with gcGeneration */\n\t\t\ttombstoneGeneration?: undefined;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * The Tombstone Generation value in effect when this file was created.\n\t\t\t * Legacy - new containers would get gcGeneration instead (if anything)\n\t\t\t */\n\t\t\ttombstoneGeneration: number;\n\t };\n\n/**\n * Deprecated properties formerly included in @see IGCMetadata.\n * These may be found in old snapshots, so we need to support them for backwards compatibility.\n */\nexport interface IGCMetadata_Deprecated {\n\t/**\n\t * How long to wait after an object is unreferenced before deleting it via GC Sweep\n\t *\n\t * @deprecated Replaced by @see IGCMetadata.tombstoneTimeoutMs\n\t */\n\treadonly sweepTimeoutMs?: number;\n}\n\n/**\n * GC-specific metadata to be written into the summary.\n *\n * @legacy\n * @alpha\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\t * @deprecated use GCFeatureMatrix.gcGeneration instead. @see GCFeatureMatrix.gcGeneration\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/**\n\t * How long to wait after an object is unreferenced before it becomes a Tombstone.\n\t *\n\t * After this point, there's a grace period before the object is deleted.\n\t * @see IGCRuntimeOptions.sweepGracePeriodMs\n\t *\n\t * So the full sweep timeout in a session is tombstoneTimeoutMs + sweepGracePeriodMs.\n\t */\n\treadonly tombstoneTimeoutMs?: number;\n}\n\n/**\n * The statistics of the system state after a garbage collection mark phase run.\n * @legacy\n * @alpha\n */\nexport interface IMarkPhaseStats {\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/**\n * The statistics of the system state after a garbage collection sweep phase run.\n * @legacy\n * @alpha\n */\nexport interface ISweepPhaseStats {\n\t/** The number of nodes in the lifetime of the container. */\n\tlifetimeNodeCount: number;\n\t/** The number of data stores in the lifetime of the container. */\n\tlifetimeDataStoreCount: number;\n\t/** The number of attachment blobs in the lifetime of the container. */\n\tlifetimeAttachmentBlobCount: number;\n\t/** The number of deleted nodes in the container. */\n\tdeletedNodeCount: number;\n\t/** The number of deleted data stores in the container. */\n\tdeletedDataStoreCount: number;\n\t/** The number of deleted attachment blobs in the container. */\n\tdeletedAttachmentBlobCount: number;\n}\n\n/**\n * The statistics of the system state after a garbage collection run.\n * @legacy\n * @alpha\n */\nexport interface IGCStats extends IMarkPhaseStats, ISweepPhaseStats {}\n\n/**\n * The types of GC nodes in the GC reference graph.\n * @legacy\n * @alpha\n */\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} as const;\n\n/**\n * @legacy\n * @alpha\n */\nexport type GCNodeType = (typeof GCNodeType)[keyof typeof GCNodeType];\n\n/**\n * The type of a garbage collection message.\n * @internal\n */\nexport const GarbageCollectionMessageType = {\n\t/** Message sent directing GC to delete the given nodes */\n\tSweep: \"Sweep\",\n\t/** Message sent notifying GC that a Tombstoned object was Loaded */\n\tTombstoneLoaded: \"TombstoneLoaded\",\n} as const;\n\n/**\n * @internal\n */\nexport type GarbageCollectionMessageType =\n\t(typeof GarbageCollectionMessageType)[keyof typeof GarbageCollectionMessageType];\n\n/**\n * The garbage collection sweep message.\n * @internal\n */\nexport interface ISweepMessage {\n\t/** @see GarbageCollectionMessageType.Sweep */\n\ttype: typeof GarbageCollectionMessageType.Sweep;\n\t/** The ids of nodes that are deleted. */\n\tdeletedNodeIds: string[];\n}\n\n/**\n * The GC TombstoneLoaded message.\n * @internal\n */\nexport interface ITombstoneLoadedMessage {\n\t/** @see GarbageCollectionMessageType.TombstoneLoaded */\n\ttype: typeof GarbageCollectionMessageType.TombstoneLoaded;\n\t/** The id of Tombstoned node that was loaded. */\n\tnodePath: string;\n}\n\n/**\n * Type for a message to be used for sending / received garbage collection messages.\n * @internal\n */\nexport type GarbageCollectionMessage = ISweepMessage | ITombstoneLoadedMessage;\n\n/**\n * Defines the APIs for the runtime object to be passed to the garbage collector.\n */\nexport interface IGarbageCollectionRuntime {\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: readonly 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: readonly string[]): readonly string[];\n\t/** Called to notify the runtime of routes that are tombstones. */\n\tupdateTombstonedRoutes(tombstoneRoutes: readonly 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}\n\n/** Defines the contract for the garbage collector. */\nexport interface IGarbageCollector {\n\t/**\n\t * Tells the time at which session expiry timer started in a previous container.\n\t * This is only set when loading from a stashed container and will be equal to the\n\t * original container's local client time when it was loaded (and started the session expiry timer).\n\t */\n\treadonly sessionExpiryTimerStarted: number | undefined;\n\t/** Tells whether GC should run or not. */\n\treadonly shouldRunGC: boolean;\n\t/** The count of data stores whose GC state updated since the last summary. */\n\treadonly updatedDSCountSinceLastSummary: number;\n\t/** Tells whether tombstone feature is enabled and enforced. */\n\treadonly tombstoneEnforcementAllowed: boolean;\n\t/** Tells whether loading a tombstone object should fail or merely log. */\n\treadonly throwOnTombstoneLoad: boolean;\n\t/** Tells whether using a tombstone object should fail or merely log. */\n\treadonly throwOnTombstoneUsage: 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?: ITelemetryLoggerExt;\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(result: IRefreshSummaryResult): Promise<void>;\n\t/**\n\t * Called when a node with the given path is updated. If the node is inactive or tombstoned, this will log an error\n\t * or throw an error if failing on incorrect usage is configured.\n\t */\n\tnodeUpdated(props: IGCNodeUpdatedProps): void;\n\t/** Called when a reference is added to a node. Used to identify nodes that were referenced between summaries. */\n\taddedOutboundReference(\n\t\tfromNodePath: string,\n\t\ttoNodePath: string,\n\t\ttimestampMs: number,\n\t\tautorecovery?: true,\n\t): void;\n\t/** Called to process a garbage collection message. */\n\tprocessMessage(\n\t\tmessage: ContainerRuntimeGCMessage,\n\t\tmessageTimestampMs: number,\n\t\tlocal: boolean,\n\t): 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/**\n * Info needed by GC when notified that a node was updated (loaded or changed)\n * @internal\n */\nexport interface IGCNodeUpdatedProps {\n\t/** Type and path of the updated node */\n\tnode: { type: (typeof GCNodeType)[\"DataStore\" | \"Blob\"]; path: string };\n\t/** Whether the node (or a subpath) was loaded or changed. */\n\treason: \"Loaded\" | \"Changed\" | \"Realized\";\n\t/**\n\t * The op-based timestamp when the node changed. If the update is from receiving an op, this should\n\t * be the timestamp of the op. If not, this should be the timestamp of the last op processed.\n\t */\n\ttimestampMs: number | undefined;\n\t/** The package path of the node. This may not be available if the node hasn't been loaded yet */\n\tpackagePath?: readonly string[];\n\t/** The original request for loads to preserve it in telemetry */\n\trequest?: IRequest;\n\t/** If the node was loaded via request path, the header data. May be modified from the original request */\n\theaderData?: RuntimeHeaderData;\n\t/** Any other properties to be logged. */\n\tadditionalProps?: ITelemetryPropertiesExt;\n}\n\n/** Parameters necessary for creating a GarbageCollector. */\nexport interface IGarbageCollectorCreateParams {\n\treadonly runtime: IGarbageCollectionRuntime;\n\treadonly gcOptions: IGCRuntimeOptions;\n\treadonly baseLogger: ITelemetryLoggerExt;\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 submitMessage: (message: ContainerRuntimeGCMessage) => void;\n\treadonly sessionExpiryTimerStarted?: number | undefined;\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface IGCRuntimeOptions {\n\t/**\n\t * Flag that if true, will enable the full Sweep Phase of garbage collection for this session,\n\t * where Tombstoned objects are permanently deleted from the container.\n\t *\n\t * IMPORTANT: This only applies if this document is allowed to run Sweep Phase.\n\t *\n\t * Current default behavior is for Sweep Phase not to delete Tombstoned objects,\n\t * but merely to prevent them from being loaded.\n\t */\n\tenableGCSweep?: true;\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 * Delay between when Tombstone should run and when the object should be deleted.\n\t * This grace period gives a chance to intervene to recover if needed, before Sweep deletes the object.\n\t * If not present, a default (non-zero) value will be used.\n\t */\n\tsweepGracePeriodMs?: 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. GC may not be enabled for old documents created pre-GC.\n\t */\n\treadonly gcEnabled: boolean;\n\t/**\n\t * Tracks if sweep phase is allowed 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/** Is Tombstone AutoRecovery enabled? Useful for preventing the GC \"TombstoneLoaded\" op, for compatibility reasons */\n\treadonly tombstoneAutorecoveryEnabled: boolean;\n\t/**\n\t * Tracks if sweep phase should run or not, or if it should run only for attachment blobs.\n\t * Even if the sweep phase is allowed for a document (see sweepEnabled), it may be disabled or partially enabled\n\t * for the session, depending on a variety of other configurations present.\n\t */\n\treadonly shouldRunSweep: \"YES\" | \"ONLY_BLOBS\" | \"NO\";\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 can be Tombstoned - i.e. GC knows it can't be referenced again (revived). */\n\treadonly tombstoneTimeoutMs: number | undefined;\n\t/**\n\t * The delay between tombstone and sweep. Not persisted, so concurrent sessions may use different values.\n\t * Sweep is implemented in an eventually-consistent way so this is acceptable.\n\t */\n\treadonly sweepGracePeriodMs: number;\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, objects are marked as tombstones as a step along the\n\t * way before they are fully deleted.\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 \"warning\"\n\t * step before sweep, where objects wrongly marked as unreferenced 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\t/** The current version of GC data in the running code */\n\treadonly gcVersionInEffect: GCVersion;\n\t/** It is easier for users to diagnose InactiveObject usage if we throw on load, which this option enables */\n\treadonly throwOnInactiveLoad: boolean | undefined;\n\t/** If true, throw an error when a tombstone data store is retrieved */\n\treadonly throwOnTombstoneLoad: boolean;\n\t/** If true, throw an error when a tombstone data store is used. */\n\treadonly throwOnTombstoneUsage: boolean;\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 tombstoned */\n\tTombstoneReady: \"TombstoneReady\",\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\n/**\n * Represents the result of a GC run.\n */\nexport interface IGCResult {\n\t/** The ids of nodes that are referenced in the referenced graph */\n\treferencedNodeIds: string[];\n\t/** The ids of nodes that are not-referenced or deleted in the referenced graph */\n\tdeletedNodeIds: string[];\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"gcHelpers.d.ts","sourceRoot":"","sources":["../../src/gc/gcHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,OAAO,EACN,6BAA6B,EAI7B,sBAAsB,EACtB,MAAM,8CAA8C,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAEhF,OAAO,EACN,eAAe,EACf,SAAS,EACT,WAAW,EAIX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEN,8BAA8B,EAC9B,uBAAuB,EACvB,MAAM,2BAA2B,CAAC;AAEnC,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,SAAS,CAM9D;AAED,2FAA2F;AAC3F,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,eAAe,GAAG,MAAM,CAK5E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CACjC,aAAa,EAAE,eAAe,EAC9B,iBAAiB,EAAE,MAAM,GAAG,SAAS,GACnC,OAAO,CAUT;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,uBAAuB,GAC9B,uBAAuB,CAWzB;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC5C,QAAQ,EAAE,uBAAuB,EACjC,QAAQ,EAAE,uBAAuB,GAC/B,uBAAuB,CAsCzB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,sBAAsB,GAAG,sBAAsB,CAQlF;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,0BAY/B;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAC1C,cAAc,EAAE,aAAa,EAC7B,gBAAgB,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAC7C,OAAO,CAAC,8BAA8B,CAAC,CAgCzC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,6BAA6B,8CA0DjF;AAWD,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;;;;;GAOG;AACH,wBAAgB,iCAAiC,CAChD,qBAAqB,EAAE,KAAK,EAC5B,cAAc,EAAE,QAAQ,GAAG,eAAe,GAAG,SAAS,GACpD,OAAO,CAGT"}
1
+ {"version":3,"file":"gcHelpers.d.ts","sourceRoot":"","sources":["../../src/gc/gcHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,OAAO,EACN,6BAA6B,EAI7B,sBAAsB,EACtB,MAAM,8CAA8C,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAEhF,OAAO,EACN,eAAe,EACf,SAAS,EACT,WAAW,EAIX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEN,8BAA8B,EAC9B,uBAAuB,EACvB,MAAM,2BAA2B,CAAC;AAEnC,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,SAAS,CAM9D;AAED,2FAA2F;AAC3F,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,eAAe,GAAG,MAAM,CAK5E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CACjC,aAAa,EAAE,eAAe,EAC9B,iBAAiB,EAAE,MAAM,GAAG,SAAS,GACnC,OAAO,CAUT;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,uBAAuB,GAC9B,uBAAuB,CAWzB;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC5C,QAAQ,EAAE,uBAAuB,EACjC,QAAQ,EAAE,uBAAuB,GAC/B,uBAAuB,CAsCzB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,sBAAsB,GAAG,sBAAsB,CAQlF;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,0BAc/B;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAC1C,cAAc,EAAE,aAAa,EAC7B,gBAAgB,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAC7C,OAAO,CAAC,8BAA8B,CAAC,CAoCzC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,6BAA6B,8CA8DjF;AAWD,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAInD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;;;;;GAOG;AACH,wBAAgB,iCAAiC,CAChD,qBAAqB,EAAE,KAAK,EAC5B,cAAc,EAAE,QAAQ,GAAG,eAAe,GAAG,SAAS,GACpD,OAAO,CAGT"}