@fluidframework/container-runtime 2.0.0-internal.8.0.0 → 2.0.0-rc.1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (453) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +1 -7
  3. package/api-extractor-esm.json +4 -0
  4. package/api-extractor-lint.json +1 -10
  5. package/api-extractor.json +1 -9
  6. package/api-report/container-runtime.api.md +18 -17
  7. package/dist/blobManager.d.ts +8 -3
  8. package/dist/blobManager.d.ts.map +1 -1
  9. package/dist/blobManager.js +15 -4
  10. package/dist/blobManager.js.map +1 -1
  11. package/dist/container-runtime-alpha.d.ts +265 -17
  12. package/dist/container-runtime-beta.d.ts +0 -42
  13. package/dist/container-runtime-public.d.ts +0 -42
  14. package/dist/container-runtime-untrimmed.d.ts +32 -17
  15. package/dist/containerRuntime.d.ts +8 -4
  16. package/dist/containerRuntime.d.ts.map +1 -1
  17. package/dist/containerRuntime.js +15 -32
  18. package/dist/containerRuntime.js.map +1 -1
  19. package/dist/dataStoreContext.d.ts +5 -2
  20. package/dist/dataStoreContext.d.ts.map +1 -1
  21. package/dist/dataStoreContext.js +10 -3
  22. package/dist/dataStoreContext.js.map +1 -1
  23. package/dist/dataStores.d.ts +10 -3
  24. package/dist/dataStores.d.ts.map +1 -1
  25. package/dist/dataStores.js +51 -8
  26. package/dist/dataStores.js.map +1 -1
  27. package/dist/gc/garbageCollection.d.ts +8 -12
  28. package/dist/gc/garbageCollection.d.ts.map +1 -1
  29. package/dist/gc/garbageCollection.js +84 -105
  30. package/dist/gc/garbageCollection.js.map +1 -1
  31. package/dist/gc/gcConfigs.d.ts.map +1 -1
  32. package/dist/gc/gcConfigs.js +26 -19
  33. package/dist/gc/gcConfigs.js.map +1 -1
  34. package/dist/gc/gcDefinitions.d.ts +29 -7
  35. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  36. package/dist/gc/gcDefinitions.js +5 -3
  37. package/dist/gc/gcDefinitions.js.map +1 -1
  38. package/dist/gc/gcSummaryStateTracker.d.ts +1 -1
  39. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  40. package/dist/gc/gcSummaryStateTracker.js +3 -0
  41. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  42. package/dist/gc/gcTelemetry.d.ts +13 -6
  43. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  44. package/dist/gc/gcTelemetry.js +22 -23
  45. package/dist/gc/gcTelemetry.js.map +1 -1
  46. package/dist/gc/index.d.ts +1 -1
  47. package/dist/gc/index.d.ts.map +1 -1
  48. package/dist/gc/index.js +2 -1
  49. package/dist/gc/index.js.map +1 -1
  50. package/dist/messageTypes.d.ts +1 -1
  51. package/dist/messageTypes.js +1 -1
  52. package/dist/messageTypes.js.map +1 -1
  53. package/dist/opLifecycle/definitions.d.ts +1 -1
  54. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  55. package/dist/opLifecycle/definitions.js.map +1 -1
  56. package/dist/opLifecycle/outbox.d.ts +4 -4
  57. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  58. package/dist/opLifecycle/outbox.js +4 -1
  59. package/dist/opLifecycle/outbox.js.map +1 -1
  60. package/dist/packageVersion.d.ts +1 -1
  61. package/dist/packageVersion.d.ts.map +1 -1
  62. package/dist/packageVersion.js +1 -1
  63. package/dist/packageVersion.js.map +1 -1
  64. package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -1
  65. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  66. package/dist/summary/runningSummarizer.d.ts +5 -0
  67. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  68. package/dist/summary/runningSummarizer.js +46 -17
  69. package/dist/summary/runningSummarizer.js.map +1 -1
  70. package/dist/summary/summarizer.d.ts +1 -1
  71. package/dist/summary/summarizer.js +1 -1
  72. package/dist/summary/summarizer.js.map +1 -1
  73. package/dist/summary/summarizerTypes.d.ts +3 -1
  74. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  75. package/dist/summary/summarizerTypes.js.map +1 -1
  76. package/dist/summary/summaryCollection.d.ts +7 -7
  77. package/dist/summary/summaryCollection.js +1 -1
  78. package/dist/summary/summaryCollection.js.map +1 -1
  79. package/lib/{batchTracker.d.ts → batchTracker.d.mts} +1 -1
  80. package/lib/batchTracker.d.mts.map +1 -0
  81. package/lib/{batchTracker.js → batchTracker.mjs} +1 -1
  82. package/lib/batchTracker.mjs.map +1 -0
  83. package/lib/{blobManager.d.ts → blobManager.d.mts} +9 -4
  84. package/lib/blobManager.d.mts.map +1 -0
  85. package/lib/{blobManager.js → blobManager.mjs} +17 -6
  86. package/lib/blobManager.mjs.map +1 -0
  87. package/lib/{connectionTelemetry.d.ts → connectionTelemetry.d.mts} +1 -1
  88. package/lib/connectionTelemetry.d.mts.map +1 -0
  89. package/lib/{connectionTelemetry.js → connectionTelemetry.mjs} +1 -1
  90. package/lib/connectionTelemetry.mjs.map +1 -0
  91. package/lib/{container-runtime-alpha.d.ts → container-runtime-alpha.d.mts} +265 -17
  92. package/lib/{container-runtime-beta.d.ts → container-runtime-beta.d.mts} +0 -42
  93. package/lib/{container-runtime-public.d.ts → container-runtime-public.d.mts} +0 -42
  94. package/lib/{container-runtime-untrimmed.d.ts → container-runtime-untrimmed.d.mts} +32 -17
  95. package/lib/{containerHandleContext.d.ts → containerHandleContext.d.mts} +2 -2
  96. package/lib/containerHandleContext.d.mts.map +1 -0
  97. package/lib/{containerHandleContext.js → containerHandleContext.mjs} +1 -1
  98. package/lib/containerHandleContext.mjs.map +1 -0
  99. package/lib/{containerRuntime.d.ts → containerRuntime.d.mts} +14 -14
  100. package/lib/containerRuntime.d.mts.map +1 -0
  101. package/lib/{containerRuntime.js → containerRuntime.mjs} +31 -25
  102. package/lib/containerRuntime.mjs.map +1 -0
  103. package/lib/{dataStore.d.ts → dataStore.d.mts} +3 -3
  104. package/lib/dataStore.d.mts.map +1 -0
  105. package/lib/{dataStore.js → dataStore.mjs} +1 -1
  106. package/lib/dataStore.mjs.map +1 -0
  107. package/lib/{dataStoreContext.d.ts → dataStoreContext.d.mts} +7 -4
  108. package/lib/dataStoreContext.d.mts.map +1 -0
  109. package/lib/{dataStoreContext.js → dataStoreContext.mjs} +13 -6
  110. package/lib/dataStoreContext.mjs.map +1 -0
  111. package/lib/{dataStoreContexts.d.ts → dataStoreContexts.d.mts} +2 -2
  112. package/lib/dataStoreContexts.d.mts.map +1 -0
  113. package/lib/{dataStoreContexts.js → dataStoreContexts.mjs} +1 -1
  114. package/lib/dataStoreContexts.mjs.map +1 -0
  115. package/lib/{dataStoreRegistry.d.ts → dataStoreRegistry.d.mts} +1 -1
  116. package/lib/dataStoreRegistry.d.mts.map +1 -0
  117. package/lib/{dataStoreRegistry.js → dataStoreRegistry.mjs} +1 -5
  118. package/lib/dataStoreRegistry.mjs.map +1 -0
  119. package/lib/{dataStores.d.ts → dataStores.d.mts} +17 -10
  120. package/lib/dataStores.d.mts.map +1 -0
  121. package/lib/{dataStores.js → dataStores.mjs} +58 -16
  122. package/lib/dataStores.mjs.map +1 -0
  123. package/lib/{deltaManagerProxyBase.d.ts → deltaManagerProxyBase.d.mts} +1 -1
  124. package/lib/deltaManagerProxyBase.d.mts.map +1 -0
  125. package/lib/{deltaManagerProxyBase.js → deltaManagerProxyBase.mjs} +1 -1
  126. package/lib/deltaManagerProxyBase.mjs.map +1 -0
  127. package/lib/{deltaManagerSummarizerProxy.d.ts → deltaManagerSummarizerProxy.d.mts} +2 -2
  128. package/lib/deltaManagerSummarizerProxy.d.mts.map +1 -0
  129. package/lib/{deltaManagerSummarizerProxy.js → deltaManagerSummarizerProxy.mjs} +3 -3
  130. package/lib/deltaManagerSummarizerProxy.mjs.map +1 -0
  131. package/lib/{deltaScheduler.d.ts → deltaScheduler.d.mts} +1 -1
  132. package/lib/deltaScheduler.d.mts.map +1 -0
  133. package/lib/{deltaScheduler.js → deltaScheduler.mjs} +1 -1
  134. package/lib/deltaScheduler.mjs.map +1 -0
  135. package/lib/{error.d.ts → error.d.mts} +1 -1
  136. package/lib/error.d.mts.map +1 -0
  137. package/lib/{error.js → error.mjs} +1 -1
  138. package/lib/error.mjs.map +1 -0
  139. package/lib/gc/{garbageCollection.d.ts → garbageCollection.d.mts} +13 -17
  140. package/lib/gc/garbageCollection.d.mts.map +1 -0
  141. package/lib/gc/{garbageCollection.js → garbageCollection.mjs} +97 -118
  142. package/lib/gc/garbageCollection.mjs.map +1 -0
  143. package/lib/gc/{gcConfigs.d.ts → gcConfigs.d.mts} +3 -3
  144. package/lib/gc/gcConfigs.d.mts.map +1 -0
  145. package/lib/gc/{gcConfigs.js → gcConfigs.mjs} +29 -22
  146. package/lib/gc/gcConfigs.mjs.map +1 -0
  147. package/lib/gc/{gcDefinitions.d.ts → gcDefinitions.d.mts} +33 -11
  148. package/lib/gc/gcDefinitions.d.mts.map +1 -0
  149. package/lib/gc/{gcDefinitions.js → gcDefinitions.mjs} +5 -3
  150. package/lib/gc/gcDefinitions.mjs.map +1 -0
  151. package/lib/gc/{gcHelpers.d.ts → gcHelpers.d.mts} +3 -3
  152. package/lib/gc/{gcHelpers.d.ts.map → gcHelpers.d.mts.map} +1 -1
  153. package/lib/gc/{gcHelpers.js → gcHelpers.mjs} +1 -1
  154. package/lib/gc/gcHelpers.mjs.map +1 -0
  155. package/lib/gc/{gcReferenceGraphAlgorithm.d.ts → gcReferenceGraphAlgorithm.d.mts} +2 -2
  156. package/lib/gc/gcReferenceGraphAlgorithm.d.mts.map +1 -0
  157. package/lib/gc/{gcReferenceGraphAlgorithm.js → gcReferenceGraphAlgorithm.mjs} +1 -1
  158. package/lib/gc/gcReferenceGraphAlgorithm.mjs.map +1 -0
  159. package/lib/gc/{gcSummaryDefinitions.d.ts → gcSummaryDefinitions.d.mts} +1 -1
  160. package/lib/gc/gcSummaryDefinitions.d.mts.map +1 -0
  161. package/lib/gc/{gcSummaryDefinitions.js → gcSummaryDefinitions.mjs} +1 -1
  162. package/lib/gc/gcSummaryDefinitions.mjs.map +1 -0
  163. package/lib/gc/{gcSummaryStateTracker.d.ts → gcSummaryStateTracker.d.mts} +5 -5
  164. package/lib/gc/gcSummaryStateTracker.d.mts.map +1 -0
  165. package/lib/gc/{gcSummaryStateTracker.js → gcSummaryStateTracker.mjs} +5 -2
  166. package/lib/gc/gcSummaryStateTracker.mjs.map +1 -0
  167. package/lib/gc/{gcTelemetry.d.ts → gcTelemetry.d.mts} +18 -11
  168. package/lib/gc/gcTelemetry.d.mts.map +1 -0
  169. package/lib/gc/{gcTelemetry.js → gcTelemetry.mjs} +24 -25
  170. package/lib/gc/gcTelemetry.mjs.map +1 -0
  171. package/lib/gc/{gcUnreferencedStateTracker.d.ts → gcUnreferencedStateTracker.d.mts} +2 -2
  172. package/lib/gc/gcUnreferencedStateTracker.d.mts.map +1 -0
  173. package/lib/gc/{gcUnreferencedStateTracker.js → gcUnreferencedStateTracker.mjs} +2 -2
  174. package/lib/gc/gcUnreferencedStateTracker.mjs.map +1 -0
  175. package/lib/gc/{index.d.ts → index.d.mts} +9 -9
  176. package/lib/gc/index.d.mts.map +1 -0
  177. package/lib/gc/{index.js → index.mjs} +8 -8
  178. package/lib/gc/index.mjs.map +1 -0
  179. package/lib/{index.d.ts → index.d.mts} +8 -8
  180. package/lib/index.d.mts.map +1 -0
  181. package/lib/{index.js → index.mjs} +7 -9
  182. package/lib/index.mjs.map +1 -0
  183. package/lib/{messageTypes.d.ts → messageTypes.d.mts} +5 -5
  184. package/lib/messageTypes.d.mts.map +1 -0
  185. package/lib/{messageTypes.js → messageTypes.mjs} +2 -2
  186. package/lib/messageTypes.mjs.map +1 -0
  187. package/lib/{metadata.d.ts → metadata.d.mts} +1 -1
  188. package/lib/metadata.d.mts.map +1 -0
  189. package/lib/{metadata.js → metadata.mjs} +1 -1
  190. package/lib/metadata.mjs.map +1 -0
  191. package/lib/opLifecycle/{batchManager.d.ts → batchManager.d.mts} +3 -3
  192. package/lib/opLifecycle/batchManager.d.mts.map +1 -0
  193. package/lib/opLifecycle/{batchManager.js → batchManager.mjs} +1 -1
  194. package/lib/opLifecycle/batchManager.mjs.map +1 -0
  195. package/lib/opLifecycle/{definitions.d.ts → definitions.d.mts} +3 -3
  196. package/lib/opLifecycle/definitions.d.mts.map +1 -0
  197. package/lib/opLifecycle/{definitions.js → definitions.mjs} +1 -1
  198. package/lib/opLifecycle/definitions.mjs.map +1 -0
  199. package/lib/opLifecycle/index.d.mts +13 -0
  200. package/lib/opLifecycle/index.d.mts.map +1 -0
  201. package/lib/opLifecycle/index.mjs +12 -0
  202. package/lib/opLifecycle/index.mjs.map +1 -0
  203. package/lib/opLifecycle/{opCompressor.d.ts → opCompressor.d.mts} +2 -2
  204. package/lib/opLifecycle/opCompressor.d.mts.map +1 -0
  205. package/lib/opLifecycle/{opCompressor.js → opCompressor.mjs} +3 -3
  206. package/lib/opLifecycle/opCompressor.mjs.map +1 -0
  207. package/lib/opLifecycle/{opDecompressor.d.ts → opDecompressor.d.mts} +2 -2
  208. package/lib/opLifecycle/opDecompressor.d.mts.map +1 -0
  209. package/lib/opLifecycle/{opDecompressor.js → opDecompressor.mjs} +2 -2
  210. package/lib/opLifecycle/opDecompressor.mjs.map +1 -0
  211. package/lib/opLifecycle/{opGroupingManager.d.ts → opGroupingManager.d.mts} +2 -2
  212. package/lib/opLifecycle/opGroupingManager.d.mts.map +1 -0
  213. package/lib/opLifecycle/{opGroupingManager.js → opGroupingManager.mjs} +1 -1
  214. package/lib/opLifecycle/opGroupingManager.mjs.map +1 -0
  215. package/lib/opLifecycle/{opSplitter.d.ts → opSplitter.d.mts} +2 -2
  216. package/lib/opLifecycle/opSplitter.d.mts.map +1 -0
  217. package/lib/opLifecycle/{opSplitter.js → opSplitter.mjs} +3 -3
  218. package/lib/opLifecycle/opSplitter.mjs.map +1 -0
  219. package/lib/opLifecycle/{outbox.d.ts → outbox.d.mts} +11 -11
  220. package/lib/opLifecycle/outbox.d.mts.map +1 -0
  221. package/lib/opLifecycle/{outbox.js → outbox.mjs} +6 -3
  222. package/lib/opLifecycle/outbox.mjs.map +1 -0
  223. package/lib/opLifecycle/{remoteMessageProcessor.d.ts → remoteMessageProcessor.d.mts} +5 -5
  224. package/lib/opLifecycle/remoteMessageProcessor.d.mts.map +1 -0
  225. package/lib/opLifecycle/{remoteMessageProcessor.js → remoteMessageProcessor.mjs} +2 -2
  226. package/lib/opLifecycle/remoteMessageProcessor.mjs.map +1 -0
  227. package/lib/{opProperties.d.ts → opProperties.d.mts} +1 -1
  228. package/lib/opProperties.d.mts.map +1 -0
  229. package/lib/{opProperties.js → opProperties.mjs} +1 -1
  230. package/lib/opProperties.mjs.map +1 -0
  231. package/lib/{packageVersion.d.ts → packageVersion.d.mts} +2 -2
  232. package/lib/packageVersion.d.mts.map +1 -0
  233. package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
  234. package/lib/packageVersion.mjs.map +1 -0
  235. package/lib/{pendingStateManager.d.ts → pendingStateManager.d.mts} +2 -2
  236. package/lib/pendingStateManager.d.mts.map +1 -0
  237. package/lib/{pendingStateManager.js → pendingStateManager.mjs} +2 -2
  238. package/lib/pendingStateManager.mjs.map +1 -0
  239. package/lib/{scheduleManager.d.ts → scheduleManager.d.mts} +1 -5
  240. package/lib/scheduleManager.d.mts.map +1 -0
  241. package/lib/{scheduleManager.js → scheduleManager.mjs} +3 -3
  242. package/lib/scheduleManager.mjs.map +1 -0
  243. package/lib/{storageServiceWithAttachBlobs.d.ts → storageServiceWithAttachBlobs.d.mts} +1 -1
  244. package/lib/storageServiceWithAttachBlobs.d.mts.map +1 -0
  245. package/lib/{storageServiceWithAttachBlobs.js → storageServiceWithAttachBlobs.mjs} +1 -1
  246. package/lib/storageServiceWithAttachBlobs.mjs.map +1 -0
  247. package/lib/summary/{index.d.ts → index.d.mts} +13 -13
  248. package/lib/summary/index.d.mts.map +1 -0
  249. package/lib/summary/{index.js → index.mjs} +12 -12
  250. package/lib/summary/index.mjs.map +1 -0
  251. package/lib/summary/{orderedClientElection.d.ts → orderedClientElection.d.mts} +1 -5
  252. package/lib/summary/orderedClientElection.d.mts.map +1 -0
  253. package/lib/summary/{orderedClientElection.js → orderedClientElection.mjs} +2 -2
  254. package/lib/summary/orderedClientElection.mjs.map +1 -0
  255. package/lib/summary/{runWhileConnectedCoordinator.d.ts → runWhileConnectedCoordinator.d.mts} +3 -3
  256. package/lib/summary/runWhileConnectedCoordinator.d.mts.map +1 -0
  257. package/lib/summary/{runWhileConnectedCoordinator.js → runWhileConnectedCoordinator.mjs} +1 -1
  258. package/lib/summary/runWhileConnectedCoordinator.mjs.map +1 -0
  259. package/lib/summary/{runningSummarizer.d.ts → runningSummarizer.d.mts} +10 -5
  260. package/lib/summary/runningSummarizer.d.mts.map +1 -0
  261. package/lib/summary/{runningSummarizer.js → runningSummarizer.mjs} +50 -21
  262. package/lib/summary/runningSummarizer.mjs.map +1 -0
  263. package/lib/summary/{summarizer.d.ts → summarizer.d.mts} +6 -6
  264. package/lib/summary/summarizer.d.mts.map +1 -0
  265. package/lib/summary/{summarizer.js → summarizer.mjs} +5 -5
  266. package/lib/summary/summarizer.mjs.map +1 -0
  267. package/lib/summary/{summarizerClientElection.d.ts → summarizerClientElection.d.mts} +3 -3
  268. package/lib/summary/summarizerClientElection.d.mts.map +1 -0
  269. package/lib/summary/{summarizerClientElection.js → summarizerClientElection.mjs} +1 -1
  270. package/lib/summary/summarizerClientElection.mjs.map +1 -0
  271. package/lib/summary/{summarizerHeuristics.d.ts → summarizerHeuristics.d.mts} +4 -4
  272. package/lib/summary/summarizerHeuristics.d.mts.map +1 -0
  273. package/lib/summary/{summarizerHeuristics.js → summarizerHeuristics.mjs} +1 -1
  274. package/lib/summary/summarizerHeuristics.mjs.map +1 -0
  275. package/lib/summary/summarizerNode/{index.d.ts → index.d.mts} +4 -4
  276. package/lib/summary/summarizerNode/index.d.mts.map +1 -0
  277. package/lib/summary/summarizerNode/{index.js → index.mjs} +3 -3
  278. package/lib/summary/summarizerNode/index.mjs.map +1 -0
  279. package/lib/summary/summarizerNode/{summarizerNode.d.ts → summarizerNode.d.mts} +2 -2
  280. package/lib/summary/summarizerNode/summarizerNode.d.mts.map +1 -0
  281. package/lib/summary/summarizerNode/{summarizerNode.js → summarizerNode.mjs} +2 -2
  282. package/lib/summary/summarizerNode/summarizerNode.mjs.map +1 -0
  283. package/lib/summary/summarizerNode/{summarizerNodeUtils.d.ts → summarizerNodeUtils.d.mts} +1 -1
  284. package/lib/summary/summarizerNode/summarizerNodeUtils.d.mts.map +1 -0
  285. package/lib/summary/summarizerNode/{summarizerNodeUtils.js → summarizerNodeUtils.mjs} +1 -1
  286. package/lib/summary/summarizerNode/summarizerNodeUtils.mjs.map +1 -0
  287. package/lib/summary/summarizerNode/{summarizerNodeWithGc.d.ts → summarizerNodeWithGc.d.mts} +3 -3
  288. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.mts.map +1 -0
  289. package/lib/summary/summarizerNode/{summarizerNodeWithGc.js → summarizerNodeWithGc.mjs} +4 -4
  290. package/lib/summary/summarizerNode/summarizerNodeWithGc.mjs.map +1 -0
  291. package/lib/summary/{summarizerTypes.d.ts → summarizerTypes.d.mts} +7 -5
  292. package/lib/summary/summarizerTypes.d.mts.map +1 -0
  293. package/lib/summary/{summarizerTypes.js → summarizerTypes.mjs} +1 -1
  294. package/lib/summary/summarizerTypes.mjs.map +1 -0
  295. package/lib/summary/{summaryCollection.d.ts → summaryCollection.d.mts} +8 -8
  296. package/lib/summary/summaryCollection.d.mts.map +1 -0
  297. package/lib/summary/{summaryCollection.js → summaryCollection.mjs} +2 -2
  298. package/lib/summary/summaryCollection.mjs.map +1 -0
  299. package/lib/summary/{summaryFormat.d.ts → summaryFormat.d.mts} +2 -2
  300. package/lib/summary/summaryFormat.d.mts.map +1 -0
  301. package/lib/summary/{summaryFormat.js → summaryFormat.mjs} +1 -1
  302. package/lib/summary/summaryFormat.mjs.map +1 -0
  303. package/lib/summary/{summaryGenerator.d.ts → summaryGenerator.d.mts} +3 -3
  304. package/lib/summary/summaryGenerator.d.mts.map +1 -0
  305. package/lib/summary/{summaryGenerator.js → summaryGenerator.mjs} +1 -1
  306. package/lib/summary/summaryGenerator.mjs.map +1 -0
  307. package/lib/summary/{summaryManager.d.ts → summaryManager.d.mts} +5 -5
  308. package/lib/summary/summaryManager.d.mts.map +1 -0
  309. package/lib/summary/{summaryManager.js → summaryManager.mjs} +2 -2
  310. package/lib/summary/summaryManager.mjs.map +1 -0
  311. package/lib/{throttler.d.ts → throttler.d.mts} +1 -1
  312. package/lib/throttler.d.mts.map +1 -0
  313. package/lib/{throttler.js → throttler.mjs} +1 -1
  314. package/lib/throttler.mjs.map +1 -0
  315. package/package.json +139 -39
  316. package/src/blobManager.ts +15 -4
  317. package/src/containerRuntime.ts +15 -7
  318. package/src/dataStoreContext.ts +11 -4
  319. package/src/dataStores.ts +61 -7
  320. package/src/gc/garbageCollection.ts +108 -121
  321. package/src/gc/gcConfigs.ts +28 -20
  322. package/src/gc/gcDefinitions.ts +30 -7
  323. package/src/gc/gcSummaryStateTracker.ts +5 -1
  324. package/src/gc/gcTelemetry.ts +22 -21
  325. package/src/gc/index.ts +3 -0
  326. package/src/messageTypes.ts +1 -1
  327. package/src/opLifecycle/definitions.ts +1 -1
  328. package/src/opLifecycle/outbox.ts +5 -2
  329. package/src/packageVersion.ts +1 -1
  330. package/src/summary/runWhileConnectedCoordinator.ts +1 -1
  331. package/src/summary/runningSummarizer.ts +58 -25
  332. package/src/summary/summarizer.ts +1 -1
  333. package/src/summary/summarizerTypes.ts +3 -1
  334. package/src/summary/summaryCollection.ts +7 -7
  335. package/tsconfig.json +6 -4
  336. package/lib/batchTracker.d.ts.map +0 -1
  337. package/lib/batchTracker.js.map +0 -1
  338. package/lib/blobManager.d.ts.map +0 -1
  339. package/lib/blobManager.js.map +0 -1
  340. package/lib/connectionTelemetry.d.ts.map +0 -1
  341. package/lib/connectionTelemetry.js.map +0 -1
  342. package/lib/containerHandleContext.d.ts.map +0 -1
  343. package/lib/containerHandleContext.js.map +0 -1
  344. package/lib/containerRuntime.d.ts.map +0 -1
  345. package/lib/containerRuntime.js.map +0 -1
  346. package/lib/dataStore.d.ts.map +0 -1
  347. package/lib/dataStore.js.map +0 -1
  348. package/lib/dataStoreContext.d.ts.map +0 -1
  349. package/lib/dataStoreContext.js.map +0 -1
  350. package/lib/dataStoreContexts.d.ts.map +0 -1
  351. package/lib/dataStoreContexts.js.map +0 -1
  352. package/lib/dataStoreRegistry.d.ts.map +0 -1
  353. package/lib/dataStoreRegistry.js.map +0 -1
  354. package/lib/dataStores.d.ts.map +0 -1
  355. package/lib/dataStores.js.map +0 -1
  356. package/lib/deltaManagerProxyBase.d.ts.map +0 -1
  357. package/lib/deltaManagerProxyBase.js.map +0 -1
  358. package/lib/deltaManagerSummarizerProxy.d.ts.map +0 -1
  359. package/lib/deltaManagerSummarizerProxy.js.map +0 -1
  360. package/lib/deltaScheduler.d.ts.map +0 -1
  361. package/lib/deltaScheduler.js.map +0 -1
  362. package/lib/error.d.ts.map +0 -1
  363. package/lib/error.js.map +0 -1
  364. package/lib/gc/garbageCollection.d.ts.map +0 -1
  365. package/lib/gc/garbageCollection.js.map +0 -1
  366. package/lib/gc/gcConfigs.d.ts.map +0 -1
  367. package/lib/gc/gcConfigs.js.map +0 -1
  368. package/lib/gc/gcDefinitions.d.ts.map +0 -1
  369. package/lib/gc/gcDefinitions.js.map +0 -1
  370. package/lib/gc/gcHelpers.js.map +0 -1
  371. package/lib/gc/gcReferenceGraphAlgorithm.d.ts.map +0 -1
  372. package/lib/gc/gcReferenceGraphAlgorithm.js.map +0 -1
  373. package/lib/gc/gcSummaryDefinitions.d.ts.map +0 -1
  374. package/lib/gc/gcSummaryDefinitions.js.map +0 -1
  375. package/lib/gc/gcSummaryStateTracker.d.ts.map +0 -1
  376. package/lib/gc/gcSummaryStateTracker.js.map +0 -1
  377. package/lib/gc/gcTelemetry.d.ts.map +0 -1
  378. package/lib/gc/gcTelemetry.js.map +0 -1
  379. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +0 -1
  380. package/lib/gc/gcUnreferencedStateTracker.js.map +0 -1
  381. package/lib/gc/index.d.ts.map +0 -1
  382. package/lib/gc/index.js.map +0 -1
  383. package/lib/index.d.ts.map +0 -1
  384. package/lib/index.js.map +0 -1
  385. package/lib/messageTypes.d.ts.map +0 -1
  386. package/lib/messageTypes.js.map +0 -1
  387. package/lib/metadata.d.ts.map +0 -1
  388. package/lib/metadata.js.map +0 -1
  389. package/lib/opLifecycle/batchManager.d.ts.map +0 -1
  390. package/lib/opLifecycle/batchManager.js.map +0 -1
  391. package/lib/opLifecycle/definitions.d.ts.map +0 -1
  392. package/lib/opLifecycle/definitions.js.map +0 -1
  393. package/lib/opLifecycle/index.d.ts +0 -13
  394. package/lib/opLifecycle/index.d.ts.map +0 -1
  395. package/lib/opLifecycle/index.js +0 -12
  396. package/lib/opLifecycle/index.js.map +0 -1
  397. package/lib/opLifecycle/opCompressor.d.ts.map +0 -1
  398. package/lib/opLifecycle/opCompressor.js.map +0 -1
  399. package/lib/opLifecycle/opDecompressor.d.ts.map +0 -1
  400. package/lib/opLifecycle/opDecompressor.js.map +0 -1
  401. package/lib/opLifecycle/opGroupingManager.d.ts.map +0 -1
  402. package/lib/opLifecycle/opGroupingManager.js.map +0 -1
  403. package/lib/opLifecycle/opSplitter.d.ts.map +0 -1
  404. package/lib/opLifecycle/opSplitter.js.map +0 -1
  405. package/lib/opLifecycle/outbox.d.ts.map +0 -1
  406. package/lib/opLifecycle/outbox.js.map +0 -1
  407. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +0 -1
  408. package/lib/opLifecycle/remoteMessageProcessor.js.map +0 -1
  409. package/lib/opProperties.d.ts.map +0 -1
  410. package/lib/opProperties.js.map +0 -1
  411. package/lib/packageVersion.d.ts.map +0 -1
  412. package/lib/packageVersion.js.map +0 -1
  413. package/lib/pendingStateManager.d.ts.map +0 -1
  414. package/lib/pendingStateManager.js.map +0 -1
  415. package/lib/scheduleManager.d.ts.map +0 -1
  416. package/lib/scheduleManager.js.map +0 -1
  417. package/lib/storageServiceWithAttachBlobs.d.ts.map +0 -1
  418. package/lib/storageServiceWithAttachBlobs.js.map +0 -1
  419. package/lib/summary/index.d.ts.map +0 -1
  420. package/lib/summary/index.js.map +0 -1
  421. package/lib/summary/orderedClientElection.d.ts.map +0 -1
  422. package/lib/summary/orderedClientElection.js.map +0 -1
  423. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +0 -1
  424. package/lib/summary/runWhileConnectedCoordinator.js.map +0 -1
  425. package/lib/summary/runningSummarizer.d.ts.map +0 -1
  426. package/lib/summary/runningSummarizer.js.map +0 -1
  427. package/lib/summary/summarizer.d.ts.map +0 -1
  428. package/lib/summary/summarizer.js.map +0 -1
  429. package/lib/summary/summarizerClientElection.d.ts.map +0 -1
  430. package/lib/summary/summarizerClientElection.js.map +0 -1
  431. package/lib/summary/summarizerHeuristics.d.ts.map +0 -1
  432. package/lib/summary/summarizerHeuristics.js.map +0 -1
  433. package/lib/summary/summarizerNode/index.d.ts.map +0 -1
  434. package/lib/summary/summarizerNode/index.js.map +0 -1
  435. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +0 -1
  436. package/lib/summary/summarizerNode/summarizerNode.js.map +0 -1
  437. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +0 -1
  438. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +0 -1
  439. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +0 -1
  440. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +0 -1
  441. package/lib/summary/summarizerTypes.d.ts.map +0 -1
  442. package/lib/summary/summarizerTypes.js.map +0 -1
  443. package/lib/summary/summaryCollection.d.ts.map +0 -1
  444. package/lib/summary/summaryCollection.js.map +0 -1
  445. package/lib/summary/summaryFormat.d.ts.map +0 -1
  446. package/lib/summary/summaryFormat.js.map +0 -1
  447. package/lib/summary/summaryGenerator.d.ts.map +0 -1
  448. package/lib/summary/summaryGenerator.js.map +0 -1
  449. package/lib/summary/summaryManager.d.ts.map +0 -1
  450. package/lib/summary/summaryManager.js.map +0 -1
  451. package/lib/throttler.d.ts.map +0 -1
  452. package/lib/throttler.js.map +0 -1
  453. package/tsconfig.esnext.json +0 -7
