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

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 (465) hide show
  1. package/dist/blobManager.d.ts +24 -11
  2. package/dist/blobManager.d.ts.map +1 -1
  3. package/dist/blobManager.js +112 -55
  4. package/dist/blobManager.js.map +1 -1
  5. package/dist/containerRuntime.d.ts +60 -75
  6. package/dist/containerRuntime.d.ts.map +1 -1
  7. package/dist/containerRuntime.js +295 -256
  8. package/dist/containerRuntime.js.map +1 -1
  9. package/dist/dataStoreContext.d.ts +39 -13
  10. package/dist/dataStoreContext.d.ts.map +1 -1
  11. package/dist/dataStoreContext.js +112 -49
  12. package/dist/dataStoreContext.js.map +1 -1
  13. package/dist/dataStores.d.ts +28 -4
  14. package/dist/dataStores.d.ts.map +1 -1
  15. package/dist/dataStores.js +107 -41
  16. package/dist/dataStores.js.map +1 -1
  17. package/dist/deltaManagerSummarizerProxy.d.ts +19 -0
  18. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -0
  19. package/dist/deltaManagerSummarizerProxy.js +40 -0
  20. package/dist/deltaManagerSummarizerProxy.js.map +1 -0
  21. package/dist/gc/garbageCollection.d.ts +204 -0
  22. package/dist/gc/garbageCollection.d.ts.map +1 -0
  23. package/dist/{garbageCollection.js → gc/garbageCollection.js} +190 -554
  24. package/dist/gc/garbageCollection.js.map +1 -0
  25. package/dist/gc/gcConfigs.d.ts +22 -0
  26. package/dist/gc/gcConfigs.d.ts.map +1 -0
  27. package/dist/gc/gcConfigs.js +143 -0
  28. package/dist/gc/gcConfigs.js.map +1 -0
  29. package/dist/gc/gcDefinitions.d.ts +320 -0
  30. package/dist/gc/gcDefinitions.d.ts.map +1 -0
  31. package/dist/gc/gcDefinitions.js +81 -0
  32. package/dist/gc/gcDefinitions.js.map +1 -0
  33. package/dist/gc/gcHelpers.d.ts +86 -0
  34. package/dist/gc/gcHelpers.d.ts.map +1 -0
  35. package/dist/gc/gcHelpers.js +268 -0
  36. package/dist/gc/gcHelpers.js.map +1 -0
  37. package/dist/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
  38. package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
  39. package/dist/gc/gcReferenceGraphAlgorithm.js +49 -0
  40. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -0
  41. package/dist/gc/gcSummaryDefinitions.d.ts +52 -0
  42. package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -0
  43. package/dist/gc/gcSummaryDefinitions.js +7 -0
  44. package/dist/gc/gcSummaryDefinitions.js.map +1 -0
  45. package/dist/gc/gcSummaryStateTracker.d.ts +93 -0
  46. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
  47. package/dist/gc/gcSummaryStateTracker.js +239 -0
  48. package/dist/gc/gcSummaryStateTracker.js.map +1 -0
  49. package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  50. package/dist/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +2 -2
  51. package/dist/gc/gcSweepReadyUsageDetection.js.map +1 -0
  52. package/dist/gc/gcUnreferencedStateTracker.d.ts +34 -0
  53. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  54. package/dist/gc/gcUnreferencedStateTracker.js +94 -0
  55. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -0
  56. package/dist/gc/index.d.ts +13 -0
  57. package/dist/gc/index.d.ts.map +1 -0
  58. package/dist/gc/index.js +50 -0
  59. package/dist/gc/index.js.map +1 -0
  60. package/dist/index.d.ts +3 -7
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +5 -9
  63. package/dist/index.js.map +1 -1
  64. package/dist/opLifecycle/batchManager.d.ts +11 -13
  65. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  66. package/dist/opLifecycle/batchManager.js +26 -38
  67. package/dist/opLifecycle/batchManager.js.map +1 -1
  68. package/dist/opLifecycle/definitions.d.ts +4 -0
  69. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  70. package/dist/opLifecycle/definitions.js.map +1 -1
  71. package/dist/opLifecycle/index.d.ts +1 -1
  72. package/dist/opLifecycle/index.d.ts.map +1 -1
  73. package/dist/opLifecycle/index.js +2 -1
  74. package/dist/opLifecycle/index.js.map +1 -1
  75. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  76. package/dist/opLifecycle/opCompressor.js +25 -10
  77. package/dist/opLifecycle/opCompressor.js.map +1 -1
  78. package/dist/opLifecycle/opDecompressor.d.ts +4 -0
  79. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  80. package/dist/opLifecycle/opDecompressor.js +42 -4
  81. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  82. package/dist/opLifecycle/opSplitter.d.ts +15 -3
  83. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  84. package/dist/opLifecycle/opSplitter.js +35 -10
  85. package/dist/opLifecycle/opSplitter.js.map +1 -1
  86. package/dist/opLifecycle/outbox.d.ts +19 -3
  87. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  88. package/dist/opLifecycle/outbox.js +88 -49
  89. package/dist/opLifecycle/outbox.js.map +1 -1
  90. package/dist/packageVersion.d.ts +1 -1
  91. package/dist/packageVersion.js +1 -1
  92. package/dist/packageVersion.js.map +1 -1
  93. package/dist/pendingStateManager.d.ts +3 -3
  94. package/dist/pendingStateManager.d.ts.map +1 -1
  95. package/dist/pendingStateManager.js +20 -21
  96. package/dist/pendingStateManager.js.map +1 -1
  97. package/dist/storageServiceWithAttachBlobs.d.ts +17 -0
  98. package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -0
  99. package/dist/storageServiceWithAttachBlobs.js +32 -0
  100. package/dist/storageServiceWithAttachBlobs.js.map +1 -0
  101. package/dist/summary/index.d.ts +17 -0
  102. package/dist/summary/index.d.ts.map +1 -0
  103. package/dist/summary/index.js +46 -0
  104. package/dist/summary/index.js.map +1 -0
  105. package/dist/summary/orderedClientElection.d.ts.map +1 -0
  106. package/dist/summary/orderedClientElection.js.map +1 -0
  107. package/dist/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +3 -2
  108. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  109. package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +5 -4
  110. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -0
  111. package/{lib → dist/summary}/runningSummarizer.d.ts +19 -18
  112. package/dist/summary/runningSummarizer.d.ts.map +1 -0
  113. package/dist/{runningSummarizer.js → summary/runningSummarizer.js} +158 -56
  114. package/dist/summary/runningSummarizer.js.map +1 -0
  115. package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +4 -9
  116. package/dist/summary/summarizer.d.ts.map +1 -0
  117. package/dist/{summarizer.js → summary/summarizer.js} +9 -74
  118. package/dist/summary/summarizer.js.map +1 -0
  119. package/dist/summary/summarizerClientElection.d.ts.map +1 -0
  120. package/dist/summary/summarizerClientElection.js.map +1 -0
  121. package/{lib → dist/summary}/summarizerHeuristics.d.ts +1 -1
  122. package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
  123. package/dist/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +3 -3
  124. package/dist/summary/summarizerHeuristics.js.map +1 -0
  125. package/dist/summary/summarizerNode/index.d.ts +8 -0
  126. package/dist/summary/summarizerNode/index.d.ts.map +1 -0
  127. package/dist/summary/summarizerNode/index.js +12 -0
  128. package/dist/summary/summarizerNode/index.js.map +1 -0
  129. package/dist/summary/summarizerNode/summarizerNode.d.ts +149 -0
  130. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
  131. package/dist/summary/summarizerNode/summarizerNode.js +531 -0
  132. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -0
  133. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +125 -0
  134. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
  135. package/dist/summary/summarizerNode/summarizerNodeUtils.js +132 -0
  136. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
  137. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +22 -0
  138. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
  139. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +423 -0
  140. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
  141. package/{lib → dist/summary}/summarizerTypes.d.ts +7 -17
  142. package/dist/summary/summarizerTypes.d.ts.map +1 -0
  143. package/dist/{summarizerTypes.js → summary/summarizerTypes.js} +0 -5
  144. package/dist/summary/summarizerTypes.js.map +1 -0
  145. package/dist/summary/summaryCollection.d.ts.map +1 -0
  146. package/dist/summary/summaryCollection.js.map +1 -0
  147. package/{lib → dist/summary}/summaryFormat.d.ts +3 -21
  148. package/dist/summary/summaryFormat.d.ts.map +1 -0
  149. package/dist/{summaryFormat.js → summary/summaryFormat.js} +1 -10
  150. package/dist/summary/summaryFormat.js.map +1 -0
  151. package/dist/summary/summaryGenerator.d.ts.map +1 -0
  152. package/dist/{summaryGenerator.js → summary/summaryGenerator.js} +4 -4
  153. package/dist/summary/summaryGenerator.js.map +1 -0
  154. package/dist/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
  155. package/dist/summary/summaryManager.d.ts.map +1 -0
  156. package/dist/summary/summaryManager.js.map +1 -0
  157. package/lib/blobManager.d.ts +24 -11
  158. package/lib/blobManager.d.ts.map +1 -1
  159. package/lib/blobManager.js +109 -52
  160. package/lib/blobManager.js.map +1 -1
  161. package/lib/containerRuntime.d.ts +60 -75
  162. package/lib/containerRuntime.d.ts.map +1 -1
  163. package/lib/containerRuntime.js +267 -228
  164. package/lib/containerRuntime.js.map +1 -1
  165. package/lib/dataStoreContext.d.ts +39 -13
  166. package/lib/dataStoreContext.d.ts.map +1 -1
  167. package/lib/dataStoreContext.js +101 -38
  168. package/lib/dataStoreContext.js.map +1 -1
  169. package/lib/dataStores.d.ts +28 -4
  170. package/lib/dataStores.d.ts.map +1 -1
  171. package/lib/dataStores.js +100 -34
  172. package/lib/dataStores.js.map +1 -1
  173. package/lib/deltaManagerSummarizerProxy.d.ts +19 -0
  174. package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -0
  175. package/lib/deltaManagerSummarizerProxy.js +36 -0
  176. package/lib/deltaManagerSummarizerProxy.js.map +1 -0
  177. package/lib/gc/garbageCollection.d.ts +204 -0
  178. package/lib/gc/garbageCollection.d.ts.map +1 -0
  179. package/lib/{garbageCollection.js → gc/garbageCollection.js} +172 -535
  180. package/lib/gc/garbageCollection.js.map +1 -0
  181. package/lib/gc/gcConfigs.d.ts +22 -0
  182. package/lib/gc/gcConfigs.d.ts.map +1 -0
  183. package/lib/gc/gcConfigs.js +139 -0
  184. package/lib/gc/gcConfigs.js.map +1 -0
  185. package/lib/gc/gcDefinitions.d.ts +320 -0
  186. package/lib/gc/gcDefinitions.d.ts.map +1 -0
  187. package/lib/gc/gcDefinitions.js +78 -0
  188. package/lib/gc/gcDefinitions.js.map +1 -0
  189. package/lib/gc/gcHelpers.d.ts +86 -0
  190. package/lib/gc/gcHelpers.d.ts.map +1 -0
  191. package/lib/gc/gcHelpers.js +254 -0
  192. package/lib/gc/gcHelpers.js.map +1 -0
  193. package/lib/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
  194. package/lib/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
  195. package/lib/gc/gcReferenceGraphAlgorithm.js +45 -0
  196. package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -0
  197. package/lib/gc/gcSummaryDefinitions.d.ts +52 -0
  198. package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -0
  199. package/lib/gc/gcSummaryDefinitions.js +6 -0
  200. package/lib/gc/gcSummaryDefinitions.js.map +1 -0
  201. package/lib/gc/gcSummaryStateTracker.d.ts +93 -0
  202. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
  203. package/lib/gc/gcSummaryStateTracker.js +235 -0
  204. package/lib/gc/gcSummaryStateTracker.js.map +1 -0
  205. package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  206. package/lib/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +1 -1
  207. package/lib/gc/gcSweepReadyUsageDetection.js.map +1 -0
  208. package/lib/gc/gcUnreferencedStateTracker.d.ts +34 -0
  209. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  210. package/lib/gc/gcUnreferencedStateTracker.js +90 -0
  211. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -0
  212. package/lib/gc/index.d.ts +13 -0
  213. package/lib/gc/index.d.ts.map +1 -0
  214. package/lib/gc/index.js +12 -0
  215. package/lib/gc/index.js.map +1 -0
  216. package/lib/index.d.ts +3 -7
  217. package/lib/index.d.ts.map +1 -1
  218. package/lib/index.js +1 -4
  219. package/lib/index.js.map +1 -1
  220. package/lib/opLifecycle/batchManager.d.ts +11 -13
  221. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  222. package/lib/opLifecycle/batchManager.js +24 -37
  223. package/lib/opLifecycle/batchManager.js.map +1 -1
  224. package/lib/opLifecycle/definitions.d.ts +4 -0
  225. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  226. package/lib/opLifecycle/definitions.js.map +1 -1
  227. package/lib/opLifecycle/index.d.ts +1 -1
  228. package/lib/opLifecycle/index.d.ts.map +1 -1
  229. package/lib/opLifecycle/index.js +1 -1
  230. package/lib/opLifecycle/index.js.map +1 -1
  231. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  232. package/lib/opLifecycle/opCompressor.js +26 -11
  233. package/lib/opLifecycle/opCompressor.js.map +1 -1
  234. package/lib/opLifecycle/opDecompressor.d.ts +4 -0
  235. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  236. package/lib/opLifecycle/opDecompressor.js +42 -4
  237. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  238. package/lib/opLifecycle/opSplitter.d.ts +15 -3
  239. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  240. package/lib/opLifecycle/opSplitter.js +35 -10
  241. package/lib/opLifecycle/opSplitter.js.map +1 -1
  242. package/lib/opLifecycle/outbox.d.ts +19 -3
  243. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  244. package/lib/opLifecycle/outbox.js +90 -51
  245. package/lib/opLifecycle/outbox.js.map +1 -1
  246. package/lib/packageVersion.d.ts +1 -1
  247. package/lib/packageVersion.js +1 -1
  248. package/lib/packageVersion.js.map +1 -1
  249. package/lib/pendingStateManager.d.ts +3 -3
  250. package/lib/pendingStateManager.d.ts.map +1 -1
  251. package/lib/pendingStateManager.js +20 -21
  252. package/lib/pendingStateManager.js.map +1 -1
  253. package/lib/storageServiceWithAttachBlobs.d.ts +17 -0
  254. package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -0
  255. package/lib/storageServiceWithAttachBlobs.js +28 -0
  256. package/lib/storageServiceWithAttachBlobs.js.map +1 -0
  257. package/lib/summary/index.d.ts +17 -0
  258. package/lib/summary/index.d.ts.map +1 -0
  259. package/lib/summary/index.js +15 -0
  260. package/lib/summary/index.js.map +1 -0
  261. package/lib/summary/orderedClientElection.d.ts.map +1 -0
  262. package/lib/summary/orderedClientElection.js.map +1 -0
  263. package/lib/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +3 -2
  264. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  265. package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +5 -4
  266. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
  267. package/{dist → lib/summary}/runningSummarizer.d.ts +19 -18
  268. package/lib/summary/runningSummarizer.d.ts.map +1 -0
  269. package/lib/{runningSummarizer.js → summary/runningSummarizer.js} +159 -57
  270. package/lib/summary/runningSummarizer.js.map +1 -0
  271. package/lib/{summarizer.d.ts → summary/summarizer.d.ts} +4 -9
  272. package/lib/summary/summarizer.d.ts.map +1 -0
  273. package/lib/{summarizer.js → summary/summarizer.js} +11 -76
  274. package/lib/summary/summarizer.js.map +1 -0
  275. package/lib/summary/summarizerClientElection.d.ts.map +1 -0
  276. package/lib/summary/summarizerClientElection.js.map +1 -0
  277. package/{dist → lib/summary}/summarizerHeuristics.d.ts +1 -1
  278. package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
  279. package/lib/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +3 -3
  280. package/lib/summary/summarizerHeuristics.js.map +1 -0
  281. package/lib/summary/summarizerNode/index.d.ts +8 -0
  282. package/lib/summary/summarizerNode/index.d.ts.map +1 -0
  283. package/lib/summary/summarizerNode/index.js +7 -0
  284. package/lib/summary/summarizerNode/index.js.map +1 -0
  285. package/lib/summary/summarizerNode/summarizerNode.d.ts +149 -0
  286. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
  287. package/lib/summary/summarizerNode/summarizerNode.js +526 -0
  288. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -0
  289. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +125 -0
  290. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
  291. package/lib/summary/summarizerNode/summarizerNodeUtils.js +125 -0
  292. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
  293. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +22 -0
  294. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
  295. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +419 -0
  296. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
  297. package/{dist → lib/summary}/summarizerTypes.d.ts +7 -17
  298. package/lib/summary/summarizerTypes.d.ts.map +1 -0
  299. package/lib/summary/summarizerTypes.js +6 -0
  300. package/{dist → lib/summary}/summarizerTypes.js.map +1 -1
  301. package/lib/summary/summaryCollection.d.ts.map +1 -0
  302. package/lib/summary/summaryCollection.js.map +1 -0
  303. package/{dist → lib/summary}/summaryFormat.d.ts +3 -21
  304. package/lib/summary/summaryFormat.d.ts.map +1 -0
  305. package/lib/{summaryFormat.js → summary/summaryFormat.js} +0 -8
  306. package/lib/summary/summaryFormat.js.map +1 -0
  307. package/lib/summary/summaryGenerator.d.ts.map +1 -0
  308. package/lib/{summaryGenerator.js → summary/summaryGenerator.js} +4 -4
  309. package/lib/summary/summaryGenerator.js.map +1 -0
  310. package/lib/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
  311. package/lib/summary/summaryManager.d.ts.map +1 -0
  312. package/lib/summary/summaryManager.js.map +1 -0
  313. package/package.json +63 -60
  314. package/src/blobManager.ts +132 -69
  315. package/src/containerRuntime.ts +421 -382
  316. package/src/dataStoreContext.ts +140 -49
  317. package/src/dataStores.ts +139 -41
  318. package/src/deltaManagerSummarizerProxy.ts +46 -0
  319. package/{garbageCollection.md → src/gc/garbageCollection.md} +2 -2
  320. package/src/{garbageCollection.ts → gc/garbageCollection.ts} +245 -890
  321. package/src/gc/gcConfigs.ts +193 -0
  322. package/src/gc/gcDefinitions.ts +387 -0
  323. package/src/gc/gcHelpers.ts +332 -0
  324. package/src/gc/gcReferenceGraphAlgorithm.ts +52 -0
  325. package/src/gc/gcSummaryDefinitions.ts +54 -0
  326. package/src/gc/gcSummaryStateTracker.ts +329 -0
  327. package/src/{gcSweepReadyUsageDetection.ts → gc/gcSweepReadyUsageDetection.ts} +1 -1
  328. package/src/gc/gcUnreferencedStateTracker.ts +114 -0
  329. package/src/gc/index.ts +65 -0
  330. package/src/index.ts +10 -22
  331. package/src/opLifecycle/README.md +157 -0
  332. package/src/opLifecycle/batchManager.ts +26 -55
  333. package/src/opLifecycle/definitions.ts +4 -0
  334. package/src/opLifecycle/index.ts +1 -1
  335. package/src/opLifecycle/opCompressor.ts +32 -12
  336. package/src/opLifecycle/opDecompressor.ts +49 -5
  337. package/src/opLifecycle/opSplitter.ts +55 -12
  338. package/src/opLifecycle/outbox.ts +120 -60
  339. package/src/packageVersion.ts +1 -1
  340. package/src/pendingStateManager.ts +34 -27
  341. package/src/storageServiceWithAttachBlobs.ts +38 -0
  342. package/src/summary/index.ts +105 -0
  343. package/src/{runWhileConnectedCoordinator.ts → summary/runWhileConnectedCoordinator.ts} +7 -7
  344. package/src/{runningSummarizer.ts → summary/runningSummarizer.ts} +279 -139
  345. package/src/{summarizer.ts → summary/summarizer.ts} +12 -97
  346. package/src/{summarizerHeuristics.ts → summary/summarizerHeuristics.ts} +9 -4
  347. package/src/summary/summarizerNode/index.ts +12 -0
  348. package/src/summary/summarizerNode/summarizerNode.ts +766 -0
  349. package/src/summary/summarizerNode/summarizerNodeUtils.ts +214 -0
  350. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +644 -0
  351. package/src/{summarizerTypes.ts → summary/summarizerTypes.ts} +8 -22
  352. package/src/{summaryFormat.ts → summary/summaryFormat.ts} +3 -29
  353. package/src/{summaryGenerator.ts → summary/summaryGenerator.ts} +12 -11
  354. package/src/{summaryManager.ts → summary/summaryManager.ts} +1 -1
  355. package/dist/garbageCollection.d.ts +0 -411
  356. package/dist/garbageCollection.d.ts.map +0 -1
  357. package/dist/garbageCollection.js.map +0 -1
  358. package/dist/garbageCollectionConstants.d.ts +0 -23
  359. package/dist/garbageCollectionConstants.d.ts.map +0 -1
  360. package/dist/garbageCollectionConstants.js +0 -36
  361. package/dist/garbageCollectionConstants.js.map +0 -1
  362. package/dist/garbageCollectionHelpers.d.ts +0 -15
  363. package/dist/garbageCollectionHelpers.d.ts.map +0 -1
  364. package/dist/garbageCollectionHelpers.js +0 -27
  365. package/dist/garbageCollectionHelpers.js.map +0 -1
  366. package/dist/gcSweepReadyUsageDetection.d.ts.map +0 -1
  367. package/dist/gcSweepReadyUsageDetection.js.map +0 -1
  368. package/dist/orderedClientElection.d.ts.map +0 -1
  369. package/dist/orderedClientElection.js.map +0 -1
  370. package/dist/runWhileConnectedCoordinator.d.ts.map +0 -1
  371. package/dist/runWhileConnectedCoordinator.js.map +0 -1
  372. package/dist/runningSummarizer.d.ts.map +0 -1
  373. package/dist/runningSummarizer.js.map +0 -1
  374. package/dist/serializedSnapshotStorage.d.ts +0 -58
  375. package/dist/serializedSnapshotStorage.d.ts.map +0 -1
  376. package/dist/serializedSnapshotStorage.js +0 -110
  377. package/dist/serializedSnapshotStorage.js.map +0 -1
  378. package/dist/summarizer.d.ts.map +0 -1
  379. package/dist/summarizer.js.map +0 -1
  380. package/dist/summarizerClientElection.d.ts.map +0 -1
  381. package/dist/summarizerClientElection.js.map +0 -1
  382. package/dist/summarizerHandle.d.ts +0 -12
  383. package/dist/summarizerHandle.d.ts.map +0 -1
  384. package/dist/summarizerHandle.js +0 -22
  385. package/dist/summarizerHandle.js.map +0 -1
  386. package/dist/summarizerHeuristics.d.ts.map +0 -1
  387. package/dist/summarizerHeuristics.js.map +0 -1
  388. package/dist/summarizerTypes.d.ts.map +0 -1
  389. package/dist/summaryCollection.d.ts.map +0 -1
  390. package/dist/summaryCollection.js.map +0 -1
  391. package/dist/summaryFormat.d.ts.map +0 -1
  392. package/dist/summaryFormat.js.map +0 -1
  393. package/dist/summaryGenerator.d.ts.map +0 -1
  394. package/dist/summaryGenerator.js.map +0 -1
  395. package/dist/summaryManager.d.ts.map +0 -1
  396. package/dist/summaryManager.js.map +0 -1
  397. package/lib/garbageCollection.d.ts +0 -411
  398. package/lib/garbageCollection.d.ts.map +0 -1
  399. package/lib/garbageCollection.js.map +0 -1
  400. package/lib/garbageCollectionConstants.d.ts +0 -23
  401. package/lib/garbageCollectionConstants.d.ts.map +0 -1
  402. package/lib/garbageCollectionConstants.js +0 -33
  403. package/lib/garbageCollectionConstants.js.map +0 -1
  404. package/lib/garbageCollectionHelpers.d.ts +0 -15
  405. package/lib/garbageCollectionHelpers.d.ts.map +0 -1
  406. package/lib/garbageCollectionHelpers.js +0 -23
  407. package/lib/garbageCollectionHelpers.js.map +0 -1
  408. package/lib/gcSweepReadyUsageDetection.d.ts.map +0 -1
  409. package/lib/gcSweepReadyUsageDetection.js.map +0 -1
  410. package/lib/orderedClientElection.d.ts.map +0 -1
  411. package/lib/orderedClientElection.js.map +0 -1
  412. package/lib/runWhileConnectedCoordinator.d.ts.map +0 -1
  413. package/lib/runWhileConnectedCoordinator.js.map +0 -1
  414. package/lib/runningSummarizer.d.ts.map +0 -1
  415. package/lib/runningSummarizer.js.map +0 -1
  416. package/lib/serializedSnapshotStorage.d.ts +0 -58
  417. package/lib/serializedSnapshotStorage.d.ts.map +0 -1
  418. package/lib/serializedSnapshotStorage.js +0 -106
  419. package/lib/serializedSnapshotStorage.js.map +0 -1
  420. package/lib/summarizer.d.ts.map +0 -1
  421. package/lib/summarizer.js.map +0 -1
  422. package/lib/summarizerClientElection.d.ts.map +0 -1
  423. package/lib/summarizerClientElection.js.map +0 -1
  424. package/lib/summarizerHandle.d.ts +0 -12
  425. package/lib/summarizerHandle.d.ts.map +0 -1
  426. package/lib/summarizerHandle.js +0 -18
  427. package/lib/summarizerHandle.js.map +0 -1
  428. package/lib/summarizerHeuristics.d.ts.map +0 -1
  429. package/lib/summarizerHeuristics.js.map +0 -1
  430. package/lib/summarizerTypes.d.ts.map +0 -1
  431. package/lib/summarizerTypes.js +0 -9
  432. package/lib/summarizerTypes.js.map +0 -1
  433. package/lib/summaryCollection.d.ts.map +0 -1
  434. package/lib/summaryCollection.js.map +0 -1
  435. package/lib/summaryFormat.d.ts.map +0 -1
  436. package/lib/summaryFormat.js.map +0 -1
  437. package/lib/summaryGenerator.d.ts.map +0 -1
  438. package/lib/summaryGenerator.js.map +0 -1
  439. package/lib/summaryManager.d.ts.map +0 -1
  440. package/lib/summaryManager.js.map +0 -1
  441. package/src/garbageCollectionConstants.ts +0 -38
  442. package/src/garbageCollectionHelpers.ts +0 -37
  443. package/src/serializedSnapshotStorage.ts +0 -151
  444. package/src/summarizerHandle.ts +0 -23
  445. /package/dist/{gcSweepReadyUsageDetection.d.ts → gc/gcSweepReadyUsageDetection.d.ts} +0 -0
  446. /package/dist/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  447. /package/dist/{orderedClientElection.js → summary/orderedClientElection.js} +0 -0
  448. /package/dist/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
  449. /package/dist/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
  450. /package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  451. /package/dist/{summaryCollection.js → summary/summaryCollection.js} +0 -0
  452. /package/dist/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
  453. /package/dist/{summaryManager.js → summary/summaryManager.js} +0 -0
  454. /package/lib/{gcSweepReadyUsageDetection.d.ts → gc/gcSweepReadyUsageDetection.d.ts} +0 -0
  455. /package/lib/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  456. /package/lib/{orderedClientElection.js → summary/orderedClientElection.js} +0 -0
  457. /package/lib/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
  458. /package/lib/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
  459. /package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  460. /package/lib/{summaryCollection.js → summary/summaryCollection.js} +0 -0
  461. /package/lib/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
  462. /package/lib/{summaryManager.js → summary/summaryManager.js} +0 -0
  463. /package/src/{orderedClientElection.ts → summary/orderedClientElection.ts} +0 -0
  464. /package/src/{summarizerClientElection.ts → summary/summarizerClientElection.ts} +0 -0
  465. /package/src/{summaryCollection.ts → summary/summaryCollection.ts} +0 -0
