@fluidframework/container-runtime 2.0.0-dev.7.4.0.217212 → 2.0.0-dev.7.4.0.221926

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/api-extractor.json +0 -3
  3. package/api-report/container-runtime.api.md +77 -73
  4. package/dist/blobManager.d.ts +4 -4
  5. package/dist/blobManager.d.ts.map +1 -1
  6. package/dist/blobManager.js.map +1 -1
  7. package/dist/container-runtime-alpha.d.ts +1361 -132
  8. package/dist/container-runtime-beta.d.ts +40 -2
  9. package/dist/container-runtime-public.d.ts +40 -2
  10. package/dist/container-runtime-untrimmed.d.ts +106 -93
  11. package/dist/containerRuntime.d.ts +19 -17
  12. package/dist/containerRuntime.d.ts.map +1 -1
  13. package/dist/containerRuntime.js +44 -24
  14. package/dist/containerRuntime.js.map +1 -1
  15. package/dist/dataStores.d.ts +10 -15
  16. package/dist/dataStores.d.ts.map +1 -1
  17. package/dist/dataStores.js +63 -36
  18. package/dist/dataStores.js.map +1 -1
  19. package/dist/gc/garbageCollection.d.ts +29 -10
  20. package/dist/gc/garbageCollection.d.ts.map +1 -1
  21. package/dist/gc/garbageCollection.js +149 -67
  22. package/dist/gc/garbageCollection.js.map +1 -1
  23. package/dist/gc/gcConfigs.d.ts.map +1 -1
  24. package/dist/gc/gcConfigs.js +34 -37
  25. package/dist/gc/gcConfigs.js.map +1 -1
  26. package/dist/gc/gcDefinitions.d.ts +97 -44
  27. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  28. package/dist/gc/gcDefinitions.js +26 -16
  29. package/dist/gc/gcDefinitions.js.map +1 -1
  30. package/dist/gc/gcHelpers.d.ts +18 -25
  31. package/dist/gc/gcHelpers.d.ts.map +1 -1
  32. package/dist/gc/gcHelpers.js +29 -45
  33. package/dist/gc/gcHelpers.js.map +1 -1
  34. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  35. package/dist/gc/gcTelemetry.js +14 -3
  36. package/dist/gc/gcTelemetry.js.map +1 -1
  37. package/dist/gc/gcUnreferencedStateTracker.d.ts +11 -5
  38. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  39. package/dist/gc/gcUnreferencedStateTracker.js +43 -19
  40. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  41. package/dist/gc/index.d.ts +1 -1
  42. package/dist/gc/index.d.ts.map +1 -1
  43. package/dist/gc/index.js +4 -4
  44. package/dist/gc/index.js.map +1 -1
  45. package/dist/index.d.ts +13 -1
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +16 -5
  48. package/dist/index.js.map +1 -1
  49. package/dist/messageTypes.d.ts +13 -5
  50. package/dist/messageTypes.d.ts.map +1 -1
  51. package/dist/messageTypes.js +5 -0
  52. package/dist/messageTypes.js.map +1 -1
  53. package/dist/packageVersion.d.ts +1 -1
  54. package/dist/packageVersion.js +1 -1
  55. package/dist/packageVersion.js.map +1 -1
  56. package/dist/pendingStateManager.d.ts +1 -0
  57. package/dist/pendingStateManager.d.ts.map +1 -1
  58. package/dist/pendingStateManager.js +1 -0
  59. package/dist/pendingStateManager.js.map +1 -1
  60. package/dist/summary/orderedClientElection.d.ts +1 -1
  61. package/dist/summary/orderedClientElection.js.map +1 -1
  62. package/dist/summary/summarizerTypes.d.ts +28 -28
  63. package/dist/summary/summarizerTypes.js.map +1 -1
  64. package/dist/summary/summaryCollection.d.ts +3 -3
  65. package/dist/summary/summaryCollection.js.map +1 -1
  66. package/dist/summary/summaryFormat.d.ts +3 -3
  67. package/dist/summary/summaryFormat.js.map +1 -1
  68. package/lib/blobManager.d.ts +4 -4
  69. package/lib/blobManager.d.ts.map +1 -1
  70. package/lib/blobManager.js.map +1 -1
  71. package/lib/container-runtime-alpha.d.ts +1361 -132
  72. package/lib/container-runtime-beta.d.ts +40 -2
  73. package/lib/container-runtime-public.d.ts +40 -2
  74. package/lib/container-runtime-untrimmed.d.ts +106 -93
  75. package/lib/containerRuntime.d.ts +19 -17
  76. package/lib/containerRuntime.d.ts.map +1 -1
  77. package/lib/containerRuntime.js +46 -26
  78. package/lib/containerRuntime.js.map +1 -1
  79. package/lib/dataStores.d.ts +10 -15
  80. package/lib/dataStores.d.ts.map +1 -1
  81. package/lib/dataStores.js +65 -38
  82. package/lib/dataStores.js.map +1 -1
  83. package/lib/gc/garbageCollection.d.ts +29 -10
  84. package/lib/gc/garbageCollection.d.ts.map +1 -1
  85. package/lib/gc/garbageCollection.js +151 -69
  86. package/lib/gc/garbageCollection.js.map +1 -1
  87. package/lib/gc/gcConfigs.d.ts.map +1 -1
  88. package/lib/gc/gcConfigs.js +37 -40
  89. package/lib/gc/gcConfigs.js.map +1 -1
  90. package/lib/gc/gcDefinitions.d.ts +97 -44
  91. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  92. package/lib/gc/gcDefinitions.js +25 -15
  93. package/lib/gc/gcDefinitions.js.map +1 -1
  94. package/lib/gc/gcHelpers.d.ts +18 -25
  95. package/lib/gc/gcHelpers.d.ts.map +1 -1
  96. package/lib/gc/gcHelpers.js +27 -43
  97. package/lib/gc/gcHelpers.js.map +1 -1
  98. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  99. package/lib/gc/gcTelemetry.js +14 -3
  100. package/lib/gc/gcTelemetry.js.map +1 -1
  101. package/lib/gc/gcUnreferencedStateTracker.d.ts +11 -5
  102. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  103. package/lib/gc/gcUnreferencedStateTracker.js +43 -19
  104. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  105. package/lib/gc/index.d.ts +1 -1
  106. package/lib/gc/index.d.ts.map +1 -1
  107. package/lib/gc/index.js +1 -1
  108. package/lib/gc/index.js.map +1 -1
  109. package/lib/index.d.ts +13 -1
  110. package/lib/index.d.ts.map +1 -1
  111. package/lib/index.js +15 -1
  112. package/lib/index.js.map +1 -1
  113. package/lib/messageTypes.d.ts +13 -5
  114. package/lib/messageTypes.d.ts.map +1 -1
  115. package/lib/messageTypes.js +5 -0
  116. package/lib/messageTypes.js.map +1 -1
  117. package/lib/packageVersion.d.ts +1 -1
  118. package/lib/packageVersion.js +1 -1
  119. package/lib/packageVersion.js.map +1 -1
  120. package/lib/pendingStateManager.d.ts +1 -0
  121. package/lib/pendingStateManager.d.ts.map +1 -1
  122. package/lib/pendingStateManager.js +1 -0
  123. package/lib/pendingStateManager.js.map +1 -1
  124. package/lib/summary/orderedClientElection.d.ts +1 -1
  125. package/lib/summary/orderedClientElection.js.map +1 -1
  126. package/lib/summary/summarizerTypes.d.ts +28 -28
  127. package/lib/summary/summarizerTypes.js.map +1 -1
  128. package/lib/summary/summaryCollection.d.ts +3 -3
  129. package/lib/summary/summaryCollection.js.map +1 -1
  130. package/lib/summary/summaryFormat.d.ts +3 -3
  131. package/lib/summary/summaryFormat.js.map +1 -1
  132. package/package.json +18 -15
  133. package/src/blobManager.ts +5 -5
  134. package/src/containerRuntime.ts +66 -40
  135. package/src/dataStores.ts +118 -59
  136. package/src/gc/garbageCollection.md +14 -15
  137. package/src/gc/garbageCollection.ts +182 -75
  138. package/src/gc/gcConfigs.ts +50 -52
  139. package/src/gc/gcDefinitions.ts +112 -50
  140. package/src/gc/gcHelpers.ts +31 -52
  141. package/src/gc/gcTelemetry.ts +16 -4
  142. package/src/gc/gcUnreferencedStateTracker.ts +61 -22
  143. package/src/gc/index.ts +4 -3
  144. package/src/index.ts +17 -1
  145. package/src/messageTypes.ts +16 -2
  146. package/src/packageVersion.ts +1 -1
  147. package/src/pendingStateManager.ts +1 -0
  148. package/src/summary/orderedClientElection.ts +1 -1
  149. package/src/summary/summarizerTypes.ts +28 -28
  150. package/src/summary/summaryCollection.ts +3 -3
  151. package/src/summary/summaryFormat.ts +3 -3
  152. package/dist/id-compressor/appendOnlySortedMap.d.ts +0 -124
  153. package/dist/id-compressor/appendOnlySortedMap.d.ts.map +0 -1
  154. package/dist/id-compressor/appendOnlySortedMap.js +0 -318
  155. package/dist/id-compressor/appendOnlySortedMap.js.map +0 -1
  156. package/dist/id-compressor/finalSpace.d.ts +0 -29
  157. package/dist/id-compressor/finalSpace.d.ts.map +0 -1
  158. package/dist/id-compressor/finalSpace.js +0 -62
  159. package/dist/id-compressor/finalSpace.js.map +0 -1
  160. package/dist/id-compressor/idCompressor.d.ts +0 -54
  161. package/dist/id-compressor/idCompressor.d.ts.map +0 -1
  162. package/dist/id-compressor/idCompressor.js +0 -495
  163. package/dist/id-compressor/idCompressor.js.map +0 -1
  164. package/dist/id-compressor/identifiers.d.ts +0 -32
  165. package/dist/id-compressor/identifiers.d.ts.map +0 -1
  166. package/dist/id-compressor/identifiers.js +0 -15
  167. package/dist/id-compressor/identifiers.js.map +0 -1
  168. package/dist/id-compressor/index.d.ts +0 -13
  169. package/dist/id-compressor/index.d.ts.map +0 -1
  170. package/dist/id-compressor/index.js +0 -32
  171. package/dist/id-compressor/index.js.map +0 -1
  172. package/dist/id-compressor/persistanceUtilities.d.ts +0 -22
  173. package/dist/id-compressor/persistanceUtilities.d.ts.map +0 -1
  174. package/dist/id-compressor/persistanceUtilities.js +0 -43
  175. package/dist/id-compressor/persistanceUtilities.js.map +0 -1
  176. package/dist/id-compressor/sessionSpaceNormalizer.d.ts +0 -46
  177. package/dist/id-compressor/sessionSpaceNormalizer.d.ts.map +0 -1
  178. package/dist/id-compressor/sessionSpaceNormalizer.js +0 -80
  179. package/dist/id-compressor/sessionSpaceNormalizer.js.map +0 -1
  180. package/dist/id-compressor/sessions.d.ts +0 -115
  181. package/dist/id-compressor/sessions.d.ts.map +0 -1
  182. package/dist/id-compressor/sessions.js +0 -305
  183. package/dist/id-compressor/sessions.js.map +0 -1
  184. package/dist/id-compressor/utilities.d.ts +0 -52
  185. package/dist/id-compressor/utilities.d.ts.map +0 -1
  186. package/dist/id-compressor/utilities.js +0 -169
  187. package/dist/id-compressor/utilities.js.map +0 -1
  188. package/lib/id-compressor/appendOnlySortedMap.d.ts +0 -124
  189. package/lib/id-compressor/appendOnlySortedMap.d.ts.map +0 -1
  190. package/lib/id-compressor/appendOnlySortedMap.js +0 -314
  191. package/lib/id-compressor/appendOnlySortedMap.js.map +0 -1
  192. package/lib/id-compressor/finalSpace.d.ts +0 -29
  193. package/lib/id-compressor/finalSpace.d.ts.map +0 -1
  194. package/lib/id-compressor/finalSpace.js +0 -58
  195. package/lib/id-compressor/finalSpace.js.map +0 -1
  196. package/lib/id-compressor/idCompressor.d.ts +0 -54
  197. package/lib/id-compressor/idCompressor.d.ts.map +0 -1
  198. package/lib/id-compressor/idCompressor.js +0 -491
  199. package/lib/id-compressor/idCompressor.js.map +0 -1
  200. package/lib/id-compressor/identifiers.d.ts +0 -32
  201. package/lib/id-compressor/identifiers.d.ts.map +0 -1
  202. package/lib/id-compressor/identifiers.js +0 -11
  203. package/lib/id-compressor/identifiers.js.map +0 -1
  204. package/lib/id-compressor/index.d.ts +0 -13
  205. package/lib/id-compressor/index.d.ts.map +0 -1
  206. package/lib/id-compressor/index.js +0 -13
  207. package/lib/id-compressor/index.js.map +0 -1
  208. package/lib/id-compressor/persistanceUtilities.d.ts +0 -22
  209. package/lib/id-compressor/persistanceUtilities.d.ts.map +0 -1
  210. package/lib/id-compressor/persistanceUtilities.js +0 -34
  211. package/lib/id-compressor/persistanceUtilities.js.map +0 -1
  212. package/lib/id-compressor/sessionSpaceNormalizer.d.ts +0 -46
  213. package/lib/id-compressor/sessionSpaceNormalizer.d.ts.map +0 -1
  214. package/lib/id-compressor/sessionSpaceNormalizer.js +0 -76
  215. package/lib/id-compressor/sessionSpaceNormalizer.js.map +0 -1
  216. package/lib/id-compressor/sessions.d.ts +0 -115
  217. package/lib/id-compressor/sessions.d.ts.map +0 -1
  218. package/lib/id-compressor/sessions.js +0 -290
  219. package/lib/id-compressor/sessions.js.map +0 -1
  220. package/lib/id-compressor/utilities.d.ts +0 -52
  221. package/lib/id-compressor/utilities.d.ts.map +0 -1
  222. package/lib/id-compressor/utilities.js +0 -151
  223. package/lib/id-compressor/utilities.js.map +0 -1
  224. package/src/id-compressor/README.md +0 -69
  225. package/src/id-compressor/appendOnlySortedMap.ts +0 -366
  226. package/src/id-compressor/finalSpace.ts +0 -67
  227. package/src/id-compressor/idCompressor.ts +0 -630
  228. package/src/id-compressor/identifiers.ts +0 -42
  229. package/src/id-compressor/index.ts +0 -26
  230. package/src/id-compressor/persistanceUtilities.ts +0 -58
  231. package/src/id-compressor/sessionSpaceNormalizer.ts +0 -83
  232. package/src/id-compressor/sessions.ts +0 -405
  233. package/src/id-compressor/utilities.ts +0 -190
