@fluidframework/container-runtime 2.118.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 +68 -4
  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 -157
  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
@@ -8,6 +8,7 @@ import { UsageError } from "@fluidframework/telemetry-utils/internal";
8
8
  * @internal
9
9
  */
10
10
  export class FluidDataStoreRegistry {
11
+ map;
11
12
  get IFluidDataStoreRegistry() {
12
13
  return this;
13
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dataStoreRegistry.js","sourceRoot":"","sources":["../src/dataStoreRegistry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAMpE,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAEtE;;GAEG;AACH,MAAM,OAAO,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,UAAU,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,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACd,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;CACD","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,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAMpE,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAEtE;;GAEG;AACH,MAAM,OAAO,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,UAAU,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,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACd,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;CACD","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"]}
@@ -11,6 +11,7 @@ import { summarizerClientType } from "./summary/index.js";
11
11
  * of the DeltaManager.
12
12
  */
13
13
  export class BaseDeltaManagerProxy extends TypedEventEmitter {
14
+ deltaManager;
14
15
  get IDeltaSender() {
15
16
  return this;
16
17
  }
@@ -59,6 +60,7 @@ export class BaseDeltaManagerProxy extends TypedEventEmitter {
59
60
  get readOnlyInfo() {
60
61
  return this.deltaManager.readOnlyInfo;
61
62
  }
63
+ eventHandlers;
62
64
  constructor(deltaManager, overrides) {
63
65
  super();
64
66
  this.deltaManager = deltaManager;
@@ -119,6 +121,7 @@ export class BaseDeltaManagerProxy extends TypedEventEmitter {
119
121
  * - Summarizer client should not be active to layers below the container runtime to restrict local changes.
120
122
  */
121
123
  export class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {
124
+ deltaManager;
122
125
  static wrapIfSummarizer(deltaManager) {
123
126
  if (deltaManager.clientDetails.type === summarizerClientType) {
124
127
  return new DeltaManagerSummarizerProxy(deltaManager);
@@ -147,6 +150,8 @@ export class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {
147
150
  }
148
151
  }
149
152
  export class DeltaManagerPendingOpsProxy extends BaseDeltaManagerProxy {
153
+ deltaManager;
154
+ pendingStateManager;
150
155
  get minimumSequenceNumber() {
151
156
  const minPendingSeqNum = this.pendingStateManager.minimumPendingMessageSequenceNumber;
152
157
  /**
@@ -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"]}
@@ -18,107 +18,24 @@ import { formatTick } from "@fluidframework/telemetry-utils/internal";
18
18
  * processed, the time and number of turns it took to process the ops.
19
19
  */
20
20
  export class DeltaScheduler {
21
+ deltaManager;
22
+ runtimeEventsEmitter;
23
+ logger;
24
+ // The time for processing ops in a single turn.
25
+ static processingTime = 50;
26
+ // The increase in time for processing ops after each turn.
27
+ processingTimeIncrement = 10;
28
+ processingStartTime;
29
+ currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
30
+ // This keeps track of the number of times inbound queue has been scheduled. After a particular
31
+ // count, we log telemetry for the number of ops processed, the time and number of turns it took
32
+ // to process the ops.
33
+ schedulingCount = 0;
34
+ schedulingLog;
21
35
  constructor(deltaManager, runtimeEventsEmitter, logger) {
22
36
  this.deltaManager = deltaManager;
23
37
  this.runtimeEventsEmitter = runtimeEventsEmitter;
24
38
  this.logger = logger;
25
- // The increase in time for processing ops after each turn.
26
- this.processingTimeIncrement = 10;
27
- this.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
28
- // This keeps track of the number of times inbound queue has been scheduled. After a particular
29
- // count, we log telemetry for the number of ops processed, the time and number of turns it took
30
- // to process the ops.
31
- this.schedulingCount = 0;
32
- this.batchBegin = (message) => {
33
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
34
- if (this.processingStartTime === undefined) {
35
- this.processingStartTime = performanceNow();
36
- }
37
- if (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {
38
- // Every 500th time we are scheduling the inbound queue, we log telemetry for the
39
- // number of ops processed, the time and number of turns it took to process the ops.
40
- this.schedulingLog = {
41
- opsRemainingToProcess: 0,
42
- numberOfTurns: 1,
43
- totalProcessingTime: 0,
44
- numberOfBatchesProcessed: 0,
45
- firstSequenceNumber: message.sequenceNumber,
46
- lastSequenceNumber: message.sequenceNumber,
47
- startTime: performanceNow(),
48
- };
49
- }
50
- };
51
- this.batchEnd = (error, message) => {
52
- if (this.schedulingLog) {
53
- this.schedulingLog.numberOfBatchesProcessed++;
54
- this.schedulingLog.lastSequenceNumber = message.sequenceNumber;
55
- this.schedulingLog.opsRemainingToProcess = this.deltaManager.inbound.length;
56
- }
57
- if (this.shouldRunScheduler()) {
58
- const currentTime = performanceNow();
59
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
60
- const elapsedTime = currentTime - this.processingStartTime;
61
- if (elapsedTime > this.currentAllowedProcessingTimeForTurn) {
62
- // We have processed ops for more than the total processing time. So, pause the
63
- // queue, yield the thread and schedule a resume.
64
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
65
- this.deltaManager.inbound.pause();
66
- // Increase the total processing time. Keep doing this after each turn until all the ops have
67
- // been processed. This way we keep the responsiveness at the beginning while also making sure
68
- // that all the ops process fairly quickly.
69
- this.currentAllowedProcessingTimeForTurn += this.processingTimeIncrement;
70
- // If we are logging the telemetry this time, update the telemetry log object.
71
- if (this.schedulingLog) {
72
- this.schedulingLog.numberOfTurns++;
73
- this.schedulingLog.totalProcessingTime += elapsedTime;
74
- }
75
- setTimeout(() => {
76
- if (this.schedulingLog) {
77
- this.logger.sendTelemetryEvent({
78
- eventName: "InboundOpsPartialProcessingTime",
79
- duration: formatTick(elapsedTime),
80
- opsProcessed: this.schedulingLog.lastSequenceNumber -
81
- this.schedulingLog.firstSequenceNumber +
82
- 1,
83
- opsRemainingToProcess: this.deltaManager.inbound.length,
84
- processingTime: formatTick(this.schedulingLog.totalProcessingTime),
85
- numberOfTurns: this.schedulingLog.numberOfTurns,
86
- batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
87
- timeToResume: formatTick(performanceNow() - currentTime),
88
- });
89
- }
90
- this.deltaManager.inbound.resume();
91
- });
92
- this.processingStartTime = undefined;
93
- }
94
- }
95
- };
96
- this.inboundQueueIdle = () => {
97
- if (this.schedulingLog) {
98
- // Add the time taken for processing the final ops to the total processing time in the
99
- // telemetry log object.
100
- const currentTime = performanceNow();
101
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
102
- this.schedulingLog.totalProcessingTime += currentTime - this.processingStartTime;
103
- this.logger.sendTelemetryEvent({
104
- eventName: "InboundOpsProcessingTime",
105
- opsRemainingToProcess: this.schedulingLog.opsRemainingToProcess,
106
- numberOfTurns: this.schedulingLog.numberOfTurns,
107
- processingTime: formatTick(this.schedulingLog.totalProcessingTime),
108
- opsProcessed: this.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,
109
- batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
110
- duration: formatTick(currentTime - this.schedulingLog.startTime),
111
- schedulingCount: this.schedulingCount,
112
- });
113
- this.schedulingLog = undefined;
114
- }
115
- // If we scheduled this batch of the inbound queue, increment the counter that tracks the
116
- // number of times we have done this.
117
- this.schedulingCount++;
118
- // Reset the processing times.
119
- this.processingStartTime = undefined;
120
- this.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
121
- };
122
39
  this.deltaManager.inbound.on("idle", this.inboundQueueIdle);
123
40
  runtimeEventsEmitter.on("batchBegin", this.batchBegin);
124
41
  runtimeEventsEmitter.on("batchEnd", this.batchEnd);
@@ -128,6 +45,96 @@ export class DeltaScheduler {
128
45
  this.runtimeEventsEmitter.off("batchBegin", this.batchBegin);
129
46
  this.runtimeEventsEmitter.off("batchEnd", this.batchEnd);
130
47
  }
48
+ batchBegin = (message) => {
49
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
50
+ if (this.processingStartTime === undefined) {
51
+ this.processingStartTime = performanceNow();
52
+ }
53
+ if (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {
54
+ // Every 500th time we are scheduling the inbound queue, we log telemetry for the
55
+ // number of ops processed, the time and number of turns it took to process the ops.
56
+ this.schedulingLog = {
57
+ opsRemainingToProcess: 0,
58
+ numberOfTurns: 1,
59
+ totalProcessingTime: 0,
60
+ numberOfBatchesProcessed: 0,
61
+ firstSequenceNumber: message.sequenceNumber,
62
+ lastSequenceNumber: message.sequenceNumber,
63
+ startTime: performanceNow(),
64
+ };
65
+ }
66
+ };
67
+ batchEnd = (error, message) => {
68
+ if (this.schedulingLog) {
69
+ this.schedulingLog.numberOfBatchesProcessed++;
70
+ this.schedulingLog.lastSequenceNumber = message.sequenceNumber;
71
+ this.schedulingLog.opsRemainingToProcess = this.deltaManager.inbound.length;
72
+ }
73
+ if (this.shouldRunScheduler()) {
74
+ const currentTime = performanceNow();
75
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
76
+ const elapsedTime = currentTime - this.processingStartTime;
77
+ if (elapsedTime > this.currentAllowedProcessingTimeForTurn) {
78
+ // We have processed ops for more than the total processing time. So, pause the
79
+ // queue, yield the thread and schedule a resume.
80
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
81
+ this.deltaManager.inbound.pause();
82
+ // Increase the total processing time. Keep doing this after each turn until all the ops have
83
+ // been processed. This way we keep the responsiveness at the beginning while also making sure
84
+ // that all the ops process fairly quickly.
85
+ this.currentAllowedProcessingTimeForTurn += this.processingTimeIncrement;
86
+ // If we are logging the telemetry this time, update the telemetry log object.
87
+ if (this.schedulingLog) {
88
+ this.schedulingLog.numberOfTurns++;
89
+ this.schedulingLog.totalProcessingTime += elapsedTime;
90
+ }
91
+ setTimeout(() => {
92
+ if (this.schedulingLog) {
93
+ this.logger.sendTelemetryEvent({
94
+ eventName: "InboundOpsPartialProcessingTime",
95
+ duration: formatTick(elapsedTime),
96
+ opsProcessed: this.schedulingLog.lastSequenceNumber -
97
+ this.schedulingLog.firstSequenceNumber +
98
+ 1,
99
+ opsRemainingToProcess: this.deltaManager.inbound.length,
100
+ processingTime: formatTick(this.schedulingLog.totalProcessingTime),
101
+ numberOfTurns: this.schedulingLog.numberOfTurns,
102
+ batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
103
+ timeToResume: formatTick(performanceNow() - currentTime),
104
+ });
105
+ }
106
+ this.deltaManager.inbound.resume();
107
+ });
108
+ this.processingStartTime = undefined;
109
+ }
110
+ }
111
+ };
112
+ inboundQueueIdle = () => {
113
+ if (this.schedulingLog) {
114
+ // Add the time taken for processing the final ops to the total processing time in the
115
+ // telemetry log object.
116
+ const currentTime = performanceNow();
117
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
118
+ this.schedulingLog.totalProcessingTime += currentTime - this.processingStartTime;
119
+ this.logger.sendTelemetryEvent({
120
+ eventName: "InboundOpsProcessingTime",
121
+ opsRemainingToProcess: this.schedulingLog.opsRemainingToProcess,
122
+ numberOfTurns: this.schedulingLog.numberOfTurns,
123
+ processingTime: formatTick(this.schedulingLog.totalProcessingTime),
124
+ opsProcessed: this.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,
125
+ batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
126
+ duration: formatTick(currentTime - this.schedulingLog.startTime),
127
+ schedulingCount: this.schedulingCount,
128
+ });
129
+ this.schedulingLog = undefined;
130
+ }
131
+ // If we scheduled this batch of the inbound queue, increment the counter that tracks the
132
+ // number of times we have done this.
133
+ this.schedulingCount++;
134
+ // Reset the processing times.
135
+ this.processingStartTime = undefined;
136
+ this.currentAllowedProcessingTimeForTurn = DeltaScheduler.processingTime;
137
+ };
131
138
  /**
132
139
  * This function tells whether we should run the scheduler.
133
140
  */
@@ -137,6 +144,4 @@ export class DeltaScheduler {
137
144
  return this.deltaManager.inbound.length > 0;
138
145
  }
139
146
  }
140
- // The time for processing ops in a single turn.
141
- DeltaScheduler.processingTime = 50;
142
147
  //# 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/lib/error.js CHANGED
@@ -8,10 +8,11 @@ import { LoggingError } from "@fluidframework/telemetry-utils/internal";
8
8
  * Error indicating that a client's session has reached its time limit and is closed.
9
9
  */
10
10
  export class ClientSessionExpiredError extends LoggingError {
11
+ expiryMs;
12
+ errorType = ContainerErrorTypes.clientSessionExpiredError;
11
13
  constructor(message, expiryMs) {
12
14
  super(message, { timeoutMs: expiryMs });
13
15
  this.expiryMs = expiryMs;
14
- this.errorType = ContainerErrorTypes.clientSessionExpiredError;
15
16
  }
16
17
  }
17
18
  //# sourceMappingURL=error.js.map
package/lib/error.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,gDAAgD,CAAC;AACrF,OAAO,EAAwB,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAE9F;;GAEG;AACH,MAAM,OAAO,yBAA0B,SAAQ,YAAY;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,mBAAmB,CAAC,yBAAyB,CAAC;IAOnE,CAAC;CACD","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,OAAO,EAAE,mBAAmB,EAAE,MAAM,gDAAgD,CAAC;AACrF,OAAO,EAAwB,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAE9F;;GAEG;AACH,MAAM,OAAO,yBAA0B,SAAQ,YAAY;IAKhD;IAJD,SAAS,GAAG,mBAAmB,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","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"]}
@@ -43,12 +43,57 @@ export class GarbageCollector {
43
43
  static create(createParams) {
44
44
  return new GarbageCollector(createParams);
45
45
  }
46
+ mc;
47
+ configs;
46
48
  get serializedConfigs() {
47
49
  return JSON.stringify(this.configs);
48
50
  }
49
51
  get shouldRunGC() {
50
52
  return this.configs.gcAllowed;
51
53
  }
54
+ sessionExpiryTimerStarted;
55
+ // Keeps track of the GC state from the last run.
56
+ gcDataFromLastRun;
57
+ // Keeps a list of references (edges in the GC graph) between GC runs. Each entry has a node id and a list of
58
+ // outbound routes from that node.
59
+ newReferencesSinceLastRun = new Map();
60
+ // A list of nodes that have been tombstoned.
61
+ tombstones = [];
62
+ // A list of nodes that have been deleted during sweep phase.
63
+ deletedNodes = new Set();
64
+ // Promise when resolved returns the GC data data in the base snapshot.
65
+ baseSnapshotDataP;
66
+ // Promise when resolved initializes the GC state from the data in the base snapshot.
67
+ initializeGCStateFromBaseSnapshotP;
68
+ // The GC details generated from the base snapshot.
69
+ baseGCDetailsP;
70
+ /**
71
+ * Map of node ids to their unreferenced state tracker
72
+ * NOTE: The set of keys in this map is considered as the set of unreferenced nodes
73
+ * as of the last GC run. So in between runs, nothing should be added or removed.
74
+ */
75
+ unreferencedNodesState = new UnreferencedStateTrackerMap();
76
+ // The Timer responsible for closing the container when the session has expired
77
+ sessionExpiryTimer;
78
+ // The number of times GC has successfully completed on this instance of GarbageCollector.
79
+ completedRuns = 0;
80
+ runtime;
81
+ /**
82
+ * Called when the runtime should close because of an error.
83
+ */
84
+ closeFn;
85
+ isSummarizerClient;
86
+ summaryStateTracker;
87
+ telemetryTracker;
88
+ /**
89
+ * For a given node path, returns the node's package path.
90
+ */
91
+ getNodePackagePath;
92
+ /**
93
+ * Returns the timestamp of the last summary generated for this container.
94
+ */
95
+ getLastSummaryTimestampMs;
96
+ submitMessage;
52
97
  /**
53
98
  * Returns the count of data stores whose GC state updated since the last summary.
54
99
  */
@@ -56,61 +101,6 @@ export class GarbageCollector {
56
101
  return this.summaryStateTracker.updatedDSCountSinceLastSummary;
57
102
  }
58
103
  constructor(createParams) {
59
- // Keeps a list of references (edges in the GC graph) between GC runs. Each entry has a node id and a list of
60
- // outbound routes from that node.
61
- this.newReferencesSinceLastRun = new Map();
62
- // A list of nodes that have been tombstoned.
63
- this.tombstones = [];
64
- // A list of nodes that have been deleted during sweep phase.
65
- this.deletedNodes = new Set();
66
- /**
67
- * Map of node ids to their unreferenced state tracker
68
- * NOTE: The set of keys in this map is considered as the set of unreferenced nodes
69
- * as of the last GC run. So in between runs, nothing should be added or removed.
70
- */
71
- this.unreferencedNodesState = new UnreferencedStateTrackerMap();
72
- // The number of times GC has successfully completed on this instance of GarbageCollector.
73
- this.completedRuns = 0;
74
- /**
75
- * API for ensuring the correct auto-recovery mitigations
76
- */
77
- // TODO: consider hoisting this to an outer scope as an optimization
78
- // eslint-disable-next-line unicorn/consistent-function-scoping
79
- this.autoRecovery = (() => {
80
- // This uses a hidden state machine for forcing fullGC as part of auto-recovery,
81
- // to regenerate the GC data for each node.
82
- //
83
- // Once fullGC has been requested, we need to wait until GC has run and the summary has been acked before clearing the state.
84
- //
85
- // States:
86
- // - undefined: No need to run fullGC now.
87
- // - "requested": FullGC requested, but GC has not yet run. Keep using fullGC until back to undefined.
88
- // - "ran": FullGC ran, but the following summary has not yet been acked. Keep using fullGC until back to undefined.
89
- //
90
- // Transitions:
91
- // - autoRecovery.requestFullGCOnNextRun :: [anything] --> "requested"
92
- // - autoRecovery.onCompletedGCRun :: "requested" --> "ran"
93
- // - autoRecovery.onSummaryAck :: "ran" --> undefined
94
- let state;
95
- return {
96
- requestFullGCOnNextRun: () => {
97
- state = "requested";
98
- },
99
- onCompletedGCRun: () => {
100
- if (state === "requested") {
101
- state = "ran";
102
- }
103
- },
104
- onSummaryAck: () => {
105
- if (state === "ran") {
106
- state = undefined;
107
- }
108
- },
109
- useFullGC: () => {
110
- return state !== undefined;
111
- },
112
- };
113
- })();
114
104
  this.runtime = createParams.runtime;
115
105
  this.closeFn = createParams.closeFn;
116
106
  this.isSummarizerClient = createParams.isSummarizerClient;
@@ -238,6 +228,46 @@ export class GarbageCollector {
238
228
  return { gcData: { gcNodes }, usedRoutes };
239
229
  });
240
230
  }
231
+ /**
232
+ * API for ensuring the correct auto-recovery mitigations
233
+ */
234
+ // TODO: consider hoisting this to an outer scope as an optimization
235
+ // eslint-disable-next-line unicorn/consistent-function-scoping
236
+ autoRecovery = (() => {
237
+ // This uses a hidden state machine for forcing fullGC as part of auto-recovery,
238
+ // to regenerate the GC data for each node.
239
+ //
240
+ // Once fullGC has been requested, we need to wait until GC has run and the summary has been acked before clearing the state.
241
+ //
242
+ // States:
243
+ // - undefined: No need to run fullGC now.
244
+ // - "requested": FullGC requested, but GC has not yet run. Keep using fullGC until back to undefined.
245
+ // - "ran": FullGC ran, but the following summary has not yet been acked. Keep using fullGC until back to undefined.
246
+ //
247
+ // Transitions:
248
+ // - autoRecovery.requestFullGCOnNextRun :: [anything] --> "requested"
249
+ // - autoRecovery.onCompletedGCRun :: "requested" --> "ran"
250
+ // - autoRecovery.onSummaryAck :: "ran" --> undefined
251
+ let state;
252
+ return {
253
+ requestFullGCOnNextRun: () => {
254
+ state = "requested";
255
+ },
256
+ onCompletedGCRun: () => {
257
+ if (state === "requested") {
258
+ state = "ran";
259
+ }
260
+ },
261
+ onSummaryAck: () => {
262
+ if (state === "ran") {
263
+ state = undefined;
264
+ }
265
+ },
266
+ useFullGC: () => {
267
+ return state !== undefined;
268
+ },
269
+ };
270
+ })();
241
271
  /**
242
272
  * Called during container initialization. Initializes the tombstone and deleted nodes state from the base snapshot.
243
273
  * Also, initializes the GC state including unreferenced nodes tracking if a current reference timestamp exists.