@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
@@ -14,20 +14,14 @@ const garbage_collector_1 = require("@fluidframework/garbage-collector");
14
14
  const uuid_1 = require("uuid");
15
15
  const containerHandleContext_1 = require("./containerHandleContext");
16
16
  const dataStoreRegistry_1 = require("./dataStoreRegistry");
17
- const summarizer_1 = require("./summarizer");
18
- const summaryManager_1 = require("./summaryManager");
19
17
  const connectionTelemetry_1 = require("./connectionTelemetry");
20
18
  const pendingStateManager_1 = require("./pendingStateManager");
21
19
  const packageVersion_1 = require("./packageVersion");
22
20
  const blobManager_1 = require("./blobManager");
23
21
  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");
22
+ const summary_1 = require("./summary");
28
23
  const throttler_1 = require("./throttler");
29
- const runWhileConnectedCoordinator_1 = require("./runWhileConnectedCoordinator");
30
- const garbageCollection_1 = require("./garbageCollection");
24
+ const gc_1 = require("./gc");
31
25
  const dataStore_1 = require("./dataStore");
32
26
  const batchTracker_1 = require("./batchTracker");
33
27
  const serializedSnapshotStorage_1 = require("./serializedSnapshotStorage");
@@ -69,11 +63,6 @@ var RuntimeHeaders;
69
63
  (function (RuntimeHeaders) {
70
64
  /** True to wait for a data store to be created and loaded before returning it. */
71
65
  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
66
  /** True if the request is coming from an IFluidHandle. */
78
67
  RuntimeHeaders["viaHandle"] = "viaHandle";
79
68
  })(RuntimeHeaders = exports.RuntimeHeaders || (exports.RuntimeHeaders = {}));
@@ -84,7 +73,6 @@ exports.TombstoneResponseHeaderKey = "isTombstoned";
84
73
  /** Default values for Runtime Headers */
85
74
  exports.defaultRuntimeHeaderData = {
86
75
  wait: true,
87
- externalRequest: false,
88
76
  viaHandle: false,
89
77
  allowTombstone: false,
90
78
  };
@@ -138,8 +126,7 @@ function getDeviceSpec() {
138
126
  };
139
127
  }
140
128
  }
141
- catch (_a) {
142
- }
129
+ catch (_a) { }
143
130
  return {};
144
131
  }
145
132
  exports.getDeviceSpec = getDeviceSpec;
@@ -152,7 +139,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
152
139
  * @internal
153
140
  */
154
141
  constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, requestHandler, summaryConfiguration) {
155
- var _a, _b, _c, _d, _e, _f;
142
+ var _a, _b, _c, _d, _e, _f, _g, _h;
156
143
  if (summaryConfiguration === void 0) { summaryConfiguration = Object.assign(Object.assign({}, exports.DefaultSummaryConfiguration), (_a = runtimeOptions.summaryOptions) === null || _a === void 0 ? void 0 : _a.summaryConfigOverrides); }
157
144
  super();
158
145
  this.context = context;
@@ -165,7 +152,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
165
152
  this.summaryConfiguration = summaryConfiguration;
166
153
  this.defaultMaxConsecutiveReconnects = 7;
167
154
  this._orderSequentiallyCalls = 0;
168
- this.flushMicroTaskExists = false;
155
+ this.flushTaskExists = false;
169
156
  this.savedOps = [];
170
157
  this.consecutiveReconnects = 0;
171
158
  this.ensureNoDataModelChangesCalls = 0;
@@ -186,7 +173,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
186
173
  trackingSignalSequenceNumber: undefined,
187
174
  };
