@fluidframework/container-runtime 2.0.0-internal.3.0.2 → 2.0.0-internal.3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (474) hide show
  1. package/.eslintrc.js +19 -19
  2. package/.mocharc.js +2 -2
  3. package/api-extractor.json +2 -2
  4. package/dist/batchTracker.d.ts.map +1 -1
  5. package/dist/batchTracker.js +2 -1
  6. package/dist/batchTracker.js.map +1 -1
  7. package/dist/blobManager.d.ts +15 -2
  8. package/dist/blobManager.d.ts.map +1 -1
  9. package/dist/blobManager.js +109 -37
  10. package/dist/blobManager.js.map +1 -1
  11. package/dist/connectionTelemetry.d.ts.map +1 -1
  12. package/dist/connectionTelemetry.js +11 -9
  13. package/dist/connectionTelemetry.js.map +1 -1
  14. package/dist/containerHandleContext.d.ts.map +1 -1
  15. package/dist/containerHandleContext.js +3 -1
  16. package/dist/containerHandleContext.js.map +1 -1
  17. package/dist/containerRuntime.d.ts +23 -11
  18. package/dist/containerRuntime.d.ts.map +1 -1
  19. package/dist/containerRuntime.js +225 -132
  20. package/dist/containerRuntime.js.map +1 -1
  21. package/dist/dataStore.d.ts.map +1 -1
  22. package/dist/dataStore.js +11 -9
  23. package/dist/dataStore.js.map +1 -1
  24. package/dist/dataStoreContext.d.ts +27 -13
  25. package/dist/dataStoreContext.d.ts.map +1 -1
  26. package/dist/dataStoreContext.js +95 -56
  27. package/dist/dataStoreContext.js.map +1 -1
  28. package/dist/dataStoreContexts.d.ts.map +1 -1
  29. package/dist/dataStoreContexts.js +7 -3
  30. package/dist/dataStoreContexts.js.map +1 -1
  31. package/dist/dataStoreRegistry.d.ts.map +1 -1
  32. package/dist/dataStoreRegistry.js +3 -1
  33. package/dist/dataStoreRegistry.js.map +1 -1
  34. package/dist/dataStores.d.ts +28 -4
  35. package/dist/dataStores.d.ts.map +1 -1
  36. package/dist/dataStores.js +122 -44
  37. package/dist/dataStores.js.map +1 -1
  38. package/dist/deltaScheduler.d.ts.map +1 -1
  39. package/dist/deltaScheduler.js +8 -3
  40. package/dist/deltaScheduler.js.map +1 -1
  41. package/dist/{garbageCollection.d.ts → gc/garbageCollection.d.ts} +27 -203
  42. package/dist/gc/garbageCollection.d.ts.map +1 -0
  43. package/dist/{garbageCollection.js → gc/garbageCollection.js} +210 -400
  44. package/dist/gc/garbageCollection.js.map +1 -0
  45. package/dist/gc/gcDefinitions.d.ts +189 -0
  46. package/dist/gc/gcDefinitions.d.ts.map +1 -0
  47. package/dist/{garbageCollectionConstants.js → gc/gcDefinitions.js} +27 -2
  48. package/dist/gc/gcDefinitions.js.map +1 -0
  49. package/dist/gc/gcHelpers.d.ts +30 -0
  50. package/dist/gc/gcHelpers.d.ts.map +1 -0
  51. package/dist/gc/gcHelpers.js +65 -0
  52. package/dist/gc/gcHelpers.js.map +1 -0
  53. package/dist/gc/gcSummaryStateTracker.d.ts +86 -0
  54. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
  55. package/dist/gc/gcSummaryStateTracker.js +246 -0
  56. package/dist/gc/gcSummaryStateTracker.js.map +1 -0
  57. package/{lib → dist/gc}/gcSweepReadyUsageDetection.d.ts +5 -5
  58. package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  59. package/dist/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +15 -11
  60. package/dist/gc/gcSweepReadyUsageDetection.js.map +1 -0
  61. package/dist/gc/gcUnreferencedStateTracker.d.ts +34 -0
  62. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  63. package/dist/gc/gcUnreferencedStateTracker.js +94 -0
  64. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -0
  65. package/dist/gc/index.d.ts +11 -0
  66. package/dist/gc/index.d.ts.map +1 -0
  67. package/dist/gc/index.js +40 -0
  68. package/dist/gc/index.js.map +1 -0
  69. package/dist/index.d.ts +2 -5
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +6 -9
  72. package/dist/index.js.map +1 -1
  73. package/dist/opLifecycle/batchManager.d.ts +2 -13
  74. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  75. package/dist/opLifecycle/batchManager.js +19 -41
  76. package/dist/opLifecycle/batchManager.js.map +1 -1
  77. package/dist/opLifecycle/definitions.d.ts +4 -0
  78. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  79. package/dist/opLifecycle/definitions.js.map +1 -1
  80. package/dist/opLifecycle/index.d.ts.map +1 -1
  81. package/dist/opLifecycle/index.js.map +1 -1
  82. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  83. package/dist/opLifecycle/opCompressor.js +1 -0
  84. package/dist/opLifecycle/opCompressor.js.map +1 -1
  85. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  86. package/dist/opLifecycle/opDecompressor.js +5 -2
  87. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  88. package/dist/opLifecycle/opSplitter.d.ts +1 -1
  89. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  90. package/dist/opLifecycle/opSplitter.js +24 -13
  91. package/dist/opLifecycle/opSplitter.js.map +1 -1
  92. package/dist/opLifecycle/outbox.d.ts +19 -3
  93. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  94. package/dist/opLifecycle/outbox.js +78 -45
  95. package/dist/opLifecycle/outbox.js.map +1 -1
  96. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  97. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  98. package/dist/opProperties.d.ts.map +1 -1
  99. package/dist/opProperties.js +1 -3
  100. package/dist/opProperties.js.map +1 -1
  101. package/dist/packageVersion.d.ts +1 -1
  102. package/dist/packageVersion.js +1 -1
  103. package/dist/packageVersion.js.map +1 -1
  104. package/dist/pendingStateManager.d.ts +8 -2
  105. package/dist/pendingStateManager.d.ts.map +1 -1
  106. package/dist/pendingStateManager.js +21 -13
  107. package/dist/pendingStateManager.js.map +1 -1
  108. package/dist/scheduleManager.d.ts.map +1 -1
  109. package/dist/scheduleManager.js +3 -2
  110. package/dist/scheduleManager.js.map +1 -1
  111. package/dist/serializedSnapshotStorage.d.ts +2 -2
  112. package/dist/serializedSnapshotStorage.d.ts.map +1 -1
  113. package/dist/serializedSnapshotStorage.js +5 -3
  114. package/dist/serializedSnapshotStorage.js.map +1 -1
  115. package/dist/summary/index.d.ts +17 -0
  116. package/dist/summary/index.d.ts.map +1 -0
  117. package/dist/summary/index.js +47 -0
  118. package/dist/summary/index.js.map +1 -0
  119. package/dist/summary/orderedClientElection.d.ts.map +1 -0
  120. package/dist/{orderedClientElection.js → summary/orderedClientElection.js} +10 -4
  121. package/dist/summary/orderedClientElection.js.map +1 -0
  122. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  123. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -0
  124. package/{lib → dist/summary}/runningSummarizer.d.ts +19 -18
  125. package/dist/summary/runningSummarizer.d.ts.map +1 -0
  126. package/dist/{runningSummarizer.js → summary/runningSummarizer.js} +191 -76
  127. package/dist/summary/runningSummarizer.js.map +1 -0
  128. package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +4 -6
  129. package/dist/summary/summarizer.d.ts.map +1 -0
  130. package/dist/{summarizer.js → summary/summarizer.js} +31 -71
  131. package/dist/summary/summarizer.js.map +1 -0
  132. package/dist/summary/summarizerClientElection.d.ts.map +1 -0
  133. package/dist/summary/summarizerClientElection.js.map +1 -0
  134. package/dist/summary/summarizerHandle.d.ts.map +1 -0
  135. package/dist/summary/summarizerHandle.js.map +1 -0
  136. package/{lib → dist/summary}/summarizerHeuristics.d.ts +1 -1
  137. package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
  138. package/dist/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -9
  139. package/dist/summary/summarizerHeuristics.js.map +1 -0
  140. package/{lib → dist/summary}/summarizerTypes.d.ts +22 -22
  141. package/dist/summary/summarizerTypes.d.ts.map +1 -0
  142. package/dist/summary/summarizerTypes.js.map +1 -0
  143. package/dist/summary/summaryCollection.d.ts.map +1 -0
  144. package/dist/{summaryCollection.js → summary/summaryCollection.js} +18 -8
  145. package/dist/summary/summaryCollection.js.map +1 -0
  146. package/{lib → dist/summary}/summaryFormat.d.ts +1 -40
  147. package/dist/summary/summaryFormat.d.ts.map +1 -0
  148. package/dist/{summaryFormat.js → summary/summaryFormat.js} +19 -20
  149. package/dist/summary/summaryFormat.js.map +1 -0
  150. package/dist/summary/summaryGenerator.d.ts.map +1 -0
  151. package/dist/{summaryGenerator.js → summary/summaryGenerator.js} +33 -15
  152. package/dist/summary/summaryGenerator.js.map +1 -0
  153. package/dist/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
  154. package/dist/summary/summaryManager.d.ts.map +1 -0
  155. package/dist/{summaryManager.js → summary/summaryManager.js} +21 -9
  156. package/dist/summary/summaryManager.js.map +1 -0
  157. package/dist/throttler.d.ts +2 -2
  158. package/dist/throttler.d.ts.map +1 -1
  159. package/dist/throttler.js +4 -4
  160. package/dist/throttler.js.map +1 -1
  161. package/lib/batchTracker.d.ts.map +1 -1
  162. package/lib/batchTracker.js +2 -1
  163. package/lib/batchTracker.js.map +1 -1
  164. package/lib/blobManager.d.ts +15 -2
  165. package/lib/blobManager.d.ts.map +1 -1
  166. package/lib/blobManager.js +109 -37
  167. package/lib/blobManager.js.map +1 -1
  168. package/lib/connectionTelemetry.d.ts.map +1 -1
  169. package/lib/connectionTelemetry.js +11 -9
  170. package/lib/connectionTelemetry.js.map +1 -1
  171. package/lib/containerHandleContext.d.ts.map +1 -1
  172. package/lib/containerHandleContext.js +3 -1
  173. package/lib/containerHandleContext.js.map +1 -1
  174. package/lib/containerRuntime.d.ts +23 -11
  175. package/lib/containerRuntime.d.ts.map +1 -1
  176. package/lib/containerRuntime.js +201 -108
  177. package/lib/containerRuntime.js.map +1 -1
  178. package/lib/dataStore.d.ts.map +1 -1
  179. package/lib/dataStore.js +11 -9
  180. package/lib/dataStore.js.map +1 -1
  181. package/lib/dataStoreContext.d.ts +27 -13
  182. package/lib/dataStoreContext.d.ts.map +1 -1
  183. package/lib/dataStoreContext.js +84 -45
  184. package/lib/dataStoreContext.js.map +1 -1
  185. package/lib/dataStoreContexts.d.ts.map +1 -1
  186. package/lib/dataStoreContexts.js +7 -3
  187. package/lib/dataStoreContexts.js.map +1 -1
  188. package/lib/dataStoreRegistry.d.ts.map +1 -1
  189. package/lib/dataStoreRegistry.js +3 -1
  190. package/lib/dataStoreRegistry.js.map +1 -1
  191. package/lib/dataStores.d.ts +28 -4
  192. package/lib/dataStores.d.ts.map +1 -1
  193. package/lib/dataStores.js +120 -42
  194. package/lib/dataStores.js.map +1 -1
  195. package/lib/deltaScheduler.d.ts.map +1 -1
  196. package/lib/deltaScheduler.js +9 -4
  197. package/lib/deltaScheduler.js.map +1 -1
  198. package/lib/{garbageCollection.d.ts → gc/garbageCollection.d.ts} +27 -203
  199. package/lib/gc/garbageCollection.d.ts.map +1 -0
  200. package/lib/{garbageCollection.js → gc/garbageCollection.js} +190 -379
  201. package/lib/gc/garbageCollection.js.map +1 -0
  202. package/lib/gc/gcDefinitions.d.ts +189 -0
  203. package/lib/gc/gcDefinitions.d.ts.map +1 -0
  204. package/lib/{garbageCollectionConstants.js → gc/gcDefinitions.js} +26 -1
  205. package/lib/gc/gcDefinitions.js.map +1 -0
  206. package/lib/gc/gcHelpers.d.ts +30 -0
  207. package/lib/gc/gcHelpers.d.ts.map +1 -0
  208. package/lib/gc/gcHelpers.js +58 -0
  209. package/lib/gc/gcHelpers.js.map +1 -0
  210. package/lib/gc/gcSummaryStateTracker.d.ts +86 -0
  211. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
  212. package/lib/gc/gcSummaryStateTracker.js +242 -0
  213. package/lib/gc/gcSummaryStateTracker.js.map +1 -0
  214. package/{dist → lib/gc}/gcSweepReadyUsageDetection.d.ts +5 -5
  215. package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  216. package/lib/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +15 -11
  217. package/lib/gc/gcSweepReadyUsageDetection.js.map +1 -0
  218. package/lib/gc/gcUnreferencedStateTracker.d.ts +34 -0
  219. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  220. package/lib/gc/gcUnreferencedStateTracker.js +90 -0
  221. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -0
  222. package/lib/gc/index.d.ts +11 -0
  223. package/lib/gc/index.d.ts.map +1 -0
  224. package/lib/gc/index.js +11 -0
  225. package/lib/gc/index.js.map +1 -0
  226. package/lib/index.d.ts +2 -5
  227. package/lib/index.d.ts.map +1 -1
  228. package/lib/index.js +1 -4
  229. package/lib/index.js.map +1 -1
  230. package/lib/opLifecycle/batchManager.d.ts +2 -13
  231. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  232. package/lib/opLifecycle/batchManager.js +19 -41
  233. package/lib/opLifecycle/batchManager.js.map +1 -1
  234. package/lib/opLifecycle/definitions.d.ts +4 -0
  235. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  236. package/lib/opLifecycle/definitions.js.map +1 -1
  237. package/lib/opLifecycle/index.d.ts.map +1 -1
  238. package/lib/opLifecycle/index.js.map +1 -1
  239. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  240. package/lib/opLifecycle/opCompressor.js +1 -0
  241. package/lib/opLifecycle/opCompressor.js.map +1 -1
  242. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  243. package/lib/opLifecycle/opDecompressor.js +5 -2
  244. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  245. package/lib/opLifecycle/opSplitter.d.ts +1 -1
  246. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  247. package/lib/opLifecycle/opSplitter.js +25 -14
  248. package/lib/opLifecycle/opSplitter.js.map +1 -1
  249. package/lib/opLifecycle/outbox.d.ts +19 -3
  250. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  251. package/lib/opLifecycle/outbox.js +79 -46
  252. package/lib/opLifecycle/outbox.js.map +1 -1
  253. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  254. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  255. package/lib/opProperties.d.ts.map +1 -1
  256. package/lib/opProperties.js +1 -3
  257. package/lib/opProperties.js.map +1 -1
  258. package/lib/packageVersion.d.ts +1 -1
  259. package/lib/packageVersion.js +1 -1
  260. package/lib/packageVersion.js.map +1 -1
  261. package/lib/pendingStateManager.d.ts +8 -2
  262. package/lib/pendingStateManager.d.ts.map +1 -1
  263. package/lib/pendingStateManager.js +21 -13
  264. package/lib/pendingStateManager.js.map +1 -1
  265. package/lib/scheduleManager.d.ts.map +1 -1
  266. package/lib/scheduleManager.js +3 -2
  267. package/lib/scheduleManager.js.map +1 -1
  268. package/lib/serializedSnapshotStorage.d.ts +2 -2
  269. package/lib/serializedSnapshotStorage.d.ts.map +1 -1
  270. package/lib/serializedSnapshotStorage.js +5 -3
  271. package/lib/serializedSnapshotStorage.js.map +1 -1
  272. package/lib/summary/index.d.ts +17 -0
  273. package/lib/summary/index.d.ts.map +1 -0
  274. package/lib/summary/index.js +16 -0
  275. package/lib/summary/index.js.map +1 -0
  276. package/lib/summary/orderedClientElection.d.ts.map +1 -0
  277. package/lib/{orderedClientElection.js → summary/orderedClientElection.js} +10 -4
  278. package/lib/summary/orderedClientElection.js.map +1 -0
  279. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  280. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
  281. package/{dist → lib/summary}/runningSummarizer.d.ts +19 -18
  282. package/lib/summary/runningSummarizer.d.ts.map +1 -0
  283. package/lib/{runningSummarizer.js → summary/runningSummarizer.js} +193 -78
  284. package/lib/summary/runningSummarizer.js.map +1 -0
  285. package/lib/{summarizer.d.ts → summary/summarizer.d.ts} +4 -6
  286. package/lib/summary/summarizer.d.ts.map +1 -0
  287. package/lib/{summarizer.js → summary/summarizer.js} +33 -73
  288. package/lib/summary/summarizer.js.map +1 -0
  289. package/lib/summary/summarizerClientElection.d.ts.map +1 -0
  290. package/lib/summary/summarizerClientElection.js.map +1 -0
  291. package/lib/summary/summarizerHandle.d.ts.map +1 -0
  292. package/lib/summary/summarizerHandle.js.map +1 -0
  293. package/{dist → lib/summary}/summarizerHeuristics.d.ts +1 -1
  294. package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
  295. package/lib/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -9
  296. package/lib/summary/summarizerHeuristics.js.map +1 -0
  297. package/{dist → lib/summary}/summarizerTypes.d.ts +22 -22
  298. package/lib/summary/summarizerTypes.d.ts.map +1 -0
  299. package/lib/summary/summarizerTypes.js.map +1 -0
  300. package/lib/summary/summaryCollection.d.ts.map +1 -0
  301. package/lib/{summaryCollection.js → summary/summaryCollection.js} +18 -8
  302. package/lib/summary/summaryCollection.js.map +1 -0
  303. package/{dist → lib/summary}/summaryFormat.d.ts +1 -40
  304. package/lib/summary/summaryFormat.d.ts.map +1 -0
  305. package/lib/{summaryFormat.js → summary/summaryFormat.js} +20 -20
  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} +33 -15
  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/{summaryManager.js → summary/summaryManager.js} +21 -9
  313. package/lib/summary/summaryManager.js.map +1 -0
  314. package/lib/throttler.d.ts +2 -2
  315. package/lib/throttler.d.ts.map +1 -1
  316. package/lib/throttler.js +4 -4
  317. package/lib/throttler.js.map +1 -1
  318. package/package.json +60 -51
  319. package/prettier.config.cjs +1 -1
  320. package/src/batchTracker.ts +54 -49
  321. package/src/blobManager.ts +825 -674
  322. package/src/connectionTelemetry.ts +280 -249
  323. package/src/containerHandleContext.ts +27 -29
  324. package/src/containerRuntime.ts +3249 -2978
  325. package/src/dataStore.ts +172 -159
  326. package/src/dataStoreContext.ts +1141 -1057
  327. package/src/dataStoreContexts.ts +178 -161
  328. package/src/dataStoreRegistry.ts +25 -20
  329. package/src/dataStores.ts +880 -731
  330. package/src/deltaScheduler.ts +158 -150
  331. package/{garbageCollection.md → src/gc/garbageCollection.md} +16 -3
  332. package/src/gc/garbageCollection.ts +1506 -0
  333. package/src/gc/gcDefinitions.ts +244 -0
  334. package/src/gc/gcHelpers.ts +86 -0
  335. package/src/gc/gcSummaryStateTracker.ts +339 -0
  336. package/src/gc/gcSweepReadyUsageDetection.ts +145 -0
  337. package/src/gc/gcUnreferencedStateTracker.ts +114 -0
  338. package/src/gc/index.ts +40 -0
  339. package/src/index.ts +67 -70
  340. package/src/opLifecycle/README.md +152 -0
  341. package/src/opLifecycle/batchManager.ts +101 -144
  342. package/src/opLifecycle/definitions.ts +33 -29
  343. package/src/opLifecycle/index.ts +5 -5
  344. package/src/opLifecycle/opCompressor.ts +55 -53
  345. package/src/opLifecycle/opDecompressor.ts +100 -81
  346. package/src/opLifecycle/opSplitter.ts +233 -188
  347. package/src/opLifecycle/outbox.ts +251 -195
  348. package/src/opLifecycle/remoteMessageProcessor.ts +62 -62
  349. package/src/opProperties.ts +11 -9
  350. package/src/packageVersion.ts +1 -1
  351. package/src/pendingStateManager.ts +396 -338
  352. package/src/scheduleManager.ts +299 -269
  353. package/src/serializedSnapshotStorage.ts +126 -112
  354. package/src/summary/index.ts +99 -0
  355. package/src/summary/orderedClientElection.ts +564 -0
  356. package/src/summary/runWhileConnectedCoordinator.ts +113 -0
  357. package/src/summary/runningSummarizer.ts +788 -0
  358. package/src/summary/summarizer.ts +386 -0
  359. package/src/summary/summarizerClientElection.ts +139 -0
  360. package/src/{summarizerHandle.ts → summary/summarizerHandle.ts} +11 -9
  361. package/src/summary/summarizerHeuristics.ts +219 -0
  362. package/src/summary/summarizerTypes.ts +521 -0
  363. package/src/summary/summaryCollection.ts +450 -0
  364. package/src/summary/summaryFormat.ts +226 -0
  365. package/src/summary/summaryGenerator.ts +505 -0
  366. package/src/summary/summaryManager.ts +423 -0
  367. package/src/throttler.ts +131 -122
  368. package/tsconfig.esnext.json +6 -6
  369. package/tsconfig.json +9 -13
  370. package/dist/garbageCollection.d.ts.map +0 -1
  371. package/dist/garbageCollection.js.map +0 -1
  372. package/dist/garbageCollectionConstants.d.ts +0 -25
  373. package/dist/garbageCollectionConstants.d.ts.map +0 -1
  374. package/dist/garbageCollectionConstants.js.map +0 -1
  375. package/dist/garbageCollectionTombstoneUtils.d.ts +0 -14
  376. package/dist/garbageCollectionTombstoneUtils.d.ts.map +0 -1
  377. package/dist/garbageCollectionTombstoneUtils.js +0 -23
  378. package/dist/garbageCollectionTombstoneUtils.js.map +0 -1
  379. package/dist/gcSweepReadyUsageDetection.d.ts.map +0 -1
  380. package/dist/gcSweepReadyUsageDetection.js.map +0 -1
  381. package/dist/orderedClientElection.d.ts.map +0 -1
  382. package/dist/orderedClientElection.js.map +0 -1
  383. package/dist/runWhileConnectedCoordinator.d.ts.map +0 -1
  384. package/dist/runWhileConnectedCoordinator.js.map +0 -1
  385. package/dist/runningSummarizer.d.ts.map +0 -1
  386. package/dist/runningSummarizer.js.map +0 -1
  387. package/dist/summarizer.d.ts.map +0 -1
  388. package/dist/summarizer.js.map +0 -1
  389. package/dist/summarizerClientElection.d.ts.map +0 -1
  390. package/dist/summarizerClientElection.js.map +0 -1
  391. package/dist/summarizerHandle.d.ts.map +0 -1
  392. package/dist/summarizerHandle.js.map +0 -1
  393. package/dist/summarizerHeuristics.d.ts.map +0 -1
  394. package/dist/summarizerHeuristics.js.map +0 -1
  395. package/dist/summarizerTypes.d.ts.map +0 -1
  396. package/dist/summarizerTypes.js.map +0 -1
  397. package/dist/summaryCollection.d.ts.map +0 -1
  398. package/dist/summaryCollection.js.map +0 -1
  399. package/dist/summaryFormat.d.ts.map +0 -1
  400. package/dist/summaryFormat.js.map +0 -1
  401. package/dist/summaryGenerator.d.ts.map +0 -1
  402. package/dist/summaryGenerator.js.map +0 -1
  403. package/dist/summaryManager.d.ts.map +0 -1
  404. package/dist/summaryManager.js.map +0 -1
  405. package/lib/garbageCollection.d.ts.map +0 -1
  406. package/lib/garbageCollection.js.map +0 -1
  407. package/lib/garbageCollectionConstants.d.ts +0 -25
  408. package/lib/garbageCollectionConstants.d.ts.map +0 -1
  409. package/lib/garbageCollectionConstants.js.map +0 -1
  410. package/lib/garbageCollectionTombstoneUtils.d.ts +0 -14
  411. package/lib/garbageCollectionTombstoneUtils.d.ts.map +0 -1
  412. package/lib/garbageCollectionTombstoneUtils.js +0 -19
  413. package/lib/garbageCollectionTombstoneUtils.js.map +0 -1
  414. package/lib/gcSweepReadyUsageDetection.d.ts.map +0 -1
  415. package/lib/gcSweepReadyUsageDetection.js.map +0 -1
  416. package/lib/orderedClientElection.d.ts.map +0 -1
  417. package/lib/orderedClientElection.js.map +0 -1
  418. package/lib/runWhileConnectedCoordinator.d.ts.map +0 -1
  419. package/lib/runWhileConnectedCoordinator.js.map +0 -1
  420. package/lib/runningSummarizer.d.ts.map +0 -1
  421. package/lib/runningSummarizer.js.map +0 -1
  422. package/lib/summarizer.d.ts.map +0 -1
  423. package/lib/summarizer.js.map +0 -1
  424. package/lib/summarizerClientElection.d.ts.map +0 -1
  425. package/lib/summarizerClientElection.js.map +0 -1
  426. package/lib/summarizerHandle.d.ts.map +0 -1
  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.map +0 -1
  432. package/lib/summaryCollection.d.ts.map +0 -1
  433. package/lib/summaryCollection.js.map +0 -1
  434. package/lib/summaryFormat.d.ts.map +0 -1
  435. package/lib/summaryFormat.js.map +0 -1
  436. package/lib/summaryGenerator.d.ts.map +0 -1
  437. package/lib/summaryGenerator.js.map +0 -1
  438. package/lib/summaryManager.d.ts.map +0 -1
  439. package/lib/summaryManager.js.map +0 -1
  440. package/src/garbageCollection.ts +0 -1800
  441. package/src/garbageCollectionConstants.ts +0 -41
  442. package/src/garbageCollectionTombstoneUtils.ts +0 -28
  443. package/src/gcSweepReadyUsageDetection.ts +0 -139
  444. package/src/orderedClientElection.ts +0 -532
  445. package/src/runWhileConnectedCoordinator.ts +0 -106
  446. package/src/runningSummarizer.ts +0 -610
  447. package/src/summarizer.ts +0 -421
  448. package/src/summarizerClientElection.ts +0 -132
  449. package/src/summarizerHeuristics.ts +0 -222
  450. package/src/summarizerTypes.ts +0 -507
  451. package/src/summaryCollection.ts +0 -421
  452. package/src/summaryFormat.ts +0 -256
  453. package/src/summaryGenerator.ts +0 -450
  454. package/src/summaryManager.ts +0 -394
  455. /package/dist/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  456. /package/dist/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +0 -0
  457. /package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +0 -0
  458. /package/dist/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
  459. /package/dist/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
  460. /package/dist/{summarizerHandle.d.ts → summary/summarizerHandle.d.ts} +0 -0
  461. /package/dist/{summarizerHandle.js → summary/summarizerHandle.js} +0 -0
  462. /package/dist/{summarizerTypes.js → summary/summarizerTypes.js} +0 -0
  463. /package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  464. /package/dist/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
  465. /package/lib/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  466. /package/lib/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +0 -0
  467. /package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +0 -0
  468. /package/lib/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
  469. /package/lib/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
  470. /package/lib/{summarizerHandle.d.ts → summary/summarizerHandle.d.ts} +0 -0
  471. /package/lib/{summarizerHandle.js → summary/summarizerHandle.js} +0 -0
  472. /package/lib/{summarizerTypes.js → summary/summarizerTypes.js} +0 -0
  473. /package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  474. /package/lib/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
