@fluidframework/container-runtime 2.0.0-dev.3.1.0.125672 → 2.0.0-dev.4.2.0.153917

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 (486) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +69 -0
  3. package/dist/blobManager.d.ts +29 -24
  4. package/dist/blobManager.d.ts.map +1 -1
  5. package/dist/blobManager.js +162 -92
  6. package/dist/blobManager.js.map +1 -1
  7. package/dist/containerRuntime.d.ts +74 -76
  8. package/dist/containerRuntime.d.ts.map +1 -1
  9. package/dist/containerRuntime.js +328 -264
  10. package/dist/containerRuntime.js.map +1 -1
  11. package/dist/dataStoreContext.d.ts +39 -13
  12. package/dist/dataStoreContext.d.ts.map +1 -1
  13. package/dist/dataStoreContext.js +112 -49
  14. package/dist/dataStoreContext.js.map +1 -1
  15. package/dist/dataStores.d.ts +28 -4
  16. package/dist/dataStores.d.ts.map +1 -1
  17. package/dist/dataStores.js +107 -41
  18. package/dist/dataStores.js.map +1 -1
  19. package/dist/deltaManagerSummarizerProxy.d.ts +19 -0
  20. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -0
  21. package/dist/deltaManagerSummarizerProxy.js +40 -0
  22. package/dist/deltaManagerSummarizerProxy.js.map +1 -0
  23. package/dist/gc/garbageCollection.d.ts +204 -0
  24. package/dist/gc/garbageCollection.d.ts.map +1 -0
  25. package/dist/{garbageCollection.js → gc/garbageCollection.js} +190 -554
  26. package/dist/gc/garbageCollection.js.map +1 -0
  27. package/dist/gc/gcConfigs.d.ts +22 -0
  28. package/dist/gc/gcConfigs.d.ts.map +1 -0
  29. package/dist/gc/gcConfigs.js +143 -0
  30. package/dist/gc/gcConfigs.js.map +1 -0
  31. package/dist/gc/gcDefinitions.d.ts +320 -0
  32. package/dist/gc/gcDefinitions.d.ts.map +1 -0
  33. package/dist/gc/gcDefinitions.js +81 -0
  34. package/dist/gc/gcDefinitions.js.map +1 -0
  35. package/dist/gc/gcHelpers.d.ts +86 -0
  36. package/dist/gc/gcHelpers.d.ts.map +1 -0
  37. package/dist/gc/gcHelpers.js +268 -0
  38. package/dist/gc/gcHelpers.js.map +1 -0
  39. package/dist/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
  40. package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
  41. package/dist/gc/gcReferenceGraphAlgorithm.js +49 -0
  42. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -0
  43. package/dist/gc/gcSummaryDefinitions.d.ts +52 -0
  44. package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -0
  45. package/dist/gc/gcSummaryDefinitions.js +7 -0
  46. package/dist/gc/gcSummaryDefinitions.js.map +1 -0
  47. package/dist/gc/gcSummaryStateTracker.d.ts +93 -0
  48. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
  49. package/dist/gc/gcSummaryStateTracker.js +239 -0
  50. package/dist/gc/gcSummaryStateTracker.js.map +1 -0
  51. package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  52. package/dist/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +2 -2
  53. package/dist/gc/gcSweepReadyUsageDetection.js.map +1 -0
  54. package/dist/gc/gcUnreferencedStateTracker.d.ts +34 -0
  55. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  56. package/dist/gc/gcUnreferencedStateTracker.js +94 -0
  57. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -0
  58. package/dist/gc/index.d.ts +13 -0
  59. package/dist/gc/index.d.ts.map +1 -0
  60. package/dist/gc/index.js +50 -0
  61. package/dist/gc/index.js.map +1 -0
  62. package/dist/index.d.ts +3 -7
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +5 -9
  65. package/dist/index.js.map +1 -1
  66. package/dist/opLifecycle/batchManager.d.ts +11 -13
  67. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  68. package/dist/opLifecycle/batchManager.js +26 -38
  69. package/dist/opLifecycle/batchManager.js.map +1 -1
  70. package/dist/opLifecycle/definitions.d.ts +4 -0
  71. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  72. package/dist/opLifecycle/definitions.js.map +1 -1
  73. package/dist/opLifecycle/index.d.ts +2 -1
  74. package/dist/opLifecycle/index.d.ts.map +1 -1
  75. package/dist/opLifecycle/index.js +4 -1
  76. package/dist/opLifecycle/index.js.map +1 -1
  77. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  78. package/dist/opLifecycle/opCompressor.js +25 -10
  79. package/dist/opLifecycle/opCompressor.js.map +1 -1
  80. package/dist/opLifecycle/opDecompressor.d.ts +4 -0
  81. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  82. package/dist/opLifecycle/opDecompressor.js +43 -4
  83. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  84. package/dist/opLifecycle/opGroupingManager.d.ts +14 -0
  85. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -0
  86. package/dist/opLifecycle/opGroupingManager.js +56 -0
  87. package/dist/opLifecycle/opGroupingManager.js.map +1 -0
  88. package/dist/opLifecycle/opSplitter.d.ts +16 -4
  89. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  90. package/dist/opLifecycle/opSplitter.js +39 -15
  91. package/dist/opLifecycle/opSplitter.js.map +1 -1
  92. package/dist/opLifecycle/outbox.d.ts +21 -3
  93. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  94. package/dist/opLifecycle/outbox.js +90 -51
  95. package/dist/opLifecycle/outbox.js.map +1 -1
  96. package/dist/opLifecycle/remoteMessageProcessor.d.ts +4 -2
  97. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  98. package/dist/opLifecycle/remoteMessageProcessor.js +30 -20
  99. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  100. package/dist/packageVersion.d.ts +1 -1
  101. package/dist/packageVersion.js +1 -1
  102. package/dist/packageVersion.js.map +1 -1
  103. package/dist/pendingStateManager.d.ts +3 -3
  104. package/dist/pendingStateManager.d.ts.map +1 -1
  105. package/dist/pendingStateManager.js +20 -21
  106. package/dist/pendingStateManager.js.map +1 -1
  107. package/dist/storageServiceWithAttachBlobs.d.ts +17 -0
  108. package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -0
  109. package/dist/storageServiceWithAttachBlobs.js +32 -0
  110. package/dist/storageServiceWithAttachBlobs.js.map +1 -0
  111. package/dist/summary/index.d.ts +17 -0
  112. package/dist/summary/index.d.ts.map +1 -0
  113. package/dist/summary/index.js +48 -0
  114. package/dist/summary/index.js.map +1 -0
  115. package/dist/summary/orderedClientElection.d.ts.map +1 -0
  116. package/dist/summary/orderedClientElection.js.map +1 -0
  117. package/dist/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +3 -2
  118. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  119. package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +5 -4
  120. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -0
  121. package/{lib → dist/summary}/runningSummarizer.d.ts +23 -20
  122. package/dist/summary/runningSummarizer.d.ts.map +1 -0
  123. package/dist/{runningSummarizer.js → summary/runningSummarizer.js} +191 -74
  124. package/dist/summary/runningSummarizer.js.map +1 -0
  125. package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +4 -9
  126. package/dist/summary/summarizer.d.ts.map +1 -0
  127. package/dist/{summarizer.js → summary/summarizer.js} +10 -79
  128. package/dist/summary/summarizer.js.map +1 -0
  129. package/dist/summary/summarizerClientElection.d.ts.map +1 -0
  130. package/dist/summary/summarizerClientElection.js.map +1 -0
  131. package/dist/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +2 -1
  132. package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
  133. package/dist/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -3
  134. package/dist/summary/summarizerHeuristics.js.map +1 -0
  135. package/dist/summary/summarizerNode/index.d.ts +8 -0
  136. package/dist/summary/summarizerNode/index.d.ts.map +1 -0
  137. package/dist/summary/summarizerNode/index.js +12 -0
  138. package/dist/summary/summarizerNode/index.js.map +1 -0
  139. package/dist/summary/summarizerNode/summarizerNode.d.ts +149 -0
  140. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
  141. package/dist/summary/summarizerNode/summarizerNode.js +531 -0
  142. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -0
  143. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +125 -0
  144. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
  145. package/dist/summary/summarizerNode/summarizerNodeUtils.js +132 -0
  146. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
  147. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +148 -0
  148. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
  149. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +424 -0
  150. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
  151. package/{lib → dist/summary}/summarizerTypes.d.ts +21 -19
  152. package/dist/summary/summarizerTypes.d.ts.map +1 -0
  153. package/dist/{summarizerTypes.js → summary/summarizerTypes.js} +0 -5
  154. package/dist/summary/summarizerTypes.js.map +1 -0
  155. package/dist/summary/summaryCollection.d.ts.map +1 -0
  156. package/dist/summary/summaryCollection.js.map +1 -0
  157. package/{lib → dist/summary}/summaryFormat.d.ts +3 -21
  158. package/dist/summary/summaryFormat.d.ts.map +1 -0
  159. package/dist/{summaryFormat.js → summary/summaryFormat.js} +1 -10
  160. package/dist/summary/summaryFormat.js.map +1 -0
  161. package/{lib → dist/summary}/summaryGenerator.d.ts +28 -2
  162. package/dist/summary/summaryGenerator.d.ts.map +1 -0
  163. package/dist/{summaryGenerator.js → summary/summaryGenerator.js} +23 -20
  164. package/dist/summary/summaryGenerator.js.map +1 -0
  165. package/dist/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
  166. package/dist/summary/summaryManager.d.ts.map +1 -0
  167. package/dist/summary/summaryManager.js.map +1 -0
  168. package/lib/blobManager.d.ts +29 -24
  169. package/lib/blobManager.d.ts.map +1 -1
  170. package/lib/blobManager.js +159 -89
  171. package/lib/blobManager.js.map +1 -1
  172. package/lib/containerRuntime.d.ts +74 -76
  173. package/lib/containerRuntime.d.ts.map +1 -1
  174. package/lib/containerRuntime.js +301 -237
  175. package/lib/containerRuntime.js.map +1 -1
  176. package/lib/dataStoreContext.d.ts +39 -13
  177. package/lib/dataStoreContext.d.ts.map +1 -1
  178. package/lib/dataStoreContext.js +101 -38
  179. package/lib/dataStoreContext.js.map +1 -1
  180. package/lib/dataStores.d.ts +28 -4
  181. package/lib/dataStores.d.ts.map +1 -1
  182. package/lib/dataStores.js +100 -34
  183. package/lib/dataStores.js.map +1 -1
  184. package/lib/deltaManagerSummarizerProxy.d.ts +19 -0
  185. package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -0
  186. package/lib/deltaManagerSummarizerProxy.js +36 -0
  187. package/lib/deltaManagerSummarizerProxy.js.map +1 -0
  188. package/lib/gc/garbageCollection.d.ts +204 -0
  189. package/lib/gc/garbageCollection.d.ts.map +1 -0
  190. package/lib/{garbageCollection.js → gc/garbageCollection.js} +172 -535
  191. package/lib/gc/garbageCollection.js.map +1 -0
  192. package/lib/gc/gcConfigs.d.ts +22 -0
  193. package/lib/gc/gcConfigs.d.ts.map +1 -0
  194. package/lib/gc/gcConfigs.js +139 -0
  195. package/lib/gc/gcConfigs.js.map +1 -0
  196. package/lib/gc/gcDefinitions.d.ts +320 -0
  197. package/lib/gc/gcDefinitions.d.ts.map +1 -0
  198. package/lib/gc/gcDefinitions.js +78 -0
  199. package/lib/gc/gcDefinitions.js.map +1 -0
  200. package/lib/gc/gcHelpers.d.ts +86 -0
  201. package/lib/gc/gcHelpers.d.ts.map +1 -0
  202. package/lib/gc/gcHelpers.js +254 -0
  203. package/lib/gc/gcHelpers.js.map +1 -0
  204. package/lib/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
  205. package/lib/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
  206. package/lib/gc/gcReferenceGraphAlgorithm.js +45 -0
  207. package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -0
  208. package/lib/gc/gcSummaryDefinitions.d.ts +52 -0
  209. package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -0
  210. package/lib/gc/gcSummaryDefinitions.js +6 -0
  211. package/lib/gc/gcSummaryDefinitions.js.map +1 -0
  212. package/lib/gc/gcSummaryStateTracker.d.ts +93 -0
  213. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
  214. package/lib/gc/gcSummaryStateTracker.js +235 -0
  215. package/lib/gc/gcSummaryStateTracker.js.map +1 -0
  216. package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  217. package/lib/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +1 -1
  218. package/lib/gc/gcSweepReadyUsageDetection.js.map +1 -0
  219. package/lib/gc/gcUnreferencedStateTracker.d.ts +34 -0
  220. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  221. package/lib/gc/gcUnreferencedStateTracker.js +90 -0
  222. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -0
  223. package/lib/gc/index.d.ts +13 -0
  224. package/lib/gc/index.d.ts.map +1 -0
  225. package/lib/gc/index.js +12 -0
  226. package/lib/gc/index.js.map +1 -0
  227. package/lib/index.d.ts +3 -7
  228. package/lib/index.d.ts.map +1 -1
  229. package/lib/index.js +1 -4
  230. package/lib/index.js.map +1 -1
  231. package/lib/opLifecycle/batchManager.d.ts +11 -13
  232. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  233. package/lib/opLifecycle/batchManager.js +24 -37
  234. package/lib/opLifecycle/batchManager.js.map +1 -1
  235. package/lib/opLifecycle/definitions.d.ts +4 -0
  236. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  237. package/lib/opLifecycle/definitions.js.map +1 -1
  238. package/lib/opLifecycle/index.d.ts +2 -1
  239. package/lib/opLifecycle/index.d.ts.map +1 -1
  240. package/lib/opLifecycle/index.js +2 -1
  241. package/lib/opLifecycle/index.js.map +1 -1
  242. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  243. package/lib/opLifecycle/opCompressor.js +26 -11
  244. package/lib/opLifecycle/opCompressor.js.map +1 -1
  245. package/lib/opLifecycle/opDecompressor.d.ts +4 -0
  246. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  247. package/lib/opLifecycle/opDecompressor.js +43 -4
  248. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  249. package/lib/opLifecycle/opGroupingManager.d.ts +14 -0
  250. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -0
  251. package/lib/opLifecycle/opGroupingManager.js +52 -0
  252. package/lib/opLifecycle/opGroupingManager.js.map +1 -0
  253. package/lib/opLifecycle/opSplitter.d.ts +16 -4
  254. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  255. package/lib/opLifecycle/opSplitter.js +39 -15
  256. package/lib/opLifecycle/opSplitter.js.map +1 -1
  257. package/lib/opLifecycle/outbox.d.ts +21 -3
  258. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  259. package/lib/opLifecycle/outbox.js +92 -53
  260. package/lib/opLifecycle/outbox.js.map +1 -1
  261. package/lib/opLifecycle/remoteMessageProcessor.d.ts +4 -2
  262. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  263. package/lib/opLifecycle/remoteMessageProcessor.js +30 -20
  264. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  265. package/lib/packageVersion.d.ts +1 -1
  266. package/lib/packageVersion.js +1 -1
  267. package/lib/packageVersion.js.map +1 -1
  268. package/lib/pendingStateManager.d.ts +3 -3
  269. package/lib/pendingStateManager.d.ts.map +1 -1
  270. package/lib/pendingStateManager.js +20 -21
  271. package/lib/pendingStateManager.js.map +1 -1
  272. package/lib/storageServiceWithAttachBlobs.d.ts +17 -0
  273. package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -0
  274. package/lib/storageServiceWithAttachBlobs.js +28 -0
  275. package/lib/storageServiceWithAttachBlobs.js.map +1 -0
  276. package/lib/summary/index.d.ts +17 -0
  277. package/lib/summary/index.d.ts.map +1 -0
  278. package/lib/summary/index.js +16 -0
  279. package/lib/summary/index.js.map +1 -0
  280. package/lib/summary/orderedClientElection.d.ts.map +1 -0
  281. package/lib/summary/orderedClientElection.js.map +1 -0
  282. package/lib/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +3 -2
  283. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  284. package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +5 -4
  285. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
  286. package/{dist → lib/summary}/runningSummarizer.d.ts +23 -20
  287. package/lib/summary/runningSummarizer.d.ts.map +1 -0
  288. package/lib/{runningSummarizer.js → summary/runningSummarizer.js} +192 -75
  289. package/lib/summary/runningSummarizer.js.map +1 -0
  290. package/lib/{summarizer.d.ts → summary/summarizer.d.ts} +4 -9
  291. package/lib/summary/summarizer.d.ts.map +1 -0
  292. package/lib/{summarizer.js → summary/summarizer.js} +12 -81
  293. package/lib/summary/summarizer.js.map +1 -0
  294. package/lib/summary/summarizerClientElection.d.ts.map +1 -0
  295. package/lib/summary/summarizerClientElection.js.map +1 -0
  296. package/lib/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +2 -1
  297. package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
  298. package/lib/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -3
  299. package/lib/summary/summarizerHeuristics.js.map +1 -0
  300. package/lib/summary/summarizerNode/index.d.ts +8 -0
  301. package/lib/summary/summarizerNode/index.d.ts.map +1 -0
  302. package/lib/summary/summarizerNode/index.js +7 -0
  303. package/lib/summary/summarizerNode/index.js.map +1 -0
  304. package/lib/summary/summarizerNode/summarizerNode.d.ts +149 -0
  305. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
  306. package/lib/summary/summarizerNode/summarizerNode.js +526 -0
  307. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -0
  308. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +125 -0
  309. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
  310. package/lib/summary/summarizerNode/summarizerNodeUtils.js +125 -0
  311. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
  312. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +148 -0
  313. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
  314. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +419 -0
  315. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
  316. package/{dist → lib/summary}/summarizerTypes.d.ts +21 -19
  317. package/lib/summary/summarizerTypes.d.ts.map +1 -0
  318. package/lib/summary/summarizerTypes.js +6 -0
  319. package/lib/summary/summarizerTypes.js.map +1 -0
  320. package/lib/summary/summaryCollection.d.ts.map +1 -0
  321. package/lib/summary/summaryCollection.js.map +1 -0
  322. package/{dist → lib/summary}/summaryFormat.d.ts +3 -21
  323. package/lib/summary/summaryFormat.d.ts.map +1 -0
  324. package/lib/{summaryFormat.js → summary/summaryFormat.js} +0 -8
  325. package/lib/summary/summaryFormat.js.map +1 -0
  326. package/{dist → lib/summary}/summaryGenerator.d.ts +28 -2
  327. package/lib/summary/summaryGenerator.d.ts.map +1 -0
  328. package/lib/{summaryGenerator.js → summary/summaryGenerator.js} +21 -19
  329. package/lib/summary/summaryGenerator.js.map +1 -0
  330. package/lib/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
  331. package/lib/summary/summaryManager.d.ts.map +1 -0
  332. package/lib/summary/summaryManager.js.map +1 -0
  333. package/package.json +66 -60
  334. package/src/blobManager.ts +196 -110
  335. package/src/containerRuntime.ts +491 -391
  336. package/src/dataStoreContext.ts +140 -49
  337. package/src/dataStores.ts +139 -41
  338. package/src/deltaManagerSummarizerProxy.ts +46 -0
  339. package/{garbageCollection.md → src/gc/garbageCollection.md} +2 -2
  340. package/src/{garbageCollection.ts → gc/garbageCollection.ts} +245 -890
  341. package/src/gc/gcConfigs.ts +193 -0
  342. package/src/gc/gcDefinitions.ts +387 -0
  343. package/src/gc/gcHelpers.ts +335 -0
  344. package/src/gc/gcReferenceGraphAlgorithm.ts +52 -0
  345. package/src/gc/gcSummaryDefinitions.ts +54 -0
  346. package/src/gc/gcSummaryStateTracker.ts +329 -0
  347. package/src/{gcSweepReadyUsageDetection.ts → gc/gcSweepReadyUsageDetection.ts} +1 -1
  348. package/src/gc/gcUnreferencedStateTracker.ts +114 -0
  349. package/src/gc/index.ts +65 -0
  350. package/src/index.ts +10 -22
  351. package/src/opLifecycle/README.md +263 -0
  352. package/src/opLifecycle/batchManager.ts +26 -55
  353. package/src/opLifecycle/definitions.ts +4 -0
  354. package/src/opLifecycle/index.ts +2 -1
  355. package/src/opLifecycle/opCompressor.ts +32 -12
  356. package/src/opLifecycle/opDecompressor.ts +50 -5
  357. package/src/opLifecycle/opGroupingManager.ts +78 -0
  358. package/src/opLifecycle/opSplitter.ts +56 -17
  359. package/src/opLifecycle/outbox.ts +126 -62
  360. package/src/opLifecycle/remoteMessageProcessor.ts +38 -22
  361. package/src/packageVersion.ts +1 -1
  362. package/src/pendingStateManager.ts +34 -27
  363. package/src/storageServiceWithAttachBlobs.ts +38 -0
  364. package/src/summary/index.ts +105 -0
  365. package/src/{runWhileConnectedCoordinator.ts → summary/runWhileConnectedCoordinator.ts} +7 -7
  366. package/src/{runningSummarizer.ts → summary/runningSummarizer.ts} +318 -156
  367. package/src/{summarizer.ts → summary/summarizer.ts} +12 -105
  368. package/src/{summarizerHeuristics.ts → summary/summarizerHeuristics.ts} +13 -4
  369. package/src/summary/summarizerNode/index.ts +12 -0
  370. package/src/summary/summarizerNode/summarizerNode.ts +766 -0
  371. package/src/summary/summarizerNode/summarizerNodeUtils.ts +214 -0
  372. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +644 -0
  373. package/src/{summarizerTypes.ts → summary/summarizerTypes.ts} +28 -25
  374. package/src/{summaryFormat.ts → summary/summaryFormat.ts} +3 -29
  375. package/src/{summaryGenerator.ts → summary/summaryGenerator.ts} +34 -27
  376. package/src/{summaryManager.ts → summary/summaryManager.ts} +1 -1
  377. package/dist/garbageCollection.d.ts +0 -411
  378. package/dist/garbageCollection.d.ts.map +0 -1
  379. package/dist/garbageCollection.js.map +0 -1
  380. package/dist/garbageCollectionConstants.d.ts +0 -23
  381. package/dist/garbageCollectionConstants.d.ts.map +0 -1
  382. package/dist/garbageCollectionConstants.js +0 -36
  383. package/dist/garbageCollectionConstants.js.map +0 -1
  384. package/dist/garbageCollectionHelpers.d.ts +0 -15
  385. package/dist/garbageCollectionHelpers.d.ts.map +0 -1
  386. package/dist/garbageCollectionHelpers.js +0 -27
  387. package/dist/garbageCollectionHelpers.js.map +0 -1
  388. package/dist/gcSweepReadyUsageDetection.d.ts.map +0 -1
  389. package/dist/gcSweepReadyUsageDetection.js.map +0 -1
  390. package/dist/orderedClientElection.d.ts.map +0 -1
  391. package/dist/orderedClientElection.js.map +0 -1
  392. package/dist/runWhileConnectedCoordinator.d.ts.map +0 -1
  393. package/dist/runWhileConnectedCoordinator.js.map +0 -1
  394. package/dist/runningSummarizer.d.ts.map +0 -1
  395. package/dist/runningSummarizer.js.map +0 -1
  396. package/dist/serializedSnapshotStorage.d.ts +0 -58
  397. package/dist/serializedSnapshotStorage.d.ts.map +0 -1
  398. package/dist/serializedSnapshotStorage.js +0 -110
  399. package/dist/serializedSnapshotStorage.js.map +0 -1
  400. package/dist/summarizer.d.ts.map +0 -1
  401. package/dist/summarizer.js.map +0 -1
  402. package/dist/summarizerClientElection.d.ts.map +0 -1
  403. package/dist/summarizerClientElection.js.map +0 -1
  404. package/dist/summarizerHandle.d.ts +0 -12
  405. package/dist/summarizerHandle.d.ts.map +0 -1
  406. package/dist/summarizerHandle.js +0 -22
  407. package/dist/summarizerHandle.js.map +0 -1
  408. package/dist/summarizerHeuristics.d.ts.map +0 -1
  409. package/dist/summarizerHeuristics.js.map +0 -1
  410. package/dist/summarizerTypes.d.ts.map +0 -1
  411. package/dist/summarizerTypes.js.map +0 -1
  412. package/dist/summaryCollection.d.ts.map +0 -1
  413. package/dist/summaryCollection.js.map +0 -1
  414. package/dist/summaryFormat.d.ts.map +0 -1
  415. package/dist/summaryFormat.js.map +0 -1
  416. package/dist/summaryGenerator.d.ts.map +0 -1
  417. package/dist/summaryGenerator.js.map +0 -1
  418. package/dist/summaryManager.d.ts.map +0 -1
  419. package/dist/summaryManager.js.map +0 -1
  420. package/lib/garbageCollection.d.ts +0 -411
  421. package/lib/garbageCollection.d.ts.map +0 -1
  422. package/lib/garbageCollection.js.map +0 -1
  423. package/lib/garbageCollectionConstants.d.ts +0 -23
  424. package/lib/garbageCollectionConstants.d.ts.map +0 -1
  425. package/lib/garbageCollectionConstants.js +0 -33
  426. package/lib/garbageCollectionConstants.js.map +0 -1
  427. package/lib/garbageCollectionHelpers.d.ts +0 -15
  428. package/lib/garbageCollectionHelpers.d.ts.map +0 -1
  429. package/lib/garbageCollectionHelpers.js +0 -23
  430. package/lib/garbageCollectionHelpers.js.map +0 -1
  431. package/lib/gcSweepReadyUsageDetection.d.ts.map +0 -1
  432. package/lib/gcSweepReadyUsageDetection.js.map +0 -1
  433. package/lib/orderedClientElection.d.ts.map +0 -1
  434. package/lib/orderedClientElection.js.map +0 -1
  435. package/lib/runWhileConnectedCoordinator.d.ts.map +0 -1
  436. package/lib/runWhileConnectedCoordinator.js.map +0 -1
  437. package/lib/runningSummarizer.d.ts.map +0 -1
  438. package/lib/runningSummarizer.js.map +0 -1
  439. package/lib/serializedSnapshotStorage.d.ts +0 -58
  440. package/lib/serializedSnapshotStorage.d.ts.map +0 -1
  441. package/lib/serializedSnapshotStorage.js +0 -106
  442. package/lib/serializedSnapshotStorage.js.map +0 -1
  443. package/lib/summarizer.d.ts.map +0 -1
  444. package/lib/summarizer.js.map +0 -1
  445. package/lib/summarizerClientElection.d.ts.map +0 -1
  446. package/lib/summarizerClientElection.js.map +0 -1
  447. package/lib/summarizerHandle.d.ts +0 -12
  448. package/lib/summarizerHandle.d.ts.map +0 -1
  449. package/lib/summarizerHandle.js +0 -18
  450. package/lib/summarizerHandle.js.map +0 -1
  451. package/lib/summarizerHeuristics.d.ts.map +0 -1
  452. package/lib/summarizerHeuristics.js.map +0 -1
  453. package/lib/summarizerTypes.d.ts.map +0 -1
  454. package/lib/summarizerTypes.js +0 -9
  455. package/lib/summarizerTypes.js.map +0 -1
  456. package/lib/summaryCollection.d.ts.map +0 -1
  457. package/lib/summaryCollection.js.map +0 -1
  458. package/lib/summaryFormat.d.ts.map +0 -1
  459. package/lib/summaryFormat.js.map +0 -1
  460. package/lib/summaryGenerator.d.ts.map +0 -1
  461. package/lib/summaryGenerator.js.map +0 -1
  462. package/lib/summaryManager.d.ts.map +0 -1
  463. package/lib/summaryManager.js.map +0 -1
  464. package/src/garbageCollectionConstants.ts +0 -38
  465. package/src/garbageCollectionHelpers.ts +0 -37
  466. package/src/serializedSnapshotStorage.ts +0 -151
  467. package/src/summarizerHandle.ts +0 -23
  468. /package/dist/{gcSweepReadyUsageDetection.d.ts → gc/gcSweepReadyUsageDetection.d.ts} +0 -0
  469. /package/dist/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  470. /package/dist/{orderedClientElection.js → summary/orderedClientElection.js} +0 -0
  471. /package/dist/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
  472. /package/dist/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
  473. /package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  474. /package/dist/{summaryCollection.js → summary/summaryCollection.js} +0 -0
  475. /package/dist/{summaryManager.js → summary/summaryManager.js} +0 -0
  476. /package/lib/{gcSweepReadyUsageDetection.d.ts → gc/gcSweepReadyUsageDetection.d.ts} +0 -0
  477. /package/lib/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  478. /package/lib/{orderedClientElection.js → summary/orderedClientElection.js} +0 -0
  479. /package/lib/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
  480. /package/lib/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
  481. /package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  482. /package/lib/{summaryCollection.js → summary/summaryCollection.js} +0 -0
  483. /package/lib/{summaryManager.js → summary/summaryManager.js} +0 -0
  484. /package/src/{orderedClientElection.ts → summary/orderedClientElection.ts} +0 -0
  485. /package/src/{summarizerClientElection.ts → summary/summarizerClientElection.ts} +0 -0
  486. /package/src/{summaryCollection.ts → summary/summaryCollection.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-runtime",
3
- "version": "2.0.0-dev.3.1.0.125672",
3
+ "version": "2.0.0-dev.4.2.0.153917",
4
4
  "description": "Fluid container runtime",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -14,34 +14,6 @@
14
14
  "main": "dist/index.js",
15
15
  "module": "lib/index.js",
16
16
  "types": "dist/index.d.ts",
17
- "scripts": {
18
- "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
19
- "build:commonjs": "npm run tsc && npm run typetests:gen && npm run build:test",
20
- "build:compile": "concurrently npm:build:commonjs npm:build:esnext",
21
- "build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
22
- "build:esnext": "tsc --project ./tsconfig.esnext.json",
23
- "build:full": "npm run build",
24
- "build:full:compile": "npm run build:compile",
25
- "build:genver": "gen-version",
26
- "build:test": "tsc --project ./src/test/tsconfig.json",
27
- "ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
28
- "clean": "rimraf dist lib *.tsbuildinfo *.build.log",
29
- "eslint": "eslint --format stylish src",
30
- "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
31
- "format": "npm run prettier:fix",
32
- "lint": "npm run prettier && npm run eslint",
33
- "lint:fix": "npm run prettier:fix &&npm run eslint:fix",
34
- "prettier": "prettier --check . --ignore-path ../../../.prettierignore",
35
- "prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
36
- "test": "npm run test:mocha",
37
- "test:coverage": "nyc npm test -- --reporter xunit --reporter-option output=nyc/junit-report.xml",
38
- "test:mocha": "mocha --ignore 'dist/test/types/*' --recursive dist/test -r node_modules/@fluidframework/mocha-test-setup --unhandled-rejections=strict",
39
- "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
40
- "tsc": "tsc",
41
- "tsc:watch": "tsc --watch",
42
- "typetests:gen": "flub generate typetests --generate --dir .",
43
- "typetests:prepare": "flub generate typetests --prepare --dir . --pin"
44
- },
45
17
  "nyc": {
46
18
  "all": true,
47
19
  "cache-dir": "nyc/.cache",
@@ -64,56 +36,90 @@
64
36
  },
65
37
  "dependencies": {
66
38
  "@fluidframework/common-definitions": "^0.20.1",
67
- "@fluidframework/common-utils": "^1.0.0",
68
- "@fluidframework/container-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
69
- "@fluidframework/container-runtime-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
70
- "@fluidframework/container-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
71
- "@fluidframework/core-interfaces": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
72
- "@fluidframework/datastore": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
73
- "@fluidframework/driver-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
74
- "@fluidframework/driver-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
75
- "@fluidframework/garbage-collector": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
76
- "@fluidframework/protocol-base": "^0.1038.2000",
39
+ "@fluidframework/common-utils": "^1.1.1",
40
+ "@fluidframework/container-definitions": "2.0.0-dev.4.2.0.153917",
41
+ "@fluidframework/container-runtime-definitions": "2.0.0-dev.4.2.0.153917",
42
+ "@fluidframework/container-utils": "2.0.0-dev.4.2.0.153917",
43
+ "@fluidframework/core-interfaces": "2.0.0-dev.4.2.0.153917",
44
+ "@fluidframework/datastore": "2.0.0-dev.4.2.0.153917",
45
+ "@fluidframework/driver-definitions": "2.0.0-dev.4.2.0.153917",
46
+ "@fluidframework/driver-utils": "2.0.0-dev.4.2.0.153917",
47
+ "@fluidframework/garbage-collector": "2.0.0-dev.4.2.0.153917",
48
+ "@fluidframework/protocol-base": "^0.1039.1000",
77
49
  "@fluidframework/protocol-definitions": "^1.1.0",
78
- "@fluidframework/runtime-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
79
- "@fluidframework/runtime-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
80
- "@fluidframework/telemetry-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
50
+ "@fluidframework/runtime-definitions": "2.0.0-dev.4.2.0.153917",
51
+ "@fluidframework/runtime-utils": "2.0.0-dev.4.2.0.153917",
52
+ "@fluidframework/telemetry-utils": "2.0.0-dev.4.2.0.153917",
81
53
  "double-ended-queue": "^2.1.0-0",
82
54
  "events": "^3.1.0",
83
55
  "lz4js": "^0.2.0",
84
56
  "uuid": "^8.3.1"
85
57
  },
86
58
  "devDependencies": {
87
- "@fluid-tools/build-cli": "^0.8.0",
59
+ "@fluid-tools/build-cli": "^0.15.0",
88
60
  "@fluidframework/build-common": "^1.1.0",
89
- "@fluidframework/build-tools": "^0.8.0",
90
- "@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-internal.3.0.0",
61
+ "@fluidframework/build-tools": "^0.15.0",
62
+ "@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-internal.4.0.0",
91
63
  "@fluidframework/eslint-config-fluid": "^2.0.0",
92
- "@fluidframework/mocha-test-setup": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
93
- "@fluidframework/test-runtime-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
94
- "@microsoft/api-extractor": "^7.22.2",
95
- "@rushstack/eslint-config": "^2.5.1",
64
+ "@fluidframework/mocha-test-setup": "2.0.0-dev.4.2.0.153917",
65
+ "@fluidframework/test-runtime-utils": "2.0.0-dev.4.2.0.153917",
66
+ "@microsoft/api-extractor": "^7.34.4",
96
67
  "@types/double-ended-queue": "^2.1.0",
97
68
  "@types/events": "^3.0.0",
98
69
  "@types/mocha": "^9.1.1",
99
70
  "@types/sinon": "^7.0.13",
100
71
  "@types/uuid": "^8.3.0",
101
- "concurrently": "^6.2.0",
72
+ "concurrently": "^7.6.0",
102
73
  "copyfiles": "^2.4.1",
103
- "cross-env": "^7.0.2",
74
+ "cross-env": "^7.0.3",
104
75
  "eslint": "~8.6.0",
105
- "mocha": "^10.0.0",
106
- "nyc": "^15.0.0",
76
+ "mocha": "^10.2.0",
77
+ "mocha-json-output-reporter": "^2.0.1",
78
+ "mocha-multi-reporters": "^1.5.1",
79
+ "moment": "^2.21.0",
80
+ "nyc": "^15.1.0",
107
81
  "prettier": "~2.6.2",
108
- "rimraf": "^2.6.2",
82
+ "rimraf": "^4.4.0",
109
83
  "sinon": "^7.4.2",
110
84
  "typescript": "~4.5.5"
111
85
  },
112
86
  "typeValidation": {
113
- "version": "2.0.0-internal.3.1.0",
114
- "previousVersionStyle": "~previousMinor",
115
- "baselineRange": ">=2.0.0-internal.3.0.0 <2.0.0-internal.3.1.0",
116
- "baselineVersion": "2.0.0-internal.3.0.0",
117
- "broken": {}
87
+ "broken": {
88
+ "ClassDeclaration_ContainerRuntime": {
89
+ "forwardCompat": false
90
+ },
91
+ "TypeAliasDeclaration_SummarizerStopReason": {
92
+ "backCompat": false
93
+ }
94
+ }
95
+ },
96
+ "scripts": {
97
+ "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
98
+ "build:commonjs": "npm run tsc && npm run typetests:gen && npm run build:test",
99
+ "build:compile": "concurrently npm:build:commonjs npm:build:esnext",
100
+ "build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
101
+ "build:esnext": "tsc --project ./tsconfig.esnext.json",
102
+ "build:full": "npm run build",
103
+ "build:full:compile": "npm run build:compile",
104
+ "build:genver": "gen-version",
105
+ "build:test": "tsc --project ./src/test/tsconfig.json",
106
+ "ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
107
+ "clean": "rimraf dist lib *.tsbuildinfo *.build.log",
108
+ "eslint": "eslint --format stylish src",
109
+ "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
110
+ "format": "npm run prettier:fix",
111
+ "lint": "npm run prettier && npm run eslint",
112
+ "lint:fix": "npm run prettier:fix &&npm run eslint:fix",
113
+ "prettier": "prettier --check . --ignore-path ../../../.prettierignore",
114
+ "prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
115
+ "test": "npm run test:mocha",
116
+ "test:coverage": "nyc npm test -- --reporter xunit --reporter-option output=nyc/junit-report.xml",
117
+ "test:mocha": "mocha --ignore 'dist/test/types/*' --recursive dist/test -r node_modules/@fluidframework/mocha-test-setup --unhandled-rejections=strict",
118
+ "test:mocha:multireport": "cross-env FLUID_TEST_MULTIREPORT=1 npm run test:mocha",
119
+ "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
120
+ "tsc": "tsc",
121
+ "tsc:watch": "tsc --watch",
122
+ "typetests:gen": "fluid-type-test-generator",
123
+ "typetests:prepare": "flub generate typetests --prepare --dir . --pin"
118
124
  }
119
- }
125
+ }
@@ -28,7 +28,7 @@ import {
28
28
  IContainerRuntime,
29
29
  IContainerRuntimeEvents,
30
30
  } from "@fluidframework/container-runtime-definitions";