188
175
  this.summarizeOnDemand = (...args) => {
189
- if (this.clientDetails.type === summarizerClientElection_1.summarizerClientType) {
176
+ if (this.clientDetails.type === summary_1.summarizerClientType) {
190
177
  return this.summarizer.summarizeOnDemand(...args);
191
178
  }
192
179
  else if (this.summaryManager !== undefined) {
@@ -200,7 +187,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
200
187
  }
201
188
  };
202
189
  this.enqueueSummarize = (...args) => {
203
- if (this.clientDetails.type === summarizerClientElection_1.summarizerClientType) {
190
+ if (this.clientDetails.type === summary_1.summarizerClientType) {
204
191
  return this.summarizer.enqueueSummarize(...args);
205
192
  }
206
193
  else if (this.summaryManager !== undefined) {
@@ -235,34 +222,54 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
235
222
  this.nextSummaryNumber = loadSummaryNumber + 1;
236
223
  this.messageAtLastSummary = metadata === null || metadata === void 0 ? void 0 : metadata.message;
237
224
  this._connected = this.context.connected;
225
+ 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 */);
238
226
  this.mc = (0, telemetry_utils_1.loggerToMonitoringContext)(telemetry_utils_1.ChildLogger.create(this.logger, "ContainerRuntime"));
239
- const opSplitter = new opLifecycle_1.OpSplitter(chunks, this.context.submitBatchFn, this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompressionChunking") === true ?
240
- Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
227
+ this.mc.logger.sendTelemetryEvent({
228
+ eventName: "GCFeatureMatrix",
229
+ metadataValue: JSON.stringify(metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix),
230
+ inputs: JSON.stringify({
231
+ gcOptions_gcTombstoneGeneration: this.runtimeOptions.gcOptions[gc_1.gcTombstoneGenerationOptionName],
232
+ }),
233
+ });
234
+ this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
235
+ const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompressionChunking");
236
+ const opSplitter = new opLifecycle_1.OpSplitter(chunks, this.context.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
241
237
  this.remoteMessageProcessor = new opLifecycle_1.RemoteMessageProcessor(opSplitter, new opLifecycle_1.OpDecompressor());
242
238
  this.handleContext = new containerHandleContext_1.ContainerFluidHandleContext("", this);
243
239
  if (this.summaryConfiguration.state === "enabled") {
244
240
  this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
245
241
  }
246
- this.enableOpReentryCheck = runtimeOptions.enableOpReentryCheck === true
247
- // Allow for a break-glass config to override the options
248
- && this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableOpReentryCheck") !== true;
242
+ const disableOpReentryCheck = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableOpReentryCheck");
243
+ this.enableOpReentryCheck =
244
+ runtimeOptions.enableOpReentryCheck === true &&
245
+ // Allow for a break-glass config to override the options
246
+ disableOpReentryCheck !== true;
249
247
  this.summariesDisabled = this.isSummariesDisabled();
250
248
  this.heuristicsDisabled = this.isHeuristicsDisabled();
251
249
  this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
252
250
  this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
253
251
  this.maxConsecutiveReconnects =
254
- (_c = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _c !== void 0 ? _c : this.defaultMaxConsecutiveReconnects;
255
- this._flushMode = runtimeOptions.flushMode;
252
+ (_d = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _d !== void 0 ? _d : this.defaultMaxConsecutiveReconnects;
253
+ if (runtimeOptions.flushMode === runtime_definitions_1.FlushModeExperimental.Async &&
254
+ ((_e = context.supportedFeatures) === null || _e === void 0 ? void 0 : _e.get("referenceSequenceNumbers")) !== true) {
255
+ // The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
256
+ this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
257
+ this._flushMode = runtime_definitions_1.FlushMode.TurnBased;
258
+ }
259
+ else {
260
+ this._flushMode = runtimeOptions.flushMode;
261
+ }
256
262
  const pendingRuntimeState = context.pendingLocalState;
257
- const baseSnapshot = (_d = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _d !== void 0 ? _d : context.baseSnapshot;
258
- const maxSnapshotCacheDurationMs = (_f = (_e = this._storage) === null || _e === void 0 ? void 0 : _e.policies) === null || _f === void 0 ? void 0 : _f.maximumCacheDurationMs;
259
- if (maxSnapshotCacheDurationMs !== undefined && maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
263
+ const baseSnapshot = (_f = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _f !== void 0 ? _f : context.baseSnapshot;
264
+ const maxSnapshotCacheDurationMs = (_h = (_g = this._storage) === null || _g === void 0 ? void 0 : _g.policies) === null || _h === void 0 ? void 0 : _h.maximumCacheDurationMs;
265
+ if (maxSnapshotCacheDurationMs !== undefined &&
266
+ maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
260
267
  // This is a runtime enforcement of what's already explicit in the policy's type itself,
261
268
  // which dictates the value is either undefined or exactly 5 days in ms.
262
269
  // As long as the actual value is less than 5 days, the assumptions GC makes here are valid.
263
270
  throw new container_utils_1.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
264
271
  }
265
- this.garbageCollector = garbageCollection_1.GarbageCollector.create({
272
+ this.garbageCollector = gc_1.GarbageCollector.create({
266
273
  runtime: this,
267
274
  gcOptions: this.runtimeOptions.gcOptions,
268
275
  baseSnapshot,
@@ -270,7 +277,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
270
277
  existing,
271
278
  metadata,
272
279
  createContainerMetadata: this.createContainerMetadata,
273
- isSummarizerClient: this.context.clientDetails.type === summarizerClientElection_1.summarizerClientType,
280
+ isSummarizerClient: this.context.clientDetails.type === summary_1.summarizerClientType,
274
281
  getNodePackagePath: async (nodePath) => this.getGCNodePackagePath(nodePath),
275
282
  getLastSummaryTimestampMs: () => { var _a; return (_a = this.messageAtLastSummary) === null || _a === void 0 ? void 0 : _a.timestamp; },
276
283
  readAndParseBlob: async (id) => (0, driver_utils_1.readAndParse)(this.storage, id),
@@ -301,12 +308,15 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
301
308
  if (baseSnapshot) {
302
309
  this.summarizerNode.updateBaseSummaryState(baseSnapshot);
303
310
  }
304
- 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));
311
+ this.dataStores = new dataStores_1.DataStores((0, dataStores_1.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));
305
312
  this.blobManager = new blobManager_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (localId, blobId) => {
306
313
  if (!this.disposed) {
307
- this.submit(ContainerMessageType.BlobAttach, undefined, undefined, { localId, blobId });
314
+ this.submit(ContainerMessageType.BlobAttach, undefined, undefined, {
315
+ localId,
316
+ blobId,
317
+ });
308
318
  }
309
- }, (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());
319
+ }, (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());
310
320
  this.scheduleManager = new scheduleManager_1.ScheduleManager(context.deltaManager, this, () => this.clientId, telemetry_utils_1.ChildLogger.create(this.logger, "ScheduleManager"));
311
321
  this.pendingStateManager = new pendingStateManager_1.PendingStateManager({
312
322
  applyStashedOp: this.applyStashedOp.bind(this),
@@ -317,11 +327,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
317
327
  rollback: this.rollback.bind(this),
318
328
  orderSequentially: this.orderSequentially.bind(this),
319
329
  }, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pending);
320
- const compressionOptions = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompression") === true ?
321
- {
330
+ const disableCompression = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableCompression");
331
+ const compressionOptions = disableCompression === true
332
+ ? {
322
333
  minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
323
- compressionAlgorithm: CompressionAlgorithms.lz4
324
- } : runtimeOptions.compressionOptions;
334
+ compressionAlgorithm: CompressionAlgorithms.lz4,
335
+ }
336
+ : runtimeOptions.compressionOptions;
337
+ const disablePartialFlush = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisablePartialFlush");
325
338
  this.outbox = new opLifecycle_1.Outbox({
326
339
  shouldSend: () => this.canSendOps(),
327
340
  pendingStateManager: this.pendingStateManager,
@@ -331,29 +344,30 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
331
344
  config: {
332
345
  compressionOptions,
333
346
  maxBatchSizeInBytes: runtimeOptions.maxBatchSizeInBytes,
334
- enableOpReentryCheck: this.enableOpReentryCheck,
347
+ disablePartialFlush: disablePartialFlush === true,
335
348
  },
336
349
  logger: this.mc.logger,
337
350
  });
338
351
  this.context.quorum.on("removeMember", (clientId) => {
339
352
  this.remoteMessageProcessor.clearPartialMessagesFor(clientId);
340
353
  });
341
- this.summaryCollection = new summaryCollection_1.SummaryCollection(this.deltaManager, this.logger);
342
- this.dirtyContainer = this.context.attachState !== container_definitions_1.AttachState.Attached
343
- || this.pendingStateManager.hasPendingMessages();
354
+ this.summaryCollection = new summary_1.SummaryCollection(this.deltaManager, this.logger);
355
+ this.dirtyContainer =
356
+ this.context.attachState !== container_definitions_1.AttachState.Attached ||
357
+ this.pendingStateManager.hasPendingMessages();
344
358
  this.context.updateDirtyContainerState(this.dirtyContainer);
345
359
  if (this.summariesDisabled) {
346
360
  this.mc.logger.sendTelemetryEvent({ eventName: "SummariesDisabled" });
347
361
  }
348
362
  else {
349
363
  const orderedClientLogger = telemetry_utils_1.ChildLogger.create(this.logger, "OrderedClientElection");
350
- const orderedClientCollection = new orderedClientElection_1.OrderedClientCollection(orderedClientLogger, this.context.deltaManager, this.context.quorum);
351
- const orderedClientElectionForSummarizer = new orderedClientElection_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData !== null && electedSummarizerData !== void 0 ? electedSummarizerData : this.context.deltaManager.lastSequenceNumber, summarizerClientElection_1.SummarizerClientElection.isClientEligible);
352
- this.summarizerClientElection = new summarizerClientElection_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
353
- if (this.context.clientDetails.type === summarizerClientElection_1.summarizerClientType) {
354
- this._summarizer = new summarizer_1.Summarizer("/_summarizer", this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => runWhileConnectedCoordinator_1.RunWhileConnectedCoordinator.create(runtime));
364
+ const orderedClientCollection = new summary_1.OrderedClientCollection(orderedClientLogger, this.context.deltaManager, this.context.quorum);
365
+ const orderedClientElectionForSummarizer = new summary_1.OrderedClientElection(orderedClientLogger, orderedClientCollection, electedSummarizerData !== null && electedSummarizerData !== void 0 ? electedSummarizerData : this.context.deltaManager.lastSequenceNumber, summary_1.SummarizerClientElection.isClientEligible);
366
+ this.summarizerClientElection = new summary_1.SummarizerClientElection(orderedClientLogger, this.summaryCollection, orderedClientElectionForSummarizer, this.maxOpsSinceLastSummary);
367
+ if (this.context.clientDetails.type === summary_1.summarizerClientType) {
368
+ this._summarizer = new summary_1.Summarizer("/_summarizer", this /* ISummarizerRuntime */, () => this.summaryConfiguration, this /* ISummarizerInternalsProvider */, this.handleContext, this.summaryCollection, async (runtime) => summary_1.RunWhileConnectedCoordinator.create(runtime));
355
369
  }
356
- else if (summarizerClientElection_1.SummarizerClientElection.clientDetailsPermitElection(this.context.clientDetails)) {
370
+ else if (summary_1.SummarizerClientElection.clientDetailsPermitElection(this.context.clientDetails)) {
357
371
  // Only create a SummaryManager and SummarizerClientElection
358
372
  // if summaries are enabled and we are not the summarizer client.
359
373
  const defaultAction = () => {
@@ -373,7 +387,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
373
387
  };
374
388
  this.summaryCollection.on("default", defaultAction);
375
389
  // Create the SummaryManager and mark the initial state
376
- this.summaryManager = new summaryManager_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
390
+ this.summaryManager = new summary_1.SummaryManager(this.summarizerClientElection, this, // IConnectedState
377
391
  this.summaryCollection, this.logger, this.formRequestSummarizerFn(this.context.loader), new throttler_1.Throttler(60 * 1000, // 60 sec delay window
378
392
  30 * 1000, // 30 sec max delay
379
393
  // throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
@@ -404,12 +418,22 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
404
418
  });
405
419
  // logging hardware telemetry
406
420
  logger.sendTelemetryEvent(Object.assign({ eventName: "DeviceSpec" }, getDeviceSpec()));
407
- 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 }));
421
+ 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({
422
+ disableCompression,
423
+ disableOpReentryCheck,
424
+ disableChunking,
425
+ disableAttachReorder: this.disableAttachReorder,
426
+ disablePartialFlush,
427
+ }) }));
408
428
  (0, connectionTelemetry_1.ReportOpPerfTelemetry)(this.context.clientId, this.deltaManager, this.logger);
409
429
  (0, batchTracker_1.BindBatchTracker)(this, this.logger);
410
430
  }
411
- get IContainerRuntime() { return this; }
412
- get IFluidRouter() { return this; }
431
+ get IContainerRuntime() {
432
+ return this;
433
+ }
434
+ get IFluidRouter() {
435
+ return this;
436
+ }
413
437
  /**
414
438
  * @deprecated - use loadRuntime instead.
415
439
  * Load the stores from a snapshot and returns the runtime.
@@ -450,7 +474,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
450
474
  */
451
475
  static async loadRuntime(params) {
452
476
  var _a, _b, _c, _d;
453
- const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime } = params;
477
+ const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, } = params;
454
478
  // If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
455
479
  // back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
456
480
  const backCompatContext = context;
@@ -462,13 +486,15 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
462
486
  });
463
487
  const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, enableOfflineLoad = false, compressionOptions = {
464
488
  minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
465
- compressionAlgorithm: CompressionAlgorithms.lz4
489
+ compressionAlgorithm: CompressionAlgorithms.lz4,
466
490
  }, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, chunkSizeInBytes = Number.POSITIVE_INFINITY, enableOpReentryCheck = false, } = runtimeOptions;
467
491
  const pendingRuntimeState = context.pendingLocalState;
468
492
  const baseSnapshot = (_b = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _b !== void 0 ? _b : context.baseSnapshot;
469
- const storage = !pendingRuntimeState ?
470
- context.storage :
471
- new serializedSnapshotStorage_1.SerializedSnapshotStorage(() => { return context.storage; }, pendingRuntimeState.snapshotBlobs);
493
+ const storage = !pendingRuntimeState
494
+ ? context.storage
495
+ : new serializedSnapshotStorage_1.SerializedSnapshotStorage(() => {
496
+ return context.storage;
497
+ }, pendingRuntimeState.snapshotBlobs);
472
498
  const registry = new dataStoreRegistry_1.FluidDataStoreRegistry(registryEntries);
473
499
  const tryFetchBlob = async (blobName) => {
474
500
  const blobId = baseSnapshot === null || baseSnapshot === void 0 ? void 0 : baseSnapshot.blobs[blobName];
@@ -480,14 +506,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
480
506
  }
481
507
  };
482
508
  const [chunks, metadata, electedSummarizerData, aliases] = await Promise.all([
483
- tryFetchBlob(summaryFormat_1.chunksBlobName),
484
- tryFetchBlob(summaryFormat_1.metadataBlobName),
485
- tryFetchBlob(summaryFormat_1.electedSummarizerBlobName),
486
- tryFetchBlob(summaryFormat_1.aliasBlobName),
509
+ tryFetchBlob(summary_1.chunksBlobName),
510
+ tryFetchBlob(summary_1.metadataBlobName),
511
+ tryFetchBlob(summary_1.electedSummarizerBlobName),
512
+ tryFetchBlob(summary_1.aliasBlobName),
487
513
  ]);
488
514
  const loadExisting = existing === true || context.existing === true;
489
515
  // read snapshot blobs needed for BlobManager to load
490
- const blobManagerSnapshot = await blobManager_1.BlobManager.load(baseSnapshot === null || baseSnapshot === void 0 ? void 0 : baseSnapshot.trees[summaryFormat_1.blobsTreeName], async (id) => {
516
+ const blobManagerSnapshot = await blobManager_1.BlobManager.load(baseSnapshot === null || baseSnapshot === void 0 ? void 0 : baseSnapshot.trees[summary_1.blobsTreeName], async (id) => {
491
517
  // IContainerContext storage api return type still has undefined in 0.39 package version.
492
518
  // So once we release 0.40 container-defn package we can remove this check.
493
519
  (0, common_utils_1.assert)(storage !== undefined, 0x256 /* "storage undefined in attached container" */);
@@ -499,7 +525,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
499
525
  if (!pendingRuntimeState && runtimeSequenceNumber !== undefined) {
500
526
  const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
501
527
  // Unless bypass is explicitly set, then take action when sequence numbers mismatch.
502
- if (loadSequenceNumberVerification !== "bypass" && runtimeSequenceNumber !== protocolSequenceNumber) {
528
+ if (loadSequenceNumberVerification !== "bypass" &&
529
+ runtimeSequenceNumber !== protocolSequenceNumber) {
503
530
  // "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
504
531
  const error = new container_utils_1.DataCorruptionError(
505
532
  // pre-0.58 error message: SummaryMetadataMismatch
@@ -606,7 +633,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
606
633
  var _a;
607
634
  return (_a = this.summarizerClientElection) === null || _a === void 0 ? void 0 : _a.electedClientId;
608
635
  }
609
- get disposed() { return this._disposed; }
636
+ get disposed() {
637
+ return this._disposed;
638
+ }
610
639
  get summarizer() {
611
640
  (0, common_utils_1.assert)(this._summarizer !== undefined, 0x257 /* "This is not summarizing container" */);
612
641
  return this._summarizer;
@@ -661,6 +690,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
661
690
  this.emit("dispose");
662
691
  this.removeAllListeners();
663
692
  }
693
+ /**
694
+ * @deprecated 2.0.0-internal.3.2.0 ContainerRuntime is not an IFluidTokenProvider. Token providers should be accessed using normal provider patterns.
695
+ */
664
696
  get IFluidTokenProvider() {
665
697
  var _a;
666
698
  if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.intelligence) {
@@ -716,7 +748,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
716
748
  status: 200,
717
749
  mimeType: "fluid/object",
718
750
  value: blob,
719
- } : (0, runtime_utils_1.create404Response)(request);
751
+ }
752
+ : (0, runtime_utils_1.create404Response)(request);
720
753
  }
721
754
  else if (requestParser.pathParts.length > 0) {
722
755
  const dataStore = await this.getDataStoreFromRequest(id, request);
@@ -737,7 +770,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
737
770
  return (_a = this.dataStores.aliases.get(maybeAlias)) !== null && _a !== void 0 ? _a : maybeAlias;
738
771
  }
739
772
  async getDataStoreFromRequest(id, request) {
740
- var _a, _b, _c, _d;
773
+ var _a, _b, _c;
741
774
  const headerData = {};
742
775
  if (typeof ((_a = request.headers) === null || _a === void 0 ? void 0 : _a[RuntimeHeaders.wait]) === "boolean") {
743
776
  headerData.wait = request.headers[RuntimeHeaders.wait];
@@ -751,22 +784,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
751
784
  await this.dataStores.waitIfPendingAlias(id);
752
785
  const internalId = this.internalId(id);
753
786
  const dataStoreContext = await this.dataStores.getDataStore(internalId, headerData);
754
- /**
755
- * If GC should run and this an external app request with "externalRequest" header, we need to return
756
- * an error if the data store being requested is marked as unreferenced as per the data store's base
757
- * GC data.
758
- *
759
- * This is a workaround to handle scenarios where a data store shared with an external app is deleted
760
- * and marked as unreferenced by GC. Returning an error will fail to load the data store for the app.
761
- */
762
- if (((_d = request.headers) === null || _d === void 0 ? void 0 : _d[RuntimeHeaders.externalRequest]) && this.garbageCollector.shouldRunGC) {
763
- // The data store is referenced if used routes in the base summary has a route to self.
764
- // Older documents may not have used routes in the summary. They are considered referenced.
765
- const usedRoutes = (await dataStoreContext.getBaseGCDetails()).usedRoutes;
766
- if (!(usedRoutes === undefined || usedRoutes.includes("") || usedRoutes.includes("/"))) {
767
- throw (0, runtime_utils_1.responseToException)((0, runtime_utils_1.create404Response)(request), request);
768
- }
769
- }
770
787
  const dataStoreChannel = await dataStoreContext.realize();
771
788
  // Remove query params, leading and trailing slashes from the url. This is done to make sure the format is
772
789
  // the same as GC nodes id.
@@ -782,29 +799,29 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
782
799
  summaryNumber: this.nextSummaryNumber++, summaryFormatVersion: 1 }), this.garbageCollector.getMetadata()), {
783
800
  // The last message processed at the time of summary. If there are no new messages, use the message from the
784
801
  // last summary.
785
- message: (_a = (0, summaryFormat_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage)) !== null && _a !== void 0 ? _a : this.messageAtLastSummary });
786
- (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 });
803
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.metadataBlobName, JSON.stringify(metadata));
787
804
  }
788
805
  addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
789
806
  var _a;
790
807
  this.addMetadataToSummary(summaryTree);
791
808
  if (this.remoteMessageProcessor.partialMessages.size > 0) {
792
809
  const content = JSON.stringify([...this.remoteMessageProcessor.partialMessages]);
793
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summaryFormat_1.chunksBlobName, content);
810
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.chunksBlobName, content);
794
811
  }
795
812
  const dataStoreAliases = this.dataStores.aliases;
796
813
  if (dataStoreAliases.size > 0) {
797
- (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]));
798
815
  }