@@ -1,33 +1,27 @@
1
1
  import { AttachState, LoaderHeader, } from "@fluidframework/container-definitions";
2
- import { assert, Trace, TypedEventEmitter, unreachableCase, } from "@fluidframework/common-utils";
2
+ import { assert, Trace, TypedEventEmitter, unreachableCase } from "@fluidframework/common-utils";
3
3
  import { ChildLogger, raiseConnectedEvent, PerformanceEvent, TaggedLoggerAdapter, loggerToMonitoringContext, wrapError, } from "@fluidframework/telemetry-utils";
4
4
  import { DriverHeader, FetchSource, } from "@fluidframework/driver-definitions";
5
5
  import { readAndParse } from "@fluidframework/driver-utils";
6
6
  import { DataCorruptionError, DataProcessingError, GenericError, UsageError, } from "@fluidframework/container-utils";
7
7
  import { MessageType, SummaryType, } from "@fluidframework/protocol-definitions";
8
- import { FlushMode, gcTreeKey, channelsTreeName, } from "@fluidframework/runtime-definitions";
9
- import { addBlobToSummary, addSummarizeResultToSummary, addTreeToSummary, createRootSummarizerNodeWithGC, RequestParser, create404Response, exceptionToResponse, requestFluidObject, responseToException, seqFromTree, calculateStats, TelemetryContext, } from "@fluidframework/runtime-utils";
8
+ import { FlushMode, FlushModeExperimental, gcTreeKey, channelsTreeName, } from "@fluidframework/runtime-definitions";
9
+ import { addBlobToSummary, addSummarizeResultToSummary, addTreeToSummary, createRootSummarizerNodeWithGC, RequestParser, create404Response, exceptionToResponse, requestFluidObject, seqFromTree, calculateStats, TelemetryContext, } from "@fluidframework/runtime-utils";
10
10
  import { GCDataBuilder, trimLeadingAndTrailingSlashes } from "@fluidframework/garbage-collector";