@@ -10,29 +10,22 @@ const container_utils_1 = require("@fluidframework/container-utils");
10
10
  const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
11
11
  const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
12
12
  const runtime_utils_1 = require("@fluidframework/runtime-utils");
13
- const garbage_collector_1 = require("@fluidframework/garbage-collector");
14
13
  const uuid_1 = require("uuid");
15
14
  const containerHandleContext_1 = require("./containerHandleContext");
16
15
  const dataStoreRegistry_1 = require("./dataStoreRegistry");
17
- const summarizer_1 = require("./summarizer");
18
- const summaryManager_1 = require("./summaryManager");
19
16
  const connectionTelemetry_1 = require("./connectionTelemetry");
20
17
  const pendingStateManager_1 = require("./pendingStateManager");
21
18
  const packageVersion_1 = require("./packageVersion");
22
19
  const blobManager_1 = require("./blobManager");
23
20
  const dataStores_1 = require("./dataStores");
24
- const summaryFormat_1 = require("./summaryFormat");
25
- const summaryCollection_1 = require("./summaryCollection");
26
- const orderedClientElection_1 = require("./orderedClientElection");
27
- const summarizerClientElection_1 = require("./summarizerClientElection");
21
+ const summary_1 = require("./summary");
28
22
  const throttler_1 = require("./throttler");
