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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (563) hide show
  1. package/.eslintrc.js +21 -10
  2. package/.mocharc.js +2 -2
  3. package/api-extractor.json +2 -2
  4. package/dist/batchTracker.d.ts +1 -2
  5. package/dist/batchTracker.d.ts.map +1 -1
  6. package/dist/batchTracker.js +2 -1
  7. package/dist/batchTracker.js.map +1 -1
  8. package/dist/blobManager.d.ts +74 -42
  9. package/dist/blobManager.d.ts.map +1 -1
  10. package/dist/blobManager.js +321 -152
  11. package/dist/blobManager.js.map +1 -1
  12. package/dist/connectionTelemetry.d.ts.map +1 -1
  13. package/dist/connectionTelemetry.js +11 -9
  14. package/dist/connectionTelemetry.js.map +1 -1
  15. package/dist/containerHandleContext.d.ts.map +1 -1
  16. package/dist/containerHandleContext.js +3 -1
  17. package/dist/containerHandleContext.js.map +1 -1
  18. package/dist/containerRuntime.d.ts +148 -114
  19. package/dist/containerRuntime.d.ts.map +1 -1
  20. package/dist/containerRuntime.js +534 -342
  21. package/dist/containerRuntime.js.map +1 -1
  22. package/dist/dataStore.d.ts.map +1 -1
  23. package/dist/dataStore.js +11 -9
  24. package/dist/dataStore.js.map +1 -1
  25. package/dist/dataStoreContext.d.ts +40 -13
  26. package/dist/dataStoreContext.d.ts.map +1 -1
  27. package/dist/dataStoreContext.js +146 -66
  28. package/dist/dataStoreContext.js.map +1 -1
  29. package/dist/dataStoreContexts.d.ts.map +1 -1
  30. package/dist/dataStoreContexts.js +7 -3
  31. package/dist/dataStoreContexts.js.map +1 -1
  32. package/dist/dataStoreRegistry.d.ts.map +1 -1
  33. package/dist/dataStoreRegistry.js +3 -1
  34. package/dist/dataStoreRegistry.js.map +1 -1
  35. package/dist/dataStores.d.ts +39 -12
  36. package/dist/dataStores.d.ts.map +1 -1
  37. package/dist/dataStores.js +164 -76
  38. package/dist/dataStores.js.map +1 -1
  39. package/dist/deltaManagerSummarizerProxy.d.ts +19 -0
  40. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -0
  41. package/dist/deltaManagerSummarizerProxy.js +40 -0
  42. package/dist/deltaManagerSummarizerProxy.js.map +1 -0
  43. package/dist/deltaScheduler.d.ts.map +1 -1
  44. package/dist/deltaScheduler.js +8 -3
  45. package/dist/deltaScheduler.js.map +1 -1
  46. package/dist/gc/garbageCollection.d.ts +204 -0
  47. package/dist/gc/garbageCollection.d.ts.map +1 -0
  48. package/dist/gc/garbageCollection.js +926 -0
  49. package/dist/gc/garbageCollection.js.map +1 -0
  50. package/dist/gc/gcConfigs.d.ts +22 -0
  51. package/dist/gc/gcConfigs.d.ts.map +1 -0
  52. package/dist/gc/gcConfigs.js +143 -0
  53. package/dist/gc/gcConfigs.js.map +1 -0
  54. package/dist/gc/gcDefinitions.d.ts +320 -0
  55. package/dist/gc/gcDefinitions.d.ts.map +1 -0
  56. package/dist/gc/gcDefinitions.js +81 -0
  57. package/dist/gc/gcDefinitions.js.map +1 -0
  58. package/dist/gc/gcHelpers.d.ts +86 -0
  59. package/dist/gc/gcHelpers.d.ts.map +1 -0
  60. package/dist/gc/gcHelpers.js +268 -0
  61. package/dist/gc/gcHelpers.js.map +1 -0
  62. package/dist/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
  63. package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
  64. package/dist/gc/gcReferenceGraphAlgorithm.js +49 -0
  65. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -0
  66. package/dist/gc/gcSummaryDefinitions.d.ts +52 -0
  67. package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -0
  68. package/dist/gc/gcSummaryDefinitions.js +7 -0
  69. package/dist/gc/gcSummaryDefinitions.js.map +1 -0
  70. package/dist/gc/gcSummaryStateTracker.d.ts +93 -0
  71. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
  72. package/dist/gc/gcSummaryStateTracker.js +239 -0
  73. package/dist/gc/gcSummaryStateTracker.js.map +1 -0
  74. package/{lib → dist/gc}/gcSweepReadyUsageDetection.d.ts +5 -5
  75. package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  76. package/dist/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +15 -11
  77. package/dist/gc/gcSweepReadyUsageDetection.js.map +1 -0
  78. package/dist/gc/gcUnreferencedStateTracker.d.ts +34 -0
  79. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  80. package/dist/gc/gcUnreferencedStateTracker.js +94 -0
  81. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -0
  82. package/dist/gc/index.d.ts +13 -0
  83. package/dist/gc/index.d.ts.map +1 -0
  84. package/dist/gc/index.js +50 -0
  85. package/dist/gc/index.js.map +1 -0
  86. package/dist/index.d.ts +3 -8
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +7 -13
  89. package/dist/index.js.map +1 -1
  90. package/dist/opLifecycle/batchManager.d.ts +10 -0
  91. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  92. package/dist/opLifecycle/batchManager.js +37 -8
  93. package/dist/opLifecycle/batchManager.js.map +1 -1
  94. package/dist/opLifecycle/definitions.d.ts +29 -1
  95. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  96. package/dist/opLifecycle/definitions.js.map +1 -1
  97. package/dist/opLifecycle/index.d.ts +3 -3
  98. package/dist/opLifecycle/index.d.ts.map +1 -1
  99. package/dist/opLifecycle/index.js +3 -1
  100. package/dist/opLifecycle/index.js.map +1 -1
  101. package/dist/opLifecycle/opCompressor.d.ts +1 -1
  102. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  103. package/dist/opLifecycle/opCompressor.js +46 -17
  104. package/dist/opLifecycle/opCompressor.js.map +1 -1
  105. package/dist/opLifecycle/opDecompressor.d.ts +6 -1
  106. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  107. package/dist/opLifecycle/opDecompressor.js +72 -18
  108. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  109. package/dist/opLifecycle/opSplitter.d.ts +46 -2
  110. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  111. package/dist/opLifecycle/opSplitter.js +142 -5
  112. package/dist/opLifecycle/opSplitter.js.map +1 -1
  113. package/dist/opLifecycle/outbox.d.ts +23 -2
  114. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  115. package/dist/opLifecycle/outbox.js +101 -51
  116. package/dist/opLifecycle/outbox.js.map +1 -1
  117. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  118. package/dist/opLifecycle/remoteMessageProcessor.js +17 -2
  119. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  120. package/dist/opProperties.d.ts.map +1 -1
  121. package/dist/opProperties.js +1 -3
  122. package/dist/opProperties.js.map +1 -1
  123. package/dist/packageVersion.d.ts +1 -1
  124. package/dist/packageVersion.js +1 -1
  125. package/dist/packageVersion.js.map +1 -1
  126. package/dist/pendingStateManager.d.ts +6 -15
  127. package/dist/pendingStateManager.d.ts.map +1 -1
  128. package/dist/pendingStateManager.js +137 -165
  129. package/dist/pendingStateManager.js.map +1 -1
  130. package/dist/scheduleManager.d.ts +0 -1
  131. package/dist/scheduleManager.d.ts.map +1 -1
  132. package/dist/scheduleManager.js +11 -21
  133. package/dist/scheduleManager.js.map +1 -1
  134. package/dist/storageServiceWithAttachBlobs.d.ts +17 -0
  135. package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -0
  136. package/dist/storageServiceWithAttachBlobs.js +32 -0
  137. package/dist/storageServiceWithAttachBlobs.js.map +1 -0
  138. package/dist/summary/index.d.ts +17 -0
  139. package/dist/summary/index.d.ts.map +1 -0
  140. package/dist/summary/index.js +46 -0
  141. package/dist/summary/index.js.map +1 -0
  142. package/dist/summary/orderedClientElection.d.ts.map +1 -0
  143. package/dist/{orderedClientElection.js → summary/orderedClientElection.js} +10 -4
  144. package/dist/summary/orderedClientElection.js.map +1 -0
  145. package/{lib → dist/summary}/runWhileConnectedCoordinator.d.ts +3 -2
  146. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  147. package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +5 -4
  148. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -0
  149. package/{lib → dist/summary}/runningSummarizer.d.ts +19 -18
  150. package/dist/summary/runningSummarizer.d.ts.map +1 -0
  151. package/dist/{runningSummarizer.js → summary/runningSummarizer.js} +191 -77
  152. package/dist/summary/runningSummarizer.js.map +1 -0
  153. package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +6 -12
  154. package/dist/summary/summarizer.d.ts.map +1 -0
  155. package/dist/{summarizer.js → summary/summarizer.js} +32 -76
  156. package/dist/summary/summarizer.js.map +1 -0
  157. package/dist/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +1 -2
  158. package/dist/summary/summarizerClientElection.d.ts.map +1 -0
  159. package/dist/{summarizerClientElection.js → summary/summarizerClientElection.js} +3 -30
  160. package/dist/summary/summarizerClientElection.js.map +1 -0
  161. package/dist/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +1 -1
  162. package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
  163. package/dist/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +9 -12
  164. package/dist/summary/summarizerHeuristics.js.map +1 -0
  165. package/dist/summary/summarizerNode/index.d.ts +8 -0
  166. package/dist/summary/summarizerNode/index.d.ts.map +1 -0
  167. package/dist/summary/summarizerNode/index.js +12 -0
  168. package/dist/summary/summarizerNode/index.js.map +1 -0
  169. package/dist/summary/summarizerNode/summarizerNode.d.ts +149 -0
  170. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
  171. package/dist/summary/summarizerNode/summarizerNode.js +531 -0
  172. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -0
  173. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +125 -0
  174. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
  175. package/dist/summary/summarizerNode/summarizerNodeUtils.js +132 -0
  176. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
  177. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +22 -0
  178. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
  179. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +423 -0
  180. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
  181. package/{lib → dist/summary}/summarizerTypes.d.ts +29 -42
  182. package/dist/summary/summarizerTypes.d.ts.map +1 -0
  183. package/dist/{summarizerTypes.js → summary/summarizerTypes.js} +0 -5
  184. package/dist/summary/summarizerTypes.js.map +1 -0
  185. package/dist/summary/summaryCollection.d.ts.map +1 -0
  186. package/dist/{summaryCollection.js → summary/summaryCollection.js} +18 -8
  187. package/dist/summary/summaryCollection.js.map +1 -0
  188. package/{lib → dist/summary}/summaryFormat.d.ts +3 -21
  189. package/dist/summary/summaryFormat.d.ts.map +1 -0
  190. package/dist/{summaryFormat.js → summary/summaryFormat.js} +19 -21
  191. package/dist/summary/summaryFormat.js.map +1 -0
  192. package/dist/summary/summaryGenerator.d.ts.map +1 -0
  193. package/dist/{summaryGenerator.js → summary/summaryGenerator.js} +34 -16
  194. package/dist/summary/summaryGenerator.js.map +1 -0
  195. package/dist/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
  196. package/dist/summary/summaryManager.d.ts.map +1 -0
  197. package/dist/{summaryManager.js → summary/summaryManager.js} +21 -9
  198. package/dist/summary/summaryManager.js.map +1 -0
  199. package/dist/throttler.d.ts +2 -2
  200. package/dist/throttler.d.ts.map +1 -1
  201. package/dist/throttler.js +4 -4
  202. package/dist/throttler.js.map +1 -1
  203. package/lib/batchTracker.d.ts +1 -2
  204. package/lib/batchTracker.d.ts.map +1 -1
  205. package/lib/batchTracker.js +2 -1
  206. package/lib/batchTracker.js.map +1 -1
  207. package/lib/blobManager.d.ts +74 -42
  208. package/lib/blobManager.d.ts.map +1 -1
  209. package/lib/blobManager.js +322 -153
  210. package/lib/blobManager.js.map +1 -1
  211. package/lib/connectionTelemetry.d.ts.map +1 -1
  212. package/lib/connectionTelemetry.js +11 -9
  213. package/lib/connectionTelemetry.js.map +1 -1
  214. package/lib/containerHandleContext.d.ts.map +1 -1
  215. package/lib/containerHandleContext.js +3 -1
  216. package/lib/containerHandleContext.js.map +1 -1
  217. package/lib/containerRuntime.d.ts +148 -114
  218. package/lib/containerRuntime.d.ts.map +1 -1
  219. package/lib/containerRuntime.js +506 -314
  220. package/lib/containerRuntime.js.map +1 -1
  221. package/lib/dataStore.d.ts.map +1 -1
  222. package/lib/dataStore.js +11 -9
  223. package/lib/dataStore.js.map +1 -1
  224. package/lib/dataStoreContext.d.ts +40 -13
  225. package/lib/dataStoreContext.d.ts.map +1 -1
  226. package/lib/dataStoreContext.js +136 -56
  227. package/lib/dataStoreContext.js.map +1 -1
  228. package/lib/dataStoreContexts.d.ts.map +1 -1
  229. package/lib/dataStoreContexts.js +7 -3
  230. package/lib/dataStoreContexts.js.map +1 -1
  231. package/lib/dataStoreRegistry.d.ts.map +1 -1
  232. package/lib/dataStoreRegistry.js +3 -1
  233. package/lib/dataStoreRegistry.js.map +1 -1
  234. package/lib/dataStores.d.ts +39 -12
  235. package/lib/dataStores.d.ts.map +1 -1
  236. package/lib/dataStores.js +162 -74
  237. package/lib/dataStores.js.map +1 -1
  238. package/lib/deltaManagerSummarizerProxy.d.ts +19 -0
  239. package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -0
  240. package/lib/deltaManagerSummarizerProxy.js +36 -0
  241. package/lib/deltaManagerSummarizerProxy.js.map +1 -0
  242. package/lib/deltaScheduler.d.ts.map +1 -1
  243. package/lib/deltaScheduler.js +9 -4
  244. package/lib/deltaScheduler.js.map +1 -1
  245. package/lib/gc/garbageCollection.d.ts +204 -0
  246. package/lib/gc/garbageCollection.d.ts.map +1 -0
  247. package/lib/gc/garbageCollection.js +922 -0
  248. package/lib/gc/garbageCollection.js.map +1 -0
  249. package/lib/gc/gcConfigs.d.ts +22 -0
  250. package/lib/gc/gcConfigs.d.ts.map +1 -0
  251. package/lib/gc/gcConfigs.js +139 -0
  252. package/lib/gc/gcConfigs.js.map +1 -0
  253. package/lib/gc/gcDefinitions.d.ts +320 -0
  254. package/lib/gc/gcDefinitions.d.ts.map +1 -0
  255. package/lib/gc/gcDefinitions.js +78 -0
  256. package/lib/gc/gcDefinitions.js.map +1 -0
  257. package/lib/gc/gcHelpers.d.ts +86 -0
  258. package/lib/gc/gcHelpers.d.ts.map +1 -0
  259. package/lib/gc/gcHelpers.js +254 -0
  260. package/lib/gc/gcHelpers.js.map +1 -0
  261. package/lib/gc/gcReferenceGraphAlgorithm.d.ts +16 -0
  262. package/lib/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -0
  263. package/lib/gc/gcReferenceGraphAlgorithm.js +45 -0
  264. package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -0
  265. package/lib/gc/gcSummaryDefinitions.d.ts +52 -0
  266. package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -0
  267. package/lib/gc/gcSummaryDefinitions.js +6 -0
  268. package/lib/gc/gcSummaryDefinitions.js.map +1 -0
  269. package/lib/gc/gcSummaryStateTracker.d.ts +93 -0
  270. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
  271. package/lib/gc/gcSummaryStateTracker.js +235 -0
  272. package/lib/gc/gcSummaryStateTracker.js.map +1 -0
  273. package/{dist → lib/gc}/gcSweepReadyUsageDetection.d.ts +5 -5
  274. package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  275. package/lib/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +15 -11
  276. package/lib/gc/gcSweepReadyUsageDetection.js.map +1 -0
  277. package/lib/gc/gcUnreferencedStateTracker.d.ts +34 -0
  278. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  279. package/lib/gc/gcUnreferencedStateTracker.js +90 -0
  280. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -0
  281. package/lib/gc/index.d.ts +13 -0
  282. package/lib/gc/index.d.ts.map +1 -0
  283. package/lib/gc/index.js +12 -0
  284. package/lib/gc/index.js.map +1 -0
  285. package/lib/index.d.ts +3 -8
  286. package/lib/index.d.ts.map +1 -1
  287. package/lib/index.js +2 -6
  288. package/lib/index.js.map +1 -1
  289. package/lib/opLifecycle/batchManager.d.ts +10 -0
  290. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  291. package/lib/opLifecycle/batchManager.js +35 -7
  292. package/lib/opLifecycle/batchManager.js.map +1 -1
  293. package/lib/opLifecycle/definitions.d.ts +29 -1
  294. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  295. package/lib/opLifecycle/definitions.js.map +1 -1
  296. package/lib/opLifecycle/index.d.ts +3 -3
  297. package/lib/opLifecycle/index.d.ts.map +1 -1
  298. package/lib/opLifecycle/index.js +2 -2
  299. package/lib/opLifecycle/index.js.map +1 -1
  300. package/lib/opLifecycle/opCompressor.d.ts +1 -1
  301. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  302. package/lib/opLifecycle/opCompressor.js +47 -18
  303. package/lib/opLifecycle/opCompressor.js.map +1 -1
  304. package/lib/opLifecycle/opDecompressor.d.ts +6 -1
  305. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  306. package/lib/opLifecycle/opDecompressor.js +72 -18
  307. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  308. package/lib/opLifecycle/opSplitter.d.ts +46 -2
  309. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  310. package/lib/opLifecycle/opSplitter.js +141 -5
  311. package/lib/opLifecycle/opSplitter.js.map +1 -1
  312. package/lib/opLifecycle/outbox.d.ts +23 -2
  313. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  314. package/lib/opLifecycle/outbox.js +103 -53
  315. package/lib/opLifecycle/outbox.js.map +1 -1
  316. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  317. package/lib/opLifecycle/remoteMessageProcessor.js +17 -2
  318. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  319. package/lib/opProperties.d.ts.map +1 -1
  320. package/lib/opProperties.js +1 -3
  321. package/lib/opProperties.js.map +1 -1
  322. package/lib/packageVersion.d.ts +1 -1
  323. package/lib/packageVersion.js +1 -1
  324. package/lib/packageVersion.js.map +1 -1
  325. package/lib/pendingStateManager.d.ts +6 -15
  326. package/lib/pendingStateManager.d.ts.map +1 -1
  327. package/lib/pendingStateManager.js +137 -165
  328. package/lib/pendingStateManager.js.map +1 -1
  329. package/lib/scheduleManager.d.ts +0 -1
  330. package/lib/scheduleManager.d.ts.map +1 -1
  331. package/lib/scheduleManager.js +11 -21
  332. package/lib/scheduleManager.js.map +1 -1
  333. package/lib/storageServiceWithAttachBlobs.d.ts +17 -0
  334. package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -0
  335. package/lib/storageServiceWithAttachBlobs.js +28 -0
  336. package/lib/storageServiceWithAttachBlobs.js.map +1 -0
  337. package/lib/summary/index.d.ts +17 -0
  338. package/lib/summary/index.d.ts.map +1 -0
  339. package/lib/summary/index.js +15 -0
  340. package/lib/summary/index.js.map +1 -0
  341. package/lib/summary/orderedClientElection.d.ts.map +1 -0
  342. package/lib/{orderedClientElection.js → summary/orderedClientElection.js} +10 -4
  343. package/lib/summary/orderedClientElection.js.map +1 -0
  344. package/{dist → lib/summary}/runWhileConnectedCoordinator.d.ts +3 -2
  345. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  346. package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +5 -4
  347. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
  348. package/{dist → lib/summary}/runningSummarizer.d.ts +19 -18
  349. package/lib/summary/runningSummarizer.d.ts.map +1 -0
  350. package/lib/{runningSummarizer.js → summary/runningSummarizer.js} +193 -79
  351. package/lib/summary/runningSummarizer.js.map +1 -0
  352. package/lib/{summarizer.d.ts → summary/summarizer.d.ts} +6 -12
  353. package/lib/summary/summarizer.d.ts.map +1 -0
  354. package/lib/{summarizer.js → summary/summarizer.js} +34 -78
  355. package/lib/summary/summarizer.js.map +1 -0
  356. package/lib/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +1 -2
  357. package/lib/summary/summarizerClientElection.d.ts.map +1 -0
  358. package/lib/{summarizerClientElection.js → summary/summarizerClientElection.js} +3 -30
  359. package/lib/summary/summarizerClientElection.js.map +1 -0
  360. package/lib/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +1 -1
  361. package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
  362. package/lib/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +9 -12
  363. package/lib/summary/summarizerHeuristics.js.map +1 -0
  364. package/lib/summary/summarizerNode/index.d.ts +8 -0
  365. package/lib/summary/summarizerNode/index.d.ts.map +1 -0
  366. package/lib/summary/summarizerNode/index.js +7 -0
  367. package/lib/summary/summarizerNode/index.js.map +1 -0
  368. package/lib/summary/summarizerNode/summarizerNode.d.ts +149 -0
  369. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -0
  370. package/lib/summary/summarizerNode/summarizerNode.js +526 -0
  371. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -0
  372. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +125 -0
  373. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -0
  374. package/lib/summary/summarizerNode/summarizerNodeUtils.js +125 -0
  375. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
  376. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +22 -0
  377. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -0
  378. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +419 -0
  379. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
  380. package/{dist → lib/summary}/summarizerTypes.d.ts +29 -42
  381. package/lib/summary/summarizerTypes.d.ts.map +1 -0
  382. package/lib/summary/summarizerTypes.js +6 -0
  383. package/lib/summary/summarizerTypes.js.map +1 -0
  384. package/lib/summary/summaryCollection.d.ts.map +1 -0
  385. package/lib/{summaryCollection.js → summary/summaryCollection.js} +18 -8
  386. package/lib/summary/summaryCollection.js.map +1 -0
  387. package/{dist → lib/summary}/summaryFormat.d.ts +3 -21
  388. package/lib/summary/summaryFormat.d.ts.map +1 -0
  389. package/lib/{summaryFormat.js → summary/summaryFormat.js} +20 -21
  390. package/lib/summary/summaryFormat.js.map +1 -0
  391. package/lib/summary/summaryGenerator.d.ts.map +1 -0
  392. package/lib/{summaryGenerator.js → summary/summaryGenerator.js} +34 -16
  393. package/lib/summary/summaryGenerator.js.map +1 -0
  394. package/lib/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
  395. package/lib/summary/summaryManager.d.ts.map +1 -0
  396. package/lib/{summaryManager.js → summary/summaryManager.js} +21 -9
  397. package/lib/summary/summaryManager.js.map +1 -0
  398. package/lib/throttler.d.ts +2 -2
  399. package/lib/throttler.d.ts.map +1 -1
  400. package/lib/throttler.js +4 -4
  401. package/lib/throttler.js.map +1 -1
  402. package/package.json +67 -61
  403. package/prettier.config.cjs +1 -1
  404. package/src/batchTracker.ts +55 -50
  405. package/src/blobManager.ts +863 -594
  406. package/src/connectionTelemetry.ts +280 -249
  407. package/src/containerHandleContext.ts +27 -29
  408. package/src/containerRuntime.ts +3174 -2805
  409. package/src/dataStore.ts +172 -159
  410. package/src/dataStoreContext.ts +1141 -993
  411. package/src/dataStoreContexts.ts +178 -161
  412. package/src/dataStoreRegistry.ts +25 -20
  413. package/src/dataStores.ts +887 -716
  414. package/src/deltaManagerSummarizerProxy.ts +46 -0
  415. package/src/deltaScheduler.ts +158 -150
  416. package/{garbageCollection.md → src/gc/garbageCollection.md} +16 -3
  417. package/src/gc/garbageCollection.ts +1250 -0
  418. package/src/gc/gcConfigs.ts +193 -0
  419. package/src/gc/gcDefinitions.ts +387 -0
  420. package/src/gc/gcHelpers.ts +332 -0
  421. package/src/gc/gcReferenceGraphAlgorithm.ts +52 -0
  422. package/src/gc/gcSummaryDefinitions.ts +54 -0
  423. package/src/gc/gcSummaryStateTracker.ts +329 -0
  424. package/src/gc/gcSweepReadyUsageDetection.ts +145 -0
  425. package/src/gc/gcUnreferencedStateTracker.ts +114 -0
  426. package/src/gc/index.ts +65 -0
  427. package/src/index.ts +61 -75
  428. package/src/opLifecycle/README.md +157 -0
  429. package/src/opLifecycle/batchManager.ts +119 -86
  430. package/src/opLifecycle/definitions.ts +49 -19
  431. package/src/opLifecycle/index.ts +7 -6
  432. package/src/opLifecycle/opCompressor.ts +78 -40
  433. package/src/opLifecycle/opDecompressor.ts +148 -64
  434. package/src/opLifecycle/opSplitter.ts +269 -66
  435. package/src/opLifecycle/outbox.ts +268 -184
  436. package/src/opLifecycle/remoteMessageProcessor.ts +63 -47
  437. package/src/opProperties.ts +11 -9
  438. package/src/packageVersion.ts +1 -1
  439. package/src/pendingStateManager.ts +386 -381
  440. package/src/scheduleManager.ts +299 -280
  441. package/src/storageServiceWithAttachBlobs.ts +38 -0
  442. package/src/summary/index.ts +105 -0
  443. package/src/summary/orderedClientElection.ts +564 -0
  444. package/src/summary/runWhileConnectedCoordinator.ts +113 -0
  445. package/src/summary/runningSummarizer.ts +788 -0
  446. package/src/summary/summarizer.ts +372 -0
  447. package/src/summary/summarizerClientElection.ts +139 -0
  448. package/src/summary/summarizerHeuristics.ts +224 -0
  449. package/src/summary/summarizerNode/index.ts +12 -0
  450. package/src/summary/summarizerNode/summarizerNode.ts +766 -0
  451. package/src/summary/summarizerNode/summarizerNodeUtils.ts +214 -0
  452. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +644 -0
  453. package/src/summary/summarizerTypes.ts +507 -0
  454. package/src/summary/summaryCollection.ts +450 -0
  455. package/src/summary/summaryFormat.ts +228 -0
  456. package/src/summary/summaryGenerator.ts +505 -0
  457. package/src/summary/summaryManager.ts +423 -0
  458. package/src/throttler.ts +131 -122
  459. package/tsconfig.esnext.json +6 -6
  460. package/tsconfig.json +9 -13
  461. package/dist/garbageCollection.d.ts +0 -387
  462. package/dist/garbageCollection.d.ts.map +0 -1
  463. package/dist/garbageCollection.js +0 -1138
  464. package/dist/garbageCollection.js.map +0 -1
  465. package/dist/garbageCollectionConstants.d.ts +0 -19
  466. package/dist/garbageCollectionConstants.d.ts.map +0 -1
  467. package/dist/garbageCollectionConstants.js +0 -34
  468. package/dist/garbageCollectionConstants.js.map +0 -1
  469. package/dist/gcSweepReadyUsageDetection.d.ts.map +0 -1
  470. package/dist/gcSweepReadyUsageDetection.js.map +0 -1
  471. package/dist/orderedClientElection.d.ts.map +0 -1
  472. package/dist/orderedClientElection.js.map +0 -1
  473. package/dist/runWhileConnectedCoordinator.d.ts.map +0 -1
  474. package/dist/runWhileConnectedCoordinator.js.map +0 -1
  475. package/dist/runningSummarizer.d.ts.map +0 -1
  476. package/dist/runningSummarizer.js.map +0 -1
  477. package/dist/serializedSnapshotStorage.d.ts +0 -58
  478. package/dist/serializedSnapshotStorage.d.ts.map +0 -1
  479. package/dist/serializedSnapshotStorage.js +0 -108
  480. package/dist/serializedSnapshotStorage.js.map +0 -1
  481. package/dist/summarizer.d.ts.map +0 -1
  482. package/dist/summarizer.js.map +0 -1
  483. package/dist/summarizerClientElection.d.ts.map +0 -1
  484. package/dist/summarizerClientElection.js.map +0 -1
  485. package/dist/summarizerHandle.d.ts +0 -12
  486. package/dist/summarizerHandle.d.ts.map +0 -1
  487. package/dist/summarizerHandle.js +0 -22
  488. package/dist/summarizerHandle.js.map +0 -1
  489. package/dist/summarizerHeuristics.d.ts.map +0 -1
  490. package/dist/summarizerHeuristics.js.map +0 -1
  491. package/dist/summarizerTypes.d.ts.map +0 -1
  492. package/dist/summarizerTypes.js.map +0 -1
  493. package/dist/summaryCollection.d.ts.map +0 -1
  494. package/dist/summaryCollection.js.map +0 -1
  495. package/dist/summaryFormat.d.ts.map +0 -1
  496. package/dist/summaryFormat.js.map +0 -1
  497. package/dist/summaryGenerator.d.ts.map +0 -1
  498. package/dist/summaryGenerator.js.map +0 -1
  499. package/dist/summaryManager.d.ts.map +0 -1
  500. package/dist/summaryManager.js.map +0 -1
  501. package/lib/garbageCollection.d.ts +0 -387
  502. package/lib/garbageCollection.d.ts.map +0 -1
  503. package/lib/garbageCollection.js +0 -1133
  504. package/lib/garbageCollection.js.map +0 -1
  505. package/lib/garbageCollectionConstants.d.ts +0 -19
  506. package/lib/garbageCollectionConstants.d.ts.map +0 -1
  507. package/lib/garbageCollectionConstants.js +0 -31
  508. package/lib/garbageCollectionConstants.js.map +0 -1
  509. package/lib/gcSweepReadyUsageDetection.d.ts.map +0 -1
  510. package/lib/gcSweepReadyUsageDetection.js.map +0 -1
  511. package/lib/orderedClientElection.d.ts.map +0 -1
  512. package/lib/orderedClientElection.js.map +0 -1
  513. package/lib/runWhileConnectedCoordinator.d.ts.map +0 -1
  514. package/lib/runWhileConnectedCoordinator.js.map +0 -1
  515. package/lib/runningSummarizer.d.ts.map +0 -1
  516. package/lib/runningSummarizer.js.map +0 -1
  517. package/lib/serializedSnapshotStorage.d.ts +0 -58
  518. package/lib/serializedSnapshotStorage.d.ts.map +0 -1
  519. package/lib/serializedSnapshotStorage.js +0 -104
  520. package/lib/serializedSnapshotStorage.js.map +0 -1
  521. package/lib/summarizer.d.ts.map +0 -1
  522. package/lib/summarizer.js.map +0 -1
  523. package/lib/summarizerClientElection.d.ts.map +0 -1
  524. package/lib/summarizerClientElection.js.map +0 -1
  525. package/lib/summarizerHandle.d.ts +0 -12
  526. package/lib/summarizerHandle.d.ts.map +0 -1
  527. package/lib/summarizerHandle.js +0 -18
  528. package/lib/summarizerHandle.js.map +0 -1
  529. package/lib/summarizerHeuristics.d.ts.map +0 -1
  530. package/lib/summarizerHeuristics.js.map +0 -1
  531. package/lib/summarizerTypes.d.ts.map +0 -1
  532. package/lib/summarizerTypes.js +0 -9
  533. package/lib/summarizerTypes.js.map +0 -1
  534. package/lib/summaryCollection.d.ts.map +0 -1
  535. package/lib/summaryCollection.js.map +0 -1
  536. package/lib/summaryFormat.d.ts.map +0 -1
  537. package/lib/summaryFormat.js.map +0 -1
  538. package/lib/summaryGenerator.d.ts.map +0 -1
  539. package/lib/summaryGenerator.js.map +0 -1
  540. package/lib/summaryManager.d.ts.map +0 -1
  541. package/lib/summaryManager.js.map +0 -1
  542. package/src/garbageCollection.ts +0 -1646
  543. package/src/garbageCollectionConstants.ts +0 -35
  544. package/src/gcSweepReadyUsageDetection.ts +0 -139
  545. package/src/orderedClientElection.ts +0 -532
  546. package/src/runWhileConnectedCoordinator.ts +0 -106
  547. package/src/runningSummarizer.ts +0 -611
  548. package/src/serializedSnapshotStorage.ts +0 -146
  549. package/src/summarizer.ts +0 -421
  550. package/src/summarizerClientElection.ts +0 -161
  551. package/src/summarizerHandle.ts +0 -21
  552. package/src/summarizerHeuristics.ts +0 -222
  553. package/src/summarizerTypes.ts +0 -510
  554. package/src/summaryCollection.ts +0 -421
  555. package/src/summaryFormat.ts +0 -235
  556. package/src/summaryGenerator.ts +0 -446
  557. package/src/summaryManager.ts +0 -394
  558. /package/dist/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  559. /package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  560. /package/dist/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
  561. /package/lib/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  562. /package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  563. /package/lib/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