@@ -6,6 +6,7 @@ import { IRequest } from "@fluidframework/core-interfaces";
6
6
  import { IGarbageCollectionDetailsBase, ISummarizeResult, ITelemetryContext } from "@fluidframework/runtime-definitions";
7
7
  import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
8
8
  import { RuntimeHeaderData } from "../containerRuntime";
9
+ import { ContainerRuntimeGCMessage } from "../messageTypes";
9
10
  import { IRefreshSummaryResult } from "../summary";
10
11
  import { IGarbageCollector, IGarbageCollectorCreateParams, IGCStats, IGCMetadata } from "./gcDefinitions";
11
12
  /**
@@ -61,6 +62,7 @@ export declare class GarbageCollector implements IGarbageCollector {
61
62
  private readonly getLastSummaryTimestampMs;
62
63
  /** Returns true if connection is active, i.e. it's "write" connection and the runtime is connected. */
63
64
  private readonly activeConnection;
65
+ private readonly submitMessage;
64
66
  get summaryStateNeedsReset(): boolean;
65
67
  /** Returns the count of data stores whose GC state updated since the last summary. */
66
68
  get updatedDSCountSinceLastSummary(): number;
@@ -81,7 +83,7 @@ export declare class GarbageCollector implements IGarbageCollector {
81
83
  private updateStateFromSnapshotData;
82
84
  /**
83
85
  * Called when the connection state of the runtime changes, i.e., it connects or disconnects. GC subscribes to this
84
- * to initialize the base state for non-summarizer clients so that they can track inactive / sweep ready nodes.
86
+ * to initialize the base state for non-summarizer clients so that they can track inactive / sweep-ready nodes.
85
87
  * @param connected - Whether the runtime connected / disconnected.
86
88
  * @param clientId - The clientId of this runtime.
87
89
  */
@@ -105,10 +107,15 @@ export declare class GarbageCollector implements IGarbageCollector {
105
107
  }, telemetryContext?: ITelemetryContext): Promise<IGCStats | undefined>;