29
- const runWhileConnectedCoordinator_1 = require("./runWhileConnectedCoordinator");
30
- const garbageCollection_1 = require("./garbageCollection");
23
+ const gc_1 = require("./gc");
31
24
  const dataStore_1 = require("./dataStore");
32
25
  const batchTracker_1 = require("./batchTracker");
33
- const serializedSnapshotStorage_1 = require("./serializedSnapshotStorage");
34
26
  const scheduleManager_1 = require("./scheduleManager");
35
27
  const opLifecycle_1 = require("./opLifecycle");
28
+ const deltaManagerSummarizerProxy_1 = require("./deltaManagerSummarizerProxy");
36
29
  var ContainerMessageType;
37
30
  (function (ContainerMessageType) {
38
31
  // An op to be delivered to store
@@ -69,11 +62,6 @@ var RuntimeHeaders;
69
62
  (function (RuntimeHeaders) {
70
63
  /** True to wait for a data store to be created and loaded before returning it. */
71
64
  RuntimeHeaders["wait"] = "wait";
72
- /**
73
- * True if the request is from an external app. Used for GC to handle scenarios where a data store
74
- * is deleted and requested via an external app.
75
- */
76
- RuntimeHeaders["externalRequest"] = "externalRequest";
77
65
  /** True if the request is coming from an IFluidHandle. */
78
66
  RuntimeHeaders["viaHandle"] = "viaHandle";
79
67
  })(RuntimeHeaders = exports.RuntimeHeaders || (exports.RuntimeHeaders = {}));
@@ -84,7 +72,6 @@ exports.TombstoneResponseHeaderKey = "isTombstoned";
84
72
  /** Default values for Runtime Headers */
85
73
  exports.defaultRuntimeHeaderData = {
86
74
  wait: true,
87
- externalRequest: false,
88
75
  viaHandle: false,
89
76
  allowTombstone: false,
90
77
  };
@@ -101,7 +88,13 @@ const defaultFlushMode = runtime_definitions_1.FlushMode.TurnBased;
101
88
  // We can't estimate it fully, as we
102
89
  // - do not know what properties relay service will add
103
90
  // - we do not stringify final op, thus we do not know how much escaping will be added.
104
- const defaultMaxBatchSizeInBytes = 950 * 1024;
91
+ const defaultMaxBatchSizeInBytes = 700 * 1024;
92
+ const defaultCompressionConfig = {
93
+ // Batches with content size exceeding this value will be compressed
94
+ minimumBatchSizeInBytes: 614400,
95
+ compressionAlgorithm: CompressionAlgorithms.lz4,
96
+ };
97
+ const defaultChunkSizeInBytes = 204800;
105
98
  /**
106
99
  * @deprecated - use ContainerRuntimeMessage instead
107
100
  */
@@ -150,8 +143,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
150
143
  /**
151
144
  * @internal
152
145
  */
153
- constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, requestHandler, summaryConfiguration) {
154
- var _a, _b, _c, _d, _e, _f;
146
+ constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, requestHandler, summaryConfiguration, initializeEntryPoint) {
147
+ var _a, _b, _c, _d, _e, _f, _g, _h;
155
148
  if (summaryConfiguration === void 0) { summaryConfiguration = Object.assign(Object.assign({}, exports.DefaultSummaryConfiguration), (_a = runtimeOptions.summaryOptions) === null || _a === void 0 ? void 0 : _a.summaryConfigOverrides); }
156
149
  super();
157
150
  this.context = context;
@@ -164,8 +157,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
164
157
  this.summaryConfiguration = summaryConfiguration;
165
158
  this.defaultMaxConsecutiveReconnects = 7;
166
159
  this._orderSequentiallyCalls = 0;
167
- this.flushMicroTaskExists = false;
168
- this.savedOps = [];
160
+ this.flushTaskExists = false;
169
161
  this.consecutiveReconnects = 0;
170
162
  this.ensureNoDataModelChangesCalls = 0;
171
163
  /**
@@ -185,7 +177,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
185
177
  trackingSignalSequenceNumber: undefined,
186
178
  };
187
179
  this.summarizeOnDemand = (...args) => {
188
- if (this.clientDetails.type === summarizerClientElection_1.summarizerClientType) {
180
+ if (this.clientDetails.type === summary_1.summarizerClientType) {
189
181
  return this.summarizer.summarizeOnDemand(...args);
190
182
  }
191
183
  else if (this.summaryManager !== undefined) {
@@ -199,7 +191,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
199
191
  }
200
192
  };
201
193
  this.enqueueSummarize = (...args) => {
202
- if (this.clientDetails.type === summarizerClientElection_1.summarizerClientType) {
194
+ if (this.clientDetails.type === summary_1.summarizerClientType) {
203
195
  return this.summarizer.enqueueSummarize(...args);
204
196
  }
205
197
  else if (this.summaryManager !== undefined) {
@@ -212,6 +204,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
212
204
  throw new container_utils_1.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
213
205
  }
214
206
  };
207
+ this.innerDeltaManager = context.deltaManager;
208
+ this.deltaManager = new deltaManagerSummarizerProxy_1.DeltaManagerSummarizerProxy(context.deltaManager);
215
209
  let loadSummaryNumber;
216
210
  // Get the container creation metadata. For new container, we initialize these. For existing containers,
217
211
  // get the values from the metadata blob.
@@ -234,29 +228,46 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
234
228
  this.nextSummaryNumber = loadSummaryNumber + 1;
235
229
  this.messageAtLastSummary = metadata === null || metadata === void 0 ? void 0 : metadata.message;
236
230
  this._connected = this.context.connected;
231
+ this.gcTombstoneEnforcementAllowed = (0, gc_1.shouldAllowGcTombstoneEnforcement)((_c = metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix) === null || _c === void 0 ? void 0 : _c.tombstoneGeneration /* persisted */, this.runtimeOptions.gcOptions[gc_1.gcTombstoneGenerationOptionName] /* current */);
237
232
  this.mc = (0, telemetry_utils_1.loggerToMonitoringContext)(telemetry_utils_1.ChildLogger.create(this.logger, "ContainerRuntime"));
238
- const opSplitter = new opLifecycle_1.OpSplitter(chunks, this.context.submitBatchFn, this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompressionChunking") === true
239
- ? Number.POSITIVE_INFINITY
240
- : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
241
- this.remoteMessageProcessor = new opLifecycle_1.RemoteMessageProcessor(opSplitter, new opLifecycle_1.OpDecompressor());
233
+ this.mc.logger.sendTelemetryEvent({
234
+ eventName: "GCFeatureMatrix",
235
+ metadataValue: JSON.stringify(metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix),
236
+ inputs: JSON.stringify({
237
+ gcOptions_gcTombstoneGeneration: this.runtimeOptions.gcOptions[gc_1.gcTombstoneGenerationOptionName],
238
+ }),
239
+ });
240
+ this.telemetryDocumentId = (_d = metadata === null || metadata === void 0 ? void 0 : metadata.telemetryDocumentId) !== null && _d !== void 0 ? _d : (0, uuid_1.v4)();
241
+ this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
242
+ const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionChunkingDisabled");
243
+ const opSplitter = new opLifecycle_1.OpSplitter(chunks, this.context.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
244
+ this.remoteMessageProcessor = new opLifecycle_1.RemoteMessageProcessor(opSplitter, new opLifecycle_1.OpDecompressor(this.mc.logger));
242
245
  this.handleContext = new containerHandleContext_1.ContainerFluidHandleContext("", this);
243
246
  if (this.summaryConfiguration.state === "enabled") {
244
247
  this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
245
248
  }
249
+ const disableOpReentryCheck = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableOpReentryCheck");
246
250
  this.enableOpReentryCheck =
247
251
  runtimeOptions.enableOpReentryCheck === true &&
248
252
  // Allow for a break-glass config to override the options
249
- this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableOpReentryCheck") !== true;
253
+ disableOpReentryCheck !== true;
250
254
  this.summariesDisabled = this.isSummariesDisabled();
251
255
  this.heuristicsDisabled = this.isHeuristicsDisabled();
252
256
  this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
253
257
  this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
254
258
  this.maxConsecutiveReconnects =
255
- (_c = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _c !== void 0 ? _c : this.defaultMaxConsecutiveReconnects;
256
- this._flushMode = runtimeOptions.flushMode;
259
+ (_e = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _e !== void 0 ? _e : this.defaultMaxConsecutiveReconnects;
260
+ if (runtimeOptions.flushMode === runtime_definitions_1.FlushModeExperimental.Async &&
261
+ ((_f = context.supportedFeatures) === null || _f === void 0 ? void 0 : _f.get("referenceSequenceNumbers")) !== true) {
262
+ // The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
263
+ this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
264
+ this._flushMode = runtime_definitions_1.FlushMode.TurnBased;
265
+ }
266
+ else {
267
+ this._flushMode = runtimeOptions.flushMode;
268
+ }
257
269
  const pendingRuntimeState = context.pendingLocalState;
258
- const baseSnapshot = (_d = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _d !== void 0 ? _d : context.baseSnapshot;
259
- const maxSnapshotCacheDurationMs = (_f = (_e = this._storage) === null || _e === void 0 ? void 0 : _e.policies) === null || _f === void 0 ? void 0 : _f.maximumCacheDurationMs;
270
+ const maxSnapshotCacheDurationMs = (_h = (_g = this._storage) === null || _g === void 0 ? void 0 : _g.policies) === null || _h === void 0 ? void 0 : _h.maximumCacheDurationMs;
260
271
  if (maxSnapshotCacheDurationMs !== undefined &&
261
272
  maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
262
273
  // This is a runtime enforcement of what's already explicit in the policy's type itself,
@@ -264,29 +275,31 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
264
275
  // As long as the actual value is less than 5 days, the assumptions GC makes here are valid.
265
276
  throw new container_utils_1.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
266
277
  }
267
- this.garbageCollector = garbageCollection_1.GarbageCollector.create({
278
+ this.garbageCollector = gc_1.GarbageCollector.create({
268
279
  runtime: this,
269
280
  gcOptions: this.runtimeOptions.gcOptions,
270
- baseSnapshot,
281
+ baseSnapshot: context.baseSnapshot,
271
282
  baseLogger: this.mc.logger,
272
283
  existing,
273
284
  metadata,
274
285
  createContainerMetadata: this.createContainerMetadata,
275
- isSummarizerClient: this.context.clientDetails.type === summarizerClientElection_1.summarizerClientType,
286
+ isSummarizerClient: this.context.clientDetails.type === summary_1.summarizerClientType,
276
287
  getNodePackagePath: async (nodePath) => this.getGCNodePackagePath(nodePath),
277
288
  getLastSummaryTimestampMs: () => { var _a; return (_a = this.messageAtLastSummary) === null || _a === void 0 ? void 0 : _a.timestamp; },
278
289
  readAndParseBlob: async (id) => (0, driver_utils_1.readAndParse)(this.storage, id),
279
290
  getContainerDiagnosticId: () => this.context.id,
280
- activeConnection: () => this.deltaManager.active,
291
+ // GC runs in summarizer client and needs access to the real (non-proxy) active information. The proxy
292
+ // delta manager would always return false for summarizer client.
293
+ activeConnection: () => this.innerDeltaManager.active,
281
294
  });
282
295
  const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
283
- this.summarizerNode = (0, runtime_utils_1.createRootSummarizerNodeWithGC)(telemetry_utils_1.ChildLogger.create(this.logger, "SummarizerNode"),
296
+ this.summarizerNode = (0, summary_1.createRootSummarizerNodeWithGC)(telemetry_utils_1.ChildLogger.create(this.logger, "SummarizerNode"),
284
297
  // Summarize function to call when summarize is called. Summarizer node always tracks summary state.
285
298
  async (fullTree, trackState, telemetryContext) => this.summarizeInternal(fullTree, trackState, telemetryContext),
286
299
  // Latest change sequence number, no changes since summary applied yet
287
300
  loadedFromSequenceNumber,
288
301
  // Summary reference sequence number, undefined if no summary yet
289
- baseSnapshot ? loadedFromSequenceNumber : undefined, {
302
+ context.baseSnapshot ? loadedFromSequenceNumber : undefined, {
290
303
  // Must set to false to prevent sending summary handle which would be pointing to
291
304
  // a summary with an older protocol state.
292
305
  canReuseHandle: false,
@@ -300,10 +313,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
300
313
  async (fullGC) => this.getGCDataInternal(fullGC),
301
314
  // Function to get the GC details from the base snapshot we loaded from.
302
315
  async () => this.garbageCollector.getBaseGCDetails());
303
- if (baseSnapshot) {
304
- this.summarizerNode.updateBaseSummaryState(baseSnapshot);
316
+ if (context.baseSnapshot) {
317
+ this.summarizerNode.updateBaseSummaryState(context.baseSnapshot);
305
318
  }
306
- this.dataStores = new dataStores_1.DataStores((0, dataStores_1.getSummaryForDatastores)(baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn, getBaseGCDetailsFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn, getBaseGCDetailsFn), (id) => this.summarizerNode.deleteChild(id), this.mc.logger, async () => this.garbageCollector.getBaseGCDetails(), (path, timestampMs, packagePath) => this.garbageCollector.nodeUpdated(path, "Changed", timestampMs, packagePath), new Map(dataStoreAliasMap));
319
+ this.dataStores = new dataStores_1.DataStores((0, dataStores_1.getSummaryForDatastores)(context.baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn), (id) => this.summarizerNode.deleteChild(id), this.mc.logger, (path, timestampMs, packagePath) => this.garbageCollector.nodeUpdated(path, "Changed", timestampMs, packagePath), (path) => this.garbageCollector.isNodeDeleted(path), new Map(dataStoreAliasMap));
307
320
  this.blobManager = new blobManager_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
308
321
  if (!this.disposed) {
309
322
  this.submit(ContainerMessageType.BlobAttach, undefined, undefined, {
@@ -311,7 +324,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
311
324
  blobId,
312
325
  });
313
326
  }
314
- }, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (fromPath, toPath) => this.garbageCollector.addedOutboundReference(fromPath, toPath), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs, () => this.getCurrentReferenceTimestampMs());
327
+ }, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs, () => this.getCurrentReferenceTimestampMs());
315
328
  this.scheduleManager = new scheduleManager_1.ScheduleManager(context.deltaManager, this, () => this.clientId, telemetry_utils_1.ChildLogger.create(this.logger, "ScheduleManager"));
316
329
  this.pendingStateManager = new pendingStateManager_1.PendingStateManager({
317
330
  applyStashedOp: this.applyStashedOp.bind(this),
@@ -322,12 +335,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
322
335
  rollback: this.rollback.bind(this),
323
336
  orderSequentially: this.orderSequentially.bind(this),
324
337
  }, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pending);
325
- const compressionOptions = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompression") === true
338
+ const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionDisabled");
339
+ const compressionOptions = disableCompression === true
326
340
  ? {
327
341
  minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
328
342
  compressionAlgorithm: CompressionAlgorithms.lz4,
329
343
  }
330
344
  : runtimeOptions.compressionOptions;
345
+ const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
331
346
  this.outbox = new opLifecycle_1.Outbox({
332
347
  shouldSend: () => this.canSendOps(),
333
348
  pendingStateManager: this.pendingStateManager,
@@ -337,14 +352,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
337
352
  config: {
338
353
  compressionOptions,
339
354
  maxBatchSizeInBytes: runtimeOptions.maxBatchSizeInBytes,
340
- enableOpReentryCheck: this.enableOpReentryCheck,
355
+ disablePartialFlush: disablePartialFlush === true,
341
356
  },
342
357
  logger: this.mc.logger,
343
358
  });
344
359
  this.context.quorum.on("removeMember", (clientId) => {
345
360
  this.remoteMessageProcessor.clearPartialMessagesFor(clientId);
346
361
  });
347
- this.summaryCollection = new summaryCollection_1.SummaryCollection(this.deltaManager, this.logger);
362
+ this.summaryCollection = new summary_1.SummaryCollection(this.deltaManager, this.logger);
348
363
  this.dirtyContainer =
349
364
  this.context.attachState !== container_definitions_1.AttachState.Attached ||
350
365
  this.pendingStateManager.hasPendingMessages();
@@ -354,13 +369,16 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
354
369
  }
355
370
  else {
356
371
  const orderedClientLogger = telemetry_utils_1.ChildLogger.create(this.logger, "OrderedClientElection");
357
- const orderedClientCollection = new orderedClientElection_1.OrderedClientCollection(orderedClientLogger, this.context.deltaManager, this.context.quorum);
358
- const orderedClientElectionForSummarizer = new orderedClientElection_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData !== null && electedSummarizerData !== void 0 ? electedSummarizerData : this.context.deltaManager.lastSequenceNumber, summarizerClientElection_1.SummarizerClientElection.isClientEligible);
359
- this.summarizerClientElection = new summarizerClientElection_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
360
- if (this.context.clientDetails.type === summarizerClientElection_1.summarizerClientType) {
361
- this._summarizer = new summarizer_1.Summarizer("/_summarizer", this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => runWhileConnectedCoordinator_1.RunWhileConnectedCoordinator.create(runtime));
372
+ const orderedClientCollection = new summary_1.OrderedClientCollection(orderedClientLogger, this.context.deltaManager, this.context.quorum);
373
+ const orderedClientElectionForSummarizer = new summary_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData !== null && electedSummarizerData !== void 0 ? electedSummarizerData : this.context.deltaManager.lastSequenceNumber, summary_1.SummarizerClientElection.isClientEligible);
374
+ this.summarizerClientElection = new summary_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
375
+ if (this.context.clientDetails.type === summary_1.summarizerClientType) {
376
+ this._summarizer = new summary_1.Summarizer(this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => summary_1.RunWhileConnectedCoordinator.create(runtime,
377
+ // Summarization runs in summarizer client and needs access to the real (non-proxy) active
378
+ // information. The proxy delta manager would always return false for summarizer client.
379
+ () => this.innerDeltaManager.active));
362
380
  }
363
- else if (summarizerClientElection_1.SummarizerClientElection.clientDetailsPermitElection(this.context.clientDetails)) {
381
+ else if (summary_1.SummarizerClientElection.clientDetailsPermitElection(this.context.clientDetails)) {
364
382
  // Only create a SummaryManager and SummarizerClientElection
365
383
  // if summaries are enabled and we are not the summarizer client.
366
384
  const defaultAction = () => {
@@ -380,7 +398,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
380
398
  };
381
399
  this.summaryCollection.on("default", defaultAction);
382
400
  // Create the SummaryManager and mark the initial state
383
- this.summaryManager = new summaryManager_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
401
+ this.summaryManager = new summary_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
384
402
  this.summaryCollection, this.logger, this.formRequestSummarizerFn(this.context.loader), new throttler_1.Throttler(60 * 1000, // 60 sec delay window
385
403
  30 * 1000, // 30 sec max delay
386
404
  // throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
@@ -393,7 +411,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
393
411
  this.deltaManager.on("readonly", (readonly) => {
394
412
  // we accumulate ops while being in read-only state.
395
413
  // once user gets write permissions and we have active connection, flush all pending ops.
396
- (0, common_utils_1.assert)(readonly === this.deltaManager.readOnlyInfo.readonly, 0x124 /* "inconsistent readonly property/event state" */);
414
+ // Note that the inner (non-proxy) delta manager is needed here to get the readonly information.
415
+ (0, common_utils_1.assert)(readonly === this.innerDeltaManager.readOnlyInfo.readonly, 0x124 /* "inconsistent readonly property/event state" */);
397
416
  // We need to be very careful with when we (re)send pending ops, to ensure that we only send ops
398
417
  // when we either never send an op, or attempted to send it but we know for sure it was not
399
418
  // sequenced by server and will never be sequenced (i.e. was lost)
@@ -411,9 +430,22 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
411
430
  });
412
431
  // logging hardware telemetry
413
432
  logger.sendTelemetryEvent(Object.assign({ eventName: "DeviceSpec" }, getDeviceSpec()));
414
- this.logger.sendTelemetryEvent(Object.assign(Object.assign(Object.assign({ eventName: "ContainerLoadStats" }, this.createContainerMetadata), this.dataStores.containerLoadStats), { summaryNumber: loadSummaryNumber, summaryFormatVersion: metadata === null || metadata === void 0 ? void 0 : metadata.summaryFormatVersion, disableIsolatedChannels: metadata === null || metadata === void 0 ? void 0 : metadata.disableIsolatedChannels, gcVersion: metadata === null || metadata === void 0 ? void 0 : metadata.gcFeature }));
433
+ this.logger.sendTelemetryEvent(Object.assign(Object.assign(Object.assign({ eventName: "ContainerLoadStats" }, this.createContainerMetadata), this.dataStores.containerLoadStats), { summaryNumber: loadSummaryNumber, summaryFormatVersion: metadata === null || metadata === void 0 ? void 0 : metadata.summaryFormatVersion, disableIsolatedChannels: metadata === null || metadata === void 0 ? void 0 : metadata.disableIsolatedChannels, gcVersion: metadata === null || metadata === void 0 ? void 0 : metadata.gcFeature, options: JSON.stringify(runtimeOptions), featureGates: JSON.stringify({
434
+ disableCompression,
435
+ disableOpReentryCheck,
436
+ disableChunking,
437
+ disableAttachReorder: this.disableAttachReorder,
438
+ disablePartialFlush,
439
+ }), telemetryDocumentId: this.telemetryDocumentId }));
415
440
  (0, connectionTelemetry_1.ReportOpPerfTelemetry)(this.context.clientId, this.deltaManager, this.logger);
416
441
  (0, batchTracker_1.BindBatchTracker)(this, this.logger);
442
+ this.entryPoint = new common_utils_1.LazyPromise(async () => {
443
+ if (this.context.clientDetails.type === summary_1.summarizerClientType) {
444
+ (0, common_utils_1.assert)(this._summarizer !== undefined, 0x5bf /* Summarizer object is undefined in a summarizer client */);
445
+ return this._summarizer;
446
+ }
447
+ return initializeEntryPoint === null || initializeEntryPoint === void 0 ? void 0 : initializeEntryPoint(this);
448
+ });
417
449
  }
418
450
  get IContainerRuntime() {
419
451
  return this;
@@ -451,17 +483,20 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
451
483
  * Load the stores from a snapshot and returns the runtime.
452
484
  * @param params - An object housing the runtime properties:
453
485
  * - context - Context of the container.
454
- * - registryEntries - Mapping to the stores.
455
- * - existing - When loading from an existing snapshot
456
- * - requestHandler - Request handlers for the container runtime
486
+ * - registryEntries - Mapping from data store types to their corresponding factories.
487
+ * - existing - Pass 'true' if loading from an existing snapshot.
488
+ * - requestHandler - (optional) Request handler for the request() method of the container runtime.
489
+ * Only relevant for back-compat while we remove the request() method and move fully to entryPoint as the main pattern.
457
490
  * - runtimeOptions - Additional options to be passed to the runtime
458
491
  * - containerScope - runtime services provided with context
459
492
  * - containerRuntimeCtor - Constructor to use to create the ContainerRuntime instance.
460
493
  * This allows mixin classes to leverage this method to define their own async initializer.
494
+ * - initializeEntryPoint - Promise that resolves to an object which will act as entryPoint for the Container.
495
+ * This object should provide all the functionality that the Container is expected to provide to the loader layer.
461
496
  */
462
497
  static async loadRuntime(params) {
463
498
  var _a, _b, _c, _d;
464
- const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, } = params;
499
+ const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, initializeEntryPoint, } = params;
465
500
  // If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
466
501
  // back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
467
502
  const backCompatContext = context;
@@ -471,45 +506,36 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
471
506
  runtimeVersion: packageVersion_1.pkgVersion,
472
507
  },
473
508
  });
474
- const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, enableOfflineLoad = false, compressionOptions = {
475
- minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
476
- compressionAlgorithm: CompressionAlgorithms.lz4,
477
- }, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, chunkSizeInBytes = Number.POSITIVE_INFINITY, enableOpReentryCheck = false, } = runtimeOptions;
478
- const pendingRuntimeState = context.pendingLocalState;
479
- const baseSnapshot = (_b = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _b !== void 0 ? _b : context.baseSnapshot;
480
- const storage = !pendingRuntimeState
481
- ? context.storage
482
- : new serializedSnapshotStorage_1.SerializedSnapshotStorage(() => {
483
- return context.storage;
484
- }, pendingRuntimeState.snapshotBlobs);
509
+ const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, } = runtimeOptions;
485
510
  const registry = new dataStoreRegistry_1.FluidDataStoreRegistry(registryEntries);
486
511
  const tryFetchBlob = async (blobName) => {
487
- const blobId = baseSnapshot === null || baseSnapshot === void 0 ? void 0 : baseSnapshot.blobs[blobName];
488
- if (baseSnapshot && blobId) {
512
+ var _a;
513
+ const blobId = (_a = context.baseSnapshot) === null || _a === void 0 ? void 0 : _a.blobs[blobName];
514
+ if (context.baseSnapshot && blobId) {
489
515
  // IContainerContext storage api return type still has undefined in 0.39 package version.
490
516
  // So once we release 0.40 container-defn package we can remove this check.
491
- (0, common_utils_1.assert)(storage !== undefined, 0x1f5 /* "Attached state should have storage" */);
492
- return (0, driver_utils_1.readAndParse)(storage, blobId);
517
+ (0, common_utils_1.assert)(context.storage !== undefined, 0x1f5 /* "Attached state should have storage" */);
518
+ return (0, driver_utils_1.readAndParse)(context.storage, blobId);
493
519
  }
494
520
  };
495
521
  const [chunks, metadata, electedSummarizerData, aliases] = await Promise.all([
496
- tryFetchBlob(summaryFormat_1.chunksBlobName),
497
- tryFetchBlob(summaryFormat_1.metadataBlobName),
498
- tryFetchBlob(summaryFormat_1.electedSummarizerBlobName),
499
- tryFetchBlob(summaryFormat_1.aliasBlobName),
522
+ tryFetchBlob(summary_1.chunksBlobName),
523
+ tryFetchBlob(summary_1.metadataBlobName),
524
+ tryFetchBlob(summary_1.electedSummarizerBlobName),
525
+ tryFetchBlob(summary_1.aliasBlobName),
500
526
  ]);
501
527
  const loadExisting = existing === true || context.existing === true;
502
528
  // read snapshot blobs needed for BlobManager to load
503
- const blobManagerSnapshot = await blobManager_1.BlobManager.load(baseSnapshot === null || baseSnapshot === void 0 ? void 0 : baseSnapshot.trees[summaryFormat_1.blobsTreeName], async (id) => {
529
+ const blobManagerSnapshot = await blobManager_1.BlobManager.load((_b = context.baseSnapshot) === null || _b === void 0 ? void 0 : _b.trees[summary_1.blobsTreeName], async (id) => {
504
530
  // IContainerContext storage api return type still has undefined in 0.39 package version.
505
531
  // So once we release 0.40 container-defn package we can remove this check.
506
- (0, common_utils_1.assert)(storage !== undefined, 0x256 /* "storage undefined in attached container" */);
507
- return (0, driver_utils_1.readAndParse)(storage, id);
532
+ (0, common_utils_1.assert)(context.storage !== undefined, 0x256 /* "storage undefined in attached container" */);
533
+ return (0, driver_utils_1.readAndParse)(context.storage, id);
508
534
  });
509
535
  // Verify summary runtime sequence number matches protocol sequence number.
510
536
  const runtimeSequenceNumber = (_c = metadata === null || metadata === void 0 ? void 0 : metadata.message) === null || _c === void 0 ? void 0 : _c.sequenceNumber;
511
537
  // When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
512
- if (!pendingRuntimeState && runtimeSequenceNumber !== undefined) {
538
+ if (!context.pendingLocalState && runtimeSequenceNumber !== undefined) {
513
539
  const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
514
540
  // Unless bypass is explicitly set, then take action when sequence numbers mismatch.
515
541
  if (loadSequenceNumberVerification !== "bypass" &&
@@ -533,17 +559,15 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
533
559
  gcOptions,
534
560
  loadSequenceNumberVerification,
535
561
  flushMode,
536
- enableOfflineLoad,
537
562
  compressionOptions,
538
563
  maxBatchSizeInBytes,
539
564
  chunkSizeInBytes,
540
565
  enableOpReentryCheck,
541
- }, containerScope, logger, loadExisting, blobManagerSnapshot, storage, requestHandler);
542
- if (pendingRuntimeState) {
543
- await runtime.processSavedOps(pendingRuntimeState);
544
- // delete these once runtime has seen them to save space
545
- pendingRuntimeState.savedOps = [];
546
- }
566
+ }, containerScope, logger, loadExisting, blobManagerSnapshot, context.storage, requestHandler, undefined, // summaryConfiguration
567
+ initializeEntryPoint);
568
+ // It's possible to have ops with a reference sequence number of 0. Op sequence numbers start
569
+ // at 1, so we won't see a replayed saved op with a sequence number of 0.
570
+ await runtime.pendingStateManager.applyStashedOpsAt(0);
547
571
  // Initialize the base state of the runtime before it's returned.
548
572
  await runtime.initializeBaseState();
549
573
  return runtime;
@@ -557,9 +581,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
557
581
  get clientDetails() {
558
582
  return this.context.clientDetails;
559
583
  }
560
- get deltaManager() {
561
- return this.context.deltaManager;
562
- }
563
584
  get storage() {
564
585
  return this._storage;
565
586
  }
@@ -652,7 +673,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
652
673
  * Initializes the state from the base snapshot this container runtime loaded from.
653
674
  */
654
675
  async initializeBaseState() {
655
- await this.initializeBaseSnapshotBlobs();
656
676
  await this.garbageCollector.initializeBaseState();
657
677
  }
658
678
  dispose(error) {
@@ -677,16 +697,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
677
697
  this.emit("dispose");
678
698
  this.removeAllListeners();
679
699
  }
680
- get IFluidTokenProvider() {
681
- var _a;
682
- if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.intelligence) {
683
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
684
- return {
685
- intelligence: this.options.intelligence,
686
- };
687
- }
688
- return undefined;
689
- }
690
700
  /**
691
701
  * Notifies this object about the request made to the container.
692
702
  * @param request - Request made to the handler.
@@ -749,12 +759,18 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
749
759
  return (0, runtime_utils_1.exceptionToResponse)(error);
750
760
  }
751
761
  }
762
+ /**
763
+ * {@inheritDoc @fluidframework/container-definitions#IRuntime.getEntryPoint}
764
+ */
765
+ async getEntryPoint() {
766
+ return this.entryPoint;
767
+ }
752
768
  internalId(maybeAlias) {
753
769
  var _a;
754
770
  return (_a = this.dataStores.aliases.get(maybeAlias)) !== null && _a !== void 0 ? _a : maybeAlias;
755
771
  }
756
772
  async getDataStoreFromRequest(id, request) {
757
- var _a, _b, _c, _d;
773
+ var _a, _b, _c;
758
774
  const headerData = {};
759
775
  if (typeof ((_a = request.headers) === null || _a === void 0 ? void 0 : _a[RuntimeHeaders.wait]) === "boolean") {
760
776
  headerData.wait = request.headers[RuntimeHeaders.wait];
@@ -768,27 +784,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
768
784
  await this.dataStores.waitIfPendingAlias(id);
769
785
  const internalId = this.internalId(id);
770
786
  const dataStoreContext = await this.dataStores.getDataStore(internalId, headerData);
771
- /**
772
- * If GC should run and this an external app request with "externalRequest" header, we need to return
773
- * an error if the data store being requested is marked as unreferenced as per the data store's base
774
- * GC data.
775
- *
776
- * This is a workaround to handle scenarios where a data store shared with an external app is deleted
777
- * and marked as unreferenced by GC. Returning an error will fail to load the data store for the app.
778
- */
779
- if (((_d = request.headers) === null || _d === void 0 ? void 0 : _d[RuntimeHeaders.externalRequest]) &&
780
- this.garbageCollector.shouldRunGC) {
781
- // The data store is referenced if used routes in the base summary has a route to self.
782
- // Older documents may not have used routes in the summary. They are considered referenced.
783
- const usedRoutes = (await dataStoreContext.getBaseGCDetails()).usedRoutes;
784
- if (!(usedRoutes === undefined || usedRoutes.includes("") || usedRoutes.includes("/"))) {
785
- throw (0, runtime_utils_1.responseToException)((0, runtime_utils_1.create404Response)(request), request);
786
- }
787
- }
788
787
  const dataStoreChannel = await dataStoreContext.realize();
789
788
  // Remove query params, leading and trailing slashes from the url. This is done to make sure the format is
790
789
  // the same as GC nodes id.
791
- const urlWithoutQuery = (0, garbage_collector_1.trimLeadingAndTrailingSlashes)(request.url.split("?")[0]);
790
+ const urlWithoutQuery = (0, gc_1.trimLeadingAndTrailingSlashes)(request.url.split("?")[0]);
792
791
  this.garbageCollector.nodeUpdated(`/${urlWithoutQuery}`, "Loaded", undefined /* timestampMs */, dataStoreContext.packagePath, request === null || request === void 0 ? void 0 : request.headers);
793
792
  return dataStoreChannel;
794
793
  }
@@ -800,29 +799,29 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
800
799
  summaryNumber: this.nextSummaryNumber++, summaryFormatVersion: 1 }), this.garbageCollector.getMetadata()), {
801
800
  // The last message processed at the time of summary. If there are no new messages, use the message from the
802
801
  // last summary.
803
- message: (_a = (0, summaryFormat_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage)) !== null && _a !== void 0 ? _a : this.messageAtLastSummary });
804
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summaryFormat_1.metadataBlobName, JSON.stringify(metadata));
802
+ message: (_a = (0, summary_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage)) !== null && _a !== void 0 ? _a : this.messageAtLastSummary, telemetryDocumentId: this.telemetryDocumentId });
803
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.metadataBlobName, JSON.stringify(metadata));
805
804
  }