31
- import { AttachState } from "@fluidframework/container-definitions";
31
+ import { AttachState, ICriticalContainerError } from "@fluidframework/container-definitions";
32
32
  import {
33
33
  ChildLogger,
34
34
  loggerToMonitoringContext,
@@ -40,11 +40,11 @@ import {
40
40
  ISummaryTreeWithStats,
41
41
  ITelemetryContext,
42
42
  } from "@fluidframework/runtime-definitions";
43
- import { TombstoneResponseHeaderKey } from "./containerRuntime";
43
+ import { GenericError } from "@fluidframework/container-utils";
44
+ import { ContainerRuntime, TombstoneResponseHeaderKey } from "./containerRuntime";
45
+ import { sendGCUnexpectedUsageEvent, sweepAttachmentBlobsKey, throwOnTombstoneLoadKey } from "./gc";
44
46
  import { Throttler, formExponentialFn, IThrottler } from "./throttler";
45
- import { summarizerClientType } from "./summarizerClientElection";
46
- import { throwOnTombstoneLoadKey } from "./garbageCollectionConstants";
47
- import { sendGCUnexpectedUsageEvent } from "./garbageCollectionHelpers";
47
+ import { summarizerClientType } from "./summary";
48
48
 
49
49
  /**
50
50
  * This class represents blob (long string)
@@ -114,6 +114,7 @@ export type IBlobManagerRuntime = Pick<
114
114
  IContainerRuntime,
115
115
  "attachState" | "connected" | "logger" | "clientDetails"
116
116
  > &
117
+ Pick<ContainerRuntime, "gcTombstoneEnforcementAllowed"> &
117
118
  TypedEventEmitter<IContainerRuntimeEvents>;
118
119
 
119
120
  // Note that while offline we "submit" an op before uploading the blob, but we always
@@ -132,14 +133,13 @@ interface PendingBlob {
132
133
  status: PendingBlobStatus;
133
134
  storageId?: string;
134
135
  handleP: Deferred<IFluidHandle<ArrayBufferLike>>;
135
- uploadP: Promise<ICreateBlobResponse>;
136
- localUploadTime?: number;
137
- serverUploadTime?: number;
136
+ uploadP?: Promise<ICreateBlobResponse>;
137
+ uploadTime?: number;
138
138
  minTTLInSeconds?: number;
139
139
  }
140
140
 
141
141
  export interface IPendingBlobs {
142
- [id: string]: { blob: string };
142
+ [id: string]: { blob: string; uploadTime?: number; minTTLInSeconds?: number };
143
143
  }
144
144
 
145
145
  export interface IBlobManagerEvents {
@@ -191,6 +191,8 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
191
191
  */
192
192
  private readonly tombstonedBlobs: Set<string> = new Set();
193
193
 
194
+ private readonly sendBlobAttachOp: (localId: string, storageId?: string) => void;
195
+
194
196
  constructor(
195
197
  private readonly routeContext: IFluidHandleContext,
196
198
  snapshot: IBlobManagerLoadInfo,
@@ -205,26 +207,23 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
205
207
  * knowledge of which they cannot request the blob from storage. It's important that this op is sequenced
206
208
  * before any ops that reference the local ID, otherwise, an invalid handle could be added to the document.
207
209
  */
208
- private readonly sendBlobAttachOp: (localId: string, storageId?: string) => void,
210
+ sendBlobAttachOp: (localId: string, storageId?: string) => void,
209
211
  // Called when a blob node is requested. blobPath is the path of the blob's node in GC's graph.
210
212
  // blobPath's format - `/<BlobManager.basePath>/<blobId>`.
211
213
  private readonly blobRequested: (blobPath: string) => void,
212
- // Called when a reference is added to a blob. For instance, when creating a localId / storageId to storageId
213
- // mapping in the redirect table.
214
- // Node path formats - `/<BlobManager.basePath>/<blobId>`.
215
- private readonly addedBlobReference: (fromNodePath: string, toNodePath: string) => void,
216
214
  // Called to check if a blob has been deleted by GC.
217
215
  // blobPath's format - `/<BlobManager.basePath>/<blobId>`.
218
216
  private readonly isBlobDeleted: (blobPath: string) => boolean,
219
217
  private readonly runtime: IBlobManagerRuntime,
220
218
  stashedBlobs: IPendingBlobs = {},
221
- private readonly getCurrentReferenceTimestampMs: () => number | undefined,
219
+ private readonly closeContainer: (error?: ICriticalContainerError) => void,
222
220
  ) {
223
221
  super();
224
222
  this.mc = loggerToMonitoringContext(ChildLogger.create(this.runtime.logger, "BlobManager"));
225
223
  // Read the feature flag that tells whether to throw when a tombstone blob is requested.
226
224
  this.throwOnTombstoneLoad =
227
225
  this.mc.config.getBoolean(throwOnTombstoneLoadKey) === true &&
226
+ this.runtime.gcTombstoneEnforcementAllowed &&
228
227
  this.runtime.clientDetails.type !== summarizerClientType;
229
228
 
230
229
  this.runtime.on("disconnected", () => this.onDisconnected());
@@ -233,6 +232,21 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
233
232
  // Begin uploading stashed blobs from previous container instance
234
233
  Object.entries(stashedBlobs).forEach(([localId, entry]) => {
235
234
  const blob = stringToBuffer(entry.blob, "base64");
235
+ if (entry.minTTLInSeconds && entry.uploadTime) {
236
+ const timeLapseSinceLocalUpload = (Date.now() - entry.uploadTime) / 1000;
237
+ // stashed entries with more than half-life in storage will not be reuploaded
238
+ if (entry.minTTLInSeconds - timeLapseSinceLocalUpload > entry.minTTLInSeconds / 2) {
239
+ this.pendingBlobs.set(localId, {
240
+ blob,
241
+ status: PendingBlobStatus.OfflinePendingOp,
242
+ handleP: new Deferred(),
243
+ uploadP: undefined,
244
+ uploadTime: entry.uploadTime,
245
+ minTTLInSeconds: entry.minTTLInSeconds,
246
+ });
247
+ return;
248
+ }
249
+ }
236
250
  this.pendingBlobs.set(localId, {
237
251
  blob,
238
252
  status: PendingBlobStatus.OfflinePendingUpload,
@@ -240,6 +254,37 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
240
254
  uploadP: this.uploadBlob(localId, blob),
241
255
  });
242
256
  });
257
+
258
+ this.sendBlobAttachOp = (localId: string, blobId?: string) => {
259
+ const pendingEntry = this.pendingBlobs.get(localId);
260
+ if (pendingEntry?.uploadTime && pendingEntry?.minTTLInSeconds) {
261
+ const secondsSinceUpload = (Date.now() - pendingEntry.uploadTime) / 1000;
262
+ const expired = pendingEntry.minTTLInSeconds - secondsSinceUpload < 0;
263
+ this.mc.logger.sendTelemetryEvent({
264
+ eventName: "sendBlobAttach",
265
+ entryStatus: pendingEntry.status,
266
+ secondsSinceUpload,
267
+ minTTLInSeconds: pendingEntry.minTTLInSeconds,
268
+ expired,
269
+ });
270
+ if (expired) {
271
+ // we want to avoid submitting ops with broken handles
272
+ this.closeContainer(
273
+ new GenericError(
274
+ "Trying to submit a BlobAttach for expired blob",
275
+ undefined,
276
+ {
277
+ localId,
278
+ blobId,
279
+ entryStatus: pendingEntry.status,
280
+ secondsSinceUpload,
281
+ },
282
+ ),
283
+ );
284
+ }
285
+ }
286
+ return sendBlobAttachOp(localId, blobId);
287
+ };
243
288
  }
244
289
 
245
290
  private get pendingOfflineUploads() {
@@ -290,15 +335,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
290
335
  }
291
336
  }