11
11
  import { v4 as uuid } from "uuid";
12
12
  import { ContainerFluidHandleContext } from "./containerHandleContext";
13
13
  import { FluidDataStoreRegistry } from "./dataStoreRegistry";
14
- import { Summarizer } from "./summarizer";
15
- import { SummaryManager } from "./summaryManager";
16
- import { ReportOpPerfTelemetry, } from "./connectionTelemetry";
17
- import { PendingStateManager, } from "./pendingStateManager";
14
+ import { ReportOpPerfTelemetry } from "./connectionTelemetry";
15
+ import { PendingStateManager } from "./pendingStateManager";
18
16
  import { pkgVersion } from "./packageVersion";
19
17
  import { BlobManager } from "./blobManager";
20
18
  import { DataStores, getSummaryForDatastores } from "./dataStores";
21
- import { aliasBlobName, blobsTreeName, chunksBlobName, electedSummarizerBlobName, extractSummaryMetadataMessage, metadataBlobName, wrapSummaryInChannelsTree, } from "./summaryFormat";
22
- import { SummaryCollection } from "./summaryCollection";
23
- import { OrderedClientCollection, OrderedClientElection } from "./orderedClientElection";
24
- import { SummarizerClientElection, summarizerClientType } from "./summarizerClientElection";
19
+ import { aliasBlobName, blobsTreeName, chunksBlobName, electedSummarizerBlobName, extractSummaryMetadataMessage, metadataBlobName, Summarizer, SummaryManager, wrapSummaryInChannelsTree, SummaryCollection, OrderedClientCollection, OrderedClientElection, SummarizerClientElection, summarizerClientType, RunWhileConnectedCoordinator, } from "./summary";
25
20
  import { formExponentialFn, Throttler } from "./throttler";