@@ -322,7 +322,7 @@ export type ISummaryConfiguration =
322
322
  | ISummaryConfigurationHeuristics;
323
323
 
324
324
  /**
325
- * @internal
325
+ * @alpha
326
326
  */
327
327
  export const DefaultSummaryConfiguration: ISummaryConfiguration = {
328
328
  state: "enabled",
@@ -478,7 +478,7 @@ export enum RuntimeHeaders {
478
478
  }
479
479
 
480
480
  /** True if a tombstoned object should be returned without erroring
481
- * @internal
481
+ * @alpha
482
482
  */
483
483
  export const AllowTombstoneRequestHeaderKey = "allowTombstone"; // Belongs in the enum above, but avoiding the breaking change
484
484
  /**
@@ -489,12 +489,12 @@ export const AllowInactiveRequestHeaderKey = "allowInactive"; // Belongs in the
489
489
 
490
490
  /**
491
491
  * Tombstone error responses will have this header set to true
492
- * @internal
492
+ * @alpha
493
493
  */
494
494
  export const TombstoneResponseHeaderKey = "isTombstoned";
495
495
  /**
496
496
  * Inactive error responses will have this header set to true
497
- * @internal
497
+ * @alpha
498
498
  */
499
499
  export const InactiveResponseHeaderKey = "isInactive";
500
500
 
@@ -1394,9 +1394,6 @@ export class ContainerRuntime
1394
1394
  getNodePackagePath: async (nodePath: string) => this.getGCNodePackagePath(nodePath),
1395
1395
  getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
1396
1396
  readAndParseBlob: async <T>(id: string) => readAndParse<T>(this.storage, id),
1397
- // GC runs in summarizer client and needs access to the real (non-proxy) active information. The proxy
1398
- // delta manager would always return false for summarizer client.
1399
- activeConnection: () => this.innerDeltaManager.active,
1400
1397
  submitMessage: (message: ContainerRuntimeGCMessage) => this.submit(message),
1401
1398
  });