292
337
 
293
- /**
294
- * For a blobId, returns its path in GC's graph. The node path is of the format `/<BlobManager.basePath>/<blobId>`
295
- * This path must match the path of the blob handle returned by the createBlob API because blobs are marked
296
- * referenced by storing these handles in a referenced DDS.
297
- */
298
- private getBlobGCNodePath(blobId: string) {
299
- return `/${BlobManager.basePath}/${blobId}`;
300
- }
301
-
302
338
  /**
303
339
  * Set of actual storage IDs (i.e., IDs that can be requested from storage). This will be empty if the container is
304
340
  * detached or there are no (non-pending) attachment blobs in the document
@@ -343,7 +379,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
343
379
  }
344
380
 
345
381
  // Let runtime know that the corresponding GC node was requested.
346
- this.blobRequested(this.getBlobGCNodePath(blobId));
382
+ this.blobRequested(getGCNodePathFromBlobId(blobId));
347
383
 
348
384
  return PerformanceEvent.timedExecAsync(
349
385
  this.mc.logger,
@@ -421,11 +457,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
421
457
  */
422
458
  private setRedirection(fromId: string, toId: string | undefined) {
423
459
  this.redirectTable.set(fromId, toId);
424
- // Notify runtime of a reference added if toId is not undefined. It can be undefined when a blob is uploaded in
425
- // detached mode. In this case, the entry will be updated when the blob is updated.
426
- if (toId !== undefined) {
427
- this.addedBlobReference(this.getBlobGCNodePath(fromId), this.getBlobGCNodePath(toId));
428
- }
429
460
  }
