@fluidframework/container-runtime 2.13.0 → 2.21.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 (489) hide show
  1. package/.eslintrc.cjs +71 -5
  2. package/CHANGELOG.md +84 -0
  3. package/api-report/container-runtime.legacy.alpha.api.md +38 -232
  4. package/dist/batchTracker.d.ts +1 -2
  5. package/dist/batchTracker.d.ts.map +1 -1
  6. package/dist/batchTracker.js +1 -1
  7. package/dist/batchTracker.js.map +1 -1
  8. package/dist/blobManager/blobManager.d.ts +5 -1
  9. package/dist/blobManager/blobManager.d.ts.map +1 -1
  10. package/dist/blobManager/blobManager.js +30 -13
  11. package/dist/blobManager/blobManager.js.map +1 -1
  12. package/dist/blobManager/blobManagerSnapSum.d.ts +1 -0
  13. package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  14. package/dist/blobManager/blobManagerSnapSum.js +7 -5
  15. package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
  16. package/dist/channelCollection.d.ts +23 -12
  17. package/dist/channelCollection.d.ts.map +1 -1
  18. package/dist/channelCollection.js +85 -53
  19. package/dist/channelCollection.js.map +1 -1
  20. package/dist/connectionTelemetry.d.ts +2 -2
  21. package/dist/connectionTelemetry.d.ts.map +1 -1
  22. package/dist/connectionTelemetry.js +10 -6
  23. package/dist/connectionTelemetry.js.map +1 -1
  24. package/dist/containerHandleContext.d.ts +1 -1
  25. package/dist/containerHandleContext.d.ts.map +1 -1
  26. package/dist/containerHandleContext.js.map +1 -1
  27. package/dist/containerRuntime.d.ts +87 -94
  28. package/dist/containerRuntime.d.ts.map +1 -1
  29. package/dist/containerRuntime.js +312 -226
  30. package/dist/containerRuntime.js.map +1 -1
  31. package/dist/dataStore.d.ts +7 -3
  32. package/dist/dataStore.d.ts.map +1 -1
  33. package/dist/dataStore.js +8 -4
  34. package/dist/dataStore.js.map +1 -1
  35. package/dist/dataStoreContext.d.ts +41 -25
  36. package/dist/dataStoreContext.d.ts.map +1 -1
  37. package/dist/dataStoreContext.js +47 -29
  38. package/dist/dataStoreContext.js.map +1 -1
  39. package/dist/dataStoreContexts.d.ts +6 -2
  40. package/dist/dataStoreContexts.d.ts.map +1 -1
  41. package/dist/dataStoreContexts.js +7 -2
  42. package/dist/dataStoreContexts.js.map +1 -1
  43. package/dist/dataStoreRegistry.d.ts +1 -1
  44. package/dist/dataStoreRegistry.d.ts.map +1 -1
  45. package/dist/dataStoreRegistry.js.map +1 -1
  46. package/dist/deltaManagerProxies.d.ts +1 -17
  47. package/dist/deltaManagerProxies.d.ts.map +1 -1
  48. package/dist/deltaManagerProxies.js.map +1 -1
  49. package/dist/deltaScheduler.d.ts +9 -6
  50. package/dist/deltaScheduler.d.ts.map +1 -1
  51. package/dist/deltaScheduler.js +95 -89
  52. package/dist/deltaScheduler.js.map +1 -1
  53. package/dist/gc/garbageCollection.d.ts +21 -7
  54. package/dist/gc/garbageCollection.d.ts.map +1 -1
  55. package/dist/gc/garbageCollection.js +48 -19
  56. package/dist/gc/garbageCollection.js.map +1 -1
  57. package/dist/gc/gcConfigs.d.ts +11 -0
  58. package/dist/gc/gcConfigs.d.ts.map +1 -1
  59. package/dist/gc/gcConfigs.js +5 -2
  60. package/dist/gc/gcConfigs.js.map +1 -1
  61. package/dist/gc/gcDefinitions.d.ts +218 -70
  62. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  63. package/dist/gc/gcDefinitions.js +40 -13
  64. package/dist/gc/gcDefinitions.js.map +1 -1
  65. package/dist/gc/gcHelpers.d.ts +6 -2
  66. package/dist/gc/gcHelpers.d.ts.map +1 -1
  67. package/dist/gc/gcHelpers.js +14 -7
  68. package/dist/gc/gcHelpers.js.map +1 -1
  69. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  70. package/dist/gc/gcSummaryDefinitions.d.ts +18 -6
  71. package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -1
  72. package/dist/gc/gcSummaryDefinitions.js.map +1 -1
  73. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  74. package/dist/gc/gcSummaryStateTracker.js +2 -1
  75. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  76. package/dist/gc/gcTelemetry.d.ts +33 -11
  77. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  78. package/dist/gc/gcTelemetry.js +35 -17
  79. package/dist/gc/gcTelemetry.js.map +1 -1
  80. package/dist/gc/gcUnreferencedStateTracker.d.ts +42 -13
  81. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  82. package/dist/gc/gcUnreferencedStateTracker.js +27 -9
  83. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  84. package/dist/gc/index.d.ts +1 -0
  85. package/dist/gc/index.d.ts.map +1 -1
  86. package/dist/gc/index.js +3 -1
  87. package/dist/gc/index.js.map +1 -1
  88. package/dist/inboundBatchAggregator.d.ts +34 -0
  89. package/dist/inboundBatchAggregator.d.ts.map +1 -0
  90. package/dist/inboundBatchAggregator.js +185 -0
  91. package/dist/inboundBatchAggregator.js.map +1 -0
  92. package/dist/index.d.ts +1 -1
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js.map +1 -1
  95. package/dist/layerCompatState.d.ts +19 -0
  96. package/dist/layerCompatState.d.ts.map +1 -0
  97. package/dist/layerCompatState.js +64 -0
  98. package/dist/layerCompatState.js.map +1 -0
  99. package/dist/legacy.d.ts +0 -4
  100. package/dist/messageTypes.d.ts +14 -5
  101. package/dist/messageTypes.d.ts.map +1 -1
  102. package/dist/messageTypes.js.map +1 -1
  103. package/dist/metadata.d.ts +12 -4
  104. package/dist/metadata.d.ts.map +1 -1
  105. package/dist/metadata.js +6 -2
  106. package/dist/metadata.js.map +1 -1
  107. package/dist/opLifecycle/batchManager.d.ts +9 -3
  108. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  109. package/dist/opLifecycle/batchManager.js +3 -1
  110. package/dist/opLifecycle/batchManager.js.map +1 -1
  111. package/dist/opLifecycle/duplicateBatchDetector.d.ts +9 -3
  112. package/dist/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
  113. package/dist/opLifecycle/duplicateBatchDetector.js +11 -5
  114. package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
  115. package/dist/opLifecycle/opCompressor.d.ts +3 -2
  116. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  117. package/dist/opLifecycle/opCompressor.js +13 -19
  118. package/dist/opLifecycle/opCompressor.js.map +1 -1
  119. package/dist/opLifecycle/opDecompressor.d.ts +6 -1
  120. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  121. package/dist/opLifecycle/opDecompressor.js +16 -8
  122. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  123. package/dist/opLifecycle/opGroupingManager.d.ts +1 -2
  124. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  125. package/dist/opLifecycle/opGroupingManager.js +9 -6
  126. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  127. package/dist/opLifecycle/opSplitter.d.ts +13 -10
  128. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  129. package/dist/opLifecycle/opSplitter.js +16 -11
  130. package/dist/opLifecycle/opSplitter.js.map +1 -1
  131. package/dist/opLifecycle/outbox.d.ts +4 -4
  132. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  133. package/dist/opLifecycle/outbox.js +17 -16
  134. package/dist/opLifecycle/outbox.js.map +1 -1
  135. package/dist/opLifecycle/remoteMessageProcessor.d.ts +9 -3
  136. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  137. package/dist/opLifecycle/remoteMessageProcessor.js +3 -1
  138. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  139. package/dist/package.json +2 -1
  140. package/dist/packageVersion.d.ts +1 -1
  141. package/dist/packageVersion.js +1 -1
  142. package/dist/packageVersion.js.map +1 -1
  143. package/dist/pendingStateManager.d.ts +22 -11
  144. package/dist/pendingStateManager.d.ts.map +1 -1
  145. package/dist/pendingStateManager.js +24 -15
  146. package/dist/pendingStateManager.js.map +1 -1
  147. package/dist/summary/documentSchema.d.ts +7 -0
  148. package/dist/summary/documentSchema.d.ts.map +1 -1
  149. package/dist/summary/documentSchema.js +8 -4
  150. package/dist/summary/documentSchema.js.map +1 -1
  151. package/dist/summary/index.d.ts +1 -1
  152. package/dist/summary/index.d.ts.map +1 -1
  153. package/dist/summary/index.js.map +1 -1
  154. package/dist/summary/orderedClientElection.d.ts +94 -31
  155. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  156. package/dist/summary/orderedClientElection.js +28 -16
  157. package/dist/summary/orderedClientElection.js.map +1 -1
  158. package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -0
  159. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  160. package/dist/summary/runWhileConnectedCoordinator.js +7 -2
  161. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  162. package/dist/summary/runningSummarizer.d.ts +17 -6
  163. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  164. package/dist/summary/runningSummarizer.js +48 -19
  165. package/dist/summary/runningSummarizer.js.map +1 -1
  166. package/dist/summary/summarizer.d.ts +10 -5
  167. package/dist/summary/summarizer.d.ts.map +1 -1
  168. package/dist/summary/summarizer.js +26 -11
  169. package/dist/summary/summarizer.js.map +1 -1
  170. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  171. package/dist/summary/summarizerClientElection.js +1 -0
  172. package/dist/summary/summarizerClientElection.js.map +1 -1
  173. package/dist/summary/summarizerHeuristics.d.ts +6 -2
  174. package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
  175. package/dist/summary/summarizerHeuristics.js +13 -5
  176. package/dist/summary/summarizerHeuristics.js.map +1 -1
  177. package/dist/summary/summarizerNode/index.d.ts.map +1 -1
  178. package/dist/summary/summarizerNode/index.js.map +1 -1
  179. package/dist/summary/summarizerNode/summarizerNode.d.ts +24 -8
  180. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  181. package/dist/summary/summarizerNode/summarizerNode.js +45 -36
  182. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  183. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +48 -16
  184. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  185. package/dist/summary/summarizerNode/summarizerNodeUtils.js +3 -1
  186. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  187. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +13 -5
  188. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  189. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +15 -7
  190. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  191. package/dist/summary/summarizerTypes.d.ts +253 -135
  192. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  193. package/dist/summary/summarizerTypes.js.map +1 -1
  194. package/dist/summary/summaryCollection.d.ts +3 -4
  195. package/dist/summary/summaryCollection.d.ts.map +1 -1
  196. package/dist/summary/summaryCollection.js +10 -8
  197. package/dist/summary/summaryCollection.js.map +1 -1
  198. package/dist/summary/summaryFormat.d.ts +28 -9
  199. package/dist/summary/summaryFormat.d.ts.map +1 -1
  200. package/dist/summary/summaryFormat.js +3 -2
  201. package/dist/summary/summaryFormat.js.map +1 -1
  202. package/dist/summary/summaryGenerator.d.ts +9 -3
  203. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  204. package/dist/summary/summaryGenerator.js +22 -9
  205. package/dist/summary/summaryGenerator.js.map +1 -1
  206. package/dist/summary/summaryManager.d.ts +8 -4
  207. package/dist/summary/summaryManager.d.ts.map +1 -1
  208. package/dist/summary/summaryManager.js +20 -9
  209. package/dist/summary/summaryManager.js.map +1 -1
  210. package/dist/throttler.d.ts +26 -10
  211. package/dist/throttler.d.ts.map +1 -1
  212. package/dist/throttler.js +12 -4
  213. package/dist/throttler.js.map +1 -1
  214. package/lib/batchTracker.d.ts +1 -2
  215. package/lib/batchTracker.d.ts.map +1 -1
  216. package/lib/batchTracker.js +2 -2
  217. package/lib/batchTracker.js.map +1 -1
  218. package/lib/blobManager/blobManager.d.ts +5 -1
  219. package/lib/blobManager/blobManager.d.ts.map +1 -1
  220. package/lib/blobManager/blobManager.js +30 -13
  221. package/lib/blobManager/blobManager.js.map +1 -1
  222. package/lib/blobManager/blobManagerSnapSum.d.ts +1 -0
  223. package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  224. package/lib/blobManager/blobManagerSnapSum.js +7 -5
  225. package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
  226. package/lib/channelCollection.d.ts +23 -12
  227. package/lib/channelCollection.d.ts.map +1 -1
  228. package/lib/channelCollection.js +88 -54
  229. package/lib/channelCollection.js.map +1 -1
  230. package/lib/connectionTelemetry.d.ts +2 -2
  231. package/lib/connectionTelemetry.d.ts.map +1 -1
  232. package/lib/connectionTelemetry.js +11 -7
  233. package/lib/connectionTelemetry.js.map +1 -1
  234. package/lib/containerHandleContext.d.ts +1 -1
  235. package/lib/containerHandleContext.d.ts.map +1 -1
  236. package/lib/containerHandleContext.js.map +1 -1
  237. package/lib/containerRuntime.d.ts +87 -94
  238. package/lib/containerRuntime.d.ts.map +1 -1
  239. package/lib/containerRuntime.js +319 -228
  240. package/lib/containerRuntime.js.map +1 -1
  241. package/lib/dataStore.d.ts +7 -3
  242. package/lib/dataStore.d.ts.map +1 -1
  243. package/lib/dataStore.js +8 -4
  244. package/lib/dataStore.js.map +1 -1
  245. package/lib/dataStoreContext.d.ts +41 -25
  246. package/lib/dataStoreContext.d.ts.map +1 -1
  247. package/lib/dataStoreContext.js +47 -29
  248. package/lib/dataStoreContext.js.map +1 -1
  249. package/lib/dataStoreContexts.d.ts +6 -2
  250. package/lib/dataStoreContexts.d.ts.map +1 -1
  251. package/lib/dataStoreContexts.js +7 -2
  252. package/lib/dataStoreContexts.js.map +1 -1
  253. package/lib/dataStoreRegistry.d.ts +1 -1
  254. package/lib/dataStoreRegistry.d.ts.map +1 -1
  255. package/lib/dataStoreRegistry.js.map +1 -1
  256. package/lib/deltaManagerProxies.d.ts +1 -17
  257. package/lib/deltaManagerProxies.d.ts.map +1 -1
  258. package/lib/deltaManagerProxies.js.map +1 -1
  259. package/lib/deltaScheduler.d.ts +9 -6
  260. package/lib/deltaScheduler.d.ts.map +1 -1
  261. package/lib/deltaScheduler.js +96 -90
  262. package/lib/deltaScheduler.js.map +1 -1
  263. package/lib/gc/garbageCollection.d.ts +21 -7
  264. package/lib/gc/garbageCollection.d.ts.map +1 -1
  265. package/lib/gc/garbageCollection.js +51 -20
  266. package/lib/gc/garbageCollection.js.map +1 -1
  267. package/lib/gc/gcConfigs.d.ts +11 -0
  268. package/lib/gc/gcConfigs.d.ts.map +1 -1
  269. package/lib/gc/gcConfigs.js +4 -2
  270. package/lib/gc/gcConfigs.js.map +1 -1
  271. package/lib/gc/gcDefinitions.d.ts +218 -70
  272. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  273. package/lib/gc/gcDefinitions.js +40 -13
  274. package/lib/gc/gcDefinitions.js.map +1 -1
  275. package/lib/gc/gcHelpers.d.ts +6 -2
  276. package/lib/gc/gcHelpers.d.ts.map +1 -1
  277. package/lib/gc/gcHelpers.js +14 -7
  278. package/lib/gc/gcHelpers.js.map +1 -1
  279. package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  280. package/lib/gc/gcSummaryDefinitions.d.ts +18 -6
  281. package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -1
  282. package/lib/gc/gcSummaryDefinitions.js.map +1 -1
  283. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  284. package/lib/gc/gcSummaryStateTracker.js +2 -1
  285. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  286. package/lib/gc/gcTelemetry.d.ts +33 -11
  287. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  288. package/lib/gc/gcTelemetry.js +38 -18
  289. package/lib/gc/gcTelemetry.js.map +1 -1
  290. package/lib/gc/gcUnreferencedStateTracker.d.ts +42 -13
  291. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
  292. package/lib/gc/gcUnreferencedStateTracker.js +27 -9
  293. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  294. package/lib/gc/index.d.ts +1 -0
  295. package/lib/gc/index.d.ts.map +1 -1
  296. package/lib/gc/index.js +1 -0
  297. package/lib/gc/index.js.map +1 -1
  298. package/lib/inboundBatchAggregator.d.ts +34 -0
  299. package/lib/inboundBatchAggregator.d.ts.map +1 -0
  300. package/lib/inboundBatchAggregator.js +181 -0
  301. package/lib/inboundBatchAggregator.js.map +1 -0
  302. package/lib/index.d.ts +1 -1
  303. package/lib/index.d.ts.map +1 -1
  304. package/lib/index.js.map +1 -1
  305. package/lib/layerCompatState.d.ts +19 -0
  306. package/lib/layerCompatState.d.ts.map +1 -0
  307. package/lib/layerCompatState.js +60 -0
  308. package/lib/layerCompatState.js.map +1 -0
  309. package/lib/legacy.d.ts +0 -4
  310. package/lib/messageTypes.d.ts +14 -5
  311. package/lib/messageTypes.d.ts.map +1 -1
  312. package/lib/messageTypes.js.map +1 -1
  313. package/lib/metadata.d.ts +12 -4
  314. package/lib/metadata.d.ts.map +1 -1
  315. package/lib/metadata.js +6 -2
  316. package/lib/metadata.js.map +1 -1
  317. package/lib/opLifecycle/batchManager.d.ts +9 -3
  318. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  319. package/lib/opLifecycle/batchManager.js +3 -1
  320. package/lib/opLifecycle/batchManager.js.map +1 -1
  321. package/lib/opLifecycle/duplicateBatchDetector.d.ts +9 -3
  322. package/lib/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
  323. package/lib/opLifecycle/duplicateBatchDetector.js +11 -5
  324. package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
  325. package/lib/opLifecycle/opCompressor.d.ts +3 -2
  326. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  327. package/lib/opLifecycle/opCompressor.js +14 -20
  328. package/lib/opLifecycle/opCompressor.js.map +1 -1
  329. package/lib/opLifecycle/opDecompressor.d.ts +6 -1
  330. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  331. package/lib/opLifecycle/opDecompressor.js +17 -9
  332. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  333. package/lib/opLifecycle/opGroupingManager.d.ts +1 -2
  334. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  335. package/lib/opLifecycle/opGroupingManager.js +10 -7
  336. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  337. package/lib/opLifecycle/opSplitter.d.ts +13 -10
  338. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  339. package/lib/opLifecycle/opSplitter.js +16 -11
  340. package/lib/opLifecycle/opSplitter.js.map +1 -1
  341. package/lib/opLifecycle/outbox.d.ts +4 -4
  342. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  343. package/lib/opLifecycle/outbox.js +17 -16
  344. package/lib/opLifecycle/outbox.js.map +1 -1
  345. package/lib/opLifecycle/remoteMessageProcessor.d.ts +9 -3
  346. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  347. package/lib/opLifecycle/remoteMessageProcessor.js +3 -1
  348. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  349. package/lib/packageVersion.d.ts +1 -1
  350. package/lib/packageVersion.js +1 -1
  351. package/lib/packageVersion.js.map +1 -1
  352. package/lib/pendingStateManager.d.ts +22 -11
  353. package/lib/pendingStateManager.d.ts.map +1 -1
  354. package/lib/pendingStateManager.js +25 -16
  355. package/lib/pendingStateManager.js.map +1 -1
  356. package/lib/summary/documentSchema.d.ts +7 -0
  357. package/lib/summary/documentSchema.d.ts.map +1 -1
  358. package/lib/summary/documentSchema.js +8 -4
  359. package/lib/summary/documentSchema.js.map +1 -1
  360. package/lib/summary/index.d.ts +1 -1
  361. package/lib/summary/index.d.ts.map +1 -1
  362. package/lib/summary/index.js.map +1 -1
  363. package/lib/summary/orderedClientElection.d.ts +94 -31
  364. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  365. package/lib/summary/orderedClientElection.js +28 -16
  366. package/lib/summary/orderedClientElection.js.map +1 -1
  367. package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -0
  368. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  369. package/lib/summary/runWhileConnectedCoordinator.js +7 -2
  370. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  371. package/lib/summary/runningSummarizer.d.ts +17 -6
  372. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  373. package/lib/summary/runningSummarizer.js +48 -19
  374. package/lib/summary/runningSummarizer.js.map +1 -1
  375. package/lib/summary/summarizer.d.ts +10 -5
  376. package/lib/summary/summarizer.d.ts.map +1 -1
  377. package/lib/summary/summarizer.js +26 -11
  378. package/lib/summary/summarizer.js.map +1 -1
  379. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  380. package/lib/summary/summarizerClientElection.js +1 -0
  381. package/lib/summary/summarizerClientElection.js.map +1 -1
  382. package/lib/summary/summarizerHeuristics.d.ts +6 -2
  383. package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
  384. package/lib/summary/summarizerHeuristics.js +13 -5
  385. package/lib/summary/summarizerHeuristics.js.map +1 -1
  386. package/lib/summary/summarizerNode/index.d.ts.map +1 -1
  387. package/lib/summary/summarizerNode/index.js.map +1 -1
  388. package/lib/summary/summarizerNode/summarizerNode.d.ts +24 -8
  389. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  390. package/lib/summary/summarizerNode/summarizerNode.js +45 -36
  391. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  392. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +48 -16
  393. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  394. package/lib/summary/summarizerNode/summarizerNodeUtils.js +3 -1
  395. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  396. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +13 -5
  397. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  398. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +15 -7
  399. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  400. package/lib/summary/summarizerTypes.d.ts +253 -135
  401. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  402. package/lib/summary/summarizerTypes.js.map +1 -1
  403. package/lib/summary/summaryCollection.d.ts +3 -4
  404. package/lib/summary/summaryCollection.d.ts.map +1 -1
  405. package/lib/summary/summaryCollection.js +10 -8
  406. package/lib/summary/summaryCollection.js.map +1 -1
  407. package/lib/summary/summaryFormat.d.ts +28 -9
  408. package/lib/summary/summaryFormat.d.ts.map +1 -1
  409. package/lib/summary/summaryFormat.js +2 -2
  410. package/lib/summary/summaryFormat.js.map +1 -1
  411. package/lib/summary/summaryGenerator.d.ts +9 -3
  412. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  413. package/lib/summary/summaryGenerator.js +22 -9
  414. package/lib/summary/summaryGenerator.js.map +1 -1
  415. package/lib/summary/summaryManager.d.ts +8 -4
  416. package/lib/summary/summaryManager.d.ts.map +1 -1
  417. package/lib/summary/summaryManager.js +20 -9
  418. package/lib/summary/summaryManager.js.map +1 -1
  419. package/lib/throttler.d.ts +26 -10
  420. package/lib/throttler.d.ts.map +1 -1
  421. package/lib/throttler.js +12 -4
  422. package/lib/throttler.js.map +1 -1
  423. package/package.json +22 -31
  424. package/src/batchTracker.ts +34 -36
  425. package/src/blobManager/blobManager.ts +54 -33
  426. package/src/blobManager/blobManagerSnapSum.ts +10 -10
  427. package/src/channelCollection.ts +108 -82
  428. package/src/connectionTelemetry.ts +43 -19
  429. package/src/containerHandleContext.ts +2 -2
  430. package/src/containerRuntime.ts +492 -364
  431. package/src/dataStore.ts +17 -9
  432. package/src/dataStoreContext.ts +94 -73
  433. package/src/dataStoreContexts.ts +17 -12
  434. package/src/dataStoreRegistry.ts +1 -1
  435. package/src/deltaManagerProxies.ts +5 -5
  436. package/src/deltaScheduler.ts +24 -18
  437. package/src/gc/garbageCollection.ts +89 -40
  438. package/src/gc/gcConfigs.ts +13 -5
  439. package/src/gc/gcDefinitions.ts +224 -70
  440. package/src/gc/gcHelpers.ts +22 -11
  441. package/src/gc/gcReferenceGraphAlgorithm.ts +1 -1
  442. package/src/gc/gcSummaryDefinitions.ts +18 -6
  443. package/src/gc/gcSummaryStateTracker.ts +7 -3
  444. package/src/gc/gcTelemetry.ts +73 -30
  445. package/src/gc/gcUnreferencedStateTracker.ts +40 -16
  446. package/src/gc/index.ts +1 -0
  447. package/src/{scheduleManager.ts → inboundBatchAggregator.ts} +55 -122
  448. package/src/index.ts +0 -3
  449. package/src/layerCompatState.ts +75 -0
  450. package/src/messageTypes.ts +16 -5
  451. package/src/metadata.ts +12 -4
  452. package/src/opLifecycle/README.md +43 -34
  453. package/src/opLifecycle/batchManager.ts +12 -6
  454. package/src/opLifecycle/duplicateBatchDetector.ts +12 -6
  455. package/src/opLifecycle/opCompressor.ts +22 -25
  456. package/src/opLifecycle/opDecompressor.ts +23 -11
  457. package/src/opLifecycle/opGroupingManager.ts +16 -11
  458. package/src/opLifecycle/opSplitter.ts +24 -18
  459. package/src/opLifecycle/outbox.ts +35 -33
  460. package/src/opLifecycle/remoteMessageProcessor.ts +13 -5
  461. package/src/packageVersion.ts +1 -1
  462. package/src/pendingStateManager.ts +49 -26
  463. package/src/summary/documentSchema.ts +41 -22
  464. package/src/summary/index.ts +0 -3
  465. package/src/summary/orderedClientElection.ts +114 -49
  466. package/src/summary/runWhileConnectedCoordinator.ts +12 -3
  467. package/src/summary/runningSummarizer.ts +79 -36
  468. package/src/summary/summarizer.ts +51 -25
  469. package/src/summary/summarizerClientElection.ts +4 -2
  470. package/src/summary/summarizerHeuristics.ts +23 -12
  471. package/src/summary/summarizerNode/index.ts +1 -0
  472. package/src/summary/summarizerNode/summarizerNode.ts +54 -43
  473. package/src/summary/summarizerNode/summarizerNodeUtils.ts +48 -16
  474. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +25 -15
  475. package/src/summary/summarizerTypes.ts +253 -139
  476. package/src/summary/summaryCollection.ts +41 -31
  477. package/src/summary/summaryFormat.ts +34 -13
  478. package/src/summary/summaryGenerator.ts +39 -18
  479. package/src/summary/summaryManager.ts +36 -24
  480. package/src/throttler.ts +23 -11
  481. package/container-runtime.test-files.tar +0 -0
  482. package/dist/scheduleManager.d.ts +0 -28
  483. package/dist/scheduleManager.d.ts.map +0 -1
  484. package/dist/scheduleManager.js +0 -233
  485. package/dist/scheduleManager.js.map +0 -1
  486. package/lib/scheduleManager.d.ts +0 -28
  487. package/lib/scheduleManager.d.ts.map +0 -1
  488. package/lib/scheduleManager.js +0 -229
  489. package/lib/scheduleManager.js.map +0 -1