1402
1399
 
@@ -2271,6 +2268,7 @@ export class ContainerRuntime
2271
2268
  messageWithContext.message,
2272
2269
  local,
2273
2270
  localOpMetadata,
2271
+ (from, to) => this.garbageCollector.addedOutboundReference(from, to),
2274
2272
  );
2275
2273
  break;
2276
2274
  case ContainerMessageType.BlobAttach:
@@ -2682,6 +2680,12 @@ export class ContainerRuntime
2682
2680
  this.blobManager.setRedirectTable(blobRedirectTable);
2683
2681
  }
2684
2682
 
2683
+ // We can finalize any allocated IDs since we're the only client
2684
+ const idRange = this.idCompressor?.takeNextCreationRange();
2685
+ if (idRange !== undefined) {
2686
+ this.idCompressor?.finalizeCreationRange(idRange);
2687
+ }
2688
+
2685
2689
  const summarizeResult = this.dataStores.createSummary(telemetryContext);
2686
2690
  // Wrap data store summaries in .channels subtree.
2687
2691
  wrapSummaryInChannelsTree(summarizeResult);
@@ -2863,6 +2867,10 @@ export class ContainerRuntime
2863
2867
 
2864
2868
  /**
2865
2869
  * This is called to update objects that are tombstones.
2870
+ *
2871
+ * A Tombstoned object has been unreferenced long enough that GC knows it won't be referenced again.
2872
+ * Tombstoned objects are eventually deleted by GC.
2873
+ *
2866
2874
  * @param tombstonedRoutes - Data store and attachment blob routes that are tombstones in this Container.
2867
2875
  */