@@ -10,17 +10,18 @@ import { ChildLogger } from "@fluidframework/telemetry-utils";
10
10
  import { assert, performance } from "@fluidframework/common-utils";
11
11
  import { isRuntimeMessage } from "@fluidframework/driver-utils";
12
12
  import {
13
- DataCorruptionError,
14
- DataProcessingError,
15
- extractSafePropertiesFromMessage,
13
+ DataCorruptionError,
14
+ DataProcessingError,
15
+ extractSafePropertiesFromMessage,
16
16
  } from "@fluidframework/container-utils";
17
17
  import { DeltaScheduler } from "./deltaScheduler";
18
18
  import { pkgVersion } from "./packageVersion";
19
- import { latencyThreshold } from "./connectionTelemetry";
20
19
 
21
- type IRuntimeMessageMetadata = undefined | {
22
- batch?: boolean;
23
- };
20
+ type IRuntimeMessageMetadata =
21
+ | undefined
22
+ | {
23
+ batch?: boolean;
24
+ };
24
25
 
25
26
  /**
26
27
  * This class has the following responsibilities:
@@ -32,61 +33,63 @@ type IRuntimeMessageMetadata = undefined | {
32
33
  * unless all ops of the batch are in.
33
34
  */
34
35
  export class ScheduleManager {
35
- private readonly deltaScheduler: DeltaScheduler;
36
- private batchClientId: string | undefined;
37
- private hitError = false;
38
-
39
- constructor(
40
- private readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
41
- private readonly emitter: EventEmitter,
42
- readonly getClientId: () => string | undefined,
43
- private readonly logger: ITelemetryLogger,
44
- ) {
45
- this.deltaScheduler = new DeltaScheduler(
46
- this.deltaManager,
47
- ChildLogger.create(this.logger, "DeltaScheduler"),
48
- );
49
- void new ScheduleManagerCore(deltaManager, getClientId, logger);
50
- }
51
-
52
- public beforeOpProcessing(message: ISequencedDocumentMessage) {
53
- if (this.batchClientId !== message.clientId) {
54
- assert(this.batchClientId === undefined,
55
- 0x2a2 /* "Batch is interrupted by other client op. Should be caught by trackPending()" */);
56
-
57
- // This could be the beginning of a new batch or an individual message.
58
- this.emitter.emit("batchBegin", message);
59
- this.deltaScheduler.batchBegin(message);
60
-
61
- const batch = (message?.metadata as IRuntimeMessageMetadata)?.batch;
62
- this.batchClientId = batch ? message.clientId : undefined;
63
- }
64
- }
65
-
66
- public afterOpProcessing(error: any | undefined, message: ISequencedDocumentMessage) {
67
- // If this is no longer true, we need to revisit what we do where we set this.hitError.
68
- assert(!this.hitError, 0x2a3 /* "container should be closed on any error" */);
69
-
70
- if (error) {
71
- // We assume here that loader will close container and stop processing all future ops.
72
- // This is implicit dependency. If this flow changes, this code might no longer be correct.
73
- this.hitError = true;
74
- this.batchClientId = undefined;
75
- this.emitter.emit("batchEnd", error, message);
76
- this.deltaScheduler.batchEnd(message);
77
- return;
78
- }
79
-
80
- const batch = (message?.metadata as IRuntimeMessageMetadata)?.batch;
81
- // If no batchClientId has been set then we're in an individual batch. Else, if we get
82
- // batch end metadata, this is end of the current batch.
83
- if (this.batchClientId === undefined || batch === false) {
84
- this.batchClientId = undefined;
85
- this.emitter.emit("batchEnd", undefined, message);
86
- this.deltaScheduler.batchEnd(message);
87
- return;
88
- }
89
- }
36
+ private readonly deltaScheduler: DeltaScheduler;
37
+ private batchClientId: string | undefined;
38
+ private hitError = false;
39
+
40
+ constructor(
41
+ private readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
42
+ private readonly emitter: EventEmitter,
43
+ readonly getClientId: () => string | undefined,
44
+ private readonly logger: ITelemetryLogger,
45
+ ) {
46
+ this.deltaScheduler = new DeltaScheduler(
47
+ this.deltaManager,
48
+ ChildLogger.create(this.logger, "DeltaScheduler"),
49
+ );
50
+ void new ScheduleManagerCore(deltaManager, getClientId, logger);
51
+ }
52
+
53
+ public beforeOpProcessing(message: ISequencedDocumentMessage) {
54
+ if (this.batchClientId !== message.clientId) {
55
+ assert(
56
+ this.batchClientId === undefined,
57
+ 0x2a2 /* "Batch is interrupted by other client op. Should be caught by trackPending()" */,
58
+ );
59
+
60
+ // This could be the beginning of a new batch or an individual message.
61
+ this.emitter.emit("batchBegin", message);
62
+ this.deltaScheduler.batchBegin(message);
63
+
64
+ const batch = (message?.metadata as IRuntimeMessageMetadata)?.batch;
65
+ this.batchClientId = batch ? message.clientId : undefined;
66
+ }
67
+ }
68
+
69
+ public afterOpProcessing(error: any | undefined, message: ISequencedDocumentMessage) {
70
+ // If this is no longer true, we need to revisit what we do where we set this.hitError.
71
+ assert(!this.hitError, 0x2a3 /* "container should be closed on any error" */);
72
+
73
+ if (error) {
74
+ // We assume here that loader will close container and stop processing all future ops.
75
+ // This is implicit dependency. If this flow changes, this code might no longer be correct.
76
+ this.hitError = true;
77
+ this.batchClientId = undefined;
78
+ this.emitter.emit("batchEnd", error, message);
79
+ this.deltaScheduler.batchEnd(message);
80
+ return;
81
+ }
82
+
83
+ const batch = (message?.metadata as IRuntimeMessageMetadata)?.batch;
84
+ // If no batchClientId has been set then we're in an individual batch. Else, if we get
85
+ // batch end metadata, this is end of the current batch.
86
+ if (this.batchClientId === undefined || batch === false) {
87
+ this.batchClientId = undefined;
88
+ this.emitter.emit("batchEnd", undefined, message);
89
+ this.deltaScheduler.batchEnd(message);
90
+ return;
91
+ }
92
+ }
90
93
  }