806
805
  addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
807
806
  var _a;
808
807
  this.addMetadataToSummary(summaryTree);
809
808
  if (this.remoteMessageProcessor.partialMessages.size > 0) {
810
809
  const content = JSON.stringify([...this.remoteMessageProcessor.partialMessages]);
811
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summaryFormat_1.chunksBlobName, content);
810
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.chunksBlobName, content);
812
811
  }
813
812
  const dataStoreAliases = this.dataStores.aliases;
814
813
  if (dataStoreAliases.size > 0) {
815
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summaryFormat_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
814
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
816
815
  }
817
816
  if (this.summarizerClientElection) {
818
817
  const electedSummarizerContent = JSON.stringify((_a = this.summarizerClientElection) === null || _a === void 0 ? void 0 : _a.serialize());
819
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summaryFormat_1.electedSummarizerBlobName, electedSummarizerContent);
818
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.electedSummarizerBlobName, electedSummarizerContent);
820
819
  }
821
820
  const blobManagerSummary = this.blobManager.summarize();
822
821
  // Some storage (like git) doesn't allow empty tree, so we can omit it.
823
822
  // and the blob manager can handle the tree not existing when loading
824
823
  if (Object.keys(blobManagerSummary.summary.tree).length > 0) {
825
- (0, runtime_utils_1.addTreeToSummary)(summaryTree, summaryFormat_1.blobsTreeName, blobManagerSummary);
824
+ (0, runtime_utils_1.addTreeToSummary)(summaryTree, summary_1.blobsTreeName, blobManagerSummary);
826
825
  }