2868
2876
  public updateTombstonedRoutes(tombstonedRoutes: readonly string[]) {
@@ -78,7 +78,7 @@ import {
78
78
  summarizerClientType,
79
79
  } from "./summary";
80
80
  import { ContainerRuntime } from "./containerRuntime";
81
- import { sendGCUnexpectedUsageEvent } from "./gc";
81
+ import { detectOutboundRoutesViaDDSKey, sendGCUnexpectedUsageEvent } from "./gc";
82
82
 
83
83
  function createAttributes(
84
84
  pkg: readonly string[],
@@ -200,8 +200,8 @@ export abstract class FluidDataStoreContext
200
200
  }
201
201
 
202
202
  /**
203
- * Tombstone is a temporary feature that prevents a data store from sending / receiving ops, signals and from
204
- * loading.
203
+ * A Tombstoned object has been unreferenced long enough that GC knows it won't be referenced again.
204
+ * Tombstoned objects are eventually deleted by GC.
205
205
  */
206
206
  private _tombstoned = false;
207
207
  public get tombstoned() {
@@ -650,13 +650,20 @@ export abstract class FluidDataStoreContext
650
650
  }
651
651
 
652
652
  /**
653
+ * @deprecated There is no replacement for this, its functionality is no longer needed.
654
+ * It will be removed in a future release, sometime after 2.0.0-internal.8.0.0
655
+ *
653
656
  * Called when a new outbound reference is added to another node. This is used by garbage collection to identify
654
657
  * all references added in the system.
655
658
  * @param srcHandle - The handle of the node that added the reference.
656
659
  * @param outboundHandle - The handle of the outbound node that is referenced.
657
660
  */
658
661
  public addedGCOutboundReference(srcHandle: IFluidHandle, outboundHandle: IFluidHandle) {
659
- this._containerRuntime.addedGCOutboundReference(srcHandle, outboundHandle);
662
+ // By default, skip this call since the ContainerRuntime will detect the outbound route directly.
663
+ if (this.mc.config.getBoolean(detectOutboundRoutesViaDDSKey) === true) {
664
+ // Note: The ContainerRuntime code will check this same setting to avoid double counting.
665
+ this._containerRuntime.addedGCOutboundReference(srcHandle, outboundHandle);
666
+ }
660
667
  }
661
668
 
662
669
  /**
package/src/dataStores.ts CHANGED
@@ -33,6 +33,7 @@ import {
33
33
  create404Response,
34
34
  createResponseError,
35
35
  GCDataBuilder,
36
+ isSerializedHandle,
36
37
  responseToException,
37
38
  SummaryTreeBuilder,
38
39
  unpackChildNodesUsedRoutes,
@@ -61,7 +62,7 @@ import {
61
62
  } from "./dataStoreContext";
62
63
  import { StorageServiceWithAttachBlobs } from "./storageServiceWithAttachBlobs";
63
64
  import { IDataStoreAliasMessage, isDataStoreAliasMessage } from "./dataStore";
64
- import { GCNodeType, disableDatastoreSweepKey } from "./gc";
65
+ import { GCNodeType, detectOutboundRoutesViaDDSKey, disableDatastoreSweepKey } from "./gc";
65
66
  import { IContainerRuntimeMetadata, nonDataStorePaths, rootHasIsolatedChannels } from "./summary";
66
67
 
67
68
  type PendingAliasResolve = (success: boolean) => void;
@@ -441,6 +442,7 @@ export class DataStores implements IDisposable {
441
442
  message: ISequencedDocumentMessage,
442
443
  local: boolean,
443
444
  localMessageMetadata: unknown,
445
+ addedOutboundReference: (fromNodePath: string, toNodePath: string) => void,
444
446
  ) {
445
447
  const envelope = message.contents as IEnvelope;
446
448
  const transformed = { ...message, contents: envelope.contents };
@@ -462,6 +464,13 @@ export class DataStores implements IDisposable {
462
464
  assert(!!context, 0x162 /* "There should be a store context for the op" */);