799
816
  if (this.summarizerClientElection) {
800
817
  const electedSummarizerContent = JSON.stringify((_a = this.summarizerClientElection) === null || _a === void 0 ? void 0 : _a.serialize());
801
- (0, runtime_utils_1.addBlobToSummary)(summaryTree, summaryFormat_1.electedSummarizerBlobName, electedSummarizerContent);
818
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.electedSummarizerBlobName, electedSummarizerContent);
802
819
  }
803
820
  const blobManagerSummary = this.blobManager.summarize();
804
821
  // Some storage (like git) doesn't allow empty tree, so we can omit it.
805
822
  // and the blob manager can handle the tree not existing when loading
806
823
  if (Object.keys(blobManagerSummary.summary.tree).length > 0) {
807
- (0, runtime_utils_1.addTreeToSummary)(summaryTree, summaryFormat_1.blobsTreeName, blobManagerSummary);
824
+ (0, runtime_utils_1.addTreeToSummary)(summaryTree, summary_1.blobsTreeName, blobManagerSummary);
808
825
  }
809
826
  const gcSummary = this.garbageCollector.summarize(fullTree, trackState, telemetryContext);
810
827
  if (gcSummary !== undefined) {
@@ -933,7 +950,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
933
950
  if (reconnection) {
934
951
  this.consecutiveReconnects++;
935
952
  if (!this.shouldContinueReconnecting()) {
936
- this.closeFn(container_utils_1.DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops. Batch of ops is likely too large (over 1Mb)", "setConnectionState", undefined, {
953
+ this.closeFn(container_utils_1.DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops.", "setConnectionState", undefined, {
937
954
  dataLoss: 1,
938
955
  attempts: this.consecutiveReconnects,
939
956
  pendingMessages: this.pendingStateManager.pendingMessagesCount,
@@ -1040,7 +1057,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1040
1057
  if (message.clientId === this.clientId && this.connected) {
1041
1058
  // Check to see if the signal was lost.
1042
1059
  if (this._perfSignalData.trackingSignalSequenceNumber !== undefined &&
1043
- envelope.clientSignalSequenceNumber > this._perfSignalData.trackingSignalSequenceNumber) {
1060
+ envelope.clientSignalSequenceNumber >
1061
+ this._perfSignalData.trackingSignalSequenceNumber) {
1044
1062
  this._perfSignalData.signalsLost++;
1045
1063
  this._perfSignalData.trackingSignalSequenceNumber = undefined;
1046
1064
  this.logger.sendErrorEvent({
@@ -1051,7 +1069,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1051
1069
  clientSignalSequenceNumber: envelope.clientSignalSequenceNumber,
1052
1070
  });
1053
1071
  }
1054
- else if (envelope.clientSignalSequenceNumber === this._perfSignalData.trackingSignalSequenceNumber) {
1072
+ else if (this.consecutiveReconnects === 0 &&
1073
+ envelope.clientSignalSequenceNumber ===
1074
+ this._perfSignalData.trackingSignalSequenceNumber) {
1075
+ // only logging for the first connection and the trackingSignalSequenceNUmber.
1055
1076
  this.sendSignalTelemetryEvent(envelope.clientSignalSequenceNumber);
1056
1077
  this._perfSignalData.trackingSignalSequenceNumber = undefined;
1057
1078
  }
@@ -1138,7 +1159,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1138
1159
  return this.dataStores.createDetachedDataStoreCore(pkg, false);
1139
1160
  }
1140
1161
  async _createDataStoreWithProps(pkg, props, id = (0, uuid_1.v4)()) {
1141
- const fluidDataStore = await this.dataStores._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props).realize();
1162
+ const fluidDataStore = await this.dataStores
1163
+ ._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props)
1164
+ .realize();
1142
1165
  return (0, dataStore_1.channelToDataStore)(fluidDataStore, id, this, this.dataStores, this.mc.logger);
1143
1166
  }
1144
1167
  async _createDataStore(pkg, id = (0, uuid_1.v4)(), props) {
@@ -1153,7 +1176,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1153
1176
  * Are we in the middle of batching ops together?
1154
1177
  */
1155
1178
  currentlyBatching() {
1156
- return this.flushMode === runtime_definitions_1.FlushMode.TurnBased || this._orderSequentiallyCalls !== 0;
1179
+ return this.flushMode !== runtime_definitions_1.FlushMode.Immediate || this._orderSequentiallyCalls !== 0;
1157
1180
  }
1158
1181
  getQuorum() {
1159
1182
  return this.context.quorum;
@@ -1242,7 +1265,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1242
1265
  }
1243
1266
  const summarizeResult = this.dataStores.createSummary(telemetryContext);
1244
1267
  // Wrap data store summaries in .channels subtree.
1245
- (0, summaryFormat_1.wrapSummaryInChannelsTree)(summarizeResult);
1268
+ (0, summary_1.wrapSummaryInChannelsTree)(summarizeResult);
1246
1269
  this.addContainerStateToSummary(summarizeResult, true /* fullTree */, false /* trackState */, telemetryContext);
1247
1270
  return summarizeResult.summary;
1248
1271
  }
@@ -1258,7 +1281,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1258
1281
  async summarizeInternal(fullTree, trackState, telemetryContext) {
1259
1282
  const summarizeResult = await this.dataStores.summarize(fullTree, trackState, telemetryContext);
1260
1283
  // Wrap data store summaries in .channels subtree.
1261
- (0, summaryFormat_1.wrapSummaryInChannelsTree)(summarizeResult);
1284
+ (0, summary_1.wrapSummaryInChannelsTree)(summarizeResult);
1262
1285
  const pathPartsForChildren = [runtime_definitions_1.channelsTreeName];
1263
1286
  this.addContainerStateToSummary(summarizeResult, fullTree, trackState, telemetryContext);
1264
1287
  return Object.assign(Object.assign({}, summarizeResult), { id: "", pathPartsForChildren });
@@ -1271,7 +1294,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1271
1294
  const { fullTree = false, trackState = true, summaryLogger = this.mc.logger, runGC = this.garbageCollector.shouldRunGC, runSweep, fullGC, } = options;
1272
1295
  const telemetryContext = new runtime_utils_1.TelemetryContext();
1273
1296
  // Add the options that are used to generate this summary to the telemetry context.
1274
- telemetryContext.setAll("fluid_Summarize", "Options", {
1297
+ telemetryContext.setMultiple("fluid_Summarize", "Options", {
1275
1298
  fullTree,
1276
1299
  trackState,
1277
1300
  runGC,
@@ -1283,7 +1306,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1283
1306
  gcStats = await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC }, telemetryContext);
1284
1307
  }
1285
1308
  const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
1286
- this.logger.sendTelemetryEvent({ eventName: "SummarizeTelemetry", details: telemetryContext.serialize() });
1309
+ this.logger.sendTelemetryEvent({
1310
+ eventName: "SummarizeTelemetry",
1311
+ details: telemetryContext.serialize(),
1312
+ });
1287
1313
  (0, common_utils_1.assert)(summary.type === protocol_definitions_1.SummaryType.Tree, 0x12f /* "Container Runtime's summarize should always return a tree" */);
1288
1314
  return { stats, summary, gcStats };
1289
1315
  }
@@ -1334,6 +1360,22 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1334
1360
  this.blobManager.updateUnusedRoutes(blobManagerRoutes);
1335
1361
  this.dataStores.updateUnusedRoutes(dataStoreRoutes);
1336
1362
  }
1363
+ /**
1364
+ * @deprecated - Replaced by deleteSweepReadyNodes.
1365
+ */
1366
+ deleteUnusedNodes(unusedRoutes) {
1367
+ throw new Error("deleteUnusedRoutes should not be called");
1368
+ }
1369
+ /**
1370
+ * After GC has run and identified nodes that are sweep ready, this is called to delete the sweep ready nodes.
1371
+ * @param sweepReadyRoutes - The routes of nodes that are sweep ready and should be deleted.
1372
+ * @returns - The routes of nodes that were deleted.
1373
+ */
1374
+ deleteSweepReadyNodes(sweepReadyRoutes) {
1375
+ const { dataStoreRoutes, blobManagerRoutes } = this.getDataStoreAndBlobManagerRoutes(sweepReadyRoutes);
1376
+ const deletedRoutes = this.dataStores.deleteSweepReadyNodes(dataStoreRoutes);
1377
+ return deletedRoutes.concat(this.blobManager.deleteSweepReadyNodes(blobManagerRoutes));
1378
+ }
1337
1379
  /**
1338
1380
  * This is called to update objects that are tombstones.
1339
1381
  * @param tombstonedRoutes - Data store and attachment blob routes that are tombstones in this Container.
@@ -1359,9 +1401,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1359
1401
  getNodeType(nodePath) {
1360
1402
  var _a;
1361
1403
  if (this.isBlobPath(nodePath)) {
1362
- return garbageCollection_1.GCNodeType.Blob;
1404
+ return gc_1.GCNodeType.Blob;
1363
1405
  }
1364
- return (_a = this.dataStores.getGCNodeType(nodePath)) !== null && _a !== void 0 ? _a : garbageCollection_1.GCNodeType.Other;
1406
+ return (_a = this.dataStores.getGCNodeType(nodePath)) !== null && _a !== void 0 ? _a : gc_1.GCNodeType.Other;
1365
1407
  }
1366
1408
  /**
1367
1409
  * Called by GC to retrieve the package path of the node with the given path. The node should belong to a
@@ -1369,10 +1411,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1369
1411
  */
1370
1412
  async getGCNodePackagePath(nodePath) {
1371
1413
  switch (this.getNodeType(nodePath)) {
1372
- case garbageCollection_1.GCNodeType.Blob:
1414
+ case gc_1.GCNodeType.Blob:
1373
1415
  return [blobManager_1.BlobManager.basePath];
1374
- case garbageCollection_1.GCNodeType.DataStore:
1375
- case garbageCollection_1.GCNodeType.SubDataStore:
1416
+ case gc_1.GCNodeType.DataStore:
1417
+ case gc_1.GCNodeType.SubDataStore:
1376
1418
  return this.dataStores.getDataStorePackagePath(nodePath);
1377
1419
  default:
1378
1420
  (0, common_utils_1.assert)(false, 0x2de /* "Package path requested for unsupported node type." */);
@@ -1449,8 +1491,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1449
1491
  // We might need to catch up to the latest summary's reference sequence number before pausing.
1450
1492
  await this.waitForDeltaManagerToCatchup(latestSnapshotRefSeq, summaryNumberLogger);
1451
1493
  }
1494
+ const shouldPauseInboundSignal = this.mc.config.getBoolean("Fluid.ContainerRuntime.SubmitSummary.disableInboundSignalPause") !== true;
1452
1495
  try {
1453
1496
  await this.deltaManager.inbound.pause();
1497
+ if (shouldPauseInboundSignal) {
1498
+ await this.deltaManager.inboundSignal.pause();
1499
+ }
1454
1500
  const summaryRefSeqNum = this.deltaManager.lastSequenceNumber;
1455
1501
  const minimumSequenceNumber = this.deltaManager.minimumSequenceNumber;
1456
1502
  const message = `Summary @${summaryRefSeqNum}:${this.deltaManager.minimumSequenceNumber}`;
@@ -1551,8 +1597,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1551
1597
  // latestSnapshotVersionId from storage and it does not match with the lastAck ackHandle, then use
1552
1598
  // the one fetched from storage as parent as that is the latest.
1553
1599
  let summaryContext;
1554
- if ((lastAck === null || lastAck === void 0 ? void 0 : lastAck.summaryAck.contents.handle) !== latestSnapshotVersionId
1555
- && latestSnapshotVersionId !== undefined) {
1600
+ if ((lastAck === null || lastAck === void 0 ? void 0 : lastAck.summaryAck.contents.handle) !== latestSnapshotVersionId &&
1601
+ latestSnapshotVersionId !== undefined) {
1556
1602
  summaryContext = {
1557
1603
  proposalHandle: undefined,
1558
1604
  ackHandle: latestSnapshotVersionId,
@@ -1595,7 +1641,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1595
1641
  }
1596
1642
  let clientSequenceNumber;
1597
1643
  try {
1598
- clientSequenceNumber = this.submitSummaryMessage(summaryMessage);
1644
+ clientSequenceNumber = this.submitSummaryMessage(summaryMessage, summaryRefSeqNum);
1599
1645
  }
1600
1646
  catch (error) {
1601
1647
  return Object.assign(Object.assign({ stage: "upload" }, uploadData), { error });
@@ -1609,6 +1655,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1609
1655
  this.summarizerNode.clearSummary();
1610
1656
  // Restart the delta manager
1611
1657
  this.deltaManager.inbound.resume();
1658
+ if (shouldPauseInboundSignal) {
1659
+ this.deltaManager.inboundSignal.resume();
1660
+ }
1612
1661
  }
1613
1662
  }
1614
1663
  hasPendingMessages() {
@@ -1654,14 +1703,16 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1654
1703
  this.verifyCanSubmitOps();
1655
1704
  // There should be no ops in detached container state!
1656
1705
  (0, common_utils_1.assert)(this.attachState !== container_definitions_1.AttachState.Detached, 0x132 /* "sending ops in detached container" */);
1657
- const deserializedContent = { type, contents };
1658
- const serializedContent = JSON.stringify(deserializedContent);
1706
+ const serializedContent = JSON.stringify({ type, contents });
1659
1707
  if (this.deltaManager.readOnlyInfo.readonly) {
1660
- this.logger.sendTelemetryEvent({ eventName: "SubmitOpInReadonly", connected: this.connected });
1708
+ this.logger.sendTelemetryEvent({
1709
+ eventName: "SubmitOpInReadonly",
1710
+ connected: this.connected,
1711
+ });
1661
1712
  }
1662
1713
  const message = {
1663
1714
  contents: serializedContent,
1664
- deserializedContent,
1715
+ deserializedContent: JSON.parse(serializedContent),
1665
1716
  metadata,
1666
1717
  localOpMetadata,
1667
1718
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
@@ -1687,8 +1738,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1687
1738
  // issue than sending.
1688
1739
  // Please note that this does not change file format, so it can be disabled in the future if this
1689
1740
  // optimization no longer makes sense (for example, batch compression may make it less appealing).
1690
- if (this.currentlyBatching() && type === ContainerMessageType.Attach &&
1691
- this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder") !== true) {
1741
+ if (this.currentlyBatching() &&
1742
+ type === ContainerMessageType.Attach &&
1743
+ this.disableAttachReorder !== true) {
1692
1744
  this.outbox.submitAttach(message);
1693
1745
  }
1694
1746
  else {
@@ -1697,13 +1749,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1697
1749
  if (!this.currentlyBatching()) {
1698
1750
  this.flush();
1699
1751
  }
1700
- else if (!this.flushMicroTaskExists) {
1701
- this.flushMicroTaskExists = true;
1702
- // Queue a microtask to detect the end of the turn and force a flush.
1703
- Promise.resolve().then(() => {
1704
- this.flushMicroTaskExists = false;
1705
- this.flush();
1706
- }).catch((error) => { this.closeFn(error); });
1752
+ else {
1753
+ this.scheduleFlush();
1707
1754
  }
1708
1755
  }
1709
1756
  catch (error) {
@@ -1714,14 +1761,47 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1714
1761
  this.updateDocumentDirtyState(true);
1715
1762
  }
1716
1763
  }
1717
- submitSummaryMessage(contents) {
1764
+ scheduleFlush() {
1765
+ if (this.flushTaskExists) {
1766
+ return;
1767
+ }
1768
+ this.flushTaskExists = true;
1769
+ const flush = () => {
1770
+ this.flushTaskExists = false;
1771
+ try {
1772
+ this.flush();
1773
+ }
1774
+ catch (error) {
1775
+ this.closeFn(error);
1776
+ }
1777
+ };
1778
+ switch (this.flushMode) {
1779
+ case runtime_definitions_1.FlushMode.TurnBased:
1780
+ // When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
1781
+ // batch at the end of the turn
1782
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1783
+ Promise.resolve().then(flush);
1784
+ break;
1785
+ // FlushModeExperimental is experimental and not exposed directly in the runtime APIs
1786
+ case runtime_definitions_1.FlushModeExperimental.Async:
1787
+ // When in Async flush mode, the runtime will accumulate all operations across JS turns and send them as a single
1788
+ // batch when all micro-tasks are complete.
1789
+ // Compared to TurnBased, this flush mode will capture more ops into the same batch.
1790
+ setTimeout(flush, 0);
1791
+ break;
1792
+ default:
1793
+ (0, common_utils_1.assert)(this._orderSequentiallyCalls > 0, 0x587 /* Unreachable unless running under orderSequentially */);
1794
+ break;
1795
+ }
1796
+ }
1797
+ submitSummaryMessage(contents, referenceSequenceNumber) {
1718
1798
  this.verifyNotClosed();
1719
1799
  (0, common_utils_1.assert)(this.connected, 0x133 /* "Container disconnected when trying to submit system message" */);
1720
1800
  // System message should not be sent in the middle of the batch.
1721
1801
  (0, common_utils_1.assert)(this.outbox.isEmpty, 0x3d4 /* System op in the middle of a batch */);
1722
1802
  // back-compat: ADO #1385: Make this call unconditional in the future
1723
1803
  return this.context.submitSummaryFn !== undefined
1724
- ? this.context.submitSummaryFn(contents)
1804
+ ? this.context.submitSummaryFn(contents, referenceSequenceNumber)
1725
1805
  : this.context.submitFn(protocol_definitions_1.MessageType.Summarize, contents, false);
1726
1806
  }
1727
1807
  /**
@@ -1818,7 +1898,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1818
1898
  // It should only be done by the summarizerNode, if required.
1819
1899
  // When fetching from storage we will always get the latest version and do not use the ackHandle.
1820
1900
  const fetchLatestSnapshot = async () => {
1821
- const fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
1901
+ let fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
1822
1902
  eventName: "RefreshLatestSummaryAckFetch",
1823
1903
  ackHandle,
1824
1904
  targetSequenceNumber: summaryRefSeq,
@@ -1834,13 +1914,21 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1834
1914
  * state.
1835
1915
  */
1836
1916
  if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
1837
- const error = container_utils_1.DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
1917
+ /* before failing, let's try to retrieve the latest snapshot for that specific ackHandle */
1918
+ fetchResult = await this.fetchSnapshotFromStorage(summaryLogger, {
1919
+ eventName: "RefreshLatestSummaryAckFetch",
1838
1920
  ackHandle,
1839
- summaryRefSeq,
1840
- latestSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
1841
- });
1842
- this.closeFn(error);
1843
- throw error;
1921
+ targetSequenceNumber: summaryRefSeq,
1922
+ }, readAndParseBlob, ackHandle);
1923
+ if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
1924
+ const error = container_utils_1.DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
1925
+ ackHandle,
1926
+ summaryRefSeq,
1927
+ fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
1928
+ });
1929
+ this.closeFn(error);
1930
+ throw error;
1931
+ }
1844
1932
  }
1845
1933
  // In case we had to retrieve the latest snapshot and it is different than summaryRefSeq,
1846
1934
  // wait for the delta manager to catch up before refreshing the latest Summary.
@@ -1875,10 +1963,13 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1875
1963
  return { latestSnapshotRefSeq, latestSnapshotVersionId: versionId };
1876
1964
  }
1877
1965
  async fetchLatestSnapshotFromStorage(logger, event, readAndParseBlob) {
1966
+ return this.fetchSnapshotFromStorage(logger, event, readAndParseBlob, null /* latest */);
1967
+ }
1968
+ async fetchSnapshotFromStorage(logger, event, readAndParseBlob, versionId) {
1878
1969
  return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
1879
1970
  const stats = {};
1880
1971
  const trace = common_utils_1.Trace.start();
1881
- const versions = await this.storage.getVersions(null, 1, "refreshLatestSummaryAckFromServer", driver_definitions_1.FetchSource.noCache);
1972
+ const versions = await this.storage.getVersions(versionId, 1, "refreshLatestSummaryAckFromServer", versionId === null ? driver_definitions_1.FetchSource.noCache : undefined);
1882
1973
  (0, common_utils_1.assert)(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
1883
1974
  stats.getVersionDuration = trace.trace().duration;
1884
1975
  const maybeSnapshot = await this.storage.getSnapshotTree(versions[0]);
@@ -1898,13 +1989,15 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1898
1989
  notifyAttaching(snapshot) {
1899
1990
  var _a;
1900
1991
  if ((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) {
1901
- this.baseSnapshotBlobs = serializedSnapshotStorage_1.SerializedSnapshotStorage.serializeTreeWithBlobContents(snapshot);
1992
+ this.baseSnapshotBlobs =
1993
+ serializedSnapshotStorage_1.SerializedSnapshotStorage.serializeTreeWithBlobContents(snapshot);
1902
1994
  }
1903
1995
  }
1904
1996
  async initializeBaseSnapshotBlobs() {
1905
1997
  var _a;
1906
1998
  if (!((_a = this.mc.config.getBoolean("enableOfflineLoad")) !== null && _a !== void 0 ? _a : this.runtimeOptions.enableOfflineLoad) ||
1907
- this.attachState !== container_definitions_1.AttachState.Attached || this.context.pendingLocalState) {
1999
+ this.attachState !== container_definitions_1.AttachState.Attached ||
2000
+ this.context.pendingLocalState) {
1908
2001
  return;
1909
2002
  }
1910
2003
  (0, common_utils_1.assert)(!!this.context.baseSnapshot, 0x2e5 /* "Must have a base snapshot" */);
@@ -1953,7 +2046,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1953
2046
  [container_definitions_1.LoaderHeader.cache]: false,
1954
2047
  [container_definitions_1.LoaderHeader.clientDetails]: {
1955
2048
  capabilities: { interactive: false },
1956
- type: summarizerClientElection_1.summarizerClientType,
2049
+ type: summary_1.summarizerClientType,
1957
2050
  },
1958
2051
  [driver_definitions_1.DriverHeader.summarizingClient]: true,
1959
2052
  [container_definitions_1.LoaderHeader.reconnect]: false,