26
- import { RunWhileConnectedCoordinator } from "./runWhileConnectedCoordinator";
27
- import { GarbageCollector, GCNodeType, } from "./garbageCollection";
28
- import { channelToDataStore, isDataStoreAliasMessage, } from "./dataStore";
21
+ import { GarbageCollector, GCNodeType, gcTombstoneGenerationOptionName, shouldAllowGcTombstoneEnforcement, } from "./gc";
22
+ import { channelToDataStore, isDataStoreAliasMessage } from "./dataStore";
29
23
  import { BindBatchTracker } from "./batchTracker";
30
- import { SerializedSnapshotStorage } from "./serializedSnapshotStorage";
24
+ import { SerializedSnapshotStorage, } from "./serializedSnapshotStorage";
31
25
  import { ScheduleManager } from "./scheduleManager";
32
26
  import { OpCompressor, OpDecompressor, Outbox, OpSplitter, RemoteMessageProcessor, } from "./opLifecycle";
33
27
  export var ContainerMessageType;
@@ -66,11 +60,6 @@ export var RuntimeHeaders;
66
60
  (function (RuntimeHeaders) {
67
61
  /** True to wait for a data store to be created and loaded before returning it. */
68
62
  RuntimeHeaders["wait"] = "wait";
69
- /**
70
- * True if the request is from an external app. Used for GC to handle scenarios where a data store
71
- * is deleted and requested via an external app.
72
- */
73
- RuntimeHeaders["externalRequest"] = "externalRequest";
74
63
  /** True if the request is coming from an IFluidHandle. */
75
64
  RuntimeHeaders["viaHandle"] = "viaHandle";
76
65
  })(RuntimeHeaders || (RuntimeHeaders = {}));
@@ -81,7 +70,6 @@ export const TombstoneResponseHeaderKey = "isTombstoned";
81
70
  /** Default values for Runtime Headers */