827
826
  const gcSummary = this.garbageCollector.summarize(fullTree, trackState, telemetryContext);
828
827
  if (gcSummary !== undefined) {
@@ -916,7 +915,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
916
915
  // If attachment blobs were added while disconnected, we need to delay
917
916
  // propagation of the "connected" event until we have uploaded them to
918
917
  // ensure we don't submit ops referencing a blob that has not been uploaded
919
- const connecting = connected && !this._connected && !this.deltaManager.readOnlyInfo.readonly;
918
+ // Note that the inner (non-proxy) delta manager is needed here to get the readonly information.
919
+ const connecting = connected && !this._connected && !this.innerDeltaManager.readOnlyInfo.readonly;
920
920
  if (connecting && this.blobManager.hasPendingOfflineUploads) {
921
921
  (0, common_utils_1.assert)(!this.delayConnectClientId, 0x392 /* Connect event delay must be canceled before subsequent connect event */);
922
922
  (0, common_utils_1.assert)(!!clientId, 0x393 /* Must have clientId when connecting */);
@@ -966,12 +966,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
966
966
  this.garbageCollector.setConnectionState(connected, clientId);
967
967
  (0, telemetry_utils_1.raiseConnectedEvent)(this.mc.logger, this, connected, clientId);
968
968
  }
969
+ async notifyOpReplay(message) {
970
+ await this.pendingStateManager.applyStashedOpsAt(message.sequenceNumber);
971
+ }
969
972
  process(messageArg, local) {
970
973
  var _a;
971
974
  this.verifyNotClosed();
972
- if ((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) {
973
- this.savedOps.push(messageArg);
974
- }
975
975
  // Whether or not the message is actually a runtime message.
976
976
  // It may be a legacy runtime message (ie already unpacked and ContainerMessageType)
977
977
  // or something different, like a system message.
@@ -1011,7 +1011,19 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1011
1011
  case ContainerMessageType.Rejoin:
1012
1012
  break;
1013
1013
  default:
1014
- (0, common_utils_1.assert)(!runtimeMessage, 0x3ce /* Runtime message of unknown type */);
1014
+ if (runtimeMessage) {
1015
+ const error = container_utils_1.DataProcessingError.create(
1016
+ // Former assert 0x3ce
1017
+ "Runtime message of unknown type", "OpProcessing", message, {
1018
+ local,
1019
+ type: message.type,
1020
+ contentType: typeof message.contents,
1021
+ batch: (_a = message.metadata) === null || _a === void 0 ? void 0 : _a.batch,
1022
+ compression: message.compression,
1023
+ });
1024
+ this.closeFn(error);
1025
+ throw error;
1026
+ }
1015
1027
  }
1016
1028
  // For back-compat, notify only about runtime messages for now.
1017
1029
  if (runtimeMessage) {
@@ -1072,7 +1084,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1072
1084
  }
1073
1085
  else if (envelope.clientSignalSequenceNumber ===
1074
1086
  this._perfSignalData.trackingSignalSequenceNumber) {
1075
- this.sendSignalTelemetryEvent(envelope.clientSignalSequenceNumber);
1087
+ // only logging for the first connection and the trackingSignalSequenceNUmber.
1088
+ if (this.consecutiveReconnects === 0) {
1089
+ this.sendSignalTelemetryEvent(envelope.clientSignalSequenceNumber);
1090
+ }
1076
1091
  this._perfSignalData.trackingSignalSequenceNumber = undefined;
1077
1092
  }
1078
1093
  }
@@ -1169,13 +1184,15 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1169
1184
  .realize();
1170
1185
  }