@@ -24,6 +24,7 @@ import {
24
24
 
25
25
  import { IThrottler } from "../throttler.js";
26
26
 
27
+ // eslint-disable-next-line import/no-deprecated
27
28
  import { Summarizer } from "./summarizer.js";
28
29
  import { ISummarizerClientElection } from "./summarizerClientElection.js";
29
30
  import {
@@ -102,11 +103,11 @@ export class SummaryManager
102
103
  private summarizer?: ISummarizer;
103
104
  private _disposed = false;
104
105
 
105
- public get disposed() {
106
+ public get disposed(): boolean {
106
107
  return this._disposed;
107
108
  }
108
109
 
109
- public get currentState() {
110
+ public get currentState(): SummaryManagerState {
110
111
  return this.state;
111
112
  }
112
113
 
@@ -118,8 +119,10 @@ export class SummaryManager
118
119
  "opsSinceLastAck" | "addOpListener" | "removeOpListener"
119
120
  >,
120
121
  parentLogger: ITelemetryBaseLogger,
121
- /** Creates summarizer by asking interactive container to spawn summarizing container and
122
- * get back its Summarizer instance. */
122
+ /**
123
+ * Creates summarizer by asking interactive container to spawn summarizing container and
124
+ * get back its Summarizer instance.
125
+ */
123
126
  private readonly createSummarizerFn: () => Promise<ISummarizer>,
124
127
  private readonly startThrottler: IThrottler,
125
128
  {
@@ -154,7 +157,7 @@ export class SummaryManager
154
157
  this.refreshSummarizer();
155
158
  }
156
159
 
157
- private readonly handleConnected = (clientId: string) => {
160
+ private readonly handleConnected = (clientId: string): void => {
158
161
  this.latestClientId = clientId;
159
162
  // If we have a summarizer, it should have been either cancelled on disconnected by now.
160
163
  // But because of lastSummary process, it can still hang around, so there is not much we can
@@ -162,11 +165,13 @@ export class SummaryManager
162
165
  this.refreshSummarizer();
163
166
  };
164
167
 
165
- private readonly handleDisconnected = () => {
168
+ private readonly handleDisconnected = (): void => {
166
169
  this.refreshSummarizer();
167
170
  };
168
171
 
169
- private static readonly isStartingOrRunning = (state: SummaryManagerState) =>
172
+ private static readonly isStartingOrRunning = (
173
+ state: SummaryManagerState,
174
+ ): state is SummaryManagerState.Starting | SummaryManagerState.Running =>
170
175
  state === SummaryManagerState.Starting || state === SummaryManagerState.Running;
171
176
 
172
177
  private getShouldSummarizeState(): ShouldSummarizeState {
@@ -199,7 +204,7 @@ export class SummaryManager
199
204
  return { shouldSummarize: true };
200
205
  }
201
206
 
202
- private readonly refreshSummarizer = () => {
207
+ private readonly refreshSummarizer = (): void => {
203
208
  // Transition states depending on shouldSummarize, which is a calculated property
204
209
  // that is only true if this client is connected and is the elected summarizer.
205
210
  const shouldSummarizeState = this.getShouldSummarizeState();
@@ -232,7 +237,7 @@ export class SummaryManager
232
237
  }
233
238
  };
234
239
 
235
- private startSummarization() {
240
+ private startSummarization(): void {
236
241
  assert(this.state === SummaryManagerState.Off, 0x261 /* "Expected: off" */);
237
242
  this.state = SummaryManagerState.Starting;
238
243
 
@@ -280,6 +285,7 @@ export class SummaryManager
280
285
  // which would happen when we have a high enough number of unsummarized ops.
281
286
  if (
282
287
  startWithInitialDelay ||
288
+ // eslint-disable-next-line import/no-deprecated
283
289
  !Summarizer.stopReasonCanRunLastSummary(shouldSummarizeState.stopReason)
284
290
  ) {
285
291
  this.state = SummaryManagerState.Starting;
@@ -328,6 +334,7 @@ export class SummaryManager
328
334
  // If failure happened on container load, we may not yet realized that socket disconnected, so check
329
335
  // offlineError.
330
336
  const category =
337
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
331
338
  error?.errorType === DriverErrorTypes.offlineError ? "generic" : "error";
332
339
  this.logger.sendTelemetryEvent(
333
340
  {
@@ -352,7 +359,7 @@ export class SummaryManager
352
359
  });
353
360
  }
354
361
 
355
- private stop(reason: SummarizerStopReason) {
362
+ private stop(reason: SummarizerStopReason): void {
356
363
  if (!SummaryManager.isStartingOrRunning(this.state)) {
357
364
  return;
358
365
  }
@@ -401,10 +408,10 @@ export class SummaryManager
401
408
  }
402
409
 
403
410
  if (delayMs > 0) {
404
- let timer;
405
- let resolveOpPromiseFn;
411
+ let timer: number | undefined;
412
+ let resolveOpPromiseFn: (value: void | PromiseLike<void>) => void;
406
413
  // Create a listener that will break the delay if we've exceeded the initial delay ops count.
407
- const opsListenerFn = () => {
414
+ const opsListenerFn = (): void => {
408
415
  if (this.summaryCollection.opsSinceLastAck >= this.opsToBypassInitialDelay) {
409
416
  clearTimeout(timer);
410
417
  resolveOpPromiseFn();
@@ -427,7 +434,7 @@ export class SummaryManager
427
434
 
428
435
  public summarizeOnDemand(options: IOnDemandSummarizeOptions): ISummarizeResults {
429
436
  if (this.summarizer === undefined) {
430
- throw Error("No running summarizer client");
437
+ throw new Error("No running summarizer client");
431
438
  // TODO: could spawn a summarizer client temporarily.
432
439
  }
433
440
  return this.summarizer.summarizeOnDemand(options);
@@ -435,13 +442,13 @@ export class SummaryManager
435
442
 
436
443
  public enqueueSummarize(options: IEnqueueSummarizeOptions): EnqueueSummarizeResult {
437
444
  if (this.summarizer === undefined) {
438
- throw Error("No running summarizer client");
445
+ throw new Error("No running summarizer client");
439
446
  // TODO: could spawn a summarizer client temporarily.
440
447
  }
441
448
  return this.summarizer.enqueueSummarize(options);
442
449
  }
443
450
 
444
- public dispose() {
451
+ public dispose(): void {
445
452
  this.clientElection.off("electedSummarizerChanged", this.refreshSummarizer);
446
453
  this.connectedState.off("connected", this.handleConnected);
447
454
  this.connectedState.off("disconnected", this.handleDisconnected);
@@ -449,26 +456,31 @@ export class SummaryManager
449
456
  this._disposed = true;
450
457
  }
451
458
 
452
- private readonly forwardedEvents = new Map<any, () => void>();
459
+ private readonly forwardedEvents = new Map<string, () => void>();
453
460
 
454
- private setupForwardedEvents() {
455
- [
461
+ private setupForwardedEvents(): void {
462
+ for (const event of [
456
463
  "summarize",
457
464
  "summarizeAllAttemptsFailed",
458
465
  "summarizerStop",
459
466
  "summarizerStart",
460
467
  "summarizerStartupFailed",
461
- ].forEach((event) => {
462
- const listener = (...args: any[]) => {
468
+ ]) {
469
+ const listener = (...args: unknown[]): void => {
463
470
  this.emit(event, ...args);
464
471
  };
472
+ // TODO: better typing here
473
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
465
474
  this.summarizer?.on(event as any, listener);
466
475
  this.forwardedEvents.set(event, listener);
467
- });
476
+ }
468
477
  }
469
478
 
470
- private cleanupForwardedEvents() {
471
- this.forwardedEvents.forEach((listener, event) => this.summarizer?.off(event, listener));
479
+ private cleanupForwardedEvents(): void {
480
+ for (const [event, listener] of this.forwardedEvents.entries()) {
481
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
482
+ this.summarizer?.off(event as any, listener);
483
+ }
472
484
  this.forwardedEvents.clear();
473
485
  }
474
486
  }
package/src/throttler.ts CHANGED
@@ -16,9 +16,13 @@ export interface IThrottler {
16
16
  */
17
17
  readonly numAttempts: number;
18
18
 
19
- /** Width of sliding delay window in milliseconds. */
19
+ /**
20
+ * Width of sliding delay window in milliseconds.
21
+ */
20
22
  readonly delayWindowMs: number;
21
- /** Maximum delay allowed in milliseconds. */
23
+ /**
24
+ * Maximum delay allowed in milliseconds.
25
+ */
22
26
  readonly maxDelayMs: number;
23
27
  /**
24
28
  * Delay function used to calculate what the delay should be.
@@ -35,7 +39,7 @@ export interface IThrottler {
35
39
  export class Throttler implements IThrottler {
36
40
  private startTimes: number[] = [];
37
41
 
38
- public get numAttempts() {
42
+ public get numAttempts(): number {
39
43
  return this.startTimes.length;
40
44
  }
41
45
 
@@ -51,16 +55,20 @@ export class Throttler implements IThrottler {
51
55
  * Latest attempt time after compensating for the delay time itself
52
56
  * by adding the delay time to the actual time.
53
57
  */
54
- public get latestAttemptTime() {
58
+ public get latestAttemptTime(): number | undefined {
55
59
  return this.startTimes.length > 0
56
60
  ? this.startTimes[this.startTimes.length - 1]
57
61
  : undefined;
58
62
  }
59
63
 
60
64
  constructor(
61
- /** Width of sliding delay window in milliseconds. */
65
+ /**
66
+ * Width of sliding delay window in milliseconds.
67
+ */
62
68
  public readonly delayWindowMs: number,
63
- /** Maximum delay allowed in milliseconds. */
69
+ /**
70
+ * Maximum delay allowed in milliseconds.
71
+ */
64
72
  public readonly maxDelayMs: number,
65
73
  /**
66
74
  * Delay function used to calculate what the delay should be.
@@ -70,7 +78,7 @@ export class Throttler implements IThrottler {
70
78
  public readonly delayFn: (numAttempts: number) => number,
71
79
  ) {}
72
80
 
73
- public getDelay() {
81
+ public getDelay(): number {
74
82
  const now = Date.now();
75
83
 
76
84
  const latestAttemptTime = this.latestAttemptTime;
@@ -131,7 +139,9 @@ export const formExponentialFn =
131
139
  : coefficient * Math.pow(multiplier, numAttempts) + offset,
132
140
  );
133
141
 
134
- /** f(n) = C x (B^(n+A)) + F = (C x B^A) x B^n + F */
142
+ /**
143
+ * f(n) = C x (B^(n+A)) + F = (C x B^A) x B^n + F
144
+ */
135
145
  export const formExponentialFnWithAttemptOffset = (
136
146
  attemptOffset: number,
137
147
  {
@@ -140,7 +150,7 @@ export const formExponentialFnWithAttemptOffset = (
140
150
  offset = 0,
141
151
  initialDelay = undefined as number | undefined,
142
152
  } = {},
143
- ) =>
153
+ ): IThrottler["delayFn"] =>
144
154
  formExponentialFn({
145
155
  multiplier,
146
156
  coefficient: coefficient * Math.pow(multiplier, attemptOffset),
@@ -160,11 +170,13 @@ export const formLinearFn =
160
170
  (numAttempts) =>
161
171
  Math.max(0, coefficient * numAttempts + offset);
162
172
 
163
- /** f(n) = C x (n+A) + F = C x n + (C x A + F) */
173
+ /**
174
+ * f(n) = C x (n+A) + F = C x n + (C x A + F)
175
+ */
164
176
  export const formLinearFnWithAttemptOffset = (
165
177
  attemptOffset: number,
166
178
  { coefficient = 1, offset = 0 } = {},
167
- ) =>
179
+ ): IThrottler["delayFn"] =>
168
180
  formLinearFn({
169
181
  coefficient,
170
182
  offset: coefficient * attemptOffset + offset,
Binary file
@@ -1,28 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import type { EventEmitter } from "@fluid-internal/client-utils";
6
- import { IDeltaManagerFull } from "@fluidframework/container-definitions/internal";
7
- import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
8
- import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
9
- /**
10
- * This class has the following responsibilities:
11
- *
12
- * 1. It tracks batches as we process ops and raises "batchBegin" and "batchEnd" events.
13
- * As part of it, it validates batch correctness (i.e. no system ops in the middle of batch)
14
- *
15
- * 2. It creates instance of ScheduleManagerCore that ensures we never start processing ops from batch
16
- * unless all ops of the batch are in.
17
- */
18
- export declare class ScheduleManager {
19
- private readonly deltaManager;
20
- private readonly emitter;
21
- readonly getClientId: () => string | undefined;
22
- private readonly logger;
23
- private readonly deltaScheduler;
24
- constructor(deltaManager: IDeltaManagerFull, emitter: EventEmitter, getClientId: () => string | undefined, logger: ITelemetryLoggerExt);
25
- batchBegin(message: ISequencedDocumentMessage): void;
26
- batchEnd(error: any | undefined, message: ISequencedDocumentMessage): void;
27
- }
28
- //# sourceMappingURL=scheduleManager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduleManager.d.ts","sourceRoot":"","sources":["../src/scheduleManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AAEnF,OAAO,EAEN,yBAAyB,EACzB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EACN,mBAAmB,EAKnB,MAAM,0CAA0C,CAAC;AAYlD;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAI1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM;IANxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;gBAG9B,YAAY,EAAE,iBAAiB,EAC/B,OAAO,EAAE,YAAY,EAC7B,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS,EAC7B,MAAM,EAAE,mBAAmB;IAStC,UAAU,CAAC,OAAO,EAAE,yBAAyB;IAK7C,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,SAAS,EAAE,OAAO,EAAE,yBAAyB;CAI1E"}
@@ -1,233 +0,0 @@
1
- "use strict";
2
- /*!
3
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
- * Licensed under the MIT License.
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.ScheduleManager = void 0;
8
- const client_utils_1 = require("@fluid-internal/client-utils");
9
- const internal_1 = require("@fluidframework/core-utils/internal");
10
- const internal_2 = require("@fluidframework/driver-utils/internal");
11
- const internal_3 = require("@fluidframework/telemetry-utils/internal");
12
- const deltaScheduler_js_1 = require("./deltaScheduler.js");
13
- const packageVersion_js_1 = require("./packageVersion.js");
14
- /**
15
- * This class has the following responsibilities:
16
- *
17
- * 1. It tracks batches as we process ops and raises "batchBegin" and "batchEnd" events.
18
- * As part of it, it validates batch correctness (i.e. no system ops in the middle of batch)
19
- *
20
- * 2. It creates instance of ScheduleManagerCore that ensures we never start processing ops from batch
21
- * unless all ops of the batch are in.
22
- */
23
- class ScheduleManager {
24
- constructor(deltaManager, emitter, getClientId, logger) {
25
- this.deltaManager = deltaManager;
26
- this.emitter = emitter;
27
- this.getClientId = getClientId;
28
- this.logger = logger;
29
- this.deltaScheduler = new deltaScheduler_js_1.DeltaScheduler(this.deltaManager, (0, internal_3.createChildLogger)({ logger: this.logger, namespace: "DeltaScheduler" }));
30
- void new ScheduleManagerCore(deltaManager, getClientId, logger);
31
- }
32
- batchBegin(message) {
33
- this.emitter.emit("batchBegin", message);
34
- this.deltaScheduler.batchBegin(message);
35
- }
36
- batchEnd(error, message) {
37
- this.emitter.emit("batchEnd", error, message);
38
- this.deltaScheduler.batchEnd(message);
39
- }
40
- }
41
- exports.ScheduleManager = ScheduleManager;
42
- /**
43
- * This class controls pausing and resuming of inbound queue to ensure that we never
44
- * start processing ops in a batch IF we do not have all ops in the batch.
45
- */
46
- class ScheduleManagerCore {
47
- constructor(deltaManager, getClientId, logger) {
48
- this.deltaManager = deltaManager;
49
- this.getClientId = getClientId;
50
- this.logger = logger;
51
- this.localPaused = false;
52
- this.timePaused = 0;
53
- this.batchCount = 0;
54
- // Listen for delta manager sends and add batch metadata to messages
55
- this.deltaManager.on("prepareSend", (messages) => {
56
- if (messages.length === 0) {
57
- return;
58
- }
59
- // First message will have the batch flag set to true if doing a batched send
60
- const firstMessageMetadata = messages[0].metadata;
61
- if (!firstMessageMetadata?.batch) {
62
- return;
63
- }
64
- // If the batch contains only a single op, clear the batch flag.
65
- if (messages.length === 1) {
66
- delete firstMessageMetadata.batch;
67
- return;
68
- }
69
- // Set the batch flag to false on the last message to indicate the end of the send batch
70
- const lastMessage = messages[messages.length - 1];
71
- // TODO: It's not clear if this shallow clone is required, as opposed to just setting "batch" to false.
72
- lastMessage.metadata = { ...lastMessage.metadata, batch: false };
73
- });
74
- // Listen for updates and peek at the inbound
75
- this.deltaManager.inbound.on("push", (message) => {
76
- this.trackPending(message);
77
- });
78
- // Start with baseline - empty inbound queue.
79
- (0, internal_1.assert)(!this.localPaused, 0x293 /* "initial state" */);
80
- const allPending = this.deltaManager.inbound.toArray();
81
- for (const pending of allPending) {
82
- this.trackPending(pending);
83
- }
84
- // We are intentionally directly listening to the "op" to inspect system ops as well.
85
- // If we do not observe system ops, we are likely to hit 0x296 assert when system ops
86
- // precedes start of incomplete batch.
87
- this.deltaManager.on("op", (message) => this.afterOpProcessing(message));
88
- }
89
- /**
90
- * The only public function in this class - called when we processed an op,
91
- * to make decision if op processing should be paused or not after that.
92
- */
93
- afterOpProcessing(message) {
94
- (0, internal_1.assert)(!this.localPaused, 0x294 /* "can't have op processing paused if we are processing an op" */);
95
- // If the inbound queue is ever empty, nothing to do!
96
- if (this.deltaManager.inbound.length === 0) {
97
- (0, internal_1.assert)(this.pauseSequenceNumber === undefined, 0x295 /* "there should be no pending batch if we have no ops" */);
98
- return;
99
- }
100
- // The queue is
101
- // 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:
102
- // - here (processing ops until reaching start of incomplete batch)
103
- // - in trackPending(), when queue was empty and start of batch showed up.
104
- // 2. resumed when batch end comes in (in trackPending())
105
- // do we have incomplete batch to worry about?
106
- if (this.pauseSequenceNumber !== undefined) {
107
- if (message.sequenceNumber >= this.pauseSequenceNumber) {
108
- throw internal_3.DataProcessingError.create(
109
- // Former assert 0x296
110
- "Incomplete batch", "ScheduleManager", message, {
111
- type: message.type,
112
- contentType: typeof message.contents,
113
- batch: message.metadata?.batch,
114
- compression: message.compression,
115
- pauseSeqNum: this.pauseSequenceNumber,
116
- });
117
- }
118
- // If the next op is the start of incomplete batch, then we can't process it until it's fully in - pause!
119
- if (message.sequenceNumber + 1 === this.pauseSequenceNumber) {
120
- this.pauseQueue();
121
- }
122
- }
123
- }
124
- pauseQueue() {
125
- (0, internal_1.assert)(!this.localPaused, 0x297 /* "always called from resumed state" */);
126
- this.localPaused = true;
127
- this.timePaused = client_utils_1.performance.now();
128
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
129
- this.deltaManager.inbound.pause();
130
- }
131
- resumeQueue(startBatch, messageEndBatch) {
132
- const endBatch = messageEndBatch.sequenceNumber;
133
- const duration = this.localPaused ? client_utils_1.performance.now() - this.timePaused : undefined;
134
- this.batchCount++;
135
- if (this.batchCount % 1000 === 1) {
136
- this.logger.sendTelemetryEvent({
137
- eventName: "BatchStats",
138
- sequenceNumber: endBatch,
139
- length: endBatch - startBatch + 1,
140
- msnDistance: endBatch - messageEndBatch.minimumSequenceNumber,
141
- duration,
142
- batchCount: this.batchCount,
143
- interrupted: this.localPaused,
144
- });
145
- }
146
- // Return early if no change in value
147
- if (!this.localPaused) {
148
- return;
149
- }
150
- this.localPaused = false;
151
- this.deltaManager.inbound.resume();
152
- }
153
- /**
154
- * Called for each incoming op (i.e. inbound "push" notification)
155
- */
156
- trackPending(message) {
157
- (0, internal_1.assert)(this.deltaManager.inbound.length !== 0, 0x298 /* "we have something in the queue that generates this event" */);
158
- (0, internal_1.assert)((this.currentBatchClientId === undefined) === (this.pauseSequenceNumber === undefined), 0x299 /* "non-synchronized state" */);
159
- const metadata = message.metadata;
160
- // batchMetadata will be true for the message that starts a batch, false for the one that ends it, and
161
- // undefined for all other messages.
162
- const batchMetadata = metadata?.batch;
163
- // Protocol messages are never part of a runtime batch of messages
164
- if (!(0, internal_2.isRuntimeMessage)(message)) {
165
- // Protocol messages should never show up in the middle of the batch!
166
- if (this.currentBatchClientId !== undefined) {
167
- throw internal_3.DataProcessingError.create("Received a system message during batch processing", // Formerly known as assert 0x29a
168
- "trackPending", message, {
169
- runtimeVersion: packageVersion_js_1.pkgVersion,
170
- batchClientId:
171
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
172
- this.currentBatchClientId === null ? "null" : this.currentBatchClientId,
173
- pauseSequenceNumber: this.pauseSequenceNumber,
174
- localBatch: this.currentBatchClientId === this.getClientId(),
175
- messageType: message.type,
176
- });
177
- }
178
- (0, internal_1.assert)(batchMetadata === undefined, 0x29b /* "system op in a batch?" */);
179
- (0, internal_1.assert)(!this.localPaused, 0x29c /* "we should be processing ops when there is no active batch" */);
180
- return;
181
- }
182
- if (this.currentBatchClientId === undefined && batchMetadata === undefined) {
183
- (0, internal_1.assert)(!this.localPaused, 0x29d /* "we should be processing ops when there is no active batch" */);
184
- return;
185
- }
186
- // If we got here, the message is part of a batch. Either starting, in progress, or ending.
187
- // If this is not the start of the batch, error out if the message was sent by a client other than the one that
188
- // started the current batch (it should not be possible for ops from other clients to get interleaved with a batch).
189
- if (this.currentBatchClientId !== undefined &&
190
- this.currentBatchClientId !== message.clientId) {
191
- throw new internal_3.DataCorruptionError("OpBatchIncomplete", {
192
- runtimeVersion: packageVersion_js_1.pkgVersion,
193
- batchClientId:
194
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
195
- this.currentBatchClientId === null ? "null" : this.currentBatchClientId,
196
- pauseSequenceNumber: this.pauseSequenceNumber,
197
- localBatch: this.currentBatchClientId === this.getClientId(),
198
- localMessage: message.clientId === this.getClientId(),
199
- ...(0, internal_3.extractSafePropertiesFromMessage)(message),
200
- });
201
- }
202
- // The queue is
203
- // 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:
204
- // - in afterOpProcessing() - processing ops until reaching start of incomplete batch
205
- // - here, when queue was empty and start of batch showed up (batchMetadata === true below).
206
- // 2. resumed when batch end comes in (batchMetadata === false below)
207
- if (batchMetadata) {
208
- (0, internal_1.assert)(this.currentBatchClientId === undefined, 0x29e /* "there can't be active batch" */);
209
- (0, internal_1.assert)(!this.localPaused, 0x29f /* "we should be processing ops when there is no active batch" */);
210
- this.pauseSequenceNumber = message.sequenceNumber;
211
- // TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
212
- this.currentBatchClientId = message.clientId;
213
- // Start of the batch
214
- // Only pause processing if queue has no other ops!
215
- // If there are any other ops in the queue, processing will be stopped when they are processed!
216
- if (this.deltaManager.inbound.length === 1) {
217
- this.pauseQueue();
218
- }
219
- }
220
- else if (batchMetadata === false) {
221
- (0, internal_1.assert)(this.pauseSequenceNumber !== undefined, 0x2a0 /* "batch presence was validated above" */);
222
- // Batch is complete, we can process it!
223
- this.resumeQueue(this.pauseSequenceNumber, message);
224
- this.pauseSequenceNumber = undefined;
225
- this.currentBatchClientId = undefined;
226
- }
227
- else {
228
- // Continuation of current batch. Do nothing
229
- (0, internal_1.assert)(this.currentBatchClientId !== undefined, 0x2a1 /* "logic error" */);
230
- }
231
- }
232
- }
233
- //# sourceMappingURL=scheduleManager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduleManager.js","sourceRoot":"","sources":["../src/scheduleManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { EventEmitter } from \"@fluid-internal/client-utils\";\nimport { performance } from \"@fluid-internal/client-utils\";\nimport { IDeltaManagerFull } from \"@fluidframework/container-definitions/internal\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { isRuntimeMessage } from \"@fluidframework/driver-utils/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tDataCorruptionError,\n\tDataProcessingError,\n\tcreateChildLogger,\n\textractSafePropertiesFromMessage,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { DeltaScheduler } from \"./deltaScheduler.js\";\nimport { IBatchMetadata } from \"./metadata.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\ntype IRuntimeMessageMetadata =\n\t| undefined\n\t| {\n\t\t\tbatch?: boolean;\n\t };\n\n/**\n * This class has the following responsibilities:\n *\n * 1. It tracks batches as we process ops and raises \"batchBegin\" and \"batchEnd\" events.\n * As part of it, it validates batch correctness (i.e. no system ops in the middle of batch)\n *\n * 2. It creates instance of ScheduleManagerCore that ensures we never start processing ops from batch\n * unless all ops of the batch are in.\n */\nexport class ScheduleManager {\n\tprivate readonly deltaScheduler: DeltaScheduler;\n\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManagerFull,\n\t\tprivate readonly emitter: EventEmitter,\n\t\treadonly getClientId: () => string | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {\n\t\tthis.deltaScheduler = new DeltaScheduler(\n\t\t\tthis.deltaManager,\n\t\t\tcreateChildLogger({ logger: this.logger, namespace: \"DeltaScheduler\" }),\n\t\t);\n\t\tvoid new ScheduleManagerCore(deltaManager, getClientId, logger);\n\t}\n\n\tpublic batchBegin(message: ISequencedDocumentMessage) {\n\t\tthis.emitter.emit(\"batchBegin\", message);\n\t\tthis.deltaScheduler.batchBegin(message);\n\t}\n\n\tpublic batchEnd(error: any | undefined, message: ISequencedDocumentMessage) {\n\t\tthis.emitter.emit(\"batchEnd\", error, message);\n\t\tthis.deltaScheduler.batchEnd(message);\n\t}\n}\n\n/**\n * This class controls pausing and resuming of inbound queue to ensure that we never\n * start processing ops in a batch IF we do not have all ops in the batch.\n */\nclass ScheduleManagerCore {\n\tprivate pauseSequenceNumber: number | undefined;\n\tprivate currentBatchClientId: string | undefined;\n\tprivate localPaused = false;\n\tprivate timePaused = 0;\n\tprivate batchCount = 0;\n\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManagerFull,\n\t\tprivate readonly getClientId: () => string | undefined,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {\n\t\t// Listen for delta manager sends and add batch metadata to messages\n\t\tthis.deltaManager.on(\"prepareSend\", (messages: IDocumentMessage[]) => {\n\t\t\tif (messages.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// First message will have the batch flag set to true if doing a batched send\n\t\t\tconst firstMessageMetadata = messages[0].metadata as IRuntimeMessageMetadata;\n\t\t\tif (!firstMessageMetadata?.batch) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If the batch contains only a single op, clear the batch flag.\n\t\t\tif (messages.length === 1) {\n\t\t\t\tdelete firstMessageMetadata.batch;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the batch flag to false on the last message to indicate the end of the send batch\n\t\t\tconst lastMessage = messages[messages.length - 1];\n\t\t\t// TODO: It's not clear if this shallow clone is required, as opposed to just setting \"batch\" to false.\n\n\t\t\tlastMessage.metadata = { ...(lastMessage.metadata as any), batch: false };\n\t\t});\n\n\t\t// Listen for updates and peek at the inbound\n\t\tthis.deltaManager.inbound.on(\"push\", (message: ISequencedDocumentMessage) => {\n\t\t\tthis.trackPending(message);\n\t\t});\n\n\t\t// Start with baseline - empty inbound queue.\n\t\tassert(!this.localPaused, 0x293 /* \"initial state\" */);\n\n\t\tconst allPending = this.deltaManager.inbound.toArray();\n\t\tfor (const pending of allPending) {\n\t\t\tthis.trackPending(pending);\n\t\t}\n\n\t\t// We are intentionally directly listening to the \"op\" to inspect system ops as well.\n\t\t// If we do not observe system ops, we are likely to hit 0x296 assert when system ops\n\t\t// precedes start of incomplete batch.\n\t\tthis.deltaManager.on(\"op\", (message) => this.afterOpProcessing(message));\n\t}\n\n\t/**\n\t * The only public function in this class - called when we processed an op,\n\t * to make decision if op processing should be paused or not after that.\n\t */\n\tpublic afterOpProcessing(message: ISequencedDocumentMessage) {\n\t\tassert(\n\t\t\t!this.localPaused,\n\t\t\t0x294 /* \"can't have op processing paused if we are processing an op\" */,\n\t\t);\n\n\t\t// If the inbound queue is ever empty, nothing to do!\n\t\tif (this.deltaManager.inbound.length === 0) {\n\t\t\tassert(\n\t\t\t\tthis.pauseSequenceNumber === undefined,\n\t\t\t\t0x295 /* \"there should be no pending batch if we have no ops\" */,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// The queue is\n\t\t// 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:\n\t\t// - here (processing ops until reaching start of incomplete batch)\n\t\t// - in trackPending(), when queue was empty and start of batch showed up.\n\t\t// 2. resumed when batch end comes in (in trackPending())\n\n\t\t// do we have incomplete batch to worry about?\n\t\tif (this.pauseSequenceNumber !== undefined) {\n\t\t\tif (message.sequenceNumber >= this.pauseSequenceNumber) {\n\t\t\t\tthrow DataProcessingError.create(\n\t\t\t\t\t// Former assert 0x296\n\t\t\t\t\t\"Incomplete batch\",\n\t\t\t\t\t\"ScheduleManager\",\n\t\t\t\t\tmessage,\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: message.type,\n\t\t\t\t\t\tcontentType: typeof message.contents,\n\t\t\t\t\t\tbatch: (message.metadata as IBatchMetadata | undefined)?.batch,\n\t\t\t\t\t\tcompression: message.compression,\n\t\t\t\t\t\tpauseSeqNum: this.pauseSequenceNumber,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// If the next op is the start of incomplete batch, then we can't process it until it's fully in - pause!\n\t\t\tif (message.sequenceNumber + 1 === this.pauseSequenceNumber) {\n\t\t\t\tthis.pauseQueue();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate pauseQueue() {\n\t\tassert(!this.localPaused, 0x297 /* \"always called from resumed state\" */);\n\t\tthis.localPaused = true;\n\t\tthis.timePaused = performance.now();\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tthis.deltaManager.inbound.pause();\n\t}\n\n\tprivate resumeQueue(startBatch: number, messageEndBatch: ISequencedDocumentMessage) {\n\t\tconst endBatch = messageEndBatch.sequenceNumber;\n\t\tconst duration = this.localPaused ? performance.now() - this.timePaused : undefined;\n\n\t\tthis.batchCount++;\n\t\tif (this.batchCount % 1000 === 1) {\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"BatchStats\",\n\t\t\t\tsequenceNumber: endBatch,\n\t\t\t\tlength: endBatch - startBatch + 1,\n\t\t\t\tmsnDistance: endBatch - messageEndBatch.minimumSequenceNumber,\n\t\t\t\tduration,\n\t\t\t\tbatchCount: this.batchCount,\n\t\t\t\tinterrupted: this.localPaused,\n\t\t\t});\n\t\t}\n\n\t\t// Return early if no change in value\n\t\tif (!this.localPaused) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.localPaused = false;\n\n\t\tthis.deltaManager.inbound.resume();\n\t}\n\n\t/**\n\t * Called for each incoming op (i.e. inbound \"push\" notification)\n\t */\n\tprivate trackPending(message: ISequencedDocumentMessage) {\n\t\tassert(\n\t\t\tthis.deltaManager.inbound.length !== 0,\n\t\t\t0x298 /* \"we have something in the queue that generates this event\" */,\n\t\t);\n\n\t\tassert(\n\t\t\t(this.currentBatchClientId === undefined) === (this.pauseSequenceNumber === undefined),\n\t\t\t0x299 /* \"non-synchronized state\" */,\n\t\t);\n\n\t\tconst metadata = message.metadata as IRuntimeMessageMetadata;\n\t\t// batchMetadata will be true for the message that starts a batch, false for the one that ends it, and\n\t\t// undefined for all other messages.\n\t\tconst batchMetadata = metadata?.batch;\n\n\t\t// Protocol messages are never part of a runtime batch of messages\n\t\tif (!isRuntimeMessage(message)) {\n\t\t\t// Protocol messages should never show up in the middle of the batch!\n\t\t\tif (this.currentBatchClientId !== undefined) {\n\t\t\t\tthrow DataProcessingError.create(\n\t\t\t\t\t\"Received a system message during batch processing\", // Formerly known as assert 0x29a\n\t\t\t\t\t\"trackPending\",\n\t\t\t\t\tmessage,\n\t\t\t\t\t{\n\t\t\t\t\t\truntimeVersion: pkgVersion,\n\t\t\t\t\t\tbatchClientId:\n\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n\t\t\t\t\t\t\tthis.currentBatchClientId === null ? \"null\" : this.currentBatchClientId,\n\t\t\t\t\t\tpauseSequenceNumber: this.pauseSequenceNumber,\n\t\t\t\t\t\tlocalBatch: this.currentBatchClientId === this.getClientId(),\n\t\t\t\t\t\tmessageType: message.type,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tassert(batchMetadata === undefined, 0x29b /* \"system op in a batch?\" */);\n\t\t\tassert(\n\t\t\t\t!this.localPaused,\n\t\t\t\t0x29c /* \"we should be processing ops when there is no active batch\" */,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.currentBatchClientId === undefined && batchMetadata === undefined) {\n\t\t\tassert(\n\t\t\t\t!this.localPaused,\n\t\t\t\t0x29d /* \"we should be processing ops when there is no active batch\" */,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// If we got here, the message is part of a batch. Either starting, in progress, or ending.\n\n\t\t// If this is not the start of the batch, error out if the message was sent by a client other than the one that\n\t\t// started the current batch (it should not be possible for ops from other clients to get interleaved with a batch).\n\t\tif (\n\t\t\tthis.currentBatchClientId !== undefined &&\n\t\t\tthis.currentBatchClientId !== message.clientId\n\t\t) {\n\t\t\tthrow new DataCorruptionError(\"OpBatchIncomplete\", {\n\t\t\t\truntimeVersion: pkgVersion,\n\t\t\t\tbatchClientId:\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n\t\t\t\t\tthis.currentBatchClientId === null ? \"null\" : this.currentBatchClientId,\n\t\t\t\tpauseSequenceNumber: this.pauseSequenceNumber,\n\t\t\t\tlocalBatch: this.currentBatchClientId === this.getClientId(),\n\t\t\t\tlocalMessage: message.clientId === this.getClientId(),\n\t\t\t\t...extractSafePropertiesFromMessage(message),\n\t\t\t});\n\t\t}\n\n\t\t// The queue is\n\t\t// 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:\n\t\t// - in afterOpProcessing() - processing ops until reaching start of incomplete batch\n\t\t// - here, when queue was empty and start of batch showed up (batchMetadata === true below).\n\t\t// 2. resumed when batch end comes in (batchMetadata === false below)\n\n\t\tif (batchMetadata) {\n\t\t\tassert(\n\t\t\t\tthis.currentBatchClientId === undefined,\n\t\t\t\t0x29e /* \"there can't be active batch\" */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t!this.localPaused,\n\t\t\t\t0x29f /* \"we should be processing ops when there is no active batch\" */,\n\t\t\t);\n\t\t\tthis.pauseSequenceNumber = message.sequenceNumber;\n\t\t\t// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)\n\n\t\t\tthis.currentBatchClientId = message.clientId as string;\n\t\t\t// Start of the batch\n\t\t\t// Only pause processing if queue has no other ops!\n\t\t\t// If there are any other ops in the queue, processing will be stopped when they are processed!\n\t\t\tif (this.deltaManager.inbound.length === 1) {\n\t\t\t\tthis.pauseQueue();\n\t\t\t}\n\t\t} else if (batchMetadata === false) {\n\t\t\tassert(\n\t\t\t\tthis.pauseSequenceNumber !== undefined,\n\t\t\t\t0x2a0 /* \"batch presence was validated above\" */,\n\t\t\t);\n\t\t\t// Batch is complete, we can process it!\n\t\t\tthis.resumeQueue(this.pauseSequenceNumber, message);\n\t\t\tthis.pauseSequenceNumber = undefined;\n\t\t\tthis.currentBatchClientId = undefined;\n\t\t} else {\n\t\t\t// Continuation of current batch. Do nothing\n\t\t\tassert(this.currentBatchClientId !== undefined, 0x2a1 /* \"logic error\" */);\n\t\t}\n\t}\n}\n"]}
@@ -1,28 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import type { EventEmitter } from "@fluid-internal/client-utils";
6
- import { IDeltaManagerFull } from "@fluidframework/container-definitions/internal";
7
- import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
8
- import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
9
- /**
10
- * This class has the following responsibilities:
11
- *
12
- * 1. It tracks batches as we process ops and raises "batchBegin" and "batchEnd" events.
13
- * As part of it, it validates batch correctness (i.e. no system ops in the middle of batch)
14
- *
15
- * 2. It creates instance of ScheduleManagerCore that ensures we never start processing ops from batch
16
- * unless all ops of the batch are in.
17
- */
18
- export declare class ScheduleManager {
19
- private readonly deltaManager;
20
- private readonly emitter;
21
- readonly getClientId: () => string | undefined;
22
- private readonly logger;
23
- private readonly deltaScheduler;
24
- constructor(deltaManager: IDeltaManagerFull, emitter: EventEmitter, getClientId: () => string | undefined, logger: ITelemetryLoggerExt);
25
- batchBegin(message: ISequencedDocumentMessage): void;
26
- batchEnd(error: any | undefined, message: ISequencedDocumentMessage): void;
27
- }
28
- //# sourceMappingURL=scheduleManager.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduleManager.d.ts","sourceRoot":"","sources":["../src/scheduleManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AAEnF,OAAO,EAEN,yBAAyB,EACzB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EACN,mBAAmB,EAKnB,MAAM,0CAA0C,CAAC;AAYlD;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAI1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM;IANxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;gBAG9B,YAAY,EAAE,iBAAiB,EAC/B,OAAO,EAAE,YAAY,EAC7B,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS,EAC7B,MAAM,EAAE,mBAAmB;IAStC,UAAU,CAAC,OAAO,EAAE,yBAAyB;IAK7C,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,SAAS,EAAE,OAAO,EAAE,yBAAyB;CAI1E"}