82
71
  export const defaultRuntimeHeaderData = {
83
72
  wait: true,
84
- externalRequest: false,
85
73
  viaHandle: false,
86
74
  allowTombstone: false,
87
75
  };
@@ -134,8 +122,7 @@ export function getDeviceSpec() {
134
122
  };
135
123
  }
136
124
  }
137
- catch (_a) {
138
- }
125
+ catch (_a) { }
139
126
  return {};
140
127
  }
141
128
  /**
@@ -147,7 +134,7 @@ export class ContainerRuntime extends TypedEventEmitter {
147
134
  * @internal
148
135
  */
149
136
  constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, requestHandler, summaryConfiguration) {
150
- var _a, _b, _c, _d, _e, _f;
137
+ var _a, _b, _c, _d, _e, _f, _g, _h;
151
138
  if (summaryConfiguration === void 0) { summaryConfiguration = Object.assign(Object.assign({}, DefaultSummaryConfiguration), (_a = runtimeOptions.summaryOptions) === null || _a === void 0 ? void 0 : _a.summaryConfigOverrides); }
152
139
  super();
153
140
  this.context = context;
@@ -160,7 +147,7 @@ export class ContainerRuntime extends TypedEventEmitter {
160
147
  this.summaryConfiguration = summaryConfiguration;
161
148
  this.defaultMaxConsecutiveReconnects = 7;
162
149
  this._orderSequentiallyCalls = 0;
163
- this.flushMicroTaskExists = false;
150
+ this.flushTaskExists = false;
164
151
  this.savedOps = [];
165
152
  this.consecutiveReconnects = 0;
166
153
  this.ensureNoDataModelChangesCalls = 0;
@@ -230,28 +217,48 @@ export class ContainerRuntime extends TypedEventEmitter {
230
217
  this.nextSummaryNumber = loadSummaryNumber + 1;
231
218
  this.messageAtLastSummary = metadata === null || metadata === void 0 ? void 0 : metadata.message;
232
219
  this._connected = this.context.connected;
220
+ this.gcTombstoneEnforcementAllowed = shouldAllowGcTombstoneEnforcement((_c = metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix) === null || _c === void 0 ? void 0 : _c.tombstoneGeneration /* persisted */, this.runtimeOptions.gcOptions[gcTombstoneGenerationOptionName] /* current */);
233
221
  this.mc = loggerToMonitoringContext(ChildLogger.create(this.logger, "ContainerRuntime"));
234
- const opSplitter = new OpSplitter(chunks, this.context.submitBatchFn, this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompressionChunking") === true ?
235
- Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
222
+ this.mc.logger.sendTelemetryEvent({
223
+ eventName: "GCFeatureMatrix",
224
+ metadataValue: JSON.stringify(metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix),
225
+ inputs: JSON.stringify({
226
+ gcOptions_gcTombstoneGeneration: this.runtimeOptions.gcOptions[gcTombstoneGenerationOptionName],
227
+ }),
228
+ });
229
+ this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
230
+ const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompressionChunking");
231
+ const opSplitter = new OpSplitter(chunks, this.context.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
236
232
  this.remoteMessageProcessor = new RemoteMessageProcessor(opSplitter, new OpDecompressor());
237
233
  this.handleContext = new ContainerFluidHandleContext("", this);
238
234
  if (this.summaryConfiguration.state === "enabled") {
239
235
  this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
240
236
  }
241
- this.enableOpReentryCheck = runtimeOptions.enableOpReentryCheck === true
242
- // Allow for a break-glass config to override the options
243
- && this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableOpReentryCheck") !== true;
237
+ const disableOpReentryCheck = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableOpReentryCheck");
238
+ this.enableOpReentryCheck =
239
+ runtimeOptions.enableOpReentryCheck === true &&
240
+ // Allow for a break-glass config to override the options
241
+ disableOpReentryCheck !== true;
244
242
  this.summariesDisabled = this.isSummariesDisabled();
245
243
  this.heuristicsDisabled = this.isHeuristicsDisabled();
246
244
  this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
247
245
  this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
248
246
  this.maxConsecutiveReconnects =
249
- (_c = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _c !== void 0 ? _c : this.defaultMaxConsecutiveReconnects;
250
- this._flushMode = runtimeOptions.flushMode;
247
+ (_d = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _d !== void 0 ? _d : this.defaultMaxConsecutiveReconnects;
248
+ if (runtimeOptions.flushMode === FlushModeExperimental.Async &&
249
+ ((_e = context.supportedFeatures) === null || _e === void 0 ? void 0 : _e.get("referenceSequenceNumbers")) !== true) {
250
+ // The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
251
+ this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
252
+ this._flushMode = FlushMode.TurnBased;
253
+ }
254
+ else {
255
+ this._flushMode = runtimeOptions.flushMode;
256
+ }
251
257
  const pendingRuntimeState = context.pendingLocalState;
252
- const baseSnapshot = (_d = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _d !== void 0 ? _d : context.baseSnapshot;
253
- const maxSnapshotCacheDurationMs = (_f = (_e = this._storage) === null || _e === void 0 ? void 0 : _e.policies) === null || _f === void 0 ? void 0 : _f.maximumCacheDurationMs;
254
- if (maxSnapshotCacheDurationMs !== undefined && maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
258
+ const baseSnapshot = (_f = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _f !== void 0 ? _f : context.baseSnapshot;
259
+ const maxSnapshotCacheDurationMs = (_h = (_g = this._storage) === null || _g === void 0 ? void 0 : _g.policies) === null || _h === void 0 ? void 0 : _h.maximumCacheDurationMs;
260
+ if (maxSnapshotCacheDurationMs !== undefined &&
261
+ maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
255
262
  // This is a runtime enforcement of what's already explicit in the policy's type itself,
256
263
  // which dictates the value is either undefined or exactly 5 days in ms.
257
264
  // As long as the actual value is less than 5 days, the assumptions GC makes here are valid.
@@ -296,12 +303,15 @@ export class ContainerRuntime extends TypedEventEmitter {
296
303
  if (baseSnapshot) {
297
304
  this.summarizerNode.updateBaseSummaryState(baseSnapshot);
298
305
  }
299
- this.dataStores = new DataStores(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));
306
+ this.dataStores = new DataStores(getSummaryForDatastores(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));
300
307
  this.blobManager = new BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
301
308
  if (!this.disposed) {
302
- this.submit(ContainerMessageType.BlobAttach, undefined, undefined, { localId, blobId });
309
+ this.submit(ContainerMessageType.BlobAttach, undefined, undefined, {
310
+ localId,
311
+ blobId,
312
+ });
303
313
  }
304
- }, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (fromPath, toPath) => this.garbageCollector.addedOutboundReference(fromPath, toPath), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs, () => this.getCurrentReferenceTimestampMs());
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());
305
315
  this.scheduleManager = new ScheduleManager(context.deltaManager, this, () => this.clientId, ChildLogger.create(this.logger, "ScheduleManager"));
306
316
  this.pendingStateManager = new PendingStateManager({
307
317
  applyStashedOp: this.applyStashedOp.bind(this),
@@ -312,11 +322,14 @@ export class ContainerRuntime extends TypedEventEmitter {
312
322
  rollback: this.rollback.bind(this),
313
323
  orderSequentially: this.orderSequentially.bind(this),
314
324
  }, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pending);
315
- const compressionOptions = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompression") === true ?
316
- {
325
+ const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompression");
326
+ const compressionOptions = disableCompression === true
327
+ ? {
317
328
  minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
318
- compressionAlgorithm: CompressionAlgorithms.lz4
319
- } : runtimeOptions.compressionOptions;
329
+ compressionAlgorithm: CompressionAlgorithms.lz4,
330
+ }
331
+ : runtimeOptions.compressionOptions;
332
+ const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
320
333
  this.outbox = new Outbox({
321
334
  shouldSend: () => this.canSendOps(),
322
335
  pendingStateManager: this.pendingStateManager,
@@ -326,7 +339,7 @@ export class ContainerRuntime extends TypedEventEmitter {
326
339
  config: {
327
340
  compressionOptions,
328
341
  maxBatchSizeInBytes: runtimeOptions.maxBatchSizeInBytes,
329
- enableOpReentryCheck: this.enableOpReentryCheck,
342
+ disablePartialFlush: disablePartialFlush === true,
330
343
  },
331
344
  logger: this.mc.logger,
332
345
  });
@@ -334,8 +347,9 @@ export class ContainerRuntime extends TypedEventEmitter {
334
347
  this.remoteMessageProcessor.clearPartialMessagesFor(clientId);
335
348
  });
336
349
  this.summaryCollection = new SummaryCollection(this.deltaManager, this.logger);
337
- this.dirtyContainer = this.context.attachState !== AttachState.Attached
338
- || this.pendingStateManager.hasPendingMessages();
350
+ this.dirtyContainer =
351
+ this.context.attachState !== AttachState.Attached ||
352
+ this.pendingStateManager.hasPendingMessages();
339
353
  this.context.updateDirtyContainerState(this.dirtyContainer);
340
354
  if (this.summariesDisabled) {
341
355
  this.mc.logger.sendTelemetryEvent({ eventName: "SummariesDisabled" });
@@ -399,12 +413,22 @@ export class ContainerRuntime extends TypedEventEmitter {
399
413
  });
400
414
  // logging hardware telemetry
401
415
  logger.sendTelemetryEvent(Object.assign({ eventName: "DeviceSpec" }, getDeviceSpec()));
402
- 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 }));
416
+ 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({
417
+ disableCompression,
418
+ disableOpReentryCheck,
419
+ disableChunking,
420
+ disableAttachReorder: this.disableAttachReorder,
421
+ disablePartialFlush,
422
+ }) }));
403
423
  ReportOpPerfTelemetry(this.context.clientId, this.deltaManager, this.logger);
404
424
  BindBatchTracker(this, this.logger);
405
425
  }
406
- get IContainerRuntime() { return this; }
407
- get IFluidRouter() { return this; }
426
+ get IContainerRuntime() {
427
+ return this;
428
+ }
429
+ get IFluidRouter() {
430
+ return this;
431
+ }
408
432
  /**
409
433
  * @deprecated - use loadRuntime instead.
410
434
  * Load the stores from a snapshot and returns the runtime.
@@ -445,7 +469,7 @@ export class ContainerRuntime extends TypedEventEmitter {
445
469
  */
446
470
  static async loadRuntime(params) {
447
471
  var _a, _b, _c, _d;
448
- const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime } = params;
472
+ const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, } = params;
449
473
  // If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
450
474
  // back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
451
475
  const backCompatContext = context;
@@ -457,13 +481,15 @@ export class ContainerRuntime extends TypedEventEmitter {
457
481
  });