1171
1186
  canSendOps() {
1172
- return this.connected && !this.deltaManager.readOnlyInfo.readonly;
1187
+ // Note that the real (non-proxy) delta manager is needed here to get the readonly info. This is because
1188
+ // container runtime's ability to send ops depend on the actual readonly state of the delta manager.
1189
+ return this.connected && !this.innerDeltaManager.readOnlyInfo.readonly;
1173
1190
  }
1174
1191
  /**
1175
1192
  * Are we in the middle of batching ops together?
1176
1193
  */
1177
1194
  currentlyBatching() {
1178
- return this.flushMode === runtime_definitions_1.FlushMode.TurnBased || this._orderSequentiallyCalls !== 0;
1195
+ return this.flushMode !== runtime_definitions_1.FlushMode.Immediate || this._orderSequentiallyCalls !== 0;
1179
1196
  }
1180
1197
  getQuorum() {
1181
1198
  return this.context.quorum;
@@ -1264,7 +1281,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1264
1281
  }
1265
1282
  const summarizeResult = this.dataStores.createSummary(telemetryContext);
1266
1283
  // Wrap data store summaries in .channels subtree.
1267
- (0, summaryFormat_1.wrapSummaryInChannelsTree)(summarizeResult);
1284
+ (0, summary_1.wrapSummaryInChannelsTree)(summarizeResult);
1268
1285
  this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
1269
1286
  return summarizeResult.summary;
1270
1287
  }
@@ -1280,7 +1297,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1280
1297
  async summarizeInternal(fullTree, trackState, telemetryContext) {
1281
1298
  const summarizeResult = await this.dataStores.summarize(fullTree, trackState, telemetryContext);
1282
1299
  // Wrap data store summaries in .channels subtree.
1283
- (0, summaryFormat_1.wrapSummaryInChannelsTree)(summarizeResult);
1300
+ (0, summary_1.wrapSummaryInChannelsTree)(summarizeResult);
1284
1301
  const pathPartsForChildren = [runtime_definitions_1.channelsTreeName];
1285
1302
  this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
1286
1303
  return Object.assign(Object.assign({}, summarizeResult), { id: "", pathPartsForChildren });
@@ -1291,11 +1308,19 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1291
1308
  async summarize(options) {
1292
1309
  this.verifyNotClosed();
1293
1310
  const { fullTree = false, trackState = true, summaryLogger = this.mc.logger, runGC = this.garbageCollector.shouldRunGC, runSweep, fullGC, } = options;
1311
+ const telemetryContext = new runtime_utils_1.TelemetryContext();
1312
+ // Add the options that are used to generate this summary to the telemetry context.
1313
+ telemetryContext.setMultiple("fluid_Summarize", "Options", {
1314
+ fullTree,
1315
+ trackState,
1316
+ runGC,
1317
+ fullGC,
1318
+ runSweep,
1319
+ });
1294
1320
  let gcStats;
1295
1321
  if (runGC) {
1296
- gcStats = await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC });
1322
+ gcStats = await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC }, telemetryContext);
1297
1323
  }
1298
- const telemetryContext = new runtime_utils_1.TelemetryContext();
1299
1324
  const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