430
461
 
431
462
  private deleteAndEmitsIfEmpty(id: string) {
@@ -445,9 +476,8 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
445
476
  0x386 /* Must have pending blob entry for uploaded blob */,
446
477
  );
447
478
  entry.storageId = response.id;
448
- entry.localUploadTime = Date.now();
479
+ entry.uploadTime = Date.now();
449
480
  entry.minTTLInSeconds = response.minTTLInSeconds;
450
- entry.serverUploadTime = this.getCurrentReferenceTimestampMs();
451
481
  if (this.runtime.connected) {
452
482
  if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
453
483
  // Send a blob attach op. This serves two purposes:
@@ -455,7 +485,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
455
485
  // until its storage ID is added to the next summary.
456
486
  // 2. It will create a local ID to storage ID mapping in all clients which is needed to retrieve the
457
487
  // blob from the server via the storage ID.
458
- this.logTimeInfo(entry, "sendBlobAttachResolveTTL");
459
488
  this.sendBlobAttachOp(localId, response.id);
460
489
  if (this.storageIds.has(response.id)) {
461
490
  // The blob is de-duped. Set up a local ID to storage ID mapping and return the blob. Since this is
@@ -529,7 +558,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
529
558
  * is called on reconnection.
530
559
  */
531
560
  if (entry.status !== PendingBlobStatus.OnlinePendingOp) {
532
- this.logTimeInfo(entry, "sendBlobAttachTransitionOfflineTTL");
533
561
  this.sendBlobAttachOp(localId, entry.storageId);
534
562
  }
535
563
 
@@ -551,9 +579,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
551
579
  const { localId, blobId }: { localId?: string; blobId?: string } = metadata;
552
580
  assert(localId !== undefined, 0x50d /* local ID not available on reSubmit */);
553
581
  const pendingEntry = this.pendingBlobs.get(localId);
554
- if (pendingEntry) {
555
- this.logTimeInfo(pendingEntry, "sendBlobAttachResubmitTTL");
556
- }
582
+
557
583
  if (!blobId) {
558
584
  // We submitted this op while offline. The blob should have been uploaded by now.
559
585
  assert(
@@ -566,32 +592,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
566
592
  return this.sendBlobAttachOp(localId, blobId);
567
593
  }
568
594
 
569
- private logTimeInfo(pendingEntry: PendingBlob, eventName: string) {
570
- let timeLapseSinceLocalUpload: number = 0;
571
- let timeLapseSinceServerUpload: number = 0;
572
- let expiredUsingLocalTime;
573
- let expiredUsingServerTime;
574
- if (pendingEntry.localUploadTime) {
575
- timeLapseSinceLocalUpload = (Date.now() - pendingEntry.localUploadTime) / 1000;
576
- expiredUsingLocalTime =
577
- (pendingEntry.minTTLInSeconds ?? 0) - timeLapseSinceLocalUpload < 0 ? true : false;
578
- }
579
- if (pendingEntry.serverUploadTime) {
580
- timeLapseSinceServerUpload = (Date.now() - pendingEntry.serverUploadTime) / 1000;
581
- expiredUsingServerTime =
582
- (pendingEntry.minTTLInSeconds ?? 0) - timeLapseSinceServerUpload < 0 ? true : false;
583
- }
584
- this.mc.logger.sendTelemetryEvent({
585
- eventName,
586
- entryStatus: pendingEntry.status,
587
- timeLapseSinceLocalUpload,
588
- timeLapseSinceServerUpload,
589
- minTTLInSeconds: pendingEntry.minTTLInSeconds,
590
- expiredUsingLocalTime,
591
- expiredUsingServerTime,
592
- });
593
- }
594
-
595
595
  public processBlobAttachOp(message: ISequencedDocumentMessage, local: boolean) {
596
596
  const localId = message.metadata?.localId;
597
597
  const blobId = message.metadata?.blobId;
@@ -678,6 +678,33 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
678
678
  return table;
679
679
  }
680
680
 
681
+ public summarize(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {
682
+ // if storageIds is empty, it means we are detached and have only local IDs, or that there are no blobs attached
683
+ const blobIds =
684
+ this.storageIds.size > 0
685
+ ? Array.from(this.storageIds)
686
+ : Array.from(this.redirectTable.keys());
687
+ const builder = new SummaryTreeBuilder();
688
+ blobIds.forEach((blobId) => {
689
+ builder.addAttachment(blobId);
690
+ });
691
+
692
+ // Any non-identity entries in the table need to be saved in the summary
693
+ if (this.redirectTable.size > blobIds.length) {
694
+ builder.addBlob(
695
+ BlobManager.redirectTableBlobName,
696
+ // filter out identity entries
697
+ JSON.stringify(
698
+ Array.from(this.redirectTable.entries()).filter(
699
+ ([localId, storageId]) => localId !== storageId,
700
+ ),
701
+ ),
702
+ );
703
+ }
704
+
705
+ return builder.getSummaryTree();
706
+ }
707
+
681
708
  /**
682
709
  * Generates data used for garbage collection. Each blob uploaded represents a node in the GC graph as it can be
683
710
  * individually referenced by storing its handle in a referenced DDS. Returns the list of blob ids as GC nodes.
@@ -688,27 +715,90 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
688
715
  const gcData: IGarbageCollectionData = { gcNodes: {} };
689
716
  for (const [localId, storageId] of this.redirectTable) {
690
717
  assert(!!storageId, 0x390 /* Must be attached to get GC data */);
691
- gcData.gcNodes[this.getBlobGCNodePath(localId)] = [this.getBlobGCNodePath(storageId)];
718
+ // Only return local ids as GC nodes because a blob can only be referenced via its local id. The storage
719
+ // id entries have the same key and value, ignore them.
720
+ // The outbound routes are empty because a blob node cannot reference other nodes. It can only be referenced
721
+ // by adding its handle to a referenced DDS.
722
+ if (localId !== storageId) {
723
+ gcData.gcNodes[getGCNodePathFromBlobId(localId)] = [];
724
+ }
692
725
  }
693
726
  return gcData;
694
727
  }
695
728
 
696
729
  /**
697
730
  * This is called to update blobs whose routes are unused. The unused blobs are deleted.
698
- * @param unusedRoutes - The routes of the blob nodes that are unused.
731
+ * @param unusedRoutes - The routes of the blob nodes that are unused. These routes will be based off of local ids.
699
732
  */
700
733
  public updateUnusedRoutes(unusedRoutes: string[]): void {
701
- // The routes or blob node paths are in the same format as returned in getGCData -
702
- // `/<BlobManager.basePath>/<blobId>`.
703
- for (const route of unusedRoutes) {
704
- const pathParts = route.split("/");
705
- assert(
706
- pathParts.length === 3 && pathParts[1] === BlobManager.basePath,
707
- 0x2d5 /* "Invalid blob node id in unused routes." */,
708
- );
709
- const blobId = pathParts[2];
734
+ this.deleteBlobsFromRedirectTable(unusedRoutes);
735
+ }
736
+
737
+ /**
738
+ * Delete attachment blobs that are sweep ready.
739
+ * @param sweepReadyBlobRoutes - The routes of blobs that are sweep ready and should be deleted. These routes will
740
+ * be based off of local ids.
741
+ * @returns - The routes of blobs that were deleted.
742
+ */
743
+ public deleteSweepReadyNodes(sweepReadyBlobRoutes: string[]): string[] {
744
+ // If sweep for attachment blobs is not enabled, return empty list indicating nothing is deleted.
745
+ if (this.mc.config.getBoolean(sweepAttachmentBlobsKey) !== true) {
746
+ return [];
747
+ }
748
+
749
+ this.deleteBlobsFromRedirectTable(sweepReadyBlobRoutes);
750
+ return Array.from(sweepReadyBlobRoutes);
751
+ }
752
+
753
+ /**
754
+ * Delete blobs with the given routes from the redirect table.
755
+ * The routes are GC nodes paths of format -`/<BlobManager.basePath>/<blobId>`. The blob ids are all local ids.
756
+ * Deleting the blobs involves 2 steps:
757
+ * 1. The redirect table entry for the local ids are deleted.
758
+ * 2. If the storage ids corresponding to the deleted local ids are not in-use anymore, the redirect table entries
759
+ * for the storage ids are deleted as well.
760
+ *
761
+ * Note that this does not delete the blobs from storage service immediately. Deleting the blobs from redirect table
762
+ * will remove them the next summary. The service would them delete them some time in the future.
763
+ */
764
+ private deleteBlobsFromRedirectTable(blobRoutes: string[]) {
765
+ if (blobRoutes.length === 0) {
766
+ return;
767
+ }
768
+
769
+ // This tracks the storage ids of local ids that are deleted. After the local ids have been deleted, if any of
770
+ // these storage ids are unused, they will be deleted as well.
771
+ const maybeUnusedStorageIds: Set<string> = new Set();
772
+ for (const route of blobRoutes) {
773
+ const blobId = getBlobIdFromGCNodePath(route);
774
+ if (!this.redirectTable.has(blobId)) {
775
+ this.mc.logger.sendErrorEvent({
776
+ eventName: "DeletedAttachmentBlobNotFound",
777
+ blobId,
778
+ });
779
+ continue;
780
+ }
781
+ const storageId = this.redirectTable.get(blobId);
782
+ assert(!!storageId, 0x5bb /* Must be attached to run GC */);
783
+ maybeUnusedStorageIds.add(storageId);
710
784
  this.redirectTable.delete(blobId);
711
785
  }
786
+
787
+ // Find out storage ids that are in-use and remove them from maybeUnusedStorageIds. A storage id is in-use if
788
+ // the redirect table has a local id -> storage id entry for it.
789
+ for (const [localId, storageId] of this.redirectTable.entries()) {
790
+ assert(!!storageId, 0x5bc /* Must be attached to run GC */);
791
+ // For every storage id, the redirect table has a id -> id entry. These do not make the storage id in-use.
792
+ if (maybeUnusedStorageIds.has(storageId) && localId !== storageId) {
793
+ maybeUnusedStorageIds.delete(storageId);
794
+ }
795
+ }
796
+
797
+ // For unused storage ids, delete their id -> id entries from the redirect table.
798
+ // This way they'll be absent from the next summary, and the service is free to delete them from storage.
799
+ for (const storageId of maybeUnusedStorageIds) {
800
+ this.redirectTable.delete(storageId);
801
+ }
712
802
  }
713
803
 
714
804
  /**
@@ -721,12 +811,8 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
721
811
  // The routes or blob node paths are in the same format as returned in getGCData -
722
812
  // `/<BlobManager.basePath>/<blobId>`.
723
813
  for (const route of tombstonedRoutes) {
724
- const pathParts = route.split("/");
725
- assert(
726
- pathParts.length === 3 && pathParts[1] === BlobManager.basePath,
727
- 0x50f /* Invalid blob node id in tombstoned routes. */,
728
- );
729
- tombstonedBlobsSet.add(pathParts[2]);
814
+ const blobId = getBlobIdFromGCNodePath(route);
815
+ tombstonedBlobsSet.add(blobId);
730
816
  }