458
482
  const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, enableOfflineLoad = false, compressionOptions = {
459
483
  minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
460
- compressionAlgorithm: CompressionAlgorithms.lz4
484
+ compressionAlgorithm: CompressionAlgorithms.lz4,
461
485
  }, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, chunkSizeInBytes = Number.POSITIVE_INFINITY, enableOpReentryCheck = false, } = runtimeOptions;
462
486
  const pendingRuntimeState = context.pendingLocalState;
463
487
  const baseSnapshot = (_b = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _b !== void 0 ? _b : context.baseSnapshot;
464
- const storage = !pendingRuntimeState ?
465
- context.storage :
466
- new SerializedSnapshotStorage(() => { return context.storage; }, pendingRuntimeState.snapshotBlobs);
488
+ const storage = !pendingRuntimeState
489
+ ? context.storage
490
+ : new SerializedSnapshotStorage(() => {
491
+ return context.storage;
492
+ }, pendingRuntimeState.snapshotBlobs);
467
493
  const registry = new FluidDataStoreRegistry(registryEntries);
468
494
  const tryFetchBlob = async (blobName) => {
469
495
  const blobId = baseSnapshot === null || baseSnapshot === void 0 ? void 0 : baseSnapshot.blobs[blobName];
@@ -494,7 +520,8 @@ export class ContainerRuntime extends TypedEventEmitter {
494
520
  if (!pendingRuntimeState && runtimeSequenceNumber !== undefined) {
495
521
  const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
496
522
  // Unless bypass is explicitly set, then take action when sequence numbers mismatch.
497
- if (loadSequenceNumberVerification !== "bypass" && runtimeSequenceNumber !== protocolSequenceNumber) {
523
+ if (loadSequenceNumberVerification !== "bypass" &&
524
+ runtimeSequenceNumber !== protocolSequenceNumber) {
498
525
  // "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
499
526
  const error = new DataCorruptionError(
500
527
  // pre-0.58 error message: SummaryMetadataMismatch
@@ -601,7 +628,9 @@ export class ContainerRuntime extends TypedEventEmitter {
601
628
  var _a;
602
629
  return (_a = this.summarizerClientElection) === null || _a === void 0 ? void 0 : _a.electedClientId;
603
630
  }
604
- get disposed() { return this._disposed; }
631
+ get disposed() {
632
+ return this._disposed;
633
+ }
605
634
  get summarizer() {
606
635
  assert(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
607
636
  return this._summarizer;
@@ -656,6 +685,9 @@ export class ContainerRuntime extends TypedEventEmitter {
656
685
  this.emit("dispose");
657
686
  this.removeAllListeners();
658
687
  }
688
+ /**
689
+ * @deprecated 2.0.0-internal.3.2.0 ContainerRuntime is not an IFluidTokenProvider. Token providers should be accessed using normal provider patterns.
690
+ */
659
691
  get IFluidTokenProvider() {
660
692
  var _a;
661
693
  if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.intelligence) {
@@ -711,7 +743,8 @@ export class ContainerRuntime extends TypedEventEmitter {
711
743
  status: 200,
712
744
  mimeType: "fluid/object",
713
745
  value: blob,
714
- } : create404Response(request);
746
+ }
747
+ : create404Response(request);
715
748
  }
716
749
  else if (requestParser.pathParts.length > 0) {
717
750
  const dataStore = await this.getDataStoreFromRequest(id, request);
@@ -732,7 +765,7 @@ export class ContainerRuntime extends TypedEventEmitter {
732
765
  return (_a = this.dataStores.aliases.get(maybeAlias)) !== null && _a !== void 0 ? _a : maybeAlias;
733
766
  }
734
767
  async getDataStoreFromRequest(id, request) {
735
- var _a, _b, _c, _d;
768
+ var _a, _b, _c;
736
769
  const headerData = {};
737
770
  if (typeof ((_a = request.headers) === null || _a === void 0 ? void 0 : _a[RuntimeHeaders.wait]) === "boolean") {
738
771
  headerData.wait = request.headers[RuntimeHeaders.wait];
@@ -746,22 +779,6 @@ export class ContainerRuntime extends TypedEventEmitter {
746
779
  await this.dataStores.waitIfPendingAlias(id);
747
780
  const internalId = this.internalId(id);
748
781
  const dataStoreContext = await this.dataStores.getDataStore(internalId, headerData);
749
- /**
750
- * If GC should run and this an external app request with "externalRequest" header, we need to return
751
- * an error if the data store being requested is marked as unreferenced as per the data store's base
752
- * GC data.
753
- *
754
- * This is a workaround to handle scenarios where a data store shared with an external app is deleted
755
- * and marked as unreferenced by GC. Returning an error will fail to load the data store for the app.
756
- */
757
- if (((_d = request.headers) === null || _d === void 0 ? void 0 : _d[RuntimeHeaders.externalRequest]) && this.garbageCollector.shouldRunGC) {
758
- // The data store is referenced if used routes in the base summary has a route to self.
759
- // Older documents may not have used routes in the summary. They are considered referenced.
760
- const usedRoutes = (await dataStoreContext.getBaseGCDetails()).usedRoutes;
761
- if (!(usedRoutes === undefined || usedRoutes.includes("") || usedRoutes.includes("/"))) {
762
- throw responseToException(create404Response(request), request);
763
- }
764
- }
765
782
  const dataStoreChannel = await dataStoreContext.realize();
766
783
  // Remove query params, leading and trailing slashes from the url. This is done to make sure the format is
767
784
  // the same as GC nodes id.
@@ -928,7 +945,7 @@ export class ContainerRuntime extends TypedEventEmitter {
928
945
  if (reconnection) {
929
946
  this.consecutiveReconnects++;
930
947
  if (!this.shouldContinueReconnecting()) {
931
- this.closeFn(DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops. Batch of ops is likely too large (over 1Mb)", "setConnectionState", undefined, {
948
+ this.closeFn(DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops.", "setConnectionState", undefined, {
932
949
  dataLoss: 1,
933
950
  attempts: this.consecutiveReconnects,
934
951
  pendingMessages: this.pendingStateManager.pendingMessagesCount,
@@ -1035,7 +1052,8 @@ export class ContainerRuntime extends TypedEventEmitter {
1035
1052
  if (message.clientId === this.clientId && this.connected) {
1036
1053
  // Check to see if the signal was lost.
1037
1054
  if (this._perfSignalData.trackingSignalSequenceNumber !== undefined &&
1038
- envelope.clientSignalSequenceNumber > this._perfSignalData.trackingSignalSequenceNumber) {
1055
+ envelope.clientSignalSequenceNumber >
1056
+ this._perfSignalData.trackingSignalSequenceNumber) {
1039
1057
  this._perfSignalData.signalsLost++;
1040
1058
  this._perfSignalData.trackingSignalSequenceNumber = undefined;
1041
1059
  this.logger.sendErrorEvent({
@@ -1046,7 +1064,10 @@ export class ContainerRuntime extends TypedEventEmitter {
1046
1064
  clientSignalSequenceNumber: envelope.clientSignalSequenceNumber,
1047
1065
  });
1048
1066
  }
1049
- else if (envelope.clientSignalSequenceNumber === this._perfSignalData.trackingSignalSequenceNumber) {
1067
+ else if (this.consecutiveReconnects === 0 &&
1068
+ envelope.clientSignalSequenceNumber ===
1069
+ this._perfSignalData.trackingSignalSequenceNumber) {
1070
+ // only logging for the first connection and the trackingSignalSequenceNUmber.
1050
1071
  this.sendSignalTelemetryEvent(envelope.clientSignalSequenceNumber);
1051
1072
  this._perfSignalData.trackingSignalSequenceNumber = undefined;
1052
1073
  }
@@ -1133,7 +1154,9 @@ export class ContainerRuntime extends TypedEventEmitter {
1133
1154
  return this.dataStores.createDetachedDataStoreCore(pkg, false);
1134
1155
  }
1135
1156
  async _createDataStoreWithProps(pkg, props, id = uuid()) {
1136
- const fluidDataStore = await this.dataStores._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props).realize();
1157
+ const fluidDataStore = await this.dataStores
1158
+ ._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props)
1159
+ .realize();
1137
1160
  return channelToDataStore(fluidDataStore, id, this, this.dataStores, this.mc.logger);
1138
1161
  }
1139
1162
  async _createDataStore(pkg, id = uuid(), props) {
@@ -1148,7 +1171,7 @@ export class ContainerRuntime extends TypedEventEmitter {
1148
1171
  * Are we in the middle of batching ops together?
1149
1172
  */
1150
1173
  currentlyBatching() {
1151
- return this.flushMode === FlushMode.TurnBased || this._orderSequentiallyCalls !== 0;
1174
+ return this.flushMode !== FlushMode.Immediate || this._orderSequentiallyCalls !== 0;
1152
1175
  }
1153
1176
  getQuorum() {
1154
1177
  return this.context.quorum;
@@ -1266,7 +1289,7 @@ export class ContainerRuntime extends TypedEventEmitter {
1266
1289
  const { fullTree = false, trackState = true, summaryLogger = this.mc.logger, runGC = this.garbageCollector.shouldRunGC, runSweep, fullGC, } = options;
1267
1290
  const telemetryContext = new TelemetryContext();
1268
1291
  // Add the options that are used to generate this summary to the telemetry context.
1269
- telemetryContext.setAll("fluid_Summarize", "Options", {
1292
+ telemetryContext.setMultiple("fluid_Summarize", "Options", {
1270
1293
  fullTree,
1271
1294
  trackState,
1272
1295
  runGC,
@@ -1278,7 +1301,10 @@ export class ContainerRuntime extends TypedEventEmitter {
1278
1301
  gcStats = await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC }, telemetryContext);
1279
1302
  }
1280
1303
  const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
1281
- this.logger.sendTelemetryEvent({ eventName: "SummarizeTelemetry", details: telemetryContext.serialize() });
1304
+ this.logger.sendTelemetryEvent({
1305
+ eventName: "SummarizeTelemetry",
1306
+ details: telemetryContext.serialize(),
1307
+ });
1282
1308
  assert(summary.type === SummaryType.Tree, 0x12f /* "Container Runtime's summarize should always return a tree" */);
1283
1309
  return { stats, summary, gcStats };
1284
1310
  }
@@ -1329,6 +1355,22 @@ export class ContainerRuntime extends TypedEventEmitter {
1329
1355
  this.blobManager.updateUnusedRoutes(blobManagerRoutes);
1330
1356
  this.dataStores.updateUnusedRoutes(dataStoreRoutes);
1331
1357
  }
1358
+ /**
1359
+ * @deprecated - Replaced by deleteSweepReadyNodes.
1360
+ */
1361
+ deleteUnusedNodes(unusedRoutes) {
1362
+ throw new Error("deleteUnusedRoutes should not be called");
1363
+ }
1364
+ /**
1365
+ * After GC has run and identified nodes that are sweep ready, this is called to delete the sweep ready nodes.
1366
+ * @param sweepReadyRoutes - The routes of nodes that are sweep ready and should be deleted.
1367
+ * @returns - The routes of nodes that were deleted.
1368
+ */
1369
+ deleteSweepReadyNodes(sweepReadyRoutes) {
1370
+ const { dataStoreRoutes, blobManagerRoutes } = this.getDataStoreAndBlobManagerRoutes(sweepReadyRoutes);
1371
+ const deletedRoutes = this.dataStores.deleteSweepReadyNodes(dataStoreRoutes);
1372
+ return deletedRoutes.concat(this.blobManager.deleteSweepReadyNodes(blobManagerRoutes));
1373
+ }
1332
1374
  /**
1333
1375
  * This is called to update objects that are tombstones.
1334
1376
  * @param tombstonedRoutes - Data store and attachment blob routes that are tombstones in this Container.
@@ -1444,8 +1486,12 @@ export class ContainerRuntime extends TypedEventEmitter {
1444
1486
  // We might need to catch up to the latest summary's reference sequence number before pausing.
1445
1487
  await this.waitForDeltaManagerToCatchup(latestSnapshotRefSeq, summaryNumberLogger);
1446
1488
  }
1489
+ const shouldPauseInboundSignal = this.mc.config.getBoolean("Fluid.ContainerRuntime.SubmitSummary.disableInboundSignalPause") !== true;
1447
1490
  try {
1448
1491
  await this.deltaManager.inbound.pause();
1492
+ if (shouldPauseInboundSignal) {
1493
+ await this.deltaManager.inboundSignal.pause();
1494
+ }
1449
1495
  const summaryRefSeqNum = this.deltaManager.lastSequenceNumber;
1450
1496
  const minimumSequenceNumber = this.deltaManager.minimumSequenceNumber;
1451
1497
  const message = `Summary @${summaryRefSeqNum}:${this.deltaManager.minimumSequenceNumber}`;
@@ -1546,8 +1592,8 @@ export class ContainerRuntime extends TypedEventEmitter {
1546
1592
  // latestSnapshotVersionId from storage and it does not match with the lastAck ackHandle, then use
1547
1593
  // the one fetched from storage as parent as that is the latest.
1548
1594
  let summaryContext;
1549
- if ((lastAck === null || lastAck === void 0 ? void 0 : lastAck.summaryAck.contents.handle) !== latestSnapshotVersionId
1550
- && latestSnapshotVersionId !== undefined) {
1595
+ if ((lastAck === null || lastAck === void 0 ? void 0 : lastAck.summaryAck.contents.handle) !== latestSnapshotVersionId &&
1596
+ latestSnapshotVersionId !== undefined) {
1551
1597
  summaryContext = {
1552
1598
  proposalHandle: undefined,
1553
1599
  ackHandle: latestSnapshotVersionId,
@@ -1590,7 +1636,7 @@ export class ContainerRuntime extends TypedEventEmitter {
1590
1636
  }
1591
1637
  let clientSequenceNumber;
1592
1638
  try {
1593
- clientSequenceNumber = this.submitSummaryMessage(summaryMessage);
1639
+ clientSequenceNumber = this.submitSummaryMessage(summaryMessage, summaryRefSeqNum);
1594
1640
  }
1595
1641
  catch (error) {
1596
1642
  return Object.assign(Object.assign({ stage: "upload" }, uploadData), { error });
@@ -1604,6 +1650,9 @@ export class ContainerRuntime extends TypedEventEmitter {
1604
1650
  this.summarizerNode.clearSummary();
1605
1651
  // Restart the delta manager
1606
1652
  this.deltaManager.inbound.resume();
1653
+ if (shouldPauseInboundSignal) {
1654
+ this.deltaManager.inboundSignal.resume();
1655
+ }
1607
1656
  }
1608
1657
  }
1609
1658
  hasPendingMessages() {
@@ -1649,14 +1698,16 @@ export class ContainerRuntime extends TypedEventEmitter {
1649
1698
  this.verifyCanSubmitOps();
1650
1699
  // There should be no ops in detached container state!
1651
1700
  assert(this.attachState !== AttachState.Detached, 0x132 /* "sending ops in detached container" */);
1652
- const deserializedContent = { type, contents };
1653
- const serializedContent = JSON.stringify(deserializedContent);
1701
+ const serializedContent = JSON.stringify({ type, contents });
1654
1702
  if (this.deltaManager.readOnlyInfo.readonly) {
1655
- this.logger.sendTelemetryEvent({ eventName: "SubmitOpInReadonly", connected: this.connected });
1703
+ this.logger.sendTelemetryEvent({
1704
+ eventName: "SubmitOpInReadonly",
1705
+ connected: this.connected,
1706
+ });
1656
1707
  }
1657
1708
  const message = {
1658
1709
  contents: serializedContent,
1659
- deserializedContent,
1710
+ deserializedContent: JSON.parse(serializedContent),
1660
1711
  metadata,
1661
1712
  localOpMetadata,
1662
1713
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
@@ -1682,8 +1733,9 @@ export class ContainerRuntime extends TypedEventEmitter {
1682
1733
  // issue than sending.
1683
1734
  // Please note that this does not change file format, so it can be disabled in the future if this
1684
1735
  // optimization no longer makes sense (for example, batch compression may make it less appealing).
1685
- if (this.currentlyBatching() && type === ContainerMessageType.Attach &&
1686
- this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder") !== true) {
1736
+ if (this.currentlyBatching() &&
1737
+ type === ContainerMessageType.Attach &&
1738
+ this.disableAttachReorder !== true) {
1687
1739
  this.outbox.submitAttach(message);
1688
1740
  }
1689
1741
  else {
@@ -1692,13 +1744,8 @@ export class ContainerRuntime extends TypedEventEmitter {
1692
1744
  if (!this.currentlyBatching()) {
1693
1745
  this.flush();
1694
1746
  }
1695
- else if (!this.flushMicroTaskExists) {
1696
- this.flushMicroTaskExists = true;
1697
- // Queue a microtask to detect the end of the turn and force a flush.
1698
- Promise.resolve().then(() => {
1699
- this.flushMicroTaskExists = false;
1700
- this.flush();
1701
- }).catch((error) => { this.closeFn(error); });
1747
+ else {
1748
+ this.scheduleFlush();
1702
1749
  }
1703
1750
  }
1704
1751
  catch (error) {
@@ -1709,14 +1756,47 @@ export class ContainerRuntime extends TypedEventEmitter {
1709
1756
  this.updateDocumentDirtyState(true);
1710
1757
  }
1711
1758
  }
1712
- submitSummaryMessage(contents) {
1759
+ scheduleFlush() {
1760
+ if (this.flushTaskExists) {
1761
+ return;
1762
+ }
1763
+ this.flushTaskExists = true;
1764
+ const flush = () => {
1765
+ this.flushTaskExists = false;
1766
+ try {
1767
+ this.flush();
1768
+ }
1769
+ catch (error) {
1770
+ this.closeFn(error);
1771
+ }
1772
+ };
1773
+ switch (this.flushMode) {
1774
+ case FlushMode.TurnBased:
1775
+ // When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
1776
+ // batch at the end of the turn
1777
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1778
+ Promise.resolve().then(flush);
1779
+ break;
1780
+ // FlushModeExperimental is experimental and not exposed directly in the runtime APIs
1781
+ case FlushModeExperimental.Async:
1782
+ // When in Async flush mode, the runtime will accumulate all operations across JS turns and send them as a single
1783
+ // batch when all micro-tasks are complete.
1784
+ // Compared to TurnBased, this flush mode will capture more ops into the same batch.
1785
+ setTimeout(flush, 0);
1786
+ break;
1787
+ default:
1788
+ assert(this._orderSequentiallyCalls > 0, 0x587 /* Unreachable unless running under orderSequentially */);
1789
+ break;
1790
+ }
1791
+ }
1792
+ submitSummaryMessage(contents, referenceSequenceNumber) {
1713
1793
  this.verifyNotClosed();
1714
1794
  assert(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
1715
1795
  // System message should not be sent in the middle of the batch.
1716
1796
  assert(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
1717
1797
  // back-compat: ADO #1385: Make this call unconditional in the future
1718
1798
  return this.context.submitSummaryFn !== undefined
1719
- ? this.context.submitSummaryFn(contents)
1799
+ ? this.context.submitSummaryFn(contents, referenceSequenceNumber)
1720
1800
  : this.context.submitFn(MessageType.Summarize, contents, false);
1721
1801
  }
1722
1802
  /**
@@ -1813,7 +1893,7 @@ export class ContainerRuntime extends TypedEventEmitter {
1813
1893
  // It should only be done by the summarizerNode, if required.
1814
1894
  // When fetching from storage we will always get the latest version and do not use the ackHandle.
1815
1895
  const fetchLatestSnapshot = async () => {
1816
- const fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
1896
+ let fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
1817
1897
  eventName: "RefreshLatestSummaryAckFetch",
1818
1898
  ackHandle,
1819
1899
  targetSequenceNumber: summaryRefSeq,
@@ -1829,13 +1909,21 @@ export class ContainerRuntime extends TypedEventEmitter {
1829
1909
  * state.
1830
1910
  */
1831
1911
  if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
1832
- const error = DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
1912
+ /* before failing, let's try to retrieve the latest snapshot for that specific ackHandle */
1913
+ fetchResult = await this.fetchSnapshotFromStorage(summaryLogger, {
1914
+ eventName: "RefreshLatestSummaryAckFetch",
1833
1915
  ackHandle,
1834
- summaryRefSeq,
1835
- latestSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
1836
- });
1837
- this.closeFn(error);
1838
- throw error;
1916
+ targetSequenceNumber: summaryRefSeq,
1917
+ }, readAndParseBlob, ackHandle);
1918
+ if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
1919
+ const error = DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
1920
+ ackHandle,
1921
+ summaryRefSeq,
1922
+ fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
1923
+ });
1924
+ this.closeFn(error);
1925
+ throw error;
1926
+ }
1839
1927
  }
1840
1928
  // In case we had to retrieve the latest snapshot and it is different than summaryRefSeq,
1841
1929
  // wait for the delta manager to catch up before refreshing the latest Summary.
@@ -1870,10 +1958,13 @@ export class ContainerRuntime extends TypedEventEmitter {
1870
1958
  return { latestSnapshotRefSeq, latestSnapshotVersionId: versionId };
1871
1959
  }
1872
1960
  async fetchLatestSnapshotFromStorage(logger, event, readAndParseBlob) {
1961
+ return this.fetchSnapshotFromStorage(logger, event, readAndParseBlob, null /* latest */);
1962
+ }
1963
+ async fetchSnapshotFromStorage(logger, event, readAndParseBlob, versionId) {
1873
1964
  return PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
1874
1965
  const stats = {};
1875
1966
  const trace = Trace.start();
1876
- const versions = await this.storage.getVersions(null, 1, "refreshLatestSummaryAckFromServer", FetchSource.noCache);
1967
+ const versions = await this.storage.getVersions(versionId, 1, "refreshLatestSummaryAckFromServer", versionId === null ? FetchSource.noCache : undefined);
1877
1968
  assert(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
1878
1969
  stats.getVersionDuration = trace.trace().duration;
1879
1970
  const maybeSnapshot = await this.storage.getSnapshotTree(versions[0]);
@@ -1893,13 +1984,15 @@ export class ContainerRuntime extends TypedEventEmitter {
1893
1984
  notifyAttaching(snapshot) {
1894
1985
  var _a;
1895
1986
  if ((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) {
1896
- this.baseSnapshotBlobs = SerializedSnapshotStorage.serializeTreeWithBlobContents(snapshot);
1987
+ this.baseSnapshotBlobs =
1988
+ SerializedSnapshotStorage.serializeTreeWithBlobContents(snapshot);
1897
1989
  }
1898
1990
  }
1899
1991
  async initializeBaseSnapshotBlobs() {
1900
1992
  var _a;
1901
1993
  if (!((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) ||
1902
- this.attachState !== AttachState.Attached || this.context.pendingLocalState) {
1994
+ this.attachState !== AttachState.Attached ||
1995
+ this.context.pendingLocalState) {
1903
1996
  return;
1904
1997
  }
1905
1998
  assert(!!this.context.baseSnapshot, 0x2e5 /* "Must have a base snapshot" */);