91
94
 
92
95
  /**
@@ -94,222 +97,238 @@ export class ScheduleManager {
94
97
  * start processing ops in a batch IF we do not have all ops in the batch.
95
98
  */
96
99
  class ScheduleManagerCore {
97
- private pauseSequenceNumber: number | undefined;
98
- private currentBatchClientId: string | undefined;
99
- private localPaused = false;
100
- private timePaused = 0;
101
- private batchCount = 0;
102
-
103
- constructor(
104
- private readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
105
- private readonly getClientId: () => string | undefined,
106
- private readonly logger: ITelemetryLogger,
107
- ) {
108
- // Listen for delta manager sends and add batch metadata to messages
109
- this.deltaManager.on("prepareSend", (messages: IDocumentMessage[]) => {
110
- if (messages.length === 0) {
111
- return;
112
- }
113
-
114
- // First message will have the batch flag set to true if doing a batched send
115
- const firstMessageMetadata = messages[0].metadata as IRuntimeMessageMetadata;
116
- if (!firstMessageMetadata?.batch) {
117
- return;
118
- }
119
-
120
- // If the batch contains only a single op, clear the batch flag.
121
- if (messages.length === 1) {
122
- delete firstMessageMetadata.batch;
123
- return;
124
- }
125
-
126
- // Set the batch flag to false on the last message to indicate the end of the send batch
127
- const lastMessage = messages[messages.length - 1];
128
- lastMessage.metadata = { ...lastMessage.metadata, batch: false };
129
- });
130
-
131
- // Listen for updates and peek at the inbound
132
- this.deltaManager.inbound.on(
133
- "push",
134
- (message: ISequencedDocumentMessage) => {
135
- this.trackPending(message);
136
- });
137
-
138
- // Start with baseline - empty inbound queue.
139
- assert(!this.localPaused, 0x293 /* "initial state" */);
140
-
141
- const allPending = this.deltaManager.inbound.toArray();
142
- for (const pending of allPending) {
143
- this.trackPending(pending);
144
- }
145
-
146
- // We are intentionally directly listening to the "op" to inspect system ops as well.
147
- // If we do not observe system ops, we are likely to hit 0x296 assert when system ops
148
- // precedes start of incomplete batch.
149
- this.deltaManager.on("op", (message) => this.afterOpProcessing(message.sequenceNumber));
150
- }
151
-
152
- /**
153
- * The only public function in this class - called when we processed an op,
154
- * to make decision if op processing should be paused or not after that.
155
- */
156
- public afterOpProcessing(sequenceNumber: number) {
157
- assert(!this.localPaused, 0x294 /* "can't have op processing paused if we are processing an op" */);
158
-
159
- // If the inbound queue is ever empty, nothing to do!
160
- if (this.deltaManager.inbound.length === 0) {
161
- assert(this.pauseSequenceNumber === undefined,
162
- 0x295 /* "there should be no pending batch if we have no ops" */);
163
- return;
164
- }
165
-
166
- // The queue is
167
- // 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:
168
- // - here (processing ops until reaching start of incomplete batch)
169
- // - in trackPending(), when queue was empty and start of batch showed up.
170
- // 2. resumed when batch end comes in (in trackPending())
171
-
172
- // do we have incomplete batch to worry about?
173
- if (this.pauseSequenceNumber !== undefined) {
174
- assert(sequenceNumber < this.pauseSequenceNumber,
175
- 0x296 /* "we should never start processing incomplete batch!" */);
176
- // If the next op is the start of incomplete batch, then we can't process it until it's fully in - pause!
177
- if (sequenceNumber + 1 === this.pauseSequenceNumber) {
178
- this.pauseQueue();
179
- }
180
- }
181
- }
182
-
183
- private pauseQueue() {
184
- assert(!this.localPaused, 0x297 /* "always called from resumed state" */);
185
- this.localPaused = true;
186
- this.timePaused = performance.now();
187
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
188
- this.deltaManager.inbound.pause();
189
- }
190
-
191
- private resumeQueue(startBatch: number, messageEndBatch: ISequencedDocumentMessage) {
192
- const endBatch = messageEndBatch.sequenceNumber;
193
- const duration = this.localPaused ? (performance.now() - this.timePaused) : undefined;
194
-
195
- this.batchCount++;
196
- if (this.batchCount % 1000 === 1) {
197
- this.logger.sendTelemetryEvent({
198
- eventName: "BatchStats",
199
- sequenceNumber: endBatch,
200
- length: endBatch - startBatch + 1,
201
- msnDistance: endBatch - messageEndBatch.minimumSequenceNumber,
202
- duration,
203
- batchCount: this.batchCount,
204
- interrupted: this.localPaused,
205
- });
206
- }
207
-
208
- // Return early if no change in value
209
- if (!this.localPaused) {
210
- return;
211
- }
212
-
213
- this.localPaused = false;
214
-
215
- // Random round number - we want to know when batch waiting paused op processing.
216
- if (duration !== undefined && duration > latencyThreshold) {
217
- this.logger.sendErrorEvent({
218
- eventName: "MaxBatchWaitTimeExceeded",
219
- duration,
220
- sequenceNumber: endBatch,
221
- length: endBatch - startBatch,
222
- });
223
- }
224
-
225
- this.deltaManager.inbound.resume();
226
- }
227
-
228
- /**
229
- * Called for each incoming op (i.e. inbound "push" notification)
230
- */
231
- private trackPending(message: ISequencedDocumentMessage) {
232
- assert(this.deltaManager.inbound.length !== 0,
233
- 0x298 /* "we have something in the queue that generates this event" */);
234
-
235
- assert((this.currentBatchClientId === undefined) === (this.pauseSequenceNumber === undefined),
236
- 0x299 /* "non-synchronized state" */);
237
-
238
- const metadata = message.metadata as IRuntimeMessageMetadata;
239
- const batchMetadata = metadata?.batch;
240
-
241
- // Protocol messages are never part of a runtime batch of messages
242
- if (!isRuntimeMessage(message)) {
243
- // Protocol messages should never show up in the middle of the batch!
244
- if (this.currentBatchClientId !== undefined) {
245
- throw DataProcessingError.create(
246
- "Received a system message during batch processing", // Formerly known as assert 0x29a
247
- "trackPending",
248
- message,
249
- {
250
- runtimeVersion: pkgVersion,
251
- batchClientId: this.currentBatchClientId,
252
- pauseSequenceNumber: this.pauseSequenceNumber,
253
- localBatch: this.currentBatchClientId === this.getClientId(),
254
- messageType: message.type,
255
- });
256
- }
257
-
258
- assert(batchMetadata === undefined, 0x29b /* "system op in a batch?" */);
259
- assert(!this.localPaused, 0x29c /* "we should be processing ops when there is no active batch" */);
260
- return;
261
- }
262
-
263
- if (this.currentBatchClientId === undefined && batchMetadata === undefined) {
264
- assert(!this.localPaused, 0x29d /* "we should be processing ops when there is no active batch" */);
265
- return;
266
- }
267
-
268
- // If the client ID changes then we can move the pause point. If it stayed the same then we need to check.
269
- // If batchMetadata is not undefined then if it's true we've begun a new batch - if false we've ended
270
- // the previous one
271
- if (this.currentBatchClientId !== undefined || batchMetadata === false) {
272
- if (this.currentBatchClientId !== message.clientId) {
273
- // "Batch not closed, yet message from another client!"
274
- throw new DataCorruptionError(
275
- "OpBatchIncomplete",
276
- {
277
- runtimeVersion: pkgVersion,
278
- batchClientId: this.currentBatchClientId,
279
- pauseSequenceNumber: this.pauseSequenceNumber,
280
- localBatch: this.currentBatchClientId === this.getClientId(),
281
- localMessage: message.clientId === this.getClientId(),
282
- ...extractSafePropertiesFromMessage(message),
283
- });
284
- }
285
- }
286
-
287
- // The queue is
288
- // 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:
289
- // - in afterOpProcessing() - processing ops until reaching start of incomplete batch
290
- // - here (batchMetadata == false below), when queue was empty and start of batch showed up.
291
- // 2. resumed when batch end comes in (batchMetadata === true case below)
292
-
293
- if (batchMetadata) {
294
- assert(this.currentBatchClientId === undefined, 0x29e /* "there can't be active batch" */);
295
- assert(!this.localPaused, 0x29f /* "we should be processing ops when there is no active batch" */);
296
- this.pauseSequenceNumber = message.sequenceNumber;
297
- this.currentBatchClientId = message.clientId;
298
- // Start of the batch
299
- // Only pause processing if queue has no other ops!
300
- // If there are any other ops in the queue, processing will be stopped when they are processed!
301
- if (this.deltaManager.inbound.length === 1) {
302
- this.pauseQueue();
303
- }
304
- } else if (batchMetadata === false) {
305
- assert(this.pauseSequenceNumber !== undefined, 0x2a0 /* "batch presence was validated above" */);
306
- // Batch is complete, we can process it!
307
- this.resumeQueue(this.pauseSequenceNumber, message);
308
- this.pauseSequenceNumber = undefined;
309
- this.currentBatchClientId = undefined;
310
- } else {
311
- // Continuation of current batch. Do nothing
312
- assert(this.currentBatchClientId !== undefined, 0x2a1 /* "logic error" */);
313
- }
314
- }
100
+ private pauseSequenceNumber: number | undefined;
101
+ private currentBatchClientId: string | undefined;
102
+ private localPaused = false;
103
+ private timePaused = 0;
104
+ private batchCount = 0;
105
+
106
+ constructor(
107
+ private readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
108
+ private readonly getClientId: () => string | undefined,
109
+ private readonly logger: ITelemetryLogger,
110
+ ) {
111
+ // Listen for delta manager sends and add batch metadata to messages
112
+ this.deltaManager.on("prepareSend", (messages: IDocumentMessage[]) => {
113
+ if (messages.length === 0) {
114
+ return;
115
+ }
116
+
117
+ // First message will have the batch flag set to true if doing a batched send
118
+ const firstMessageMetadata = messages[0].metadata as IRuntimeMessageMetadata;
119
+ if (!firstMessageMetadata?.batch) {
120
+ return;
121
+ }
122
+
123
+ // If the batch contains only a single op, clear the batch flag.
124
+ if (messages.length === 1) {
125
+ delete firstMessageMetadata.batch;
126
+ return;
127
+ }
128
+
129
+ // Set the batch flag to false on the last message to indicate the end of the send batch
130
+ const lastMessage = messages[messages.length - 1];
131
+ lastMessage.metadata = { ...lastMessage.metadata, batch: false };
132
+ });
133
+
134
+ // Listen for updates and peek at the inbound
135
+ this.deltaManager.inbound.on("push", (message: ISequencedDocumentMessage) => {
136
+ this.trackPending(message);
137
+ });
138
+
139
+ // Start with baseline - empty inbound queue.
140
+ assert(!this.localPaused, 0x293 /* "initial state" */);
141
+
142
+ const allPending = this.deltaManager.inbound.toArray();
143
+ for (const pending of allPending) {
144
+ this.trackPending(pending);
145
+ }
146
+
147
+ // We are intentionally directly listening to the "op" to inspect system ops as well.
148
+ // If we do not observe system ops, we are likely to hit 0x296 assert when system ops
149
+ // precedes start of incomplete batch.
150
+ this.deltaManager.on("op", (message) => this.afterOpProcessing(message.sequenceNumber));
151
+ }
152
+
153
+ /**
154
+ * The only public function in this class - called when we processed an op,
155
+ * to make decision if op processing should be paused or not after that.
156
+ */
157
+ public afterOpProcessing(sequenceNumber: number) {
158
+ assert(
159
+ !this.localPaused,
160
+ 0x294 /* "can't have op processing paused if we are processing an op" */,
161
+ );
162
+
163
+ // If the inbound queue is ever empty, nothing to do!
164
+ if (this.deltaManager.inbound.length === 0) {
165
+ assert(
166
+ this.pauseSequenceNumber === undefined,
167
+ 0x295 /* "there should be no pending batch if we have no ops" */,
168
+ );
169
+ return;
170
+ }
171
+
172
+ // The queue is
173
+ // 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:
174
+ // - here (processing ops until reaching start of incomplete batch)
175
+ // - in trackPending(), when queue was empty and start of batch showed up.
176
+ // 2. resumed when batch end comes in (in trackPending())
177
+
178
+ // do we have incomplete batch to worry about?
179
+ if (this.pauseSequenceNumber !== undefined) {
180
+ assert(
181
+ sequenceNumber < this.pauseSequenceNumber,
182
+ 0x296 /* "we should never start processing incomplete batch!" */,
183
+ );
184
+ // If the next op is the start of incomplete batch, then we can't process it until it's fully in - pause!
185
+ if (sequenceNumber + 1 === this.pauseSequenceNumber) {
186
+ this.pauseQueue();
187
+ }
188
+ }
189
+ }
190
+
191
+ private pauseQueue() {
192
+ assert(!this.localPaused, 0x297 /* "always called from resumed state" */);
193
+ this.localPaused = true;
194
+ this.timePaused = performance.now();
195
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
196
+ this.deltaManager.inbound.pause();
197
+ }
198
+
199
+ private resumeQueue(startBatch: number, messageEndBatch: ISequencedDocumentMessage) {
200
+ const endBatch = messageEndBatch.sequenceNumber;
201
+ const duration = this.localPaused ? performance.now() - this.timePaused : undefined;
202
+
203
+ this.batchCount++;
204
+ if (this.batchCount % 1000 === 1) {
205
+ this.logger.sendTelemetryEvent({
206
+ eventName: "BatchStats",
207
+ sequenceNumber: endBatch,
208
+ length: endBatch - startBatch + 1,
209
+ msnDistance: endBatch - messageEndBatch.minimumSequenceNumber,
210
+ duration,
211
+ batchCount: this.batchCount,
212
+ interrupted: this.localPaused,
213
+ });
214
+ }
215
+
216
+ // Return early if no change in value
217
+ if (!this.localPaused) {
218
+ return;
219
+ }
220
+
221
+ this.localPaused = false;
222
+
223
+ this.deltaManager.inbound.resume();
224
+ }
225
+
226
+ /**
227
+ * Called for each incoming op (i.e. inbound "push" notification)
228
+ */
229
+ private trackPending(message: ISequencedDocumentMessage) {
230
+ assert(
231
+ this.deltaManager.inbound.length !== 0,
232
+ 0x298 /* "we have something in the queue that generates this event" */,
233
+ );
234
+
235
+ assert(
236
+ (this.currentBatchClientId === undefined) === (this.pauseSequenceNumber === undefined),
237
+ 0x299 /* "non-synchronized state" */,
238
+ );
239
+
240
+ const metadata = message.metadata as IRuntimeMessageMetadata;
241
+ // batchMetadata will be true for the message that starts a batch, false for the one that ends it, and
242
+ // undefined for all other messages.
243
+ const batchMetadata = metadata?.batch;
244
+
245
+ // Protocol messages are never part of a runtime batch of messages
246
+ if (!isRuntimeMessage(message)) {
247
+ // Protocol messages should never show up in the middle of the batch!
248
+ if (this.currentBatchClientId !== undefined) {
249
+ throw DataProcessingError.create(
250
+ "Received a system message during batch processing", // Formerly known as assert 0x29a
251
+ "trackPending",
252
+ message,
253
+ {
254
+ runtimeVersion: pkgVersion,
255
+ batchClientId: this.currentBatchClientId,
256
+ pauseSequenceNumber: this.pauseSequenceNumber,
257
+ localBatch: this.currentBatchClientId === this.getClientId(),
258
+ messageType: message.type,
259
+ },
260
+ );
261
+ }
262
+
263
+ assert(batchMetadata === undefined, 0x29b /* "system op in a batch?" */);
264
+ assert(
265
+ !this.localPaused,
266
+ 0x29c /* "we should be processing ops when there is no active batch" */,
267
+ );
268
+ return;
269
+ }
270
+
271
+ if (this.currentBatchClientId === undefined && batchMetadata === undefined) {
272
+ assert(
273
+ !this.localPaused,
274
+ 0x29d /* "we should be processing ops when there is no active batch" */,
275
+ );
276
+ return;
277
+ }
278
+
279
+ // If we got here, the message is part of a batch. Either starting, in progress, or ending.
280
+
281
+ // If this is not the start of the batch, error out if the message was sent by a client other than the one that
282
+ // started the current batch (it should not be possible for ops from other clients to get interleaved with a batch).
283
+ if (
284
+ this.currentBatchClientId !== undefined &&
285
+ this.currentBatchClientId !== message.clientId
286
+ ) {
287
+ throw new DataCorruptionError("OpBatchIncomplete", {
288
+ runtimeVersion: pkgVersion,
289
+ batchClientId: this.currentBatchClientId,
290
+ pauseSequenceNumber: this.pauseSequenceNumber,
291
+ localBatch: this.currentBatchClientId === this.getClientId(),
292
+ localMessage: message.clientId === this.getClientId(),
293
+ ...extractSafePropertiesFromMessage(message),
294
+ });
295
+ }
296
+
297
+ // The queue is
298
+ // 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:
299
+ // - in afterOpProcessing() - processing ops until reaching start of incomplete batch
300
+ // - here, when queue was empty and start of batch showed up (batchMetadata === true below).
301
+ // 2. resumed when batch end comes in (batchMetadata === false below)
302
+
303
+ if (batchMetadata) {
304
+ assert(
305
+ this.currentBatchClientId === undefined,
306
+ 0x29e /* "there can't be active batch" */,
307
+ );
308
+ assert(
309
+ !this.localPaused,
310
+ 0x29f /* "we should be processing ops when there is no active batch" */,
311
+ );
312
+ this.pauseSequenceNumber = message.sequenceNumber;
313
+ this.currentBatchClientId = message.clientId;
314
+ // Start of the batch
315
+ // Only pause processing if queue has no other ops!
316
+ // If there are any other ops in the queue, processing will be stopped when they are processed!
317
+ if (this.deltaManager.inbound.length === 1) {
318
+ this.pauseQueue();
319
+ }
320
+ } else if (batchMetadata === false) {
321
+ assert(
322
+ this.pauseSequenceNumber !== undefined,
323
+ 0x2a0 /* "batch presence was validated above" */,
324
+ );
325
+ // Batch is complete, we can process it!
326
+ this.resumeQueue(this.pauseSequenceNumber, message);
327
+ this.pauseSequenceNumber = undefined;
328
+ this.currentBatchClientId = undefined;
329
+ } else {
330
+ // Continuation of current batch. Do nothing
331
+ assert(this.currentBatchClientId !== undefined, 0x2a1 /* "logic error" */);
332
+ }
333
+ }
315
334
  }