@fluidframework/container-runtime 2.117.0 → 3.0.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 (326) hide show
  1. package/CHANGELOG.md +70 -2
  2. package/README.md +53 -50
  3. package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
  4. package/api-report/container-runtime.legacy.alpha.api.md +3 -1
  5. package/api-report/container-runtime.legacy.beta.api.md +3 -1
  6. package/container-runtime.test-files.tar +0 -0
  7. package/dist/batchTracker.d.ts.map +1 -1
  8. package/dist/batchTracker.js +5 -1
  9. package/dist/batchTracker.js.map +1 -1
  10. package/dist/blobManager/blobManager.d.ts +1 -1
  11. package/dist/blobManager/blobManager.d.ts.map +1 -1
  12. package/dist/blobManager/blobManager.js +264 -231
  13. package/dist/blobManager/blobManager.js.map +1 -1
  14. package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  15. package/dist/channelCollection.d.ts.map +1 -1
  16. package/dist/channelCollection.js +70 -58
  17. package/dist/channelCollection.js.map +1 -1
  18. package/dist/connectionTelemetry.js +38 -20
  19. package/dist/connectionTelemetry.js.map +1 -1
  20. package/dist/containerCompatibility.d.ts +3 -3
  21. package/dist/containerCompatibility.d.ts.map +1 -1
  22. package/dist/containerCompatibility.js +36 -45
  23. package/dist/containerCompatibility.js.map +1 -1
  24. package/dist/containerHandleContext.d.ts.map +1 -1
  25. package/dist/containerHandleContext.js +4 -0
  26. package/dist/containerHandleContext.js.map +1 -1
  27. package/dist/containerRuntime.d.ts +4 -4
  28. package/dist/containerRuntime.d.ts.map +1 -1
  29. package/dist/containerRuntime.js +346 -223
  30. package/dist/containerRuntime.js.map +1 -1
  31. package/dist/dataStore.d.ts.map +1 -1
  32. package/dist/dataStore.js +9 -1
  33. package/dist/dataStore.js.map +1 -1
  34. package/dist/dataStoreContext.d.ts.map +1 -1
  35. package/dist/dataStoreContext.js +184 -127
  36. package/dist/dataStoreContext.js.map +1 -1
  37. package/dist/dataStoreContexts.js +43 -42
  38. package/dist/dataStoreContexts.js.map +1 -1
  39. package/dist/dataStoreRegistry.js +1 -0
  40. package/dist/dataStoreRegistry.js.map +1 -1
  41. package/dist/deltaManagerProxies.js +5 -0
  42. package/dist/deltaManagerProxies.js.map +1 -1
  43. package/dist/deltaScheduler.js +104 -99
  44. package/dist/deltaScheduler.js.map +1 -1
  45. package/dist/error.js +2 -1
  46. package/dist/error.js.map +1 -1
  47. package/dist/gc/garbageCollection.js +85 -55
  48. package/dist/gc/garbageCollection.js.map +1 -1
  49. package/dist/gc/gcConfigs.js +2 -3
  50. package/dist/gc/gcConfigs.js.map +1 -1
  51. package/dist/gc/gcHelpers.js +12 -13
  52. package/dist/gc/gcHelpers.js.map +1 -1
  53. package/dist/gc/gcReferenceGraphAlgorithm.js +1 -2
  54. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  55. package/dist/gc/gcSummaryStateTracker.js +8 -3
  56. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  57. package/dist/gc/gcTelemetry.js +12 -5
  58. package/dist/gc/gcTelemetry.js.map +1 -1
  59. package/dist/gc/gcUnreferencedStateTracker.js +18 -1
  60. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  61. package/dist/inboundBatchAggregator.js +122 -117
  62. package/dist/inboundBatchAggregator.js.map +1 -1
  63. package/dist/metadata.d.ts.map +1 -1
  64. package/dist/metadata.js +3 -3
  65. package/dist/metadata.js.map +1 -1
  66. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  67. package/dist/opLifecycle/batchManager.js +11 -5
  68. package/dist/opLifecycle/batchManager.js.map +1 -1
  69. package/dist/opLifecycle/duplicateBatchDetector.js +18 -18
  70. package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
  71. package/dist/opLifecycle/index.d.ts +2 -2
  72. package/dist/opLifecycle/index.d.ts.map +1 -1
  73. package/dist/opLifecycle/index.js +2 -1
  74. package/dist/opLifecycle/index.js.map +1 -1
  75. package/dist/opLifecycle/opCompressor.js +2 -1
  76. package/dist/opLifecycle/opCompressor.js.map +1 -1
  77. package/dist/opLifecycle/opDecompressor.js +10 -6
  78. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  79. package/dist/opLifecycle/opGroupingManager.js +5 -3
  80. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  81. package/dist/opLifecycle/opSerialization.d.ts +11 -1
  82. package/dist/opLifecycle/opSerialization.d.ts.map +1 -1
  83. package/dist/opLifecycle/opSerialization.js +22 -6
  84. package/dist/opLifecycle/opSerialization.js.map +1 -1
  85. package/dist/opLifecycle/opSplitter.d.ts +17 -1
  86. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  87. package/dist/opLifecycle/opSplitter.js +46 -9
  88. package/dist/opLifecycle/opSplitter.js.map +1 -1
  89. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  90. package/dist/opLifecycle/outbox.js +17 -13
  91. package/dist/opLifecycle/outbox.js.map +1 -1
  92. package/dist/opLifecycle/remoteMessageProcessor.js +6 -3
  93. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  94. package/dist/opProperties.d.ts.map +1 -1
  95. package/dist/packageVersion.d.ts +1 -1
  96. package/dist/packageVersion.d.ts.map +1 -1
  97. package/dist/packageVersion.js +1 -1
  98. package/dist/packageVersion.js.map +1 -1
  99. package/dist/pendingStateManager.js +54 -47
  100. package/dist/pendingStateManager.js.map +1 -1
  101. package/dist/runCounter.js +10 -30
  102. package/dist/runCounter.js.map +1 -1
  103. package/dist/runtimeLayerCompatState.d.ts +1 -1
  104. package/dist/runtimeLayerCompatState.d.ts.map +1 -1
  105. package/dist/runtimeLayerCompatState.js +31 -11
  106. package/dist/runtimeLayerCompatState.js.map +1 -1
  107. package/dist/signalTelemetryProcessing.js +15 -17
  108. package/dist/signalTelemetryProcessing.js.map +1 -1
  109. package/dist/storageServiceWithAttachBlobs.js +2 -0
  110. package/dist/storageServiceWithAttachBlobs.js.map +1 -1
  111. package/dist/summary/documentSchema.d.ts.map +1 -1
  112. package/dist/summary/documentSchema.js +51 -13
  113. package/dist/summary/documentSchema.js.map +1 -1
  114. package/dist/summary/orderedClientElection.js +25 -17
  115. package/dist/summary/orderedClientElection.js.map +1 -1
  116. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  117. package/dist/summary/summarizerClientElection.js +18 -7
  118. package/dist/summary/summarizerClientElection.js.map +1 -1
  119. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  120. package/dist/summary/summarizerNode/summarizerNode.js +22 -13
  121. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  122. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  123. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +20 -6
  124. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  125. package/dist/summary/summarizerUtils.d.ts.map +1 -1
  126. package/dist/summary/summarizerUtils.js +4 -3
  127. package/dist/summary/summarizerUtils.js.map +1 -1
  128. package/dist/summary/summaryCollection.js +23 -11
  129. package/dist/summary/summaryCollection.js.map +1 -1
  130. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js +4 -2
  131. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
  132. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
  133. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js +65 -46
  134. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
  135. package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
  136. package/dist/summary/summaryDelayLoadedModule/summarizer.js +15 -6
  137. package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
  138. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js +30 -25
  139. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
  140. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js +9 -0
  141. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  142. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js +3 -5
  143. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
  144. package/dist/summary/summaryFormat.d.ts.map +1 -1
  145. package/dist/summary/summaryFormat.js +7 -7
  146. package/dist/summary/summaryFormat.js.map +1 -1
  147. package/dist/summary/summaryHelpers.js +5 -5
  148. package/dist/summary/summaryHelpers.js.map +1 -1
  149. package/dist/summary/summaryManager.js +66 -54
  150. package/dist/summary/summaryManager.js.map +1 -1
  151. package/dist/throttler.d.ts.map +1 -1
  152. package/dist/throttler.js +4 -1
  153. package/dist/throttler.js.map +1 -1
  154. package/dist/versionMarks/inboundBatch.d.ts +8 -6
  155. package/dist/versionMarks/inboundBatch.d.ts.map +1 -1
  156. package/dist/versionMarks/inboundBatch.js +11 -7
  157. package/dist/versionMarks/inboundBatch.js.map +1 -1
  158. package/dist/versionMarks/versionMarkResolver.d.ts +30 -23
  159. package/dist/versionMarks/versionMarkResolver.d.ts.map +1 -1
  160. package/dist/versionMarks/versionMarkResolver.js +112 -63
  161. package/dist/versionMarks/versionMarkResolver.js.map +1 -1
  162. package/lib/batchTracker.d.ts.map +1 -1
  163. package/lib/batchTracker.js +5 -1
  164. package/lib/batchTracker.js.map +1 -1
  165. package/lib/blobManager/blobManager.d.ts +1 -1
  166. package/lib/blobManager/blobManager.d.ts.map +1 -1
  167. package/lib/blobManager/blobManager.js +264 -231
  168. package/lib/blobManager/blobManager.js.map +1 -1
  169. package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  170. package/lib/channelCollection.d.ts.map +1 -1
  171. package/lib/channelCollection.js +65 -53
  172. package/lib/channelCollection.js.map +1 -1
  173. package/lib/connectionTelemetry.js +36 -18
  174. package/lib/connectionTelemetry.js.map +1 -1
  175. package/lib/containerCompatibility.d.ts +3 -3
  176. package/lib/containerCompatibility.d.ts.map +1 -1
  177. package/lib/containerCompatibility.js +33 -42
  178. package/lib/containerCompatibility.js.map +1 -1
  179. package/lib/containerHandleContext.d.ts.map +1 -1
  180. package/lib/containerHandleContext.js +4 -0
  181. package/lib/containerHandleContext.js.map +1 -1
  182. package/lib/containerRuntime.d.ts +4 -4
  183. package/lib/containerRuntime.d.ts.map +1 -1
  184. package/lib/containerRuntime.js +341 -218
  185. package/lib/containerRuntime.js.map +1 -1
  186. package/lib/dataStore.d.ts.map +1 -1
  187. package/lib/dataStore.js +9 -1
  188. package/lib/dataStore.js.map +1 -1
  189. package/lib/dataStoreContext.d.ts.map +1 -1
  190. package/lib/dataStoreContext.js +182 -125
  191. package/lib/dataStoreContext.js.map +1 -1
  192. package/lib/dataStoreContexts.js +43 -42
  193. package/lib/dataStoreContexts.js.map +1 -1
  194. package/lib/dataStoreRegistry.js +1 -0
  195. package/lib/dataStoreRegistry.js.map +1 -1
  196. package/lib/deltaManagerProxies.js +5 -0
  197. package/lib/deltaManagerProxies.js.map +1 -1
  198. package/lib/deltaScheduler.js +104 -99
  199. package/lib/deltaScheduler.js.map +1 -1
  200. package/lib/error.js +2 -1
  201. package/lib/error.js.map +1 -1
  202. package/lib/gc/garbageCollection.js +85 -55
  203. package/lib/gc/garbageCollection.js.map +1 -1
  204. package/lib/gc/gcSummaryStateTracker.js +8 -3
  205. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  206. package/lib/gc/gcTelemetry.js +12 -5
  207. package/lib/gc/gcTelemetry.js.map +1 -1
  208. package/lib/gc/gcUnreferencedStateTracker.js +18 -1
  209. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  210. package/lib/inboundBatchAggregator.js +122 -117
  211. package/lib/inboundBatchAggregator.js.map +1 -1
  212. package/lib/legacy.d.ts +1 -1
  213. package/lib/legacyAlpha.d.ts +1 -1
  214. package/lib/metadata.d.ts.map +1 -1
  215. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  216. package/lib/opLifecycle/batchManager.js +8 -2
  217. package/lib/opLifecycle/batchManager.js.map +1 -1
  218. package/lib/opLifecycle/duplicateBatchDetector.js +18 -18
  219. package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
  220. package/lib/opLifecycle/index.d.ts +2 -2
  221. package/lib/opLifecycle/index.d.ts.map +1 -1
  222. package/lib/opLifecycle/index.js +2 -2
  223. package/lib/opLifecycle/index.js.map +1 -1
  224. package/lib/opLifecycle/opCompressor.js +3 -2
  225. package/lib/opLifecycle/opCompressor.js.map +1 -1
  226. package/lib/opLifecycle/opDecompressor.js +10 -6
  227. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  228. package/lib/opLifecycle/opGroupingManager.js +3 -1
  229. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  230. package/lib/opLifecycle/opSerialization.d.ts +11 -1
  231. package/lib/opLifecycle/opSerialization.d.ts.map +1 -1
  232. package/lib/opLifecycle/opSerialization.js +16 -0
  233. package/lib/opLifecycle/opSerialization.js.map +1 -1
  234. package/lib/opLifecycle/opSplitter.d.ts +17 -1
  235. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  236. package/lib/opLifecycle/opSplitter.js +44 -7
  237. package/lib/opLifecycle/opSplitter.js.map +1 -1
  238. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  239. package/lib/opLifecycle/outbox.js +14 -10
  240. package/lib/opLifecycle/outbox.js.map +1 -1
  241. package/lib/opLifecycle/remoteMessageProcessor.js +4 -1
  242. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  243. package/lib/opProperties.d.ts.map +1 -1
  244. package/lib/packageVersion.d.ts +1 -1
  245. package/lib/packageVersion.d.ts.map +1 -1
  246. package/lib/packageVersion.js +1 -1
  247. package/lib/packageVersion.js.map +1 -1
  248. package/lib/pendingStateManager.js +52 -45
  249. package/lib/pendingStateManager.js.map +1 -1
  250. package/lib/public.d.ts +1 -1
  251. package/lib/runCounter.js +10 -30
  252. package/lib/runCounter.js.map +1 -1
  253. package/lib/runtimeLayerCompatState.d.ts +1 -1
  254. package/lib/runtimeLayerCompatState.d.ts.map +1 -1
  255. package/lib/runtimeLayerCompatState.js +28 -8
  256. package/lib/runtimeLayerCompatState.js.map +1 -1
  257. package/lib/signalTelemetryProcessing.js +15 -17
  258. package/lib/signalTelemetryProcessing.js.map +1 -1
  259. package/lib/storageServiceWithAttachBlobs.js +2 -0
  260. package/lib/storageServiceWithAttachBlobs.js.map +1 -1
  261. package/lib/summary/documentSchema.d.ts.map +1 -1
  262. package/lib/summary/documentSchema.js +51 -13
  263. package/lib/summary/documentSchema.js.map +1 -1
  264. package/lib/summary/orderedClientElection.js +25 -17
  265. package/lib/summary/orderedClientElection.js.map +1 -1
  266. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  267. package/lib/summary/summarizerClientElection.js +18 -7
  268. package/lib/summary/summarizerClientElection.js.map +1 -1
  269. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  270. package/lib/summary/summarizerNode/summarizerNode.js +22 -13
  271. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  272. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  273. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +20 -6
  274. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  275. package/lib/summary/summarizerUtils.d.ts.map +1 -1
  276. package/lib/summary/summarizerUtils.js +1 -0
  277. package/lib/summary/summarizerUtils.js.map +1 -1
  278. package/lib/summary/summaryCollection.js +23 -11
  279. package/lib/summary/summaryCollection.js.map +1 -1
  280. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js +4 -2
  281. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
  282. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
  283. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js +65 -46
  284. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
  285. package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
  286. package/lib/summary/summaryDelayLoadedModule/summarizer.js +15 -6
  287. package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
  288. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js +30 -25
  289. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
  290. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js +9 -0
  291. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  292. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js +3 -5
  293. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
  294. package/lib/summary/summaryFormat.d.ts.map +1 -1
  295. package/lib/summary/summaryManager.js +66 -54
  296. package/lib/summary/summaryManager.js.map +1 -1
  297. package/lib/throttler.d.ts.map +1 -1
  298. package/lib/throttler.js +4 -1
  299. package/lib/throttler.js.map +1 -1
  300. package/lib/versionMarks/inboundBatch.d.ts +8 -6
  301. package/lib/versionMarks/inboundBatch.d.ts.map +1 -1
  302. package/lib/versionMarks/inboundBatch.js +10 -5
  303. package/lib/versionMarks/inboundBatch.js.map +1 -1
  304. package/lib/versionMarks/versionMarkResolver.d.ts +30 -23
  305. package/lib/versionMarks/versionMarkResolver.d.ts.map +1 -1
  306. package/lib/versionMarks/versionMarkResolver.js +112 -63
  307. package/lib/versionMarks/versionMarkResolver.js.map +1 -1
  308. package/package.json +60 -102
  309. package/src/containerCompatibility.ts +33 -42
  310. package/src/containerRuntime.ts +15 -12
  311. package/src/opLifecycle/index.ts +7 -1
  312. package/src/opLifecycle/opCompressor.ts +2 -2
  313. package/src/opLifecycle/opSerialization.ts +22 -1
  314. package/src/opLifecycle/opSplitter.ts +63 -6
  315. package/src/packageVersion.ts +1 -1
  316. package/src/runtimeLayerCompatState.ts +28 -21
  317. package/src/summary/documentSchema.ts +31 -6
  318. package/src/versionMarks/DEV.md +595 -158
  319. package/src/versionMarks/inboundBatch.ts +18 -8
  320. package/src/versionMarks/versionMarkResolver.ts +144 -75
  321. package/tsconfig.json +1 -1
  322. package/internal.d.ts +0 -11
  323. package/legacy/alpha.d.ts +0 -11
  324. package/legacy.d.ts +0 -11
  325. /package/api-extractor/{api-extractor.current.json → api-extractor-report.current.json} +0 -0
  326. /package/api-extractor/{api-extractor.legacy.json → api-extractor-report.legacy.json} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"dataStoreRegistry.js","sourceRoot":"","sources":["../src/dataStoreRegistry.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAAoE;AAMpE,uEAAsE;AAEtE;;GAEG;AACH,MAAa,sBAAsB;IAMlC,IAAW,uBAAuB;QACjC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,YAAY,YAAgD;QAC3D,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;QACrB,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,qBAAU,CAAC,6BAA6B,CAAC,CAAC;YACrD,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;IACF,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,IAAY;QAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;IAEM,OAAO,CAAC,IAAY;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,IAAA,wBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACd,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;CACD;AApCD,wDAoCC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { isPromiseLike } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tFluidDataStoreRegistryEntry,\n\tIFluidDataStoreRegistry,\n\tNamedFluidDataStoreRegistryEntries,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * @internal\n */\nexport class FluidDataStoreRegistry implements IFluidDataStoreRegistry {\n\tprivate readonly map: Map<\n\t\tstring,\n\t\tFluidDataStoreRegistryEntry | Promise<FluidDataStoreRegistryEntry>\n\t>;\n\n\tpublic get IFluidDataStoreRegistry(): IFluidDataStoreRegistry {\n\t\treturn this;\n\t}\n\n\tconstructor(namedEntries: NamedFluidDataStoreRegistryEntries) {\n\t\tthis.map = new Map();\n\t\tfor (const entry of namedEntries) {\n\t\t\tif (this.map.has(entry[0])) {\n\t\t\t\tthrow new UsageError(\"Duplicate entry names exist\");\n\t\t\t}\n\t\t\tthis.map.set(entry[0], entry[1]);\n\t\t}\n\t}\n\n\tpublic async get(name: string): Promise<FluidDataStoreRegistryEntry | undefined> {\n\t\tif (this.map.has(name)) {\n\t\t\treturn this.map.get(name);\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tpublic getSync(name: string): FluidDataStoreRegistryEntry | undefined {\n\t\tconst entry = this.map.get(name);\n\t\tif (!isPromiseLike(entry)) {\n\t\t\treturn entry;\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"dataStoreRegistry.js","sourceRoot":"","sources":["../src/dataStoreRegistry.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAAoE;AAMpE,uEAAsE;AAEtE;;GAEG;AACH,MAAa,sBAAsB;IACjB,GAAG,CAGlB;IAEF,IAAW,uBAAuB;QACjC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,YAAY,YAAgD;QAC3D,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;QACrB,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,qBAAU,CAAC,6BAA6B,CAAC,CAAC;YACrD,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;IACF,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,IAAY;QAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;IAEM,OAAO,CAAC,IAAY;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,IAAA,wBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACd,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;CACD;AApCD,wDAoCC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { isPromiseLike } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tFluidDataStoreRegistryEntry,\n\tIFluidDataStoreRegistry,\n\tNamedFluidDataStoreRegistryEntries,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * @internal\n */\nexport class FluidDataStoreRegistry implements IFluidDataStoreRegistry {\n\tprivate readonly map: Map<\n\t\tstring,\n\t\tFluidDataStoreRegistryEntry | Promise<FluidDataStoreRegistryEntry>\n\t>;\n\n\tpublic get IFluidDataStoreRegistry(): IFluidDataStoreRegistry {\n\t\treturn this;\n\t}\n\n\tconstructor(namedEntries: NamedFluidDataStoreRegistryEntries) {\n\t\tthis.map = new Map();\n\t\tfor (const entry of namedEntries) {\n\t\t\tif (this.map.has(entry[0])) {\n\t\t\t\tthrow new UsageError(\"Duplicate entry names exist\");\n\t\t\t}\n\t\t\tthis.map.set(entry[0], entry[1]);\n\t\t}\n\t}\n\n\tpublic async get(name: string): Promise<FluidDataStoreRegistryEntry | undefined> {\n\t\tif (this.map.has(name)) {\n\t\t\treturn this.map.get(name);\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tpublic getSync(name: string): FluidDataStoreRegistryEntry | undefined {\n\t\tconst entry = this.map.get(name);\n\t\tif (!isPromiseLike(entry)) {\n\t\t\treturn entry;\n\t\t}\n\n\t\treturn undefined;\n\t}\n}\n"]}
@@ -14,6 +14,7 @@ const index_js_1 = require("./summary/index.js");
14
14
  * of the DeltaManager.
15
15
  */
16
16
  class BaseDeltaManagerProxy extends client_utils_1.TypedEventEmitter {
17
+ deltaManager;
17
18
  get IDeltaSender() {
18
19
  return this;
19
20
  }
@@ -62,6 +63,7 @@ class BaseDeltaManagerProxy extends client_utils_1.TypedEventEmitter {
62
63
  get readOnlyInfo() {
63
64
  return this.deltaManager.readOnlyInfo;
64
65
  }
66
+ eventHandlers;
65
67
  constructor(deltaManager, overrides) {
66
68
  super();
67
69
  this.deltaManager = deltaManager;
@@ -123,6 +125,7 @@ exports.BaseDeltaManagerProxy = BaseDeltaManagerProxy;
123
125
  * - Summarizer client should not be active to layers below the container runtime to restrict local changes.
124
126
  */
125
127
  class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {
128
+ deltaManager;
126
129
  static wrapIfSummarizer(deltaManager) {
127
130
  if (deltaManager.clientDetails.type === index_js_1.summarizerClientType) {
128
131
  return new DeltaManagerSummarizerProxy(deltaManager);
@@ -152,6 +155,8 @@ class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {
152
155
  }
153
156
  exports.DeltaManagerSummarizerProxy = DeltaManagerSummarizerProxy;
154
157
  class DeltaManagerPendingOpsProxy extends BaseDeltaManagerProxy {
158
+ deltaManager;
159
+ pendingStateManager;
155
160
  get minimumSequenceNumber() {
156
161
  const minPendingSeqNum = this.pendingStateManager.minimumPendingMessageSequenceNumber;
157
162
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"deltaManagerProxies.js","sourceRoot":"","sources":["../src/deltaManagerProxies.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 { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type {\n\tIConnectionDetails,\n\tIDeltaManagerEvents,\n\tIDeltaManagerFull,\n\tIDeltaQueue,\n\tIDeltaSender,\n\tReadOnlyInfo,\n} from \"@fluidframework/container-definitions/internal\";\nimport type { IErrorBase } from \"@fluidframework/core-interfaces\";\nimport type { IClientDetails } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIAnyDriverError,\n\tIClientConfiguration,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tISignalMessage,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport type { PendingStateManager } from \"./pendingStateManager.js\";\nimport { summarizerClientType } from \"./summary/index.js\";\n\n/**\n * Interface defining event handlers for the BaseDeltaManagerProxy.\n * These handlers allow customization of behavior for various DeltaManager events.\n */\nexport interface BaseDeltaManagerProxyEventHandlers {\n\t/**\n\t * Event handler triggered when the readonly state changes.\n\t * @param readonly - Indicates if the connection is readonly.\n\t * @param readonlyConnectionReason - Optional reason and error details for the readonly state.\n\t */\n\tonReadonly: (\n\t\treadonly: boolean,\n\t\treadonlyConnectionReason?: { reason: string; error?: IErrorBase },\n\t) => void;\n\n\t/**\n\t * Event handler triggered before sending a message.\n\t * @param messageBuffer - The buffer of messages to be sent.\n\t */\n\tonPrepareSend: (messageBuffer: unknown[]) => void;\n\n\t/**\n\t * Event handler triggered when an operation is submitted.\n\t * @param message - The document message being submitted.\n\t */\n\tonSubmitOp: (message: IDocumentMessage) => void;\n\n\t/**\n\t * Event handler triggered when an operation is received.\n\t * @param message - The sequenced document message received.\n\t * @param processingTime - The time taken to process the message.\n\t */\n\tonOp: (message: ISequencedDocumentMessage, processingTime: number) => void;\n\n\t/**\n\t * Event handler triggered when a pong response is received.\n\t * @param latency - The latency of the pong response.\n\t */\n\tonPong: (latency: number) => void;\n\n\t/**\n\t * Event handler triggered when a connection is established.\n\t * @param details - The connection details.\n\t * @param opsBehind - Optional number of operations behind the latest state.\n\t */\n\tonConnect: (details: IConnectionDetails, opsBehind?: number) => void;\n\n\t/**\n\t * Event handler triggered when a disconnection occurs.\n\t * @param reason - The reason for the disconnection.\n\t * @param error - Optional error details for the disconnection.\n\t */\n\tonDisconnect: (reason: string, error?: IAnyDriverError) => void;\n}\n\n/**\n * Base class for DeltaManager proxy that proxy's access to the real DeltaManager.\n *\n * This class allows us to build proxy functionality without actually having to implement all the methods\n * of the DeltaManager.\n */\nexport class BaseDeltaManagerProxy\n\textends TypedEventEmitter<IDeltaManagerEvents>\n\timplements IDeltaManagerFull\n{\n\tpublic get IDeltaSender(): IDeltaSender {\n\t\treturn this;\n\t}\n\n\tpublic get inbound(): IDeltaQueue<ISequencedDocumentMessage> {\n\t\treturn this.deltaManager.inbound;\n\t}\n\n\tpublic get outbound(): IDeltaQueue<IDocumentMessage[]> {\n\t\treturn this.deltaManager.outbound;\n\t}\n\n\tpublic get inboundSignal(): IDeltaQueue<ISignalMessage> {\n\t\treturn this.deltaManager.inboundSignal;\n\t}\n\n\tpublic get minimumSequenceNumber(): number {\n\t\treturn this.deltaManager.minimumSequenceNumber;\n\t}\n\n\tpublic get lastSequenceNumber(): number {\n\t\treturn this.deltaManager.lastSequenceNumber;\n\t}\n\n\tpublic get lastMessage(): ISequencedDocumentMessage | undefined {\n\t\treturn this.deltaManager.lastMessage;\n\t}\n\n\tpublic get lastKnownSeqNumber(): number {\n\t\treturn this.deltaManager.lastKnownSeqNumber;\n\t}\n\n\tpublic get initialSequenceNumber(): number {\n\t\treturn this.deltaManager.initialSequenceNumber;\n\t}\n\n\tpublic get hasCheckpointSequenceNumber(): boolean {\n\t\treturn this.deltaManager.hasCheckpointSequenceNumber;\n\t}\n\n\tpublic get clientDetails(): IClientDetails {\n\t\treturn this.deltaManager.clientDetails;\n\t}\n\n\tpublic get version(): string {\n\t\treturn this.deltaManager.version;\n\t}\n\n\tpublic get maxMessageSize(): number {\n\t\treturn this.deltaManager.maxMessageSize;\n\t}\n\n\tpublic get serviceConfiguration(): IClientConfiguration | undefined {\n\t\treturn this.deltaManager.serviceConfiguration;\n\t}\n\n\tpublic get active(): boolean {\n\t\treturn this.deltaManager.active;\n\t}\n\n\tpublic get readOnlyInfo(): ReadOnlyInfo {\n\t\treturn this.deltaManager.readOnlyInfo;\n\t}\n\n\tprivate readonly eventHandlers: BaseDeltaManagerProxyEventHandlers;\n\n\tconstructor(\n\t\tprotected readonly deltaManager: IDeltaManagerFull,\n\t\toverrides?: Partial<BaseDeltaManagerProxyEventHandlers>,\n\t) {\n\t\tsuper();\n\n\t\tthis.eventHandlers = {\n\t\t\tonPrepareSend: (messageBuffer: unknown[]): void => {\n\t\t\t\tthis.emit(\"prepareSend\", messageBuffer);\n\t\t\t},\n\t\t\tonSubmitOp: (message: IDocumentMessage): void => {\n\t\t\t\tthis.emit(\"submitOp\", message);\n\t\t\t},\n\t\t\tonOp: (message: ISequencedDocumentMessage, processingTime: number): void => {\n\t\t\t\tthis.emit(\"op\", message, processingTime);\n\t\t\t},\n\t\t\tonPong: (latency: number): void => {\n\t\t\t\tthis.emit(\"pong\", latency);\n\t\t\t},\n\t\t\tonConnect: (details: IConnectionDetails, opsBehind?: number): void => {\n\t\t\t\tthis.emit(\"connect\", details, opsBehind);\n\t\t\t},\n\t\t\tonDisconnect: (reason: string, error?: IAnyDriverError): void => {\n\t\t\t\tthis.emit(\"disconnect\", reason, error);\n\t\t\t},\n\t\t\tonReadonly: (\n\t\t\t\treadonly: boolean,\n\t\t\t\treadonlyConnectionReason?: { reason: string; error?: IErrorBase },\n\t\t\t): void => {\n\t\t\t\tthis.emit(\"readonly\", readonly, readonlyConnectionReason);\n\t\t\t},\n\n\t\t\t...overrides,\n\t\t};\n\n\t\t// We are expecting this class to have many listeners, so we suppress noisy \"MaxListenersExceededWarning\" logging.\n\t\tsuper.setMaxListeners(0);\n\n\t\tthis.deltaManager.on(\"prepareSend\", this.eventHandlers.onPrepareSend);\n\t\tthis.deltaManager.on(\"submitOp\", this.eventHandlers.onSubmitOp);\n\t\tthis.deltaManager.on(\"op\", this.eventHandlers.onOp);\n\t\tthis.deltaManager.on(\"pong\", this.eventHandlers.onPong);\n\t\tthis.deltaManager.on(\"connect\", this.eventHandlers.onConnect);\n\t\tthis.deltaManager.on(\"disconnect\", this.eventHandlers.onDisconnect);\n\t\tthis.deltaManager.on(\"readonly\", this.eventHandlers.onReadonly);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.deltaManager.off(\"prepareSend\", this.eventHandlers.onPrepareSend);\n\t\tthis.deltaManager.off(\"submitOp\", this.eventHandlers.onSubmitOp);\n\t\tthis.deltaManager.off(\"op\", this.eventHandlers.onOp);\n\t\tthis.deltaManager.off(\"pong\", this.eventHandlers.onPong);\n\t\tthis.deltaManager.off(\"connect\", this.eventHandlers.onConnect);\n\t\tthis.deltaManager.off(\"disconnect\", this.eventHandlers.onDisconnect);\n\t\tthis.deltaManager.off(\"readonly\", this.eventHandlers.onReadonly);\n\t\tthis.removeAllListeners();\n\t}\n\n\tpublic submitSignal(content: string, targetClientId?: string): void {\n\t\treturn this.deltaManager.submitSignal(content, targetClientId);\n\t}\n\n\tpublic flush(): void {\n\t\treturn this.deltaManager.flush();\n\t}\n}\n\n/**\n * Proxy to the real IDeltaManager for restricting certain access to layers below container runtime in summarizer clients:\n * - Summarizer client should be read-only to layers below the container runtime to restrict local changes.\n * - Summarizer client should not be active to layers below the container runtime to restrict local changes.\n */\nexport class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {\n\tpublic static wrapIfSummarizer(deltaManager: IDeltaManagerFull): IDeltaManagerFull {\n\t\tif (deltaManager.clientDetails.type === summarizerClientType) {\n\t\t\treturn new DeltaManagerSummarizerProxy(deltaManager);\n\t\t}\n\t\treturn deltaManager;\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/class-literal-property-style\n\tpublic get active(): boolean {\n\t\t// Summarize clients should not be active. There shouldn't be any local changes (writes) in the summarizer\n\t\t// except for the SummarizeOp which is generated by the runtime.\n\t\treturn false;\n\t}\n\n\tpublic get readOnlyInfo(): ReadOnlyInfo {\n\t\t// Summarizer clients should be read-only as far as the runtime and layers below are concerned. There shouldn't\n\t\t// be any local changes (writes) in the summarizer except for the summarize op which is generated by the runtime.\n\n\t\treturn {\n\t\t\treadonly: true,\n\t\t\tforced: false,\n\t\t\tpermissions: undefined,\n\t\t\tstorageOnly: false,\n\t\t};\n\t}\n\n\tconstructor(protected readonly deltaManager: IDeltaManagerFull) {\n\t\tsuper(deltaManager, { onReadonly: () => {} });\n\t}\n}\n\nexport class DeltaManagerPendingOpsProxy extends BaseDeltaManagerProxy {\n\tpublic get minimumSequenceNumber(): number {\n\t\tconst minPendingSeqNum = this.pendingStateManager.minimumPendingMessageSequenceNumber;\n\t\t/**\n\t\t * The reason why the minimum pending sequence number can be less than the delta manager's minimum sequence\n\t\t * number (DM's msn) is that when we are processing messages in the container runtime/delta manager, the delta\n\t\t * manager's msn can be updated to continually increase. In the meantime, the pending state manager's op which\n\t\t * hasn't been sent can still have a lower sequence number than the DM's msn (think about a disconnected\n\t\t * scenario). To successfully resubmit that pending op it has to be rebased first by the DDS. The DDS still\n\t\t * needs to keep the local data for that op that has a reference sequence number lower than the DM's msn. To\n\t\t * achieve this, the msn passed to the DDS needs to be the minimum of the DM's msn and the minimum pending\n\t\t * sequence number, so that it can keep the relevant local data to generate the right data for the new op\n\t\t * during resubmission.\n\t\t */\n\t\tif (\n\t\t\tminPendingSeqNum !== undefined &&\n\t\t\tminPendingSeqNum < this.deltaManager.minimumSequenceNumber\n\t\t) {\n\t\t\treturn minPendingSeqNum;\n\t\t}\n\t\treturn this.deltaManager.minimumSequenceNumber;\n\t}\n\n\tpublic get lastMessage(): ISequencedDocumentMessage | undefined {\n\t\tif (this.deltaManager.lastMessage === undefined) {\n\t\t\treturn this.deltaManager.lastMessage;\n\t\t}\n\t\treturn {\n\t\t\t...this.deltaManager.lastMessage,\n\t\t\tminimumSequenceNumber: this.minimumSequenceNumber,\n\t\t};\n\t}\n\n\tconstructor(\n\t\tprotected readonly deltaManager: IDeltaManagerFull,\n\t\tprivate readonly pendingStateManager: Pick<\n\t\t\tPendingStateManager,\n\t\t\t\"minimumPendingMessageSequenceNumber\"\n\t\t>,\n\t) {\n\t\tsuper(deltaManager, {\n\t\t\tonOp: (message: ISequencedDocumentMessage, processingTime: number): void => {\n\t\t\t\tconst messageIntercept = {\n\t\t\t\t\t...message,\n\t\t\t\t\tminimumSequenceNumber: this.minimumSequenceNumber,\n\t\t\t\t};\n\t\t\t\tthis.emit(\"op\", messageIntercept, processingTime);\n\t\t\t},\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"deltaManagerProxies.js","sourceRoot":"","sources":["../src/deltaManagerProxies.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 { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type {\n\tIConnectionDetails,\n\tIDeltaManagerEvents,\n\tIDeltaManagerFull,\n\tIDeltaQueue,\n\tIDeltaSender,\n\tReadOnlyInfo,\n} from \"@fluidframework/container-definitions/internal\";\nimport type { IErrorBase } from \"@fluidframework/core-interfaces\";\nimport type { IClientDetails } from \"@fluidframework/driver-definitions\";\nimport type {\n\tIAnyDriverError,\n\tIClientConfiguration,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tISignalMessage,\n} from \"@fluidframework/driver-definitions/internal\";\n\nimport type { PendingStateManager } from \"./pendingStateManager.js\";\nimport { summarizerClientType } from \"./summary/index.js\";\n\n/**\n * Interface defining event handlers for the BaseDeltaManagerProxy.\n * These handlers allow customization of behavior for various DeltaManager events.\n */\nexport interface BaseDeltaManagerProxyEventHandlers {\n\t/**\n\t * Event handler triggered when the readonly state changes.\n\t * @param readonly - Indicates if the connection is readonly.\n\t * @param readonlyConnectionReason - Optional reason and error details for the readonly state.\n\t */\n\tonReadonly: (\n\t\treadonly: boolean,\n\t\treadonlyConnectionReason?: { reason: string; error?: IErrorBase },\n\t) => void;\n\n\t/**\n\t * Event handler triggered before sending a message.\n\t * @param messageBuffer - The buffer of messages to be sent.\n\t */\n\tonPrepareSend: (messageBuffer: unknown[]) => void;\n\n\t/**\n\t * Event handler triggered when an operation is submitted.\n\t * @param message - The document message being submitted.\n\t */\n\tonSubmitOp: (message: IDocumentMessage) => void;\n\n\t/**\n\t * Event handler triggered when an operation is received.\n\t * @param message - The sequenced document message received.\n\t * @param processingTime - The time taken to process the message.\n\t */\n\tonOp: (message: ISequencedDocumentMessage, processingTime: number) => void;\n\n\t/**\n\t * Event handler triggered when a pong response is received.\n\t * @param latency - The latency of the pong response.\n\t */\n\tonPong: (latency: number) => void;\n\n\t/**\n\t * Event handler triggered when a connection is established.\n\t * @param details - The connection details.\n\t * @param opsBehind - Optional number of operations behind the latest state.\n\t */\n\tonConnect: (details: IConnectionDetails, opsBehind?: number) => void;\n\n\t/**\n\t * Event handler triggered when a disconnection occurs.\n\t * @param reason - The reason for the disconnection.\n\t * @param error - Optional error details for the disconnection.\n\t */\n\tonDisconnect: (reason: string, error?: IAnyDriverError) => void;\n}\n\n/**\n * Base class for DeltaManager proxy that proxy's access to the real DeltaManager.\n *\n * This class allows us to build proxy functionality without actually having to implement all the methods\n * of the DeltaManager.\n */\nexport class BaseDeltaManagerProxy\n\textends TypedEventEmitter<IDeltaManagerEvents>\n\timplements IDeltaManagerFull\n{\n\tpublic get IDeltaSender(): IDeltaSender {\n\t\treturn this;\n\t}\n\n\tpublic get inbound(): IDeltaQueue<ISequencedDocumentMessage> {\n\t\treturn this.deltaManager.inbound;\n\t}\n\n\tpublic get outbound(): IDeltaQueue<IDocumentMessage[]> {\n\t\treturn this.deltaManager.outbound;\n\t}\n\n\tpublic get inboundSignal(): IDeltaQueue<ISignalMessage> {\n\t\treturn this.deltaManager.inboundSignal;\n\t}\n\n\tpublic get minimumSequenceNumber(): number {\n\t\treturn this.deltaManager.minimumSequenceNumber;\n\t}\n\n\tpublic get lastSequenceNumber(): number {\n\t\treturn this.deltaManager.lastSequenceNumber;\n\t}\n\n\tpublic get lastMessage(): ISequencedDocumentMessage | undefined {\n\t\treturn this.deltaManager.lastMessage;\n\t}\n\n\tpublic get lastKnownSeqNumber(): number {\n\t\treturn this.deltaManager.lastKnownSeqNumber;\n\t}\n\n\tpublic get initialSequenceNumber(): number {\n\t\treturn this.deltaManager.initialSequenceNumber;\n\t}\n\n\tpublic get hasCheckpointSequenceNumber(): boolean {\n\t\treturn this.deltaManager.hasCheckpointSequenceNumber;\n\t}\n\n\tpublic get clientDetails(): IClientDetails {\n\t\treturn this.deltaManager.clientDetails;\n\t}\n\n\tpublic get version(): string {\n\t\treturn this.deltaManager.version;\n\t}\n\n\tpublic get maxMessageSize(): number {\n\t\treturn this.deltaManager.maxMessageSize;\n\t}\n\n\tpublic get serviceConfiguration(): IClientConfiguration | undefined {\n\t\treturn this.deltaManager.serviceConfiguration;\n\t}\n\n\tpublic get active(): boolean {\n\t\treturn this.deltaManager.active;\n\t}\n\n\tpublic get readOnlyInfo(): ReadOnlyInfo {\n\t\treturn this.deltaManager.readOnlyInfo;\n\t}\n\n\tprivate readonly eventHandlers: BaseDeltaManagerProxyEventHandlers;\n\n\tconstructor(\n\t\tprotected readonly deltaManager: IDeltaManagerFull,\n\t\toverrides?: Partial<BaseDeltaManagerProxyEventHandlers>,\n\t) {\n\t\tsuper();\n\n\t\tthis.eventHandlers = {\n\t\t\tonPrepareSend: (messageBuffer: unknown[]): void => {\n\t\t\t\tthis.emit(\"prepareSend\", messageBuffer);\n\t\t\t},\n\t\t\tonSubmitOp: (message: IDocumentMessage): void => {\n\t\t\t\tthis.emit(\"submitOp\", message);\n\t\t\t},\n\t\t\tonOp: (message: ISequencedDocumentMessage, processingTime: number): void => {\n\t\t\t\tthis.emit(\"op\", message, processingTime);\n\t\t\t},\n\t\t\tonPong: (latency: number): void => {\n\t\t\t\tthis.emit(\"pong\", latency);\n\t\t\t},\n\t\t\tonConnect: (details: IConnectionDetails, opsBehind?: number): void => {\n\t\t\t\tthis.emit(\"connect\", details, opsBehind);\n\t\t\t},\n\t\t\tonDisconnect: (reason: string, error?: IAnyDriverError): void => {\n\t\t\t\tthis.emit(\"disconnect\", reason, error);\n\t\t\t},\n\t\t\tonReadonly: (\n\t\t\t\treadonly: boolean,\n\t\t\t\treadonlyConnectionReason?: { reason: string; error?: IErrorBase },\n\t\t\t): void => {\n\t\t\t\tthis.emit(\"readonly\", readonly, readonlyConnectionReason);\n\t\t\t},\n\n\t\t\t...overrides,\n\t\t};\n\n\t\t// We are expecting this class to have many listeners, so we suppress noisy \"MaxListenersExceededWarning\" logging.\n\t\tsuper.setMaxListeners(0);\n\n\t\tthis.deltaManager.on(\"prepareSend\", this.eventHandlers.onPrepareSend);\n\t\tthis.deltaManager.on(\"submitOp\", this.eventHandlers.onSubmitOp);\n\t\tthis.deltaManager.on(\"op\", this.eventHandlers.onOp);\n\t\tthis.deltaManager.on(\"pong\", this.eventHandlers.onPong);\n\t\tthis.deltaManager.on(\"connect\", this.eventHandlers.onConnect);\n\t\tthis.deltaManager.on(\"disconnect\", this.eventHandlers.onDisconnect);\n\t\tthis.deltaManager.on(\"readonly\", this.eventHandlers.onReadonly);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.deltaManager.off(\"prepareSend\", this.eventHandlers.onPrepareSend);\n\t\tthis.deltaManager.off(\"submitOp\", this.eventHandlers.onSubmitOp);\n\t\tthis.deltaManager.off(\"op\", this.eventHandlers.onOp);\n\t\tthis.deltaManager.off(\"pong\", this.eventHandlers.onPong);\n\t\tthis.deltaManager.off(\"connect\", this.eventHandlers.onConnect);\n\t\tthis.deltaManager.off(\"disconnect\", this.eventHandlers.onDisconnect);\n\t\tthis.deltaManager.off(\"readonly\", this.eventHandlers.onReadonly);\n\t\tthis.removeAllListeners();\n\t}\n\n\tpublic submitSignal(content: string, targetClientId?: string): void {\n\t\treturn this.deltaManager.submitSignal(content, targetClientId);\n\t}\n\n\tpublic flush(): void {\n\t\treturn this.deltaManager.flush();\n\t}\n}\n\n/**\n * Proxy to the real IDeltaManager for restricting certain access to layers below container runtime in summarizer clients:\n * - Summarizer client should be read-only to layers below the container runtime to restrict local changes.\n * - Summarizer client should not be active to layers below the container runtime to restrict local changes.\n */\nexport class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {\n\tpublic static wrapIfSummarizer(deltaManager: IDeltaManagerFull): IDeltaManagerFull {\n\t\tif (deltaManager.clientDetails.type === summarizerClientType) {\n\t\t\treturn new DeltaManagerSummarizerProxy(deltaManager);\n\t\t}\n\t\treturn deltaManager;\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/class-literal-property-style\n\tpublic get active(): boolean {\n\t\t// Summarize clients should not be active. There shouldn't be any local changes (writes) in the summarizer\n\t\t// except for the SummarizeOp which is generated by the runtime.\n\t\treturn false;\n\t}\n\n\tpublic get readOnlyInfo(): ReadOnlyInfo {\n\t\t// Summarizer clients should be read-only as far as the runtime and layers below are concerned. There shouldn't\n\t\t// be any local changes (writes) in the summarizer except for the summarize op which is generated by the runtime.\n\n\t\treturn {\n\t\t\treadonly: true,\n\t\t\tforced: false,\n\t\t\tpermissions: undefined,\n\t\t\tstorageOnly: false,\n\t\t};\n\t}\n\n\tconstructor(protected readonly deltaManager: IDeltaManagerFull) {\n\t\tsuper(deltaManager, { onReadonly: () => {} });\n\t}\n}\n\nexport class DeltaManagerPendingOpsProxy extends BaseDeltaManagerProxy {\n\tpublic get minimumSequenceNumber(): number {\n\t\tconst minPendingSeqNum = this.pendingStateManager.minimumPendingMessageSequenceNumber;\n\t\t/**\n\t\t * The reason why the minimum pending sequence number can be less than the delta manager's minimum sequence\n\t\t * number (DM's msn) is that when we are processing messages in the container runtime/delta manager, the delta\n\t\t * manager's msn can be updated to continually increase. In the meantime, the pending state manager's op which\n\t\t * hasn't been sent can still have a lower sequence number than the DM's msn (think about a disconnected\n\t\t * scenario). To successfully resubmit that pending op it has to be rebased first by the DDS. The DDS still\n\t\t * needs to keep the local data for that op that has a reference sequence number lower than the DM's msn. To\n\t\t * achieve this, the msn passed to the DDS needs to be the minimum of the DM's msn and the minimum pending\n\t\t * sequence number, so that it can keep the relevant local data to generate the right data for the new op\n\t\t * during resubmission.\n\t\t */\n\t\tif (\n\t\t\tminPendingSeqNum !== undefined &&\n\t\t\tminPendingSeqNum < this.deltaManager.minimumSequenceNumber\n\t\t) {\n\t\t\treturn minPendingSeqNum;\n\t\t}\n\t\treturn this.deltaManager.minimumSequenceNumber;\n\t}\n\n\tpublic get lastMessage(): ISequencedDocumentMessage | undefined {\n\t\tif (this.deltaManager.lastMessage === undefined) {\n\t\t\treturn this.deltaManager.lastMessage;\n\t\t}\n\t\treturn {\n\t\t\t...this.deltaManager.lastMessage,\n\t\t\tminimumSequenceNumber: this.minimumSequenceNumber,\n\t\t};\n\t}\n\n\tconstructor(\n\t\tprotected readonly deltaManager: IDeltaManagerFull,\n\t\tprivate readonly pendingStateManager: Pick<\n\t\t\tPendingStateManager,\n\t\t\t\"minimumPendingMessageSequenceNumber\"\n\t\t>,\n\t) {\n\t\tsuper(deltaManager, {\n\t\t\tonOp: (message: ISequencedDocumentMessage, processingTime: number): void => {\n\t\t\t\tconst messageIntercept = {\n\t\t\t\t\t...message,\n\t\t\t\t\tminimumSequenceNumber: this.minimumSequenceNumber,\n\t\t\t\t};\n\t\t\t\tthis.emit(\"op\", messageIntercept, processingTime);\n\t\t\t},\n\t\t});\n\t}\n}\n"]}
@@ -21,107 +21,24 @@ const internal_1 = require("@fluidframework/telemetry-utils/internal");
21
21
  * processed, the time and number of turns it took to process the ops.
22
22
  */
23
23
  class DeltaScheduler {
24
+ deltaManager;
25
+ runtimeEventsEmitter;
26
+ logger;
27
+ // The time for processing ops in a single turn.
28
+ static processingTime = 50;
29
+ // The increase in time for processing ops after each turn.
30
+ processingTimeIncrement = 10;
31
+ processingStartTime;
32
+ currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
33
+ // This keeps track of the number of times inbound queue has been scheduled. After a particular
34
+ // count, we log telemetry for the number of ops processed, the time and number of turns it took
35
+ // to process the ops.
36
+ schedulingCount = 0;
37
+ schedulingLog;
24
38
  constructor(deltaManager, runtimeEventsEmitter, logger) {
25
39
  this.deltaManager = deltaManager;
26
40
  this.runtimeEventsEmitter = runtimeEventsEmitter;
27
41
  this.logger = logger;
28
- // The increase in time for processing ops after each turn.
29
- this.processingTimeIncrement = 10;
30
- this.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
31
- // This keeps track of the number of times inbound queue has been scheduled. After a particular
32
- // count, we log telemetry for the number of ops processed, the time and number of turns it took
33
- // to process the ops.
34
- this.schedulingCount = 0;
35
- this.batchBegin = (message) => {
36
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
37
- if (this.processingStartTime === undefined) {
38
- this.processingStartTime = (0, client_utils_1.performanceNow)();
39
- }
40
- if (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {
41
- // Every 500th time we are scheduling the inbound queue, we log telemetry for the
42
- // number of ops processed, the time and number of turns it took to process the ops.
43
- this.schedulingLog = {
44
- opsRemainingToProcess: 0,
45
- numberOfTurns: 1,
46
- totalProcessingTime: 0,
47
- numberOfBatchesProcessed: 0,
48
- firstSequenceNumber: message.sequenceNumber,
49
- lastSequenceNumber: message.sequenceNumber,
50
- startTime: (0, client_utils_1.performanceNow)(),
51
- };
52
- }
53
- };
54
- this.batchEnd = (error, message) => {
55
- if (this.schedulingLog) {
56
- this.schedulingLog.numberOfBatchesProcessed++;
57
- this.schedulingLog.lastSequenceNumber = message.sequenceNumber;
58
- this.schedulingLog.opsRemainingToProcess = this.deltaManager.inbound.length;
59
- }
60
- if (this.shouldRunScheduler()) {
61
- const currentTime = (0, client_utils_1.performanceNow)();
62
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
63
- const elapsedTime = currentTime - this.processingStartTime;
64
- if (elapsedTime > this.currentAllowedProcessingTimeForTurn) {
65
- // We have processed ops for more than the total processing time. So, pause the
66
- // queue, yield the thread and schedule a resume.
67
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
68
- this.deltaManager.inbound.pause();
69
- // Increase the total processing time. Keep doing this after each turn until all the ops have
70
- // been processed. This way we keep the responsiveness at the beginning while also making sure
71
- // that all the ops process fairly quickly.
72
- this.currentAllowedProcessingTimeForTurn += this.processingTimeIncrement;
73
- // If we are logging the telemetry this time, update the telemetry log object.
74
- if (this.schedulingLog) {
75
- this.schedulingLog.numberOfTurns++;
76
- this.schedulingLog.totalProcessingTime += elapsedTime;
77
- }
78
- setTimeout(() => {
79
- if (this.schedulingLog) {
80
- this.logger.sendTelemetryEvent({
81
- eventName: "InboundOpsPartialProcessingTime",
82
- duration: (0, internal_1.formatTick)(elapsedTime),
83
- opsProcessed: this.schedulingLog.lastSequenceNumber -
84
- this.schedulingLog.firstSequenceNumber +
85
- 1,
86
- opsRemainingToProcess: this.deltaManager.inbound.length,
87
- processingTime: (0, internal_1.formatTick)(this.schedulingLog.totalProcessingTime),
88
- numberOfTurns: this.schedulingLog.numberOfTurns,
89
- batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
90
- timeToResume: (0, internal_1.formatTick)((0, client_utils_1.performanceNow)() - currentTime),
91
- });
92
- }
93
- this.deltaManager.inbound.resume();
94
- });
95
- this.processingStartTime = undefined;
96
- }
97
- }
98
- };
99
- this.inboundQueueIdle = () => {
100
- if (this.schedulingLog) {
101
- // Add the time taken for processing the final ops to the total processing time in the
102
- // telemetry log object.
103
- const currentTime = (0, client_utils_1.performanceNow)();
104
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
105
- this.schedulingLog.totalProcessingTime += currentTime - this.processingStartTime;
106
- this.logger.sendTelemetryEvent({
107
- eventName: "InboundOpsProcessingTime",
108
- opsRemainingToProcess: this.schedulingLog.opsRemainingToProcess,
109
- numberOfTurns: this.schedulingLog.numberOfTurns,
110
- processingTime: (0, internal_1.formatTick)(this.schedulingLog.totalProcessingTime),
111
- opsProcessed: this.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,
112
- batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
113
- duration: (0, internal_1.formatTick)(currentTime - this.schedulingLog.startTime),
114
- schedulingCount: this.schedulingCount,
115
- });
116
- this.schedulingLog = undefined;
117
- }
118
- // If we scheduled this batch of the inbound queue, increment the counter that tracks the
119
- // number of times we have done this.
120
- this.schedulingCount++;
121
- // Reset the processing times.
122
- this.processingStartTime = undefined;
123
- this.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
124
- };
125
42
  this.deltaManager.inbound.on("idle", this.inboundQueueIdle);
126
43
  runtimeEventsEmitter.on("batchBegin", this.batchBegin);
127
44
  runtimeEventsEmitter.on("batchEnd", this.batchEnd);
@@ -131,6 +48,96 @@ class DeltaScheduler {
131
48
  this.runtimeEventsEmitter.off("batchBegin", this.batchBegin);
132
49
  this.runtimeEventsEmitter.off("batchEnd", this.batchEnd);
133
50
  }
51
+ batchBegin = (message) => {
52
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
53
+ if (this.processingStartTime === undefined) {
54
+ this.processingStartTime = (0, client_utils_1.performanceNow)();
55
+ }
56
+ if (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {
57
+ // Every 500th time we are scheduling the inbound queue, we log telemetry for the
58
+ // number of ops processed, the time and number of turns it took to process the ops.
59
+ this.schedulingLog = {
60
+ opsRemainingToProcess: 0,
61
+ numberOfTurns: 1,
62
+ totalProcessingTime: 0,
63
+ numberOfBatchesProcessed: 0,
64
+ firstSequenceNumber: message.sequenceNumber,
65
+ lastSequenceNumber: message.sequenceNumber,
66
+ startTime: (0, client_utils_1.performanceNow)(),
67
+ };
68
+ }
69
+ };
70
+ batchEnd = (error, message) => {
71
+ if (this.schedulingLog) {
72
+ this.schedulingLog.numberOfBatchesProcessed++;
73
+ this.schedulingLog.lastSequenceNumber = message.sequenceNumber;
74
+ this.schedulingLog.opsRemainingToProcess = this.deltaManager.inbound.length;
75
+ }
76
+ if (this.shouldRunScheduler()) {
77
+ const currentTime = (0, client_utils_1.performanceNow)();
78
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
79
+ const elapsedTime = currentTime - this.processingStartTime;
80
+ if (elapsedTime > this.currentAllowedProcessingTimeForTurn) {
81
+ // We have processed ops for more than the total processing time. So, pause the
82
+ // queue, yield the thread and schedule a resume.
83
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
84
+ this.deltaManager.inbound.pause();
85
+ // Increase the total processing time. Keep doing this after each turn until all the ops have
86
+ // been processed. This way we keep the responsiveness at the beginning while also making sure
87
+ // that all the ops process fairly quickly.
88
+ this.currentAllowedProcessingTimeForTurn += this.processingTimeIncrement;
89
+ // If we are logging the telemetry this time, update the telemetry log object.
90
+ if (this.schedulingLog) {
91
+ this.schedulingLog.numberOfTurns++;
92
+ this.schedulingLog.totalProcessingTime += elapsedTime;
93
+ }
94
+ setTimeout(() => {
95
+ if (this.schedulingLog) {
96
+ this.logger.sendTelemetryEvent({
97
+ eventName: "InboundOpsPartialProcessingTime",
98
+ duration: (0, internal_1.formatTick)(elapsedTime),
99
+ opsProcessed: this.schedulingLog.lastSequenceNumber -
100
+ this.schedulingLog.firstSequenceNumber +
101
+ 1,
102
+ opsRemainingToProcess: this.deltaManager.inbound.length,
103
+ processingTime: (0, internal_1.formatTick)(this.schedulingLog.totalProcessingTime),
104
+ numberOfTurns: this.schedulingLog.numberOfTurns,
105
+ batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
106
+ timeToResume: (0, internal_1.formatTick)((0, client_utils_1.performanceNow)() - currentTime),
107
+ });
108
+ }
109
+ this.deltaManager.inbound.resume();
110
+ });
111
+ this.processingStartTime = undefined;
112
+ }
113
+ }
114
+ };
115
+ inboundQueueIdle = () => {
116
+ if (this.schedulingLog) {
117
+ // Add the time taken for processing the final ops to the total processing time in the
118
+ // telemetry log object.
119
+ const currentTime = (0, client_utils_1.performanceNow)();
120
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
121
+ this.schedulingLog.totalProcessingTime += currentTime - this.processingStartTime;
122
+ this.logger.sendTelemetryEvent({
123
+ eventName: "InboundOpsProcessingTime",
124
+ opsRemainingToProcess: this.schedulingLog.opsRemainingToProcess,
125
+ numberOfTurns: this.schedulingLog.numberOfTurns,
126
+ processingTime: (0, internal_1.formatTick)(this.schedulingLog.totalProcessingTime),
127
+ opsProcessed: this.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,
128
+ batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
129
+ duration: (0, internal_1.formatTick)(currentTime - this.schedulingLog.startTime),
130
+ schedulingCount: this.schedulingCount,
131
+ });
132
+ this.schedulingLog = undefined;
133
+ }
134
+ // If we scheduled this batch of the inbound queue, increment the counter that tracks the
135
+ // number of times we have done this.
136
+ this.schedulingCount++;
137
+ // Reset the processing times.
138
+ this.processingStartTime = undefined;
139
+ this.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
140
+ };
134
141
  /**
135
142
  * This function tells whether we should run the scheduler.
136
143
  */
@@ -141,6 +148,4 @@ class DeltaScheduler {
141
148
  }
142
149
  }
143
150
  exports.DeltaScheduler = DeltaScheduler;
144
- // The time for processing ops in a single turn.
145
- DeltaScheduler.processingTime = 50;
146
151
  //# sourceMappingURL=deltaScheduler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"deltaScheduler.js","sourceRoot":"","sources":["../src/deltaScheduler.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 { performanceNow, type TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { IDeltaManagerFull } from \"@fluidframework/container-definitions/internal\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport type { IContainerRuntimeBaseEvents } from \"@fluidframework/runtime-definitions/internal\";\nimport { formatTick, type TelemetryLoggerExt } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * DeltaScheduler is responsible for the scheduling of inbound delta queue in cases where there\n * is more than one op a particular run of the queue. It does not schedule if there is just one\n * op or just one batch in the run. It does the following two things:\n *\n * 1. If the ops have been processed for more than a specific amount of time, it pauses the queue\n * and calls setTimeout to schedule a resume of the queue. This ensures that we don't block\n * the JS thread for a long time processing ops synchronously (for example, when catching up\n * ops right after boot or catching up ops / delayed realizing data stores by summarizer).\n *\n * 2. If we scheduled a particular run of the queue, it logs telemetry for the number of ops\n * processed, the time and number of turns it took to process the ops.\n */\nexport class DeltaScheduler {\n\t// The time for processing ops in a single turn.\n\tpublic static readonly processingTime = 50;\n\n\t// The increase in time for processing ops after each turn.\n\tprivate readonly processingTimeIncrement = 10;\n\n\tprivate processingStartTime: number | undefined;\n\tprivate currentAllowedProcessingTimeForTurn: number = DeltaScheduler.processingTime;\n\n\t// This keeps track of the number of times inbound queue has been scheduled. After a particular\n\t// count, we log telemetry for the number of ops processed, the time and number of turns it took\n\t// to process the ops.\n\tprivate schedulingCount: number = 0;\n\n\tprivate schedulingLog:\n\t\t| {\n\t\t\t\topsRemainingToProcess: number;\n\t\t\t\ttotalProcessingTime: number;\n\t\t\t\tnumberOfTurns: number;\n\t\t\t\tnumberOfBatchesProcessed: number;\n\t\t\t\tlastSequenceNumber: number;\n\t\t\t\tfirstSequenceNumber: number;\n\t\t\t\tstartTime: number;\n\t\t }\n\t\t| undefined;\n\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManagerFull,\n\t\tprivate readonly runtimeEventsEmitter: TypedEventEmitter<IContainerRuntimeBaseEvents>,\n\t\tprivate readonly logger: TelemetryLoggerExt,\n\t) {\n\t\tthis.deltaManager.inbound.on(\"idle\", this.inboundQueueIdle);\n\t\truntimeEventsEmitter.on(\"batchBegin\", this.batchBegin);\n\t\truntimeEventsEmitter.on(\"batchEnd\", this.batchEnd);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.deltaManager.inbound.off(\"idle\", this.inboundQueueIdle);\n\t\tthis.runtimeEventsEmitter.off(\"batchBegin\", this.batchBegin);\n\t\tthis.runtimeEventsEmitter.off(\"batchEnd\", this.batchEnd);\n\t}\n\n\tprivate readonly batchBegin = (message: ISequencedDocumentMessage): void => {\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\tif (this.processingStartTime === undefined) {\n\t\t\tthis.processingStartTime = performanceNow();\n\t\t}\n\t\tif (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {\n\t\t\t// Every 500th time we are scheduling the inbound queue, we log telemetry for the\n\t\t\t// number of ops processed, the time and number of turns it took to process the ops.\n\t\t\tthis.schedulingLog = {\n\t\t\t\topsRemainingToProcess: 0,\n\t\t\t\tnumberOfTurns: 1,\n\t\t\t\ttotalProcessingTime: 0,\n\t\t\t\tnumberOfBatchesProcessed: 0,\n\t\t\t\tfirstSequenceNumber: message.sequenceNumber,\n\t\t\t\tlastSequenceNumber: message.sequenceNumber,\n\t\t\t\tstartTime: performanceNow(),\n\t\t\t};\n\t\t}\n\t};\n\n\tprivate readonly batchEnd = (error: unknown, message: ISequencedDocumentMessage): void => {\n\t\tif (this.schedulingLog) {\n\t\t\tthis.schedulingLog.numberOfBatchesProcessed++;\n\t\t\tthis.schedulingLog.lastSequenceNumber = message.sequenceNumber;\n\t\t\tthis.schedulingLog.opsRemainingToProcess = this.deltaManager.inbound.length;\n\t\t}\n\n\t\tif (this.shouldRunScheduler()) {\n\t\t\tconst currentTime = performanceNow();\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst elapsedTime = currentTime - this.processingStartTime!;\n\t\t\tif (elapsedTime > this.currentAllowedProcessingTimeForTurn) {\n\t\t\t\t// We have processed ops for more than the total processing time. So, pause the\n\t\t\t\t// queue, yield the thread and schedule a resume.\n\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\t\t\tthis.deltaManager.inbound.pause();\n\n\t\t\t\t// Increase the total processing time. Keep doing this after each turn until all the ops have\n\t\t\t\t// been processed. This way we keep the responsiveness at the beginning while also making sure\n\t\t\t\t// that all the ops process fairly quickly.\n\t\t\t\tthis.currentAllowedProcessingTimeForTurn += this.processingTimeIncrement;\n\n\t\t\t\t// If we are logging the telemetry this time, update the telemetry log object.\n\t\t\t\tif (this.schedulingLog) {\n\t\t\t\t\tthis.schedulingLog.numberOfTurns++;\n\t\t\t\t\tthis.schedulingLog.totalProcessingTime += elapsedTime;\n\t\t\t\t}\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (this.schedulingLog) {\n\t\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\t\teventName: \"InboundOpsPartialProcessingTime\",\n\t\t\t\t\t\t\tduration: formatTick(elapsedTime),\n\t\t\t\t\t\t\topsProcessed:\n\t\t\t\t\t\t\t\tthis.schedulingLog.lastSequenceNumber -\n\t\t\t\t\t\t\t\tthis.schedulingLog.firstSequenceNumber +\n\t\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\topsRemainingToProcess: this.deltaManager.inbound.length,\n\t\t\t\t\t\t\tprocessingTime: formatTick(this.schedulingLog.totalProcessingTime),\n\t\t\t\t\t\t\tnumberOfTurns: this.schedulingLog.numberOfTurns,\n\t\t\t\t\t\t\tbatchesProcessed: this.schedulingLog.numberOfBatchesProcessed,\n\t\t\t\t\t\t\ttimeToResume: formatTick(performanceNow() - currentTime),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tthis.deltaManager.inbound.resume();\n\t\t\t\t});\n\n\t\t\t\tthis.processingStartTime = undefined;\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate readonly inboundQueueIdle = (): void => {\n\t\tif (this.schedulingLog) {\n\t\t\t// Add the time taken for processing the final ops to the total processing time in the\n\t\t\t// telemetry log object.\n\t\t\tconst currentTime = performanceNow();\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tthis.schedulingLog.totalProcessingTime += currentTime - this.processingStartTime!;\n\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"InboundOpsProcessingTime\",\n\t\t\t\topsRemainingToProcess: this.schedulingLog.opsRemainingToProcess,\n\t\t\t\tnumberOfTurns: this.schedulingLog.numberOfTurns,\n\t\t\t\tprocessingTime: formatTick(this.schedulingLog.totalProcessingTime),\n\t\t\t\topsProcessed:\n\t\t\t\t\tthis.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,\n\t\t\t\tbatchesProcessed: this.schedulingLog.numberOfBatchesProcessed,\n\t\t\t\tduration: formatTick(currentTime - this.schedulingLog.startTime),\n\t\t\t\tschedulingCount: this.schedulingCount,\n\t\t\t});\n\n\t\t\tthis.schedulingLog = undefined;\n\t\t}\n\n\t\t// If we scheduled this batch of the inbound queue, increment the counter that tracks the\n\t\t// number of times we have done this.\n\t\tthis.schedulingCount++;\n\n\t\t// Reset the processing times.\n\t\tthis.processingStartTime = undefined;\n\t\tthis.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;\n\t};\n\n\t/**\n\t * This function tells whether we should run the scheduler.\n\t */\n\tprivate shouldRunScheduler(): boolean {\n\t\t// If there are still ops in the queue after the one we are processing now, we should\n\t\t// run the scheduler.\n\t\treturn this.deltaManager.inbound.length > 0;\n\t}\n}\n"]}
1
+ {"version":3,"file":"deltaScheduler.js","sourceRoot":"","sources":["../src/deltaScheduler.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 { performanceNow, type TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { IDeltaManagerFull } from \"@fluidframework/container-definitions/internal\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport type { IContainerRuntimeBaseEvents } from \"@fluidframework/runtime-definitions/internal\";\nimport { formatTick, type TelemetryLoggerExt } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * DeltaScheduler is responsible for the scheduling of inbound delta queue in cases where there\n * is more than one op a particular run of the queue. It does not schedule if there is just one\n * op or just one batch in the run. It does the following two things:\n *\n * 1. If the ops have been processed for more than a specific amount of time, it pauses the queue\n * and calls setTimeout to schedule a resume of the queue. This ensures that we don't block\n * the JS thread for a long time processing ops synchronously (for example, when catching up\n * ops right after boot or catching up ops / delayed realizing data stores by summarizer).\n *\n * 2. If we scheduled a particular run of the queue, it logs telemetry for the number of ops\n * processed, the time and number of turns it took to process the ops.\n */\nexport class DeltaScheduler {\n\t// The time for processing ops in a single turn.\n\tpublic static readonly processingTime = 50;\n\n\t// The increase in time for processing ops after each turn.\n\tprivate readonly processingTimeIncrement = 10;\n\n\tprivate processingStartTime: number | undefined;\n\tprivate currentAllowedProcessingTimeForTurn: number = DeltaScheduler.processingTime;\n\n\t// This keeps track of the number of times inbound queue has been scheduled. After a particular\n\t// count, we log telemetry for the number of ops processed, the time and number of turns it took\n\t// to process the ops.\n\tprivate schedulingCount: number = 0;\n\n\tprivate schedulingLog:\n\t\t| {\n\t\t\t\topsRemainingToProcess: number;\n\t\t\t\ttotalProcessingTime: number;\n\t\t\t\tnumberOfTurns: number;\n\t\t\t\tnumberOfBatchesProcessed: number;\n\t\t\t\tlastSequenceNumber: number;\n\t\t\t\tfirstSequenceNumber: number;\n\t\t\t\tstartTime: number;\n\t\t }\n\t\t| undefined;\n\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManagerFull,\n\t\tprivate readonly runtimeEventsEmitter: TypedEventEmitter<IContainerRuntimeBaseEvents>,\n\t\tprivate readonly logger: TelemetryLoggerExt,\n\t) {\n\t\tthis.deltaManager.inbound.on(\"idle\", this.inboundQueueIdle);\n\t\truntimeEventsEmitter.on(\"batchBegin\", this.batchBegin);\n\t\truntimeEventsEmitter.on(\"batchEnd\", this.batchEnd);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.deltaManager.inbound.off(\"idle\", this.inboundQueueIdle);\n\t\tthis.runtimeEventsEmitter.off(\"batchBegin\", this.batchBegin);\n\t\tthis.runtimeEventsEmitter.off(\"batchEnd\", this.batchEnd);\n\t}\n\n\tprivate readonly batchBegin = (message: ISequencedDocumentMessage): void => {\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\tif (this.processingStartTime === undefined) {\n\t\t\tthis.processingStartTime = performanceNow();\n\t\t}\n\t\tif (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {\n\t\t\t// Every 500th time we are scheduling the inbound queue, we log telemetry for the\n\t\t\t// number of ops processed, the time and number of turns it took to process the ops.\n\t\t\tthis.schedulingLog = {\n\t\t\t\topsRemainingToProcess: 0,\n\t\t\t\tnumberOfTurns: 1,\n\t\t\t\ttotalProcessingTime: 0,\n\t\t\t\tnumberOfBatchesProcessed: 0,\n\t\t\t\tfirstSequenceNumber: message.sequenceNumber,\n\t\t\t\tlastSequenceNumber: message.sequenceNumber,\n\t\t\t\tstartTime: performanceNow(),\n\t\t\t};\n\t\t}\n\t};\n\n\tprivate readonly batchEnd = (error: unknown, message: ISequencedDocumentMessage): void => {\n\t\tif (this.schedulingLog) {\n\t\t\tthis.schedulingLog.numberOfBatchesProcessed++;\n\t\t\tthis.schedulingLog.lastSequenceNumber = message.sequenceNumber;\n\t\t\tthis.schedulingLog.opsRemainingToProcess = this.deltaManager.inbound.length;\n\t\t}\n\n\t\tif (this.shouldRunScheduler()) {\n\t\t\tconst currentTime = performanceNow();\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst elapsedTime = currentTime - this.processingStartTime!;\n\t\t\tif (elapsedTime > this.currentAllowedProcessingTimeForTurn) {\n\t\t\t\t// We have processed ops for more than the total processing time. So, pause the\n\t\t\t\t// queue, yield the thread and schedule a resume.\n\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\t\t\tthis.deltaManager.inbound.pause();\n\n\t\t\t\t// Increase the total processing time. Keep doing this after each turn until all the ops have\n\t\t\t\t// been processed. This way we keep the responsiveness at the beginning while also making sure\n\t\t\t\t// that all the ops process fairly quickly.\n\t\t\t\tthis.currentAllowedProcessingTimeForTurn += this.processingTimeIncrement;\n\n\t\t\t\t// If we are logging the telemetry this time, update the telemetry log object.\n\t\t\t\tif (this.schedulingLog) {\n\t\t\t\t\tthis.schedulingLog.numberOfTurns++;\n\t\t\t\t\tthis.schedulingLog.totalProcessingTime += elapsedTime;\n\t\t\t\t}\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (this.schedulingLog) {\n\t\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\t\teventName: \"InboundOpsPartialProcessingTime\",\n\t\t\t\t\t\t\tduration: formatTick(elapsedTime),\n\t\t\t\t\t\t\topsProcessed:\n\t\t\t\t\t\t\t\tthis.schedulingLog.lastSequenceNumber -\n\t\t\t\t\t\t\t\tthis.schedulingLog.firstSequenceNumber +\n\t\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\topsRemainingToProcess: this.deltaManager.inbound.length,\n\t\t\t\t\t\t\tprocessingTime: formatTick(this.schedulingLog.totalProcessingTime),\n\t\t\t\t\t\t\tnumberOfTurns: this.schedulingLog.numberOfTurns,\n\t\t\t\t\t\t\tbatchesProcessed: this.schedulingLog.numberOfBatchesProcessed,\n\t\t\t\t\t\t\ttimeToResume: formatTick(performanceNow() - currentTime),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tthis.deltaManager.inbound.resume();\n\t\t\t\t});\n\n\t\t\t\tthis.processingStartTime = undefined;\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate readonly inboundQueueIdle = (): void => {\n\t\tif (this.schedulingLog) {\n\t\t\t// Add the time taken for processing the final ops to the total processing time in the\n\t\t\t// telemetry log object.\n\t\t\tconst currentTime = performanceNow();\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tthis.schedulingLog.totalProcessingTime += currentTime - this.processingStartTime!;\n\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"InboundOpsProcessingTime\",\n\t\t\t\topsRemainingToProcess: this.schedulingLog.opsRemainingToProcess,\n\t\t\t\tnumberOfTurns: this.schedulingLog.numberOfTurns,\n\t\t\t\tprocessingTime: formatTick(this.schedulingLog.totalProcessingTime),\n\t\t\t\topsProcessed:\n\t\t\t\t\tthis.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,\n\t\t\t\tbatchesProcessed: this.schedulingLog.numberOfBatchesProcessed,\n\t\t\t\tduration: formatTick(currentTime - this.schedulingLog.startTime),\n\t\t\t\tschedulingCount: this.schedulingCount,\n\t\t\t});\n\n\t\t\tthis.schedulingLog = undefined;\n\t\t}\n\n\t\t// If we scheduled this batch of the inbound queue, increment the counter that tracks the\n\t\t// number of times we have done this.\n\t\tthis.schedulingCount++;\n\n\t\t// Reset the processing times.\n\t\tthis.processingStartTime = undefined;\n\t\tthis.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;\n\t};\n\n\t/**\n\t * This function tells whether we should run the scheduler.\n\t */\n\tprivate shouldRunScheduler(): boolean {\n\t\t// If there are still ops in the queue after the one we are processing now, we should\n\t\t// run the scheduler.\n\t\treturn this.deltaManager.inbound.length > 0;\n\t}\n}\n"]}
package/dist/error.js CHANGED
@@ -11,10 +11,11 @@ const internal_2 = require("@fluidframework/telemetry-utils/internal");
11
11
  * Error indicating that a client's session has reached its time limit and is closed.
12
12
  */
13
13
  class ClientSessionExpiredError extends internal_2.LoggingError {
14
+ expiryMs;
15
+ errorType = internal_1.ContainerErrorTypes.clientSessionExpiredError;
14
16
  constructor(message, expiryMs) {
15
17
  super(message, { timeoutMs: expiryMs });
16
18
  this.expiryMs = expiryMs;
17
- this.errorType = internal_1.ContainerErrorTypes.clientSessionExpiredError;
18
19
  }
19
20
  }
20
21
  exports.ClientSessionExpiredError = ClientSessionExpiredError;
package/dist/error.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6EAAqF;AACrF,uEAA8F;AAE9F;;GAEG;AACH,MAAa,yBAA0B,SAAQ,uBAAY;IAG1D,YACC,OAAe,EACN,QAAgB;QAEzB,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAF/B,aAAQ,GAAR,QAAQ,CAAQ;QAJjB,cAAS,GAAG,8BAAmB,CAAC,yBAAyB,CAAC;IAOnE,CAAC;CACD;AATD,8DASC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ContainerErrorTypes } from \"@fluidframework/container-definitions/internal\";\nimport { type IFluidErrorBase, LoggingError } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * Error indicating that a client's session has reached its time limit and is closed.\n */\nexport class ClientSessionExpiredError extends LoggingError implements IFluidErrorBase {\n\treadonly errorType = ContainerErrorTypes.clientSessionExpiredError;\n\n\tconstructor(\n\t\tmessage: string,\n\t\treadonly expiryMs: number,\n\t) {\n\t\tsuper(message, { timeoutMs: expiryMs });\n\t}\n}\n"]}
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6EAAqF;AACrF,uEAA8F;AAE9F;;GAEG;AACH,MAAa,yBAA0B,SAAQ,uBAAY;IAKhD;IAJD,SAAS,GAAG,8BAAmB,CAAC,yBAAyB,CAAC;IAEnE,YACC,OAAe,EACN,QAAgB;QAEzB,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAF/B,aAAQ,GAAR,QAAQ,CAAQ;IAG1B,CAAC;CACD;AATD,8DASC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ContainerErrorTypes } from \"@fluidframework/container-definitions/internal\";\nimport { type IFluidErrorBase, LoggingError } from \"@fluidframework/telemetry-utils/internal\";\n\n/**\n * Error indicating that a client's session has reached its time limit and is closed.\n */\nexport class ClientSessionExpiredError extends LoggingError implements IFluidErrorBase {\n\treadonly errorType = ContainerErrorTypes.clientSessionExpiredError;\n\n\tconstructor(\n\t\tmessage: string,\n\t\treadonly expiryMs: number,\n\t) {\n\t\tsuper(message, { timeoutMs: expiryMs });\n\t}\n}\n"]}
@@ -46,12 +46,57 @@ class GarbageCollector {
46
46
  static create(createParams) {
47
47
  return new GarbageCollector(createParams);
48
48
  }
49
+ mc;
50
+ configs;
49
51
  get serializedConfigs() {
50
52
  return JSON.stringify(this.configs);
51
53
  }
52
54
  get shouldRunGC() {
53
55
  return this.configs.gcAllowed;
54
56
  }
57
+ sessionExpiryTimerStarted;
58
+ // Keeps track of the GC state from the last run.
59
+ gcDataFromLastRun;
60
+ // Keeps a list of references (edges in the GC graph) between GC runs. Each entry has a node id and a list of
61
+ // outbound routes from that node.
62
+ newReferencesSinceLastRun = new Map();
63
+ // A list of nodes that have been tombstoned.
64
+ tombstones = [];
65
+ // A list of nodes that have been deleted during sweep phase.
66
+ deletedNodes = new Set();
67
+ // Promise when resolved returns the GC data data in the base snapshot.
68
+ baseSnapshotDataP;
69
+ // Promise when resolved initializes the GC state from the data in the base snapshot.
70
+ initializeGCStateFromBaseSnapshotP;
71
+ // The GC details generated from the base snapshot.
72
+ baseGCDetailsP;
73
+ /**
74
+ * Map of node ids to their unreferenced state tracker
75
+ * NOTE: The set of keys in this map is considered as the set of unreferenced nodes
76
+ * as of the last GC run. So in between runs, nothing should be added or removed.
77
+ */
78
+ unreferencedNodesState = new gcUnreferencedStateTracker_js_1.UnreferencedStateTrackerMap();
79
+ // The Timer responsible for closing the container when the session has expired
80
+ sessionExpiryTimer;
81
+ // The number of times GC has successfully completed on this instance of GarbageCollector.
82
+ completedRuns = 0;
83
+ runtime;
84
+ /**
85
+ * Called when the runtime should close because of an error.
86
+ */
87
+ closeFn;
88
+ isSummarizerClient;
89
+ summaryStateTracker;
90
+ telemetryTracker;
91
+ /**
92
+ * For a given node path, returns the node's package path.
93
+ */
94
+ getNodePackagePath;
95
+ /**
96
+ * Returns the timestamp of the last summary generated for this container.
97
+ */
98
+ getLastSummaryTimestampMs;
99
+ submitMessage;
55
100
  /**
56
101
  * Returns the count of data stores whose GC state updated since the last summary.
57
102
  */
@@ -59,61 +104,6 @@ class GarbageCollector {
59
104
  return this.summaryStateTracker.updatedDSCountSinceLastSummary;
60
105
  }
61
106
  constructor(createParams) {
62
- // Keeps a list of references (edges in the GC graph) between GC runs. Each entry has a node id and a list of
63
- // outbound routes from that node.
64
- this.newReferencesSinceLastRun = new Map();
65
- // A list of nodes that have been tombstoned.
66
- this.tombstones = [];
67
- // A list of nodes that have been deleted during sweep phase.
68
- this.deletedNodes = new Set();
69
- /**
70
- * Map of node ids to their unreferenced state tracker
71
- * NOTE: The set of keys in this map is considered as the set of unreferenced nodes
72
- * as of the last GC run. So in between runs, nothing should be added or removed.
73
- */
74
- this.unreferencedNodesState = new gcUnreferencedStateTracker_js_1.UnreferencedStateTrackerMap();
75
- // The number of times GC has successfully completed on this instance of GarbageCollector.
76
- this.completedRuns = 0;
77
- /**
78
- * API for ensuring the correct auto-recovery mitigations
79
- */
80
- // TODO: consider hoisting this to an outer scope as an optimization
81
- // eslint-disable-next-line unicorn/consistent-function-scoping
82
- this.autoRecovery = (() => {
83
- // This uses a hidden state machine for forcing fullGC as part of auto-recovery,
84
- // to regenerate the GC data for each node.
85
- //
86
- // Once fullGC has been requested, we need to wait until GC has run and the summary has been acked before clearing the state.
87
- //
88
- // States:
89
- // - undefined: No need to run fullGC now.
90
- // - "requested": FullGC requested, but GC has not yet run. Keep using fullGC until back to undefined.
91
- // - "ran": FullGC ran, but the following summary has not yet been acked. Keep using fullGC until back to undefined.
92
- //
93
- // Transitions:
94
- // - autoRecovery.requestFullGCOnNextRun :: [anything] --> "requested"
95
- // - autoRecovery.onCompletedGCRun :: "requested" --> "ran"
96
- // - autoRecovery.onSummaryAck :: "ran" --> undefined
97
- let state;
98
- return {
99
- requestFullGCOnNextRun: () => {
100
- state = "requested";
101
- },
102
- onCompletedGCRun: () => {
103
- if (state === "requested") {
104
- state = "ran";
105
- }
106
- },
107
- onSummaryAck: () => {
108
- if (state === "ran") {
109
- state = undefined;
110
- }
111
- },
112
- useFullGC: () => {
113
- return state !== undefined;
114
- },
115
- };
116
- })();
117
107
  this.runtime = createParams.runtime;
118
108
  this.closeFn = createParams.closeFn;
119
109
  this.isSummarizerClient = createParams.isSummarizerClient;
@@ -241,6 +231,46 @@ class GarbageCollector {
241
231
  return { gcData: { gcNodes }, usedRoutes };
242
232
  });
243
233
  }
234
+ /**
235
+ * API for ensuring the correct auto-recovery mitigations
236
+ */
237
+ // TODO: consider hoisting this to an outer scope as an optimization
238
+ // eslint-disable-next-line unicorn/consistent-function-scoping
239
+ autoRecovery = (() => {
240
+ // This uses a hidden state machine for forcing fullGC as part of auto-recovery,
241
+ // to regenerate the GC data for each node.
242
+ //
243
+ // Once fullGC has been requested, we need to wait until GC has run and the summary has been acked before clearing the state.
244
+ //
245
+ // States:
246
+ // - undefined: No need to run fullGC now.
247
+ // - "requested": FullGC requested, but GC has not yet run. Keep using fullGC until back to undefined.
248
+ // - "ran": FullGC ran, but the following summary has not yet been acked. Keep using fullGC until back to undefined.
249
+ //
250
+ // Transitions:
251
+ // - autoRecovery.requestFullGCOnNextRun :: [anything] --> "requested"
252
+ // - autoRecovery.onCompletedGCRun :: "requested" --> "ran"
253
+ // - autoRecovery.onSummaryAck :: "ran" --> undefined
254
+ let state;
255
+ return {
256
+ requestFullGCOnNextRun: () => {
257
+ state = "requested";
258
+ },
259
+ onCompletedGCRun: () => {
260
+ if (state === "requested") {
261
+ state = "ran";
262
+ }
263
+ },
264
+ onSummaryAck: () => {
265
+ if (state === "ran") {
266
+ state = undefined;
267
+ }
268
+ },
269
+ useFullGC: () => {
270
+ return state !== undefined;
271
+ },
272
+ };
273
+ })();
244
274
  /**
245
275
  * Called during container initialization. Initializes the tombstone and deleted nodes state from the base snapshot.
246
276
  * Also, initializes the GC state including unreferenced nodes tracking if a current reference timestamp exists.