106
108
  /**
107
109
  * Runs garbage collection. It does the following:
110
+ *
108
111
  * 1. It generates / analyzes the runtime's reference graph.
112
+ *
109
113
  * 2. Generates mark phase stats.
114
+ *
110
115
  * 3. Runs Mark phase.
116
+ *
111
117
  * 4. Runs Sweep phase.
118
+ *
112
119
  * 5. Generates sweep phase stats.
113
120
  */
114
121
  private runGC;
@@ -124,19 +131,19 @@ export declare class GarbageCollector implements IGarbageCollector {
124
131
  * @param gcResult - The result of the GC run on the gcData.
125
132
  * @param allReferencedNodeIds - Nodes referenced in this GC run + referenced between previous and current GC run.
126
133
  * @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
127
- * @returns A list of sweep ready nodes, i.e., nodes that ready to be deleted.
134
+ * @returns The sets of tombstone-ready and sweep-ready nodes, i.e., nodes that ready to be tombstoned or deleted.
128
135
  */
129
136
  private runMarkPhase;
130
137
  /**
131
138
  * Runs the GC Sweep phase. It does the following:
132
- * 1. Calls the runtime to delete nodes that are sweep ready.
133
- * 2. Clears tracking for deleted nodes.
139
+ *
140
+ * 1. Marks tombstone-ready nodes as tombstones.
141
+ *
142
+ * 2. Sends a sweep op to delete nodes that are sweep-ready. Once the op is ack'd, these nodes will be deleted.
134
143
  *
135
144
  * @param gcResult - The result of the GC run on the gcData.
136
- * @param sweepReadyNodes - List of nodes that are sweep ready.
137
- * @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
138
- * @param logger - The logger to be used to log any telemetry.
139
- * @returns A list of nodes that have been deleted.
145
+ * @param tombstoneReadyNodes - List of nodes that are tombstone-ready.
146
+ * @param sweepReadyNodes - List of nodes that are sweep-ready.
140
147
  */
141
148
  private runSweepPhase;
142
149
  /**
@@ -166,6 +173,18 @@ export declare class GarbageCollector implements IGarbageCollector {
166
173
  * Called to refresh the latest summary state. This happens when either a pending summary is acked.
167
174
  */
168
175
  refreshLatestSummary(result: IRefreshSummaryResult): Promise<void>;
176
+ /**
177
+ * Process a GC message.
178
+ * @param message - The GC message from the container runtime.
179
+ * @param local - Whether it was send by this client.
180
+ */
181
+ processMessage(message: ContainerRuntimeGCMessage, local: boolean): void;
182
+ /**
183
+ * Delete nodes that are sweep-ready. Call the runtime to delete these nodes and clear the unreferenced state
184
+ * tracking for nodes that are actually deleted by the runtime.
185
+ * @param sweepReadyNodeIds - The ids of nodes that are ready to be deleted.
186
+ */
187
+ private deleteSweepReadyNodes;
169
188
  /**
170
189
  * Called when a node with the given id is updated. If the node is inactive or tombstoned, this will log an error
171
190
  * or throw an error if failing on incorrect usage is configured.
@@ -199,8 +218,8 @@ export declare class GarbageCollector implements IGarbageCollector {
199
218
  private getMarkPhaseStats;
200
219
  /**
201
220
  * Generates the stats of a garbage collection sweep phase run.
202
- * @param allDeletedNodes - All the nodes that have been deleted across all GC runs.
203
- * @param currentDeletedNodes - The nodes that have been deleted in this GC run.
221
+ * @param deletedNodes - The nodes that have been deleted until this run.
222
+ * @param sweepReadyNodes - The nodes that are sweep-ready in this GC run.
204
223
  * @param markPhaseStats - The stats of the mark phase run.
205
224
  * @returns the stats of the sweep phase run.
206
225
  */
@@ -1 +1 @@
1
- {"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../../src/gc/garbageCollection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../../src/gc/garbageCollection.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ const runtime_utils_1 = require("@fluidframework/runtime-utils");
11
11
  const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
12
12
  const containerRuntime_1 = require("../containerRuntime");
13
13
  const error_1 = require("../error");
14
+ const messageTypes_1 = require("../messageTypes");
14
15
  const gcConfigs_1 = require("./gcConfigs");
15
16
  const gcDefinitions_1 = require("./gcDefinitions");
16
17
  const gcHelpers_1 = require("./gcHelpers");
@@ -49,7 +50,7 @@ class GarbageCollector {
49
50
  }
50
51
  /** If false, loading or using a Tombstoned object should merely log, not fail */
51
52
  get tombstoneEnforcementAllowed() {
52
- return this.configs.tombstoneEnforcementAllowed;
53
+ return this.configs.sweepEnabled;
53
54
  }
54
55
  /** If true, throw an error when a tombstone data store is retrieved */
55
56
  get throwOnTombstoneLoad() {
@@ -83,6 +84,7 @@ class GarbageCollector {
83
84
  this.getNodePackagePath = createParams.getNodePackagePath;
84
85
  this.getLastSummaryTimestampMs = createParams.getLastSummaryTimestampMs;
85
86
  this.activeConnection = createParams.activeConnection;
87
+ this.submitMessage = createParams.submitMessage;
86
88
  const baseSnapshot = createParams.baseSnapshot;
87
89
  const readAndParseBlob = createParams.readAndParseBlob;
88
90
  this.mc = (0, telemetry_utils_1.createChildMonitoringContext)({
@@ -144,7 +146,7 @@ class GarbageCollector {
144
146
  /**
145
147
  * Set up the initializer which initializes the GC state from the data in base snapshot. This is done when
146
148
  * connected in write mode or when GC runs the first time. It sets up all unreferenced nodes from the base
147
- * GC state and updates their inactive or sweep ready state.
149
+ * GC state and updates their inactive or sweep-ready state.
148
150
  */
149
151
  this.initializeGCStateFromBaseSnapshotP = new core_utils_1.LazyPromise(async () => {
150
152
  /**
@@ -294,7 +296,7 @@ class GarbageCollector {
294
296
  const gcNodes = {};
295
297
  for (const [nodeId, nodeData] of Object.entries(snapshotData.gcState.gcNodes)) {
296
298
  if (nodeData.unreferencedTimestampMs !== undefined) {
297
- this.unreferencedNodesState.set(nodeId, new gcUnreferencedStateTracker_1.UnreferencedStateTracker(nodeData.unreferencedTimestampMs, this.configs.inactiveTimeoutMs, currentReferenceTimestampMs, this.configs.sweepTimeoutMs));
299
+ this.unreferencedNodesState.set(nodeId, new gcUnreferencedStateTracker_1.UnreferencedStateTracker(nodeData.unreferencedTimestampMs, this.configs.inactiveTimeoutMs, currentReferenceTimestampMs, this.configs.sweepTimeoutMs, this.configs.sweepGracePeriodMs));
298
300
  }
299
301
  gcNodes[nodeId] = Array.from(nodeData.outboundRoutes);
300
302
  }
@@ -302,7 +304,7 @@ class GarbageCollector {
302
304
  }
303
305
  /**
304
306
  * Called when the connection state of the runtime changes, i.e., it connects or disconnects. GC subscribes to this
305
- * to initialize the base state for non-summarizer clients so that they can track inactive / sweep ready nodes.
307
+ * to initialize the base state for non-summarizer clients so that they can track inactive / sweep-ready nodes.
306
308
  * @param connected - Whether the runtime connected / disconnected.
307
309
  * @param clientId - The clientId of this runtime.
308
310
  */
@@ -318,7 +320,7 @@ class GarbageCollector {
318
320
  * the receiving summarizer client.
319
321
  *
320
322
  * Ideally, this initialization should only be done for summarizer client. However, we are currently rolling out
321
- * sweep in phases and we want to track when inactive and sweep ready objects are used in any client.
323
+ * sweep in phases and we want to track when inactive and sweep-ready objects are used in any client.
322
324
  */
323
325
  if (this.activeConnection() && this.configs.shouldRunGC) {
324
326
  this.initializeGCStateFromBaseSnapshotP.catch((error) => { });
@@ -395,10 +397,15 @@ class GarbageCollector {
395
397
  }
396
398
  /**
397
399
  * Runs garbage collection. It does the following:
400
+ *
398
401
  * 1. It generates / analyzes the runtime's reference graph.
402
+ *
399
403
  * 2. Generates mark phase stats.
404
+ *
400
405
  * 3. Runs Mark phase.
406
+ *
401
407
  * 4. Runs Sweep phase.
408
+ *
402
409
  * 5. Generates sweep phase stats.
403
410
  */
404
411
  async runGC(fullGC, currentReferenceTimestampMs, logger) {
@@ -413,14 +420,15 @@ class GarbageCollector {
413
420
  // This is done before running mark phase because we need the previous GC state before it is updated.
414
421
  const markPhaseStats = this.getMarkPhaseStats(gcResult);
415
422
  // 3. Run the Mark phase.
416
- // It will mark nodes as referenced / unreferenced and return a list of node ids that are ready to be swept.
417
- const sweepReadyNodeIds = this.runMarkPhase(gcResult, allReferencedNodeIds, currentReferenceTimestampMs);
423
+ // It will mark nodes as referenced / unreferenced and return lists of tombstone-ready and sweep-ready nodes.
424
+ const { tombstoneReadyNodeIds, sweepReadyNodeIds } = this.runMarkPhase(gcResult, allReferencedNodeIds, currentReferenceTimestampMs);
418
425
  // 4. Run the Sweep phase.
419
- // It will delete sweep ready nodes and return a list of deleted node ids.
420
- const deletedNodeIds = this.runSweepPhase(gcResult, sweepReadyNodeIds);
421
- this.gcDataFromLastRun = (0, gcHelpers_1.cloneGCData)(gcData, (id) => deletedNodeIds.includes(id) /* filter out deleted nodes */);
426
+ // It will tombstone any tombstone-ready nodes, and initiate the deletion of sweep-ready nodes by sending a
427
+ // sweep op. All clients, including this one, will delete these nodes once it processes the op.
428
+ this.runSweepPhase(gcResult, tombstoneReadyNodeIds, sweepReadyNodeIds);
429
+ this.gcDataFromLastRun = (0, gcHelpers_1.cloneGCData)(gcData);
422
430
  // 5. Get the sweep phase stats.
423
- const sweepPhaseStats = this.getSweepPhaseStats(this.configs.shouldRunSweep ? this.deletedNodes : sweepReadyNodeIds, new Set(deletedNodeIds), markPhaseStats);
431
+ const sweepPhaseStats = this.getSweepPhaseStats(this.deletedNodes, sweepReadyNodeIds, markPhaseStats);
424
432
  return { ...markPhaseStats, ...sweepPhaseStats };
425
433
  }
426
434
  /**
@@ -435,7 +443,7 @@ class GarbageCollector {
435
443
  * @param gcResult - The result of the GC run on the gcData.
436
444
  * @param allReferencedNodeIds - Nodes referenced in this GC run + referenced between previous and current GC run.
437
445
  * @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
438
- * @returns A list of sweep ready nodes, i.e., nodes that ready to be deleted.
446
+ * @returns The sets of tombstone-ready and sweep-ready nodes, i.e., nodes that ready to be tombstoned or deleted.
439
447
  */
440
448
  runMarkPhase(gcResult, allReferencedNodeIds, currentReferenceTimestampMs) {
441
449
  // 1. Marks all referenced nodes by clearing their unreferenced tracker, if any.
@@ -449,17 +457,21 @@ class GarbageCollector {
449
457
  }
450
458
  }
451
459
  // 2. Mark unreferenced nodes in this run by starting unreferenced tracking for them.
460
+ const tombstoneReadyNodeIds = new Set();
452
461
  const sweepReadyNodeIds = new Set();
453
462
  for (const nodeId of gcResult.deletedNodeIds) {
454
463
  const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
455
464
  if (nodeStateTracker === undefined) {
456
- this.unreferencedNodesState.set(nodeId, new gcUnreferencedStateTracker_1.UnreferencedStateTracker(currentReferenceTimestampMs, this.configs.inactiveTimeoutMs, currentReferenceTimestampMs, this.configs.sweepTimeoutMs));
465
+ this.unreferencedNodesState.set(nodeId, new gcUnreferencedStateTracker_1.UnreferencedStateTracker(currentReferenceTimestampMs, this.configs.inactiveTimeoutMs, currentReferenceTimestampMs, this.configs.sweepTimeoutMs, this.configs.sweepGracePeriodMs));
457
466
  }
458
467
  else {
459
468
  // If a node was already unreferenced, update its tracking information. Since the current reference time
460
469
  // is from the ops seen, this will ensure that we keep updating unreferenced state as time moves forward.
461
470
  nodeStateTracker.updateTracking(currentReferenceTimestampMs);
462
- // If a node is sweep ready, store it so it can be returned.
471
+ // If a node is tombstone or sweep-ready, store it so it can be returned.
472
+ if (nodeStateTracker.state === gcDefinitions_1.UnreferencedState.TombstoneReady) {
473
+ tombstoneReadyNodeIds.add(nodeId);
474
+ }
463
475
  if (nodeStateTracker.state === gcDefinitions_1.UnreferencedState.SweepReady) {
464
476
  sweepReadyNodeIds.add(nodeId);
465
477
  }
@@ -467,62 +479,72 @@ class GarbageCollector {
467
479
  }
468
480
  // 3. Call the runtime to update referenced nodes in this run.
469
481
  this.runtime.updateUsedRoutes(gcResult.referencedNodeIds);
470
- return sweepReadyNodeIds;
482
+ return { tombstoneReadyNodeIds, sweepReadyNodeIds };
471
483
  }
472
484
  /**
473
485
  * Runs the GC Sweep phase. It does the following:
474
- * 1. Calls the runtime to delete nodes that are sweep ready.
475
- * 2. Clears tracking for deleted nodes.
486
+ *
487
+ * 1. Marks tombstone-ready nodes as tombstones.
488
+ *
489
+ * 2. Sends a sweep op to delete nodes that are sweep-ready. Once the op is ack'd, these nodes will be deleted.
476
490
  *
477
491
  * @param gcResult - The result of the GC run on the gcData.
478
- * @param sweepReadyNodes - List of nodes that are sweep ready.
479
- * @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
480
- * @param logger - The logger to be used to log any telemetry.
481
- * @returns A list of nodes that have been deleted.
492
+ * @param tombstoneReadyNodes - List of nodes that are tombstone-ready.
493
+ * @param sweepReadyNodes - List of nodes that are sweep-ready.
482
494
  */
483
- runSweepPhase(gcResult, sweepReadyNodes) {
495
+ runSweepPhase(gcResult, tombstoneReadyNodes, sweepReadyNodes) {
484
496
  /**
485
- * Currently, there are 3 modes for sweep:
486
- * Test mode - Unreferenced nodes are immediately deleted without waiting for them to be sweep ready.
487
- * Tombstone mode - Sweep ready modes are marked as tombstones instead of being deleted.
488
- * Sweep mode - Sweep ready modes are deleted.
497
+ * Under "Test Mode", unreferenced nodes are immediately deleted without waiting for them to be sweep-ready.
489
498
  *
490
- * These modes serve as staging for applications that want to enable sweep by providing an incremental
491
- * way to test and validate sweep works as expected.
499
+ * Otherwise, depending on how long it's been since the node was unreferenced, it will either be
500
+ * marked as Tombstone, or deleted by Sweep.
492
501
  */
493
502
  if (this.configs.testMode) {
494
503
  // If we are running in GC test mode, unreferenced nodes (gcResult.deletedNodeIds) are deleted.
495
504
  this.runtime.updateUnusedRoutes(gcResult.deletedNodeIds);
496
- return [];
505
+ return;
497
506
  }
507
+ // If sweep is disabled, we'll tombstone both tombstone-ready and sweep-ready nodes.
508
+ // This is important because a container may never load during a node's Sweep Grace Period,
509
+ // so that node would directly become sweep-ready skipping over tombstone-ready state,
510
+ // but should be Tombstoned since Sweep is disabled.
511
+ const { nodesToTombstone, nodesToDelete } = this.configs.shouldRunSweep
512
+ ? {
513
+ nodesToTombstone: [...tombstoneReadyNodes],
514
+ nodesToDelete: [...sweepReadyNodes],
515
+ }
516
+ : {
517
+ nodesToTombstone: [...tombstoneReadyNodes, ...sweepReadyNodes],
518
+ nodesToDelete: [],
519
+ };
498
520
  if (this.configs.tombstoneMode) {
499
- this.tombstones = Array.from(sweepReadyNodes);
500
- // If we are running in GC tombstone mode, update tombstoned routes. This enables testing scenarios
501
- // involving access to "deleted" data without actually deleting the data from summaries.
521
+ this.tombstones = nodesToTombstone;
522
+ // If we are running in GC tombstone mode, update tombstoned routes.
502
523
  this.runtime.updateTombstonedRoutes(this.tombstones);
503
- return [];
504
524
  }
505
- if (!this.configs.shouldRunSweep) {
506
- return [];
507
- }
508
- // 1. Call the runtime to delete sweep ready nodes. The runtime returns a list of nodes it deleted.
509
- // TODO: GC:Validation - validate that removed routes are not double delete and that the child routes of
510
- // removed routes are deleted as well.
511
- const deletedNodeIds = this.runtime.deleteSweepReadyNodes(Array.from(sweepReadyNodes));
512
- // 2. Clear unreferenced state tracking for deleted nodes.
513
- for (const nodeId of deletedNodeIds) {
514
- const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
515
- // TODO: GC:Validation - assert that the nodeStateTracker is defined
516
- if (nodeStateTracker !== undefined) {
517
- // Stop tracking so as to clear out any running timers.
518
- nodeStateTracker.stopTracking();
519
- // Delete the node as we don't need to track it any more.
520
- this.unreferencedNodesState.delete(nodeId);
521
- }
522
- // TODO: GC:Validation - assert that the deleted node is not a duplicate
523
- this.deletedNodes.add(nodeId);
525
+ if (this.configs.shouldRunSweep && nodesToDelete.length > 0) {
526
+ // Do not send DDS node ids in the GC op. This is an optimization to reduce its size. Since GC applies to
527
+ // to data store only, all its DDSes are deleted along with it. The DDS ids will be retrieved from the
528
+ // local state when processing the op.
529
+ const sweepReadyDSAndBlobs = nodesToDelete.filter((nodeId) => {
530
+ const nodeType = this.runtime.getNodeType(nodeId);
531
+ return nodeType === gcDefinitions_1.GCNodeType.DataStore || nodeType === gcDefinitions_1.GCNodeType.Blob;
532
+ });
533
+ const contents = {
534
+ type: gcDefinitions_1.GarbageCollectionMessageType.Sweep,
535
+ deletedNodeIds: sweepReadyDSAndBlobs,
536
+ };
537
+ // Its fine for older clients to ignore this op because it doesn't have any functional impact. This op
538
+ // is an optimization to ensure that all clients are in sync when it comes to deleted nodes to prevent their
539
+ // accidental usage. The clients will sync without the delete op too but it may take longer.
540
+ const containerGCMessage = {
541
+ type: messageTypes_1.ContainerMessageType.GC,
542
+ contents,
543
+ compatDetails: { behavior: "Ignore" },
544
+ };
545
+ this.submitMessage(containerGCMessage);
546
+ return;
524
547
  }
525
- return deletedNodeIds;
526
548
  }
527
549
  /**
528
550
  * Since GC runs periodically, the GC data that is generated only tells us the state of the world at that point in
@@ -632,6 +654,65 @@ class GarbageCollector {
632
654
  async refreshLatestSummary(result) {
633
655
  return this.summaryStateTracker.refreshLatestSummary(result);
634
656
  }
657
+ /**
658
+ * Process a GC message.
659
+ * @param message - The GC message from the container runtime.
660
+ * @param local - Whether it was send by this client.
661
+ */
662
+ processMessage(message, local) {
663
+ switch (message.contents.type) {
664
+ case "Sweep": {
665
+ // Delete the nodes whose ids are present in the contents.
666
+ this.deleteSweepReadyNodes(message.contents.deletedNodeIds);
667
+ break;
668
+ }
669
+ default: {
670
+ if (!(0, gcHelpers_1.compatBehaviorAllowsGCMessageType)(message.contents.type, message.compatDetails?.behavior)) {
671
+ const error = telemetry_utils_1.DataProcessingError.create(`Garbage collection message of unknown type ${message.contents.type}`, "processMessage");
672
+ throw error;
673
+ }
674
+ break;
675
+ }
676
+ }
677
+ }
678
+ /**
679
+ * Delete nodes that are sweep-ready. Call the runtime to delete these nodes and clear the unreferenced state
680
+ * tracking for nodes that are actually deleted by the runtime.
681
+ * @param sweepReadyNodeIds - The ids of nodes that are ready to be deleted.
682
+ */
683
+ deleteSweepReadyNodes(sweepReadyNodeIds) {
684
+ // Use a set for lookup because its much faster than array or map.
685
+ const sweepReadyNodesSet = new Set(sweepReadyNodeIds);
686
+ // The ids in the sweep-ready nodes do not contain DDS node ids. This is an optimization to reduce the size
687
+ // of the GC op. Since GC applies to data store only, all its DDSes are deleted along with it. So, get the
688
+ // DDS nodes ID from the unreferenced nodes state.
689
+ const allSweepReadyNodeIds = Array.from(sweepReadyNodeIds);
690
+ for (const [id] of this.unreferencedNodesState) {
691
+ // Ignore data store nodes since they would already be in the list.
692
+ const pathParts = id.split("/");
693
+ if (pathParts.length <= 2) {
694
+ continue;
695
+ }
696
+ // Get the data store id part. Note that this may include blobs but that's okay since the part would just
697
+ // be "_blobs" and it won't be found.
698
+ const dsId = `/${pathParts[1]}`;
699
+ if (sweepReadyNodesSet.has(dsId)) {
700
+ allSweepReadyNodeIds.push(id);
701
+ }
702
+ }
703
+ const deletedNodeIds = this.runtime.deleteSweepReadyNodes(allSweepReadyNodeIds);
704
+ // Clear unreferenced state tracking for deleted nodes.
705
+ for (const nodeId of deletedNodeIds) {
706
+ const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
707
+ if (nodeStateTracker !== undefined) {
708
+ // Stop tracking so as to clear out any running timers.
709
+ nodeStateTracker.stopTracking();
710
+ // Delete the node as we don't need to track it any more.
711
+ this.unreferencedNodesState.delete(nodeId);
712
+ }
713
+ this.deletedNodes.add(nodeId);
714
+ }
715
+ }
635
716
  /**
636
717
  * Called when a node with the given id is updated. If the node is inactive or tombstoned, this will log an error
637
718
  * or throw an error if failing on incorrect usage is configured.
@@ -777,12 +858,12 @@ class GarbageCollector {
777
858
  }
778
859
  /**
779
860
  * Generates the stats of a garbage collection sweep phase run.
780
- * @param allDeletedNodes - All the nodes that have been deleted across all GC runs.
781
- * @param currentDeletedNodes - The nodes that have been deleted in this GC run.
861
+ * @param deletedNodes - The nodes that have been deleted until this run.
862
+ * @param sweepReadyNodes - The nodes that are sweep-ready in this GC run.
782
863
  * @param markPhaseStats - The stats of the mark phase run.
783
864
  * @returns the stats of the sweep phase run.
784
865
  */
785
- getSweepPhaseStats(allDeletedNodes, currentDeletedNodes, markPhaseStats) {
866
+ getSweepPhaseStats(deletedNodes, sweepReadyNodes, markPhaseStats) {
786
867
  // Initialize the life time node counts to the mark phase node counts. If sweep is not enabled,
787
868
  // these will be the life time node count for this container.
788
869
  const sweepPhaseStats = {
@@ -793,7 +874,7 @@ class GarbageCollector {
793
874
  deletedDataStoreCount: 0,
794
875
  deletedAttachmentBlobCount: 0,
795
876
  };
796
- for (const nodeId of allDeletedNodes) {
877
+ for (const nodeId of deletedNodes) {
797
878
  sweepPhaseStats.deletedNodeCount++;
798
879
  const nodeType = this.runtime.getNodeType(nodeId);
799
880
  if (nodeType === gcDefinitions_1.GCNodeType.DataStore) {
@@ -803,24 +884,25 @@ class GarbageCollector {
803
884
  sweepPhaseStats.deletedAttachmentBlobCount++;
804
885
  }
805
886
  }
806
- if (!this.configs.shouldRunSweep) {
807
- return sweepPhaseStats;
808
- }
809
887
  // If sweep is enabled, the counts from the mark phase stats do not include nodes that have been
810
- // deleted in previous runs. Add the deleted node counts to life time stats.
888
+ // deleted in previous runs. So, add the deleted node counts to life time stats.
811
889
  sweepPhaseStats.lifetimeNodeCount += sweepPhaseStats.deletedNodeCount;
812
890
  sweepPhaseStats.lifetimeDataStoreCount += sweepPhaseStats.deletedDataStoreCount;
813
891
  sweepPhaseStats.lifetimeAttachmentBlobCount += sweepPhaseStats.deletedAttachmentBlobCount;
814
- // The node deleted in current run are counted twice - once in allDeletedNodes and again in
815
- // markPhaseStats. So, remove them from the life time stats.
816
- for (const nodeId of currentDeletedNodes) {
817
- sweepPhaseStats.lifetimeNodeCount--;
892
+ if (this.configs.shouldRunSweep) {
893
+ return sweepPhaseStats;
894
+ }
895
+ // If sweep is not enabled, the current sweep-ready node stats should be added to deleted stats since this
896
+ // is the final state the node will be in.
897
+ // If sweep is enabled, this will happen in the run after the GC op round trips back.
898
+ for (const nodeId of sweepReadyNodes) {
899
+ sweepPhaseStats.deletedNodeCount++;
818
900
  const nodeType = this.runtime.getNodeType(nodeId);
819
901
  if (nodeType === gcDefinitions_1.GCNodeType.DataStore) {
820
- sweepPhaseStats.lifetimeDataStoreCount--;
902
+ sweepPhaseStats.deletedDataStoreCount++;
821
903
  }
822
904
  else if (nodeType === gcDefinitions_1.GCNodeType.Blob) {
823
- sweepPhaseStats.lifetimeAttachmentBlobCount--;
905
+ sweepPhaseStats.deletedAttachmentBlobCount++;
824
906
  }
825
907
  }
826
908
  return sweepPhaseStats;