463
465
  context.process(transformed, local, localMessageMetadata);
464
466
 
467
+ // By default, we use the new behavior of detecting outbound routes here.
468
+ // If this setting is true, then DataStoreContext would be notifying GC instead.
469
+ if (this.mc.config.getBoolean(detectOutboundRoutesViaDDSKey) !== true) {
470
+ // Notify GC of any outbound references that were added by this op.
471
+ detectOutboundReferences(envelope, addedOutboundReference);
472
+ }
473
+
465
474
  // Notify that a GC node for the data store changed. This is used to detect if a deleted data store is
466
475
  // being used.
467
476
  this.gcNodeUpdated(
@@ -830,12 +839,15 @@ export class DataStores implements IDisposable {
830
839
 
831
840
  const dataStoreContext = this.contexts.get(dataStoreId);
832
841
  if (dataStoreContext === undefined) {
833
- this.mc.logger.sendErrorEvent({
842
+ // If the data store hasn't already been deleted, log an error because this should never happen.
843
+ // If the data store has already been deleted, log a telemetry event. This can happen because multiple GC
844
+ // sweep ops can contain the same data store. It would be interesting to track how often this happens.
845
+ const alreadyDeleted = this.isDataStoreDeleted(`/${dataStoreId}`);
846
+ this.mc.logger.sendTelemetryEvent({
834
847
  eventName: "DeletedDataStoreNotFound",
848
+ category: alreadyDeleted ? "generic" : "error",
835
849
  ...tagCodeArtifacts({ id: dataStoreId }),
836
- details: {
837
- alreadyDeleted: this.isDataStoreDeleted(dataStoreId),
838
- },
850
+ details: { alreadyDeleted },
839
851
  });
840
852
  continue;
841
853
  }
@@ -851,8 +863,11 @@ export class DataStores implements IDisposable {
851
863
  }
852
864
 
853
865
  /**
854
- * This is called to update objects whose routes are tombstones. Tombstoned datastore contexts enable testing
855
- * scenarios with accessing deleted content without actually deleting content from summaries.
866
+ * This is called to update objects whose routes are tombstones.
867
+ *
868
+ * A Tombstoned object has been unreferenced long enough that GC knows it won't be referenced again.
869
+ * Tombstoned objects are eventually deleted by GC.
870
+ *
856
871
  * @param tombstonedRoutes - The routes that are tombstones in all data stores in this Container.
857
872
  */
858
873
  public updateTombstonedRoutes(tombstonedRoutes: readonly string[]) {
@@ -944,3 +959,42 @@ export function getSummaryForDatastores(
944
959
  };
945
960
  }
946
961
  }
962
+
963
+ /**
964
+ * Traverse this op's contents and detect any outbound routes that were added by this op.
965
+ */
966
+ export function detectOutboundReferences(
967
+ envelope: IEnvelope,
968
+ addedOutboundReference: (fromNodePath: string, toNodePath: string) => void,
969
+ ): void {
970
+ // These will be built up as we traverse the envelope contents
971
+ const outboundPaths: string[] = [];
972
+ let ddsAddress: string | undefined;
973
+
974
+ function recursivelyFindHandles(obj: unknown) {
975
+ if (typeof obj === "object" && obj !== null) {
976
+ for (const [key, value] of Object.entries(obj)) {
977
+ // If 'value' is a serialized IFluidHandle, it represents a new outbound route.
978
+ if (isSerializedHandle(value)) {
979
+ outboundPaths.push(value.url);
980
+ }
981
+
982
+ // NOTE: This is taking a hard dependency on the fact that in our DataStore implementation,
983
+ // the address of the DDS is stored in a property called "address". This is not ideal.
984
+ // An alternative would be for the op envelope to include the absolute path (built up as it is submitted)
985
+ if (key === "address" && ddsAddress === undefined) {
986
+ ddsAddress = value;
987
+ }
988
+
989
+ recursivelyFindHandles(value);
990
+ }
991
+ }
992
+ }
993
+
994
+ recursivelyFindHandles(envelope.contents);
995
+
996
+ // GC node paths are all absolute paths, hence the "" prefix.
997
+ // e.g. this will yield "/dataStoreId/ddsId"
998
+ const fromPath = ["", envelope.address, ddsAddress].join("/");
999
+ outboundPaths.forEach((toPath) => addedOutboundReference(fromPath, toPath));
1000
+ }
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { LazyPromise, Timer } from "@fluidframework/core-utils";
6
+ import { assert, LazyPromise, Timer } from "@fluidframework/core-utils";
7
7
  import { IRequest } from "@fluidframework/core-interfaces";
8
8
  import {
9
9
  gcTreeKey,
@@ -20,7 +20,9 @@ import {
20
20
  ITelemetryLoggerExt,
21
21
  MonitoringContext,
22
22
  PerformanceEvent,
23
+ tagCodeArtifacts,
23
24
  } from "@fluidframework/telemetry-utils";
25
+ import { BlobManager } from "../blobManager";
24
26
  import {
25
27
  InactiveResponseHeaderKey,
26
28
  RuntimeHeaderData,
@@ -141,8 +143,6 @@ export class GarbageCollector implements IGarbageCollector {
141
143
  ) => Promise<readonly string[] | undefined>;
142
144
  /** Returns the timestamp of the last summary generated for this container. */
143
145
  private readonly getLastSummaryTimestampMs: () => number | undefined;
144
- /** Returns true if connection is active, i.e. it's "write" connection and the runtime is connected. */
145
- private readonly activeConnection: () => boolean;
146
146
 
147
147
  private readonly submitMessage: (message: ContainerRuntimeGCMessage) => void;
148
148
 
@@ -160,7 +160,6 @@ export class GarbageCollector implements IGarbageCollector {
160
160
  this.isSummarizerClient = createParams.isSummarizerClient;
161
161
  this.getNodePackagePath = createParams.getNodePackagePath;
162
162
  this.getLastSummaryTimestampMs = createParams.getLastSummaryTimestampMs;
163
- this.activeConnection = createParams.activeConnection;
164
163
  this.submitMessage = createParams.submitMessage;
165
164
 
166
165
  const baseSnapshot = createParams.baseSnapshot;
@@ -255,28 +254,18 @@ export class GarbageCollector implements IGarbageCollector {
255
254
  );
256
255
 
257
256
  /**
258
- * Set up the initializer which initializes the GC state from the data in base snapshot. This is done when
259
- * connected in write mode or when GC runs the first time. It sets up all unreferenced nodes from the base
260
- * GC state and updates their inactive or sweep-ready state.
257
+ * Set up the initializer which initializes the GC state from the data in base snapshot. It sets up GC data
258
+ * from the base GC state and starts tracking the state of unreferenced nodes.
259
+ *
260
+ * Must only be called if there is a current reference timestamp.
261
261
  */
262
262
  this.initializeGCStateFromBaseSnapshotP = new LazyPromise<void>(async () => {
263
- /**
264
- * If there is no current reference timestamp, skip initialization. We need the current timestamp to track
265
- * how long objects have been unreferenced and if they can be deleted.
266
- *
267
- * Note that the only scenario where there is no reference timestamp is when no ops have ever been processed
268
- * for this container and it is in read mode. In this scenario, there is no point in running GC anyway
269
- * because references in the container do not change without any ops, i.e., there is nothing to collect.
270
- */
271
263
  const currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();
272
- if (currentReferenceTimestampMs === undefined) {
273
- // Log an event so we can evaluate how often we run into this scenario.
274
- this.mc.logger.sendErrorEvent({
275
- eventName: "GarbageCollectorInitializedWithoutTimestamp",
276
- gcConfigs: JSON.stringify(this.configs),
277
- });
278
- return;
279
- }
264
+ assert(
265
+ currentReferenceTimestampMs !== undefined,
266
+ 0x8a4 /* Trying to initialize GC state without current timestamp */,
267
+ );
268
+
280
269
  /**
281
270
  * The base snapshot data will not be present if the container is loaded from:
282
271
  * 1. The first summary created by the detached container.
@@ -284,11 +273,31 @@ export class GarbageCollector implements IGarbageCollector {
284
273
  * 3. A summary that was generated before GC even existed.
285
274
  */
286
275
  const baseSnapshotData = await this.baseSnapshotDataP;
287
- if (baseSnapshotData === undefined) {
276
+ this.summaryStateTracker.initializeBaseState(baseSnapshotData);
277
+
278
+ if (baseSnapshotData?.gcState === undefined) {
288
279
  return;
289
280
  }
290
- this.updateStateFromSnapshotData(baseSnapshotData, currentReferenceTimestampMs);
291
- this.summaryStateTracker.initializeBaseState(baseSnapshotData);
281
+
282
+ // Update unreferenced state tracking as per the GC state in the snapshot data and update gcDataFromLastRun
283
+ // to the GC data from the snapshot data.
284
+ const gcNodes: { [id: string]: string[] } = {};
285
+ for (const [nodeId, nodeData] of Object.entries(baseSnapshotData.gcState.gcNodes)) {
286
+ if (nodeData.unreferencedTimestampMs !== undefined) {
287
+ this.unreferencedNodesState.set(
288
+ nodeId,
289
+ new UnreferencedStateTracker(
290
+ nodeData.unreferencedTimestampMs,
291
+ this.configs.inactiveTimeoutMs,
292
+ currentReferenceTimestampMs,
293
+ this.configs.tombstoneTimeoutMs,
294
+ this.configs.sweepGracePeriodMs,
295
+ ),
296
+ );
297
+ }
298
+ gcNodes[nodeId] = Array.from(nodeData.outboundRoutes);
299
+ }
300
+ this.gcDataFromLastRun = { gcNodes };
292
301
  });
293
302
 
294
303
  // Get the GC details from the GC state in the base summary. This is returned in getBaseGCDetails which is
@@ -322,8 +331,10 @@ export class GarbageCollector implements IGarbageCollector {
322
331
  }
323
332
 
324
333
  /**
325
- * Called during container initialization. Initialize from the tombstone state in the base snapshot. This is done
326
- * during initialization so that deleted or tombstoned objects are marked as such before they are loaded or used.
334
+ * Called during container initialization. Initializes the tombstone and deleted nodes state from the base snapshot.
335
+ * Also, initializes the GC state including unreferenced nodes tracking if a current reference timestamp exists.
336
+ * Note that if there is any GC state in the base snapshot, then there will definitely be a reference timestamp
337
+ * to work with - The GC state would have been generated using a timestamp which is part of the snapshot.
327
338
  */
328
339
  public async initializeBaseState(): Promise<void> {
329
340
  const baseSnapshotData = await this.baseSnapshotDataP;
@@ -350,115 +361,60 @@ export class GarbageCollector implements IGarbageCollector {
350
361
  this.tombstones = Array.from(baseSnapshotData.tombstones);
351
362
  this.runtime.updateTombstonedRoutes(this.tombstones);
352
363
  }
364
+
365
+ await this.initializeOrUpdateGCState();
353
366
  }
354
367
 
355
368
  /**
356
- * Update state from the given snapshot data. This is done during load and during refreshing state from a snapshot.
357
- * All current tracking is reset and updated from the data in the snapshot.
358
- * @param snapshotData - The snapshot data to update state from. If this is undefined, all GC state and tracking
359
- * is reset.
360
- * @param currentReferenceTimestampMs - The current reference timestamp for marking unreferenced nodes' unreferenced
361
- * timestamp.
369
+ * Initialize the GC state if not already initialized. If GC state is already initialized, update the unreferenced
370
+ * state tracking as per the current reference timestamp.
362
371
  */
363
- private updateStateFromSnapshotData(
364
- snapshotData: IGarbageCollectionSnapshotData | undefined,
365
- currentReferenceTimestampMs: number,
366
- ) {
367
- /**
368
- * Note: "newReferencesSinceLastRun" is not reset here. This is done because there may be references since the
369
- * snapshot that we are updating state from. For example, this client may have processed ops till seq#1000 and
370
- * its refreshing state from a summary that happened at seq#900. In this case, there may be references between
371
- * seq#901 and seq#1000 that we don't want to reset.
372
- * Unfortunately, there is no way to track the seq# of ops that add references, so we choose to not reset any
373
- * references here. This should be fine because, in the worst case, we may end up updating the unreferenced
374
- * timestamp of a node which will delay its deletion. Although not ideal, this will only happen in rare
375
- * scenarios, so it should be okay.
376
- */
377
-
378
- // Clear all existing unreferenced state tracking.
379
- for (const [, nodeStateTracker] of this.unreferencedNodesState) {
380
- nodeStateTracker.stopTracking();
381
- }
382
- this.unreferencedNodesState.clear();
383
-
384
- // If running sweep, the tombstone state represents the list of nodes that have been deleted during sweep.
385
- // If running in tombstone mode, the tombstone state represents the list of nodes that have been marked as
386
- // tombstones.
387
- // If this call is because we are refreshing from a snapshot due to an ack, it is likely that the GC state
388
- // in the snapshot is newer than this client's. And so, the deleted / tombstone nodes need to be updated.
389
- if (this.configs.shouldRunSweep) {
390
- const snapshotDeletedNodes = snapshotData?.deletedNodes
391
- ? new Set(snapshotData.deletedNodes)
392
- : undefined;
393
- // If the snapshot contains deleted nodes that are not yet deleted by this client, ask the runtime to
394
- // delete them.
395
- if (snapshotDeletedNodes !== undefined) {
396
- const newDeletedNodes: string[] = [];
397
- for (const nodeId of snapshotDeletedNodes) {
398
- if (!this.deletedNodes.has(nodeId)) {
399
- newDeletedNodes.push(nodeId);
400
- }
401
- }
402
- if (newDeletedNodes.length > 0) {
403
- // Call container runtime to delete these nodes and add deleted nodes to this.deletedNodes.
404
- }
405
- }
406
- } else if (this.configs.tombstoneMode) {
407
- // The snapshot may contain more or fewer tombstone nodes than this client. Update tombstone state and
408
- // notify the runtime to update its state as well.
409
- this.tombstones = snapshotData?.tombstones ? Array.from(snapshotData.tombstones) : [];
410
- this.runtime.updateTombstonedRoutes(this.tombstones);
372
+ private async initializeOrUpdateGCState() {
373
+ const currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();
374
+ if (currentReferenceTimestampMs === undefined) {
375
+ return;
411
376
  }
412
377
 
413
- // If there is no snapshot data, it means this snapshot was generated with GC disabled. Unset all GC state.
414
- if (snapshotData?.gcState === undefined) {
415
- this.gcDataFromLastRun = undefined;
378
+ // If the GC state hasn't been initialized yet, initialize it and return.
379
+ if (this.gcDataFromLastRun === undefined) {
380
+ await this.initializeGCStateFromBaseSnapshotP;
416
381
  return;
417
382
  }
418
383
 
419
- // Update unreferenced state tracking as per the GC state in the snapshot data and update gcDataFromLastRun
420
- // to the GC data from the snapshot data.
421
- const gcNodes: { [id: string]: string[] } = {};
422
- for (const [nodeId, nodeData] of Object.entries(snapshotData.gcState.gcNodes)) {
423
- if (nodeData.unreferencedTimestampMs !== undefined) {
424
- this.unreferencedNodesState.set(
425
- nodeId,
426
- new UnreferencedStateTracker(
427
- nodeData.unreferencedTimestampMs,
428
- this.configs.inactiveTimeoutMs,
429
- currentReferenceTimestampMs,
430
- this.configs.sweepTimeoutMs,
431
- this.configs.sweepGracePeriodMs,
432
- ),
433
- );
434
- }
435
- gcNodes[nodeId] = Array.from(nodeData.outboundRoutes);
384
+ // If the GC state has been initialized, update the tracking of unreferenced nodes as per the current
385
+ // reference timestamp.
386
+ for (const [, nodeStateTracker] of this.unreferencedNodesState) {
387
+ nodeStateTracker.updateTracking(currentReferenceTimestampMs);
436
388
  }
437
- this.gcDataFromLastRun = { gcNodes };
438
389
  }
439
390
 
440
391
  /**
441
392
  * Called when the connection state of the runtime changes, i.e., it connects or disconnects. GC subscribes to this
442
- * to initialize the base state for non-summarizer clients so that they can track inactive / sweep-ready nodes.
393
+ * to initialize or update the unreference state tracking.
443
394
  * @param connected - Whether the runtime connected / disconnected.
444
395
  * @param clientId - The clientId of this runtime.
445
396
  */
446
397
  public setConnectionState(connected: boolean, clientId?: string | undefined): void {
447
398
  /**
448
- * For all clients, initialize the base state when the container becomes active, i.e., it transitions
449
- * to "write" mode. This will ensure that the container's own join op is processed and there is a recent
450
- * reference timestamp that will be used to update the state of unreferenced nodes. Also, all trailing ops which
451
- * could affect the GC state will have been processed.
452
- *
453
- * If GC is up-to-date for the client and the summarizing client, there will be an doubling of both
454
- * InactiveObject_Loaded and SweepReady_Loaded errors, as there will be one from the sending client and one from
455
- * the receiving summarizer client.
399
+ * When the client connects (or reconnects), attempt to initialize or update the GC state. This will keep
400
+ * the unreferenced state tracking updated as per the reference timestamp at the time of connection.
456
401
  *
457
- * Ideally, this initialization should only be done for summarizer client. However, we are currently rolling out
458
- * sweep in phases and we want to track when inactive and sweep-ready objects are used in any client.
402
+ * During GC initialization and during connections in read mode, it is possible that either no ops are
403
+ * processed or only trailing ops are processed. This means that the GC state is not initialized or initialized
404
+ * with an older reference timestamp. So, doing this on every connection will keep the unreferenced state
405
+ * tracking up-to-date.
459
406
  */
460
- if (this.activeConnection() && this.configs.shouldRunGC) {
461
- this.initializeGCStateFromBaseSnapshotP.catch((error) => {});
407
+ if (connected && this.configs.shouldRunGC) {
408
+ this.initializeOrUpdateGCState().catch((error) => {
409
+ this.mc.logger.sendErrorEvent(
410
+ {
411
+ eventName: "GCInitializationOrUpdateFailed",
412
+ gcConfigs: JSON.stringify(this.configs),
413
+ clientId,
414
+ },
415
+ error,
416
+ );
417
+ });
462
418
  }
463
419
  }
464
420
 
@@ -536,8 +492,11 @@ export class GarbageCollector implements IGarbageCollector {
536
492
  const gcStats = await this.runGC(fullGC, currentReferenceTimestampMs, logger);
537
493
  event.end({
538
494
  ...gcStats,
539
- timestamp: currentReferenceTimestampMs,
540
- sweep: this.configs.shouldRunSweep,
495
+ details: {
496
+ timestamp: currentReferenceTimestampMs,
497
+ sweep: this.configs.shouldRunSweep,
498
+ tombstone: this.configs.throwOnTombstoneLoad,
499
+ },
541
500
  });
542
501
 
543
502
  /** Post-GC steps */
@@ -654,7 +613,7 @@ export class GarbageCollector implements IGarbageCollector {
654
613
  currentReferenceTimestampMs,
655
614
  this.configs.inactiveTimeoutMs,
656
615
  currentReferenceTimestampMs,
657
- this.configs.sweepTimeoutMs,
616
+ this.configs.tombstoneTimeoutMs,
658
617
  this.configs.sweepGracePeriodMs,
659
618
  ),
660
619
  );
@@ -880,7 +839,7 @@ export class GarbageCollector implements IGarbageCollector {
880
839
  gcFeatureMatrix: this.configs.persistedGcFeatureMatrix,
881
840
  sessionExpiryTimeoutMs: this.configs.sessionExpiryTimeoutMs,
882
841
  sweepEnabled: false, // DEPRECATED - to be removed
883
- sweepTimeoutMs: this.configs.sweepTimeoutMs,
842
+ tombstoneTimeoutMs: this.configs.tombstoneTimeoutMs,
884
843
  };
885
844
  }
886
845
 
@@ -1048,6 +1007,18 @@ export class GarbageCollector implements IGarbageCollector {
1048
1007
  return;
1049
1008
  }
1050
1009
 
1010
+ if (!toNodePath.startsWith("/")) {
1011
+ // A long time ago we stored handles with relatives paths. We don't expect to see these cases though
1012
+ // because GC was enabled only after we made the switch to always using absolute paths.
1013
+ this.mc.logger.sendErrorEvent({
1014
+ eventName: "InvalidRelativeOutboundRoute",
1015
+ ...tagCodeArtifacts({ fromId: fromNodePath, id: toNodePath }),
1016
+ });
1017
+ return;
1018
+ }
1019
+
1020
+ assert(fromNodePath.startsWith("/"), 0x8a5 /* fromNodePath must be an absolute path */);
1021
+
1051
1022
  const outboundRoutes = this.newReferencesSinceLastRun.get(fromNodePath) ?? [];
1052
1023
  outboundRoutes.push(toNodePath);
1053
1024
  this.newReferencesSinceLastRun.set(fromNodePath, outboundRoutes);
@@ -1163,9 +1134,25 @@ export class GarbageCollector implements IGarbageCollector {
1163
1134
  deletedAttachmentBlobCount: 0,
1164
1135
  };
1165
1136
 
1137
+ // The runtime can't reliably identify the type of deleted nodes. So, get the type here. This should
1138
+ // be good enough because the only types that participate in GC today are data stores, DDSes and blobs.
1139
+ const getDeletedNodeType = (nodeId: string): GCNodeType => {
1140
+ const pathParts = nodeId.split("/");
1141
+ if (pathParts[1] === BlobManager.basePath) {
1142
+ return GCNodeType.Blob;
1143
+ }
1144
+ if (pathParts.length === 2) {
1145
+ return GCNodeType.DataStore;
1146
+ }
1147
+ if (pathParts.length === 3) {
1148
+ return GCNodeType.SubDataStore;
1149
+ }
1150
+ return GCNodeType.Other;
1151
+ };
1152
+
1166
1153
  for (const nodeId of deletedNodes) {
1167
1154
  sweepPhaseStats.deletedNodeCount++;
1168
- const nodeType = this.runtime.getNodeType(nodeId);
1155
+ const nodeType = getDeletedNodeType(nodeId);
1169
1156
  if (nodeType === GCNodeType.DataStore) {
1170
1157
  sweepPhaseStats.deletedDataStoreCount++;
1171
1158
  } else if (nodeType === GCNodeType.Blob) {