731
817
 
732
818
  // Remove blobs from the tombstone list that were tombstoned but aren't anymore as per the tombstoneRoutes.
@@ -754,7 +840,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
754
840
  * 3. "valid" - It has not been deleted or tombstoned.
755
841
  */
756
842
  let state: "valid" | "tombstoned" | "deleted" = "valid";
757
- if (this.isBlobDeleted(this.getBlobGCNodePath(blobId))) {
843
+ if (this.isBlobDeleted(getGCNodePathFromBlobId(blobId))) {
758
844
  state = "deleted";
759
845
  } else if (this.tombstonedBlobs.has(blobId)) {
760
846
  state = "tombstoned";
@@ -785,7 +871,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
785
871
  ? "GC_Tombstone_Blob_Requested"
786
872
  : "GC_Deleted_Blob_Requested",
787
873
  category: shouldFail ? "error" : "generic",
788
- isSummarizerClient: this.runtime.clientDetails.type === summarizerClientType,
874
+ gcTombstoneEnforcementAllowed: this.runtime.gcTombstoneEnforcementAllowed,
789
875
  },
790
876
  [BlobManager.basePath],
791
877
  error,
@@ -795,33 +881,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
795
881
  }
796
882
  }
797
883
 
798
- public summarize(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {
799
- // if storageIds is empty, it means we are detached and have only local IDs, or that there are no blobs attached
800
- const blobIds =
801
- this.storageIds.size > 0
802
- ? Array.from(this.storageIds)
803
- : Array.from(this.redirectTable.keys());
804
- const builder = new SummaryTreeBuilder();
805
- blobIds.forEach((blobId) => {
806
- builder.addAttachment(blobId);
807
- });
808
-
809
- // Any non-identity entries in the table need to be saved in the summary
810
- if (this.redirectTable.size > blobIds.length) {
811
- builder.addBlob(
812
- BlobManager.redirectTableBlobName,
813
- // filter out identity entries
814
- JSON.stringify(
815
- Array.from(this.redirectTable.entries()).filter(
816
- ([localId, storageId]) => localId !== storageId,
817
- ),
818
- ),
819
- );
820
- }
821
-
822
- return builder.getSummaryTree();
823
- }
824
-
825
884
  public setRedirectTable(table: Map<string, string>) {
826
885
  assert(
827
886
  this.runtime.attachState === AttachState.Detached,
@@ -845,8 +904,35 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
845
904
  public getPendingBlobs(): IPendingBlobs {
846
905
  const blobs = {};
847
906
  for (const [key, entry] of this.pendingBlobs) {
848
- blobs[key] = { blob: bufferToString(entry.blob, "base64") };
907
+ blobs[key] = entry.minTTLInSeconds
908
+ ? {
909
+ blob: bufferToString(entry.blob, "base64"),
910
+ uploadTime: entry.uploadTime,
911
+ minTTLInSeconds: entry.minTTLInSeconds,
912
+ }
913
+ : { blob: bufferToString(entry.blob, "base64") };
849
914
  }
850
915
  return blobs;
851
916
  }
852
917
  }
918
+
919
+ /**
920
+ * For a blobId, returns its path in GC's graph. The node path is of the format `/<BlobManager.basePath>/<blobId>`.
921
+ * This path must match the path of the blob handle returned by the createBlob API because blobs are marked
922
+ * referenced by storing these handles in a referenced DDS.
923
+ */
924
+ function getGCNodePathFromBlobId(blobId: string) {
925
+ return `/${BlobManager.basePath}/${blobId}`;
926
+ }
927
+
928
+ /**
929
+ * For a given GC node path, return the blobId. The node path is of the format `/<BlobManager.basePath>/<blobId>`.
930
+ */
931
+ function getBlobIdFromGCNodePath(nodePath: string) {
932
+ const pathParts = nodePath.split("/");
933
+ assert(
934
+ pathParts.length === 3 && pathParts[1] === BlobManager.basePath,
935
+ 0x5bd /* Invalid blob node path */,
936
+ );
937
+ return pathParts[2];
938
+ }