1300
1325
  this.logger.sendTelemetryEvent({
1301
1326
  eventName: "SummarizeTelemetry",
@@ -1305,10 +1330,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1305
1330
  return { stats, summary, gcStats };
1306
1331
  }
1307
1332
  /**
1308
- * Implementation of IGarbageCollectionRuntime::updateStateBeforeGC.
1309
1333
  * Before GC runs, called by the garbage collector to update any pending GC state. This is mainly used to notify
1310
1334
  * the garbage collector of references detected since the last GC run. Most references are notified immediately
1311
1335
  * but there can be some for which async operation is required (such as detecting new root data stores).
1336
+ * @see IGarbageCollectionRuntime.updateStateBeforeGC
1312
1337
  */
1313
1338
  async updateStateBeforeGC() {
1314
1339
  return this.dataStores.updateStateBeforeGC();
@@ -1317,12 +1342,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1317
1342
  return this.dataStores.getGCData(fullGC);
1318
1343
  }
1319
1344
  /**
1320
- * Implementation of IGarbageCollectionRuntime::getGCData.
1321
1345
  * Generates and returns the GC data for this container.
1322
1346
  * @param fullGC - true to bypass optimizations and force full generation of GC data.
1347
+ * @see IGarbageCollectionRuntime.getGCData
1323
1348
  */
1324
1349
  async getGCData(fullGC) {
1325
- const builder = new garbage_collector_1.GCDataBuilder();
1350
+ const builder = new runtime_utils_1.GCDataBuilder();
1326
1351
  const dsGCData = await this.summarizerNode.getGCData(fullGC);
1327
1352
  builder.addNodes(dsGCData.gcNodes);
1328
1353
  const blobsGCData = this.blobManager.getGCData(fullGC);
@@ -1330,9 +1355,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1330
1355
  return builder.getGCData();
1331
1356
  }
1332
1357
  /**
1333
- * Implementation of IGarbageCollectionRuntime::updateUsedRoutes.
1334
1358
  * After GC has run, called to notify this container's nodes of routes that are used in it.
1335
1359
  * @param usedRoutes - The routes that are used in all nodes in this Container.
1360
+ * @see IGarbageCollectionRuntime.updateUsedRoutes
1336
1361
  */
1337
1362
  updateUsedRoutes(usedRoutes) {
1338
1363
  // Update our summarizer node's used routes. Updating used routes in summarizer node before
@@ -1351,6 +1376,22 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1351
1376
  this.blobManager.updateUnusedRoutes(blobManagerRoutes);
1352
1377
  this.dataStores.updateUnusedRoutes(dataStoreRoutes);
1353
1378
  }
1379
+ /**
1380
+ * @deprecated - Replaced by deleteSweepReadyNodes.
1381
+ */
1382
+ deleteUnusedNodes(unusedRoutes) {
1383
+ throw new Error("deleteUnusedRoutes should not be called");
1384
+ }
1385
+ /**
1386
+ * After GC has run and identified nodes that are sweep ready, this is called to delete the sweep ready nodes.
1387
+ * @param sweepReadyRoutes - The routes of nodes that are sweep ready and should be deleted.
1388
+ * @returns - The routes of nodes that were deleted.
1389
+ */
1390
+ deleteSweepReadyNodes(sweepReadyRoutes) {
1391
+ const { dataStoreRoutes, blobManagerRoutes } = this.getDataStoreAndBlobManagerRoutes(sweepReadyRoutes);
1392
+ const deletedRoutes = this.dataStores.deleteSweepReadyNodes(dataStoreRoutes);
1393
+ return deletedRoutes.concat(this.blobManager.deleteSweepReadyNodes(blobManagerRoutes));
1394
+ }
1354
1395
  /**
1355
1396
  * This is called to update objects that are tombstones.
1356
1397
  * @param tombstonedRoutes - Data store and attachment blob routes that are tombstones in this Container.
@@ -1376,9 +1417,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1376
1417
  getNodeType(nodePath) {
1377
1418
  var _a;
1378
1419
  if (this.isBlobPath(nodePath)) {
1379
- return garbageCollection_1.GCNodeType.Blob;
1420
+ return gc_1.GCNodeType.Blob;
1380
1421
  }
1381
- return (_a = this.dataStores.getGCNodeType(nodePath)) !== null && _a !== void 0 ? _a : garbageCollection_1.GCNodeType.Other;
1422
+ return (_a = this.dataStores.getGCNodeType(nodePath)) !== null && _a !== void 0 ? _a : gc_1.GCNodeType.Other;
1382
1423
  }
1383
1424
  /**
1384
1425
  * Called by GC to retrieve the package path of the node with the given path. The node should belong to a
@@ -1386,10 +1427,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1386
1427
  */
1387
1428
  async getGCNodePackagePath(nodePath) {
1388
1429
  switch (this.getNodeType(nodePath)) {
1389
- case garbageCollection_1.GCNodeType.Blob:
1430
+ case gc_1.GCNodeType.Blob:
1390
1431
  return [blobManager_1.BlobManager.basePath];
1391
- case garbageCollection_1.GCNodeType.DataStore:
1392
- case garbageCollection_1.GCNodeType.SubDataStore:
1432
+ case gc_1.GCNodeType.DataStore:
1433
+ case gc_1.GCNodeType.SubDataStore:
1393
1434
  return this.dataStores.getDataStorePackagePath(nodePath);
1394
1435
  default:
1395
1436
  (0, common_utils_1.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
@@ -1428,8 +1469,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1428
1469
  * Runs garbage collection and updates the reference / used state of the nodes in the container.
1429
1470
  * @returns the statistics of the garbage collection run; undefined if GC did not run.
1430
1471
  */
1431
- async collectGarbage(options) {
1432
- return this.garbageCollector.collectGarbage(options);
1472
+ async collectGarbage(options, telemetryContext) {
1473
+ return this.garbageCollector.collectGarbage(options, telemetryContext);
1433
1474
  }
1434
1475
  /**
1435
1476
  * Called when a new outbound reference is added to another node. This is used by garbage collection to identify
@@ -1450,7 +1491,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1450
1491
  */
1451
1492
  async submitSummary(options) {
1452
1493
  var _a, _b;
1453
- const { fullTree, refreshLatestAck, summaryLogger } = options;
1494
+ const { fullTree = false, refreshLatestAck, summaryLogger } = options;
1454
1495
  // The summary number for this summary. This will be updated during the summary process, so get it now and
1455
1496
  // use it for all events logged during this summary.
1456
1497
  const summaryNumber = this.nextSummaryNumber;
@@ -1466,8 +1507,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1466
1507
  // We might need to catch up to the latest summary's reference sequence number before pausing.
1467
1508
  await this.waitForDeltaManagerToCatchup(latestSnapshotRefSeq, summaryNumberLogger);
1468
1509
  }
1510
+ const shouldPauseInboundSignal = this.mc.config.getBoolean("Fluid.ContainerRuntime.SubmitSummary.disableInboundSignalPause") !== true;
1469
1511
  try {
1470
1512
  await this.deltaManager.inbound.pause();
1513
+ if (shouldPauseInboundSignal) {
1514
+ await this.deltaManager.inboundSignal.pause();
1515
+ }
1471
1516
  const summaryRefSeqNum = this.deltaManager.lastSequenceNumber;
1472
1517
  const minimumSequenceNumber = this.deltaManager.minimumSequenceNumber;
1473
1518
  const message = `Summary @${summaryRefSeqNum}:${this.deltaManager.minimumSequenceNumber}`;
@@ -1523,7 +1568,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1523
1568
  const forcedFullTree = this.garbageCollector.summaryStateNeedsReset;
1524
1569
  try {
1525
1570
  summarizeResult = await this.summarize({
1526
- fullTree: fullTree !== null && fullTree !== void 0 ? fullTree : forcedFullTree,
1571
+ fullTree: fullTree || forcedFullTree,
1527
1572
  trackState: true,
1528
1573
  summaryLogger: summaryNumberLogger,
1529
1574
  runGC: this.garbageCollector.shouldRunGC,
@@ -1612,7 +1657,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1612
1657
  }
1613
1658
  let clientSequenceNumber;
1614
1659
  try {
1615
- clientSequenceNumber = this.submitSummaryMessage(summaryMessage);
1660
+ clientSequenceNumber = this.submitSummaryMessage(summaryMessage, summaryRefSeqNum);
1616
1661
  }
1617
1662
  catch (error) {
1618
1663
  return Object.assign(Object.assign({ stage: "upload" }, uploadData), { error });
@@ -1626,6 +1671,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1626
1671
  this.summarizerNode.clearSummary();
1627
1672
  // Restart the delta manager
1628
1673
  this.deltaManager.inbound.resume();
1674
+ if (shouldPauseInboundSignal) {
1675
+ this.deltaManager.inboundSignal.resume();
1676
+ }
1629
1677
  }
1630
1678
  }
1631
1679
  hasPendingMessages() {
@@ -1671,9 +1719,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1671
1719
  this.verifyCanSubmitOps();
1672
1720
  // There should be no ops in detached container state!
1673
1721
  (0, common_utils_1.assert)(this.attachState !== container_definitions_1.AttachState.Detached, 0x132 /* "sending ops in detached container" */);
1674
- const deserializedContent = { type, contents };
1675
- const serializedContent = JSON.stringify(deserializedContent);
1676
- if (this.deltaManager.readOnlyInfo.readonly) {
1722
+ const serializedContent = JSON.stringify({ type, contents });
1723
+ // Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
1724
+ // container runtime's ability to submit ops depend on the actual readonly state of the delta manager.
1725
+ if (this.innerDeltaManager.readOnlyInfo.readonly) {
1677
1726
  this.logger.sendTelemetryEvent({
1678
1727
  eventName: "SubmitOpInReadonly",
1679
1728
  connected: this.connected,
@@ -1681,7 +1730,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1681
1730
  }
1682
1731
  const message = {
1683
1732
  contents: serializedContent,
1684
- deserializedContent,
1733
+ deserializedContent: JSON.parse(serializedContent),
1685
1734
  metadata,
1686
1735
  localOpMetadata,
1687
1736
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
@@ -1709,7 +1758,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1709
1758
  // optimization no longer makes sense (for example, batch compression may make it less appealing).
1710
1759
  if (this.currentlyBatching() &&
1711
1760
  type === ContainerMessageType.Attach &&
1712
- this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder") !== true) {
1761
+ this.disableAttachReorder !== true) {
1713
1762
  this.outbox.submitAttach(message);
1714
1763
  }
1715
1764
  else {
@@ -1718,17 +1767,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1718
1767
  if (!this.currentlyBatching()) {
1719
1768
  this.flush();
1720
1769
  }
1721
- else if (!this.flushMicroTaskExists) {
1722
- this.flushMicroTaskExists = true;
1723
- // Queue a microtask to detect the end of the turn and force a flush.
1724
- Promise.resolve()
1725
- .then(() => {
1726
- this.flushMicroTaskExists = false;
1727
- this.flush();
1728
- })
1729
- .catch((error) => {
1730
- this.closeFn(error);
1731
- });
1770
+ else {
1771
+ this.scheduleFlush();
1732
1772
  }
1733
1773
  }
1734
1774
  catch (error) {
@@ -1739,14 +1779,47 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1739
1779
  this.updateDocumentDirtyState(true);
1740
1780
  }
1741
1781
  }
1742
- submitSummaryMessage(contents) {
1782
+ scheduleFlush() {
1783
+ if (this.flushTaskExists) {
1784
+ return;
1785
+ }
1786
+ this.flushTaskExists = true;
1787
+ const flush = () => {
1788
+ this.flushTaskExists = false;
1789
+ try {
1790
+ this.flush();
1791
+ }
1792
+ catch (error) {
1793
+ this.closeFn(error);
1794
+ }
1795
+ };
1796
+ switch (this.flushMode) {
1797
+ case runtime_definitions_1.FlushMode.TurnBased:
1798
+ // When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
1799
+ // batch at the end of the turn
1800
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1801
+ Promise.resolve().then(flush);
1802
+ break;
1803
+ // FlushModeExperimental is experimental and not exposed directly in the runtime APIs
1804
+ case runtime_definitions_1.FlushModeExperimental.Async:
1805
+ // When in Async flush mode, the runtime will accumulate all operations across JS turns and send them as a single
1806
+ // batch when all micro-tasks are complete.
1807
+ // Compared to TurnBased, this flush mode will capture more ops into the same batch.
1808
+ setTimeout(flush, 0);
1809
+ break;
1810
+ default:
1811
+ (0, common_utils_1.assert)(this._orderSequentiallyCalls > 0, 0x587 /* Unreachable unless running under orderSequentially */);
1812
+ break;
1813
+ }
1814
+ }
1815
+ submitSummaryMessage(contents, referenceSequenceNumber) {
1743
1816
  this.verifyNotClosed();
1744
1817
  (0, common_utils_1.assert)(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
1745
1818
  // System message should not be sent in the middle of the batch.
1746
1819
  (0, common_utils_1.assert)(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
1747
1820
  // back-compat: ADO #1385: Make this call unconditional in the future
1748
1821
  return this.context.submitSummaryFn !== undefined
1749
- ? this.context.submitSummaryFn(contents)
1822
+ ? this.context.submitSummaryFn(contents, referenceSequenceNumber)
1750
1823
  : this.context.submitFn(protocol_definitions_1.MessageType.Summarize, contents, false);
1751
1824
  }
1752
1825
  /**
@@ -1842,14 +1915,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1842
1915
  // The call to fetch the snapshot is very expensive and not always needed.
1843
1916
  // It should only be done by the summarizerNode, if required.
1844
1917
  // When fetching from storage we will always get the latest version and do not use the ackHandle.
1845
- const snapshotTreeFetcher = async () => {
1846
- const fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
1847
- eventName: "RefreshLatestSummaryGetSnapshot",
1918
+ const fetchLatestSnapshot = async () => {
1919
+ let fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
1920
+ eventName: "RefreshLatestSummaryAckFetch",
1848
1921
  ackHandle,
1849
- summaryRefSeq,
1850
- fetchLatest: true,
1851
- });
1852
- const latestSnapshotRefSeq = await (0, runtime_utils_1.seqFromTree)(fetchResult.snapshotTree, readAndParseBlob);
1922
+ targetSequenceNumber: summaryRefSeq,
1923
+ }, readAndParseBlob);
1853
1924
  /**
1854
1925
  * If the fetched snapshot is older than the one for which the ack was received, close the container.
1855
1926
  * This should never happen because an ack should be sent after the latest summary is updated in the server.
@@ -1860,29 +1931,34 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1860
1931
  * such cases, the file will be rolled back along with the ack and we will eventually reach a consistent
1861
1932
  * state.
1862
1933
  */
1863
- if (latestSnapshotRefSeq < summaryRefSeq) {
1864
- const error = container_utils_1.DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
1934
+ if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
1935
+ /* before failing, let's try to retrieve the latest snapshot for that specific ackHandle */
1936
+ fetchResult = await this.fetchSnapshotFromStorage(summaryLogger, {
1937
+ eventName: "RefreshLatestSummaryAckFetch",
1865
1938
  ackHandle,
1866
- summaryRefSeq,
1867
- latestSnapshotRefSeq,
1868
- });
1869
- this.closeFn(error);
1870
- throw error;
1939
+ targetSequenceNumber: summaryRefSeq,
1940
+ }, readAndParseBlob, ackHandle);
1941
+ if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
1942
+ const error = container_utils_1.DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
1943
+ ackHandle,
1944
+ summaryRefSeq,
1945
+ fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
1946
+ });
1947
+ this.closeFn(error);
1948
+ throw error;
1949
+ }
1871
1950
  }
1872
- summaryLogger.sendTelemetryEvent({
1873
- eventName: "LatestSummaryRetrieved",
1874
- ackHandle,
1875
- lastSequenceNumber: latestSnapshotRefSeq,
1876
- targetSequenceNumber: summaryRefSeq,
1877
- });
1878
1951
  // In case we had to retrieve the latest snapshot and it is different than summaryRefSeq,
1879
1952
  // wait for the delta manager to catch up before refreshing the latest Summary.
1880
- await this.waitForDeltaManagerToCatchup(latestSnapshotRefSeq, summaryLogger);
1881
- return fetchResult.snapshotTree;
1953
+ await this.waitForDeltaManagerToCatchup(fetchResult.latestSnapshotRefSeq, summaryLogger);
1954
+ return {
1955
+ snapshotTree: fetchResult.snapshotTree,
1956
+ snapshotRefSeq: fetchResult.latestSnapshotRefSeq,
1957
+ };
1882
1958
  };
1883
- const result = await this.summarizerNode.refreshLatestSummary(proposalHandle, summaryRefSeq, snapshotTreeFetcher, readAndParseBlob, summaryLogger);
1959
+ const result = await this.summarizerNode.refreshLatestSummary(proposalHandle, summaryRefSeq, fetchLatestSnapshot, readAndParseBlob, summaryLogger);
1884
1960
  // Notify the garbage collector so it can update its latest summary state.
1885
- await this.garbageCollector.refreshLatestSummary(result, proposalHandle, summaryRefSeq, readAndParseBlob);
1961
+ await this.garbageCollector.refreshLatestSummary(proposalHandle, result, readAndParseBlob);
1886
1962
  }
1887
1963
  /**
1888
1964
  * Fetches the latest snapshot from storage and uses it to refresh SummarizerNode's
@@ -1891,53 +1967,45 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1891
1967
  * @returns downloaded snapshot's reference sequence number
1892
1968
  */
1893
1969
  async refreshLatestSummaryAckFromServer(summaryLogger) {
1894
- const { snapshotTree, versionId } = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
1895
- eventName: "RefreshLatestSummaryGetSnapshot",
1896
- fetchLatest: true,
1897
- });
1898
1970
  const readAndParseBlob = async (id) => (0, driver_utils_1.readAndParse)(this.storage, id);
1899
- const latestSnapshotRefSeq = await (0, runtime_utils_1.seqFromTree)(snapshotTree, readAndParseBlob);
1900
- const result = await this.summarizerNode.refreshLatestSummary(undefined, latestSnapshotRefSeq, async () => snapshotTree, readAndParseBlob, summaryLogger);
1971
+ const { snapshotTree, versionId, latestSnapshotRefSeq } = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
1972
+ eventName: "RefreshLatestSummaryFromServerFetch",
1973
+ }, readAndParseBlob);
1974
+ const fetchLatestSnapshot = {
1975
+ snapshotTree,
1976
+ snapshotRefSeq: latestSnapshotRefSeq,
1977
+ };
1978
+ const result = await this.summarizerNode.refreshLatestSummary(undefined /* proposalHandle */, latestSnapshotRefSeq, async () => fetchLatestSnapshot, readAndParseBlob, summaryLogger);
1901
1979
  // Notify the garbage collector so it can update its latest summary state.
1902
- await this.garbageCollector.refreshLatestSummary(result, undefined, latestSnapshotRefSeq, readAndParseBlob);
1980
+ await this.garbageCollector.refreshLatestSummary(undefined /* proposalHandle */, result, readAndParseBlob);
1903
1981
  return { latestSnapshotRefSeq, latestSnapshotVersionId: versionId };
1904
1982
  }
1905
- async fetchLatestSnapshotFromStorage(logger, event) {
1983
+ async fetchLatestSnapshotFromStorage(logger, event, readAndParseBlob) {
1984
+ return this.fetchSnapshotFromStorage(logger, event, readAndParseBlob, null /* latest */);
1985
+ }
1986
+ async fetchSnapshotFromStorage(logger, event, readAndParseBlob, versionId) {
1906
1987
  return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
1907
1988
  const stats = {};
1908
1989
  const trace = common_utils_1.Trace.start();
1909
- const versions = await this.storage.getVersions(null, 1, "refreshLatestSummaryAckFromServer", driver_definitions_1.FetchSource.noCache);
1990
+ const versions = await this.storage.getVersions(versionId, 1, "refreshLatestSummaryAckFromServer", versionId === null ? driver_definitions_1.FetchSource.noCache : undefined);
1910
1991
  (0, common_utils_1.assert)(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
1911
1992
  stats.getVersionDuration = trace.trace().duration;
1912
1993
  const maybeSnapshot = await this.storage.getSnapshotTree(versions[0]);
1913
1994
  (0, common_utils_1.assert)(!!maybeSnapshot, 0x138 /* "Failed to get snapshot from storage" */);
1914
1995
  stats.getSnapshotDuration = trace.trace().duration;
1996
+ const latestSnapshotRefSeq = await (0, runtime_utils_1.seqFromTree)(maybeSnapshot, readAndParseBlob);
1997
+ stats.snapshotRefSeq = latestSnapshotRefSeq;
1998
+ stats.snapshotVersion = versions[0].id;
1915
1999
  perfEvent.end(stats);
1916
- return { snapshotTree: maybeSnapshot, versionId: versions[0].id };
2000
+ return {
2001
+ snapshotTree: maybeSnapshot,
2002
+ versionId: versions[0].id,
2003
+ latestSnapshotRefSeq,
2004
+ };
1917
2005
  });
1918
2006
  }
1919
- notifyAttaching(snapshot) {
1920
- var _a;
1921
- if ((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) {
1922
- this.baseSnapshotBlobs =
1923
- serializedSnapshotStorage_1.SerializedSnapshotStorage.serializeTreeWithBlobContents(snapshot);
1924
- }
1925
- }
1926
- async initializeBaseSnapshotBlobs() {
1927
- var _a;
1928
- if (!((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) ||
1929
- this.attachState !== container_definitions_1.AttachState.Attached ||
1930
- this.context.pendingLocalState) {
1931
- return;
1932
- }
1933
- (0, common_utils_1.assert)(!!this.context.baseSnapshot, 0x2e5 /* "Must have a base snapshot" */);
1934
- this.baseSnapshotBlobs = await serializedSnapshotStorage_1.SerializedSnapshotStorage.serializeTree(this.context.baseSnapshot, this.storage);
1935
- }
2007
+ notifyAttaching() { } // do nothing (deprecated method)
1936
2008
  getPendingLocalState() {
1937
- var _a;
1938
- if (!((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad)) {
1939
- throw new container_utils_1.UsageError("can't get state when offline load disabled");
1940
- }
1941
2009
  if (this._orderSequentiallyCalls !== 0) {
1942
2010
  throw new container_utils_1.UsageError("can't get state during orderSequentially");
1943
2011
  }
@@ -1945,24 +2013,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1945
2013
  // getPendingLocalState() is only exposed through Container.closeAndGetPendingLocalState(), so it's safe
1946
2014
  // to close current batch.
1947
2015
  this.flush();
1948
- const previousPendingState = this.context.pendingLocalState;
1949
- if (previousPendingState) {
1950
- return {
1951
- pending: this.pendingStateManager.getLocalState(),
1952
- pendingAttachmentBlobs: this.blobManager.getPendingBlobs(),
1953
- snapshotBlobs: previousPendingState.snapshotBlobs,
1954
- baseSnapshot: previousPendingState.baseSnapshot,
1955
- savedOps: this.savedOps,
1956
- };
1957
- }
1958
- (0, common_utils_1.assert)(!!this.context.baseSnapshot, 0x2e6 /* "Must have a base snapshot" */);
1959
- (0, common_utils_1.assert)(!!this.baseSnapshotBlobs, 0x2e7 /* "Must serialize base snapshot blobs before getting runtime state" */);
1960
2016
  return {
1961
2017
  pending: this.pendingStateManager.getLocalState(),
1962
2018
  pendingAttachmentBlobs: this.blobManager.getPendingBlobs(),
1963
- snapshotBlobs: this.baseSnapshotBlobs,
1964
- baseSnapshot: this.context.baseSnapshot,
1965
- savedOps: this.savedOps,
1966
2019
  };
1967
2020
  }
1968
2021
  /**
@@ -1976,7 +2029,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1976
2029
  [container_definitions_1.LoaderHeader.cache]: false,
1977
2030
  [container_definitions_1.LoaderHeader.clientDetails]: {
1978
2031
  capabilities: { interactive: false },
1979
- type: summarizerClientElection_1.summarizerClientType,
2032
+ type: summary_1.summarizerClientType,
1980
2033
  },
1981
2034
  [driver_definitions_1.DriverHeader.summarizingClient]: true,
1982
2035
  [container_definitions_1.LoaderHeader.reconnect]: false,
@@ -1991,20 +2044,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1991
2044
  return summarizer;
1992
2045
  };
1993
2046
  }
1994
- async processSavedOps(state) {
1995
- for (const op of state.savedOps) {
1996
- this.process(op, false);
1997
- await this.pendingStateManager.applyStashedOpsAt(op.sequenceNumber);
1998
- }
1999
- // we may not have seen every sequence number (because of system ops) so apply everything once we
2000
- // don't have any more saved ops
2001
- await this.pendingStateManager.applyStashedOpsAt();
2002
- // If it's not the case, we should take it into account when calculating dirty state.
2003
- (0, common_utils_1.assert)(this.context.attachState === container_definitions_1.AttachState.Attached, 0x3d5 /* this function is called for attached containers only */);
2004
- if (!this.hasPendingMessages()) {
2005
- this.updateDocumentDirtyState(false);
2006
- }
2007
- }
2008
2047
  validateSummaryHeuristicConfiguration(configuration) {
2009
2048
  // eslint-disable-next-line no-restricted-syntax
2010
2049
  for (const prop in configuration) {