@fluidframework/container-runtime 2.0.0-internal.3.0.2 → 2.0.0-internal.3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (474) hide show
  1. package/.eslintrc.js +19 -19
  2. package/.mocharc.js +2 -2
  3. package/api-extractor.json +2 -2
  4. package/dist/batchTracker.d.ts.map +1 -1
  5. package/dist/batchTracker.js +2 -1
  6. package/dist/batchTracker.js.map +1 -1
  7. package/dist/blobManager.d.ts +15 -2
  8. package/dist/blobManager.d.ts.map +1 -1
  9. package/dist/blobManager.js +109 -37
  10. package/dist/blobManager.js.map +1 -1
  11. package/dist/connectionTelemetry.d.ts.map +1 -1
  12. package/dist/connectionTelemetry.js +11 -9
  13. package/dist/connectionTelemetry.js.map +1 -1
  14. package/dist/containerHandleContext.d.ts.map +1 -1
  15. package/dist/containerHandleContext.js +3 -1
  16. package/dist/containerHandleContext.js.map +1 -1
  17. package/dist/containerRuntime.d.ts +23 -11
  18. package/dist/containerRuntime.d.ts.map +1 -1
  19. package/dist/containerRuntime.js +225 -132
  20. package/dist/containerRuntime.js.map +1 -1
  21. package/dist/dataStore.d.ts.map +1 -1
  22. package/dist/dataStore.js +11 -9
  23. package/dist/dataStore.js.map +1 -1
  24. package/dist/dataStoreContext.d.ts +27 -13
  25. package/dist/dataStoreContext.d.ts.map +1 -1
  26. package/dist/dataStoreContext.js +95 -56
  27. package/dist/dataStoreContext.js.map +1 -1
  28. package/dist/dataStoreContexts.d.ts.map +1 -1
  29. package/dist/dataStoreContexts.js +7 -3
  30. package/dist/dataStoreContexts.js.map +1 -1
  31. package/dist/dataStoreRegistry.d.ts.map +1 -1
  32. package/dist/dataStoreRegistry.js +3 -1
  33. package/dist/dataStoreRegistry.js.map +1 -1
  34. package/dist/dataStores.d.ts +28 -4
  35. package/dist/dataStores.d.ts.map +1 -1
  36. package/dist/dataStores.js +122 -44
  37. package/dist/dataStores.js.map +1 -1
  38. package/dist/deltaScheduler.d.ts.map +1 -1
  39. package/dist/deltaScheduler.js +8 -3
  40. package/dist/deltaScheduler.js.map +1 -1
  41. package/dist/{garbageCollection.d.ts → gc/garbageCollection.d.ts} +27 -203
  42. package/dist/gc/garbageCollection.d.ts.map +1 -0
  43. package/dist/{garbageCollection.js → gc/garbageCollection.js} +210 -400
  44. package/dist/gc/garbageCollection.js.map +1 -0
  45. package/dist/gc/gcDefinitions.d.ts +189 -0
  46. package/dist/gc/gcDefinitions.d.ts.map +1 -0
  47. package/dist/{garbageCollectionConstants.js → gc/gcDefinitions.js} +27 -2
  48. package/dist/gc/gcDefinitions.js.map +1 -0
  49. package/dist/gc/gcHelpers.d.ts +30 -0
  50. package/dist/gc/gcHelpers.d.ts.map +1 -0
  51. package/dist/gc/gcHelpers.js +65 -0
  52. package/dist/gc/gcHelpers.js.map +1 -0
  53. package/dist/gc/gcSummaryStateTracker.d.ts +86 -0
  54. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
  55. package/dist/gc/gcSummaryStateTracker.js +246 -0
  56. package/dist/gc/gcSummaryStateTracker.js.map +1 -0
  57. package/{lib → dist/gc}/gcSweepReadyUsageDetection.d.ts +5 -5
  58. package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  59. package/dist/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +15 -11
  60. package/dist/gc/gcSweepReadyUsageDetection.js.map +1 -0
  61. package/dist/gc/gcUnreferencedStateTracker.d.ts +34 -0
  62. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  63. package/dist/gc/gcUnreferencedStateTracker.js +94 -0
  64. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -0
  65. package/dist/gc/index.d.ts +11 -0
  66. package/dist/gc/index.d.ts.map +1 -0
  67. package/dist/gc/index.js +40 -0
  68. package/dist/gc/index.js.map +1 -0
  69. package/dist/index.d.ts +2 -5
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +6 -9
  72. package/dist/index.js.map +1 -1
  73. package/dist/opLifecycle/batchManager.d.ts +2 -13
  74. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  75. package/dist/opLifecycle/batchManager.js +19 -41
  76. package/dist/opLifecycle/batchManager.js.map +1 -1
  77. package/dist/opLifecycle/definitions.d.ts +4 -0
  78. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  79. package/dist/opLifecycle/definitions.js.map +1 -1
  80. package/dist/opLifecycle/index.d.ts.map +1 -1
  81. package/dist/opLifecycle/index.js.map +1 -1
  82. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  83. package/dist/opLifecycle/opCompressor.js +1 -0
  84. package/dist/opLifecycle/opCompressor.js.map +1 -1
  85. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  86. package/dist/opLifecycle/opDecompressor.js +5 -2
  87. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  88. package/dist/opLifecycle/opSplitter.d.ts +1 -1
  89. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  90. package/dist/opLifecycle/opSplitter.js +24 -13
  91. package/dist/opLifecycle/opSplitter.js.map +1 -1
  92. package/dist/opLifecycle/outbox.d.ts +19 -3
  93. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  94. package/dist/opLifecycle/outbox.js +78 -45
  95. package/dist/opLifecycle/outbox.js.map +1 -1
  96. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  97. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  98. package/dist/opProperties.d.ts.map +1 -1
  99. package/dist/opProperties.js +1 -3
  100. package/dist/opProperties.js.map +1 -1
  101. package/dist/packageVersion.d.ts +1 -1
  102. package/dist/packageVersion.js +1 -1
  103. package/dist/packageVersion.js.map +1 -1
  104. package/dist/pendingStateManager.d.ts +8 -2
  105. package/dist/pendingStateManager.d.ts.map +1 -1
  106. package/dist/pendingStateManager.js +21 -13
  107. package/dist/pendingStateManager.js.map +1 -1
  108. package/dist/scheduleManager.d.ts.map +1 -1
  109. package/dist/scheduleManager.js +3 -2
  110. package/dist/scheduleManager.js.map +1 -1
  111. package/dist/serializedSnapshotStorage.d.ts +2 -2
  112. package/dist/serializedSnapshotStorage.d.ts.map +1 -1
  113. package/dist/serializedSnapshotStorage.js +5 -3
  114. package/dist/serializedSnapshotStorage.js.map +1 -1
  115. package/dist/summary/index.d.ts +17 -0
  116. package/dist/summary/index.d.ts.map +1 -0
  117. package/dist/summary/index.js +47 -0
  118. package/dist/summary/index.js.map +1 -0
  119. package/dist/summary/orderedClientElection.d.ts.map +1 -0
  120. package/dist/{orderedClientElection.js → summary/orderedClientElection.js} +10 -4
  121. package/dist/summary/orderedClientElection.js.map +1 -0
  122. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  123. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -0
  124. package/{lib → dist/summary}/runningSummarizer.d.ts +19 -18
  125. package/dist/summary/runningSummarizer.d.ts.map +1 -0
  126. package/dist/{runningSummarizer.js → summary/runningSummarizer.js} +191 -76
  127. package/dist/summary/runningSummarizer.js.map +1 -0
  128. package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +4 -6
  129. package/dist/summary/summarizer.d.ts.map +1 -0
  130. package/dist/{summarizer.js → summary/summarizer.js} +31 -71
  131. package/dist/summary/summarizer.js.map +1 -0
  132. package/dist/summary/summarizerClientElection.d.ts.map +1 -0
  133. package/dist/summary/summarizerClientElection.js.map +1 -0
  134. package/dist/summary/summarizerHandle.d.ts.map +1 -0
  135. package/dist/summary/summarizerHandle.js.map +1 -0
  136. package/{lib → dist/summary}/summarizerHeuristics.d.ts +1 -1
  137. package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
  138. package/dist/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -9
  139. package/dist/summary/summarizerHeuristics.js.map +1 -0
  140. package/{lib → dist/summary}/summarizerTypes.d.ts +22 -22
  141. package/dist/summary/summarizerTypes.d.ts.map +1 -0
  142. package/dist/summary/summarizerTypes.js.map +1 -0
  143. package/dist/summary/summaryCollection.d.ts.map +1 -0
  144. package/dist/{summaryCollection.js → summary/summaryCollection.js} +18 -8
  145. package/dist/summary/summaryCollection.js.map +1 -0
  146. package/{lib → dist/summary}/summaryFormat.d.ts +1 -40
  147. package/dist/summary/summaryFormat.d.ts.map +1 -0
  148. package/dist/{summaryFormat.js → summary/summaryFormat.js} +19 -20
  149. package/dist/summary/summaryFormat.js.map +1 -0
  150. package/dist/summary/summaryGenerator.d.ts.map +1 -0
  151. package/dist/{summaryGenerator.js → summary/summaryGenerator.js} +33 -15
  152. package/dist/summary/summaryGenerator.js.map +1 -0
  153. package/dist/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
  154. package/dist/summary/summaryManager.d.ts.map +1 -0
  155. package/dist/{summaryManager.js → summary/summaryManager.js} +21 -9
  156. package/dist/summary/summaryManager.js.map +1 -0
  157. package/dist/throttler.d.ts +2 -2
  158. package/dist/throttler.d.ts.map +1 -1
  159. package/dist/throttler.js +4 -4
  160. package/dist/throttler.js.map +1 -1
  161. package/lib/batchTracker.d.ts.map +1 -1
  162. package/lib/batchTracker.js +2 -1
  163. package/lib/batchTracker.js.map +1 -1
  164. package/lib/blobManager.d.ts +15 -2
  165. package/lib/blobManager.d.ts.map +1 -1
  166. package/lib/blobManager.js +109 -37
  167. package/lib/blobManager.js.map +1 -1
  168. package/lib/connectionTelemetry.d.ts.map +1 -1
  169. package/lib/connectionTelemetry.js +11 -9
  170. package/lib/connectionTelemetry.js.map +1 -1
  171. package/lib/containerHandleContext.d.ts.map +1 -1
  172. package/lib/containerHandleContext.js +3 -1
  173. package/lib/containerHandleContext.js.map +1 -1
  174. package/lib/containerRuntime.d.ts +23 -11
  175. package/lib/containerRuntime.d.ts.map +1 -1
  176. package/lib/containerRuntime.js +201 -108
  177. package/lib/containerRuntime.js.map +1 -1
  178. package/lib/dataStore.d.ts.map +1 -1
  179. package/lib/dataStore.js +11 -9
  180. package/lib/dataStore.js.map +1 -1
  181. package/lib/dataStoreContext.d.ts +27 -13
  182. package/lib/dataStoreContext.d.ts.map +1 -1
  183. package/lib/dataStoreContext.js +84 -45
  184. package/lib/dataStoreContext.js.map +1 -1
  185. package/lib/dataStoreContexts.d.ts.map +1 -1
  186. package/lib/dataStoreContexts.js +7 -3
  187. package/lib/dataStoreContexts.js.map +1 -1
  188. package/lib/dataStoreRegistry.d.ts.map +1 -1
  189. package/lib/dataStoreRegistry.js +3 -1
  190. package/lib/dataStoreRegistry.js.map +1 -1
  191. package/lib/dataStores.d.ts +28 -4
  192. package/lib/dataStores.d.ts.map +1 -1
  193. package/lib/dataStores.js +120 -42
  194. package/lib/dataStores.js.map +1 -1
  195. package/lib/deltaScheduler.d.ts.map +1 -1
  196. package/lib/deltaScheduler.js +9 -4
  197. package/lib/deltaScheduler.js.map +1 -1
  198. package/lib/{garbageCollection.d.ts → gc/garbageCollection.d.ts} +27 -203
  199. package/lib/gc/garbageCollection.d.ts.map +1 -0
  200. package/lib/{garbageCollection.js → gc/garbageCollection.js} +190 -379
  201. package/lib/gc/garbageCollection.js.map +1 -0
  202. package/lib/gc/gcDefinitions.d.ts +189 -0
  203. package/lib/gc/gcDefinitions.d.ts.map +1 -0
  204. package/lib/{garbageCollectionConstants.js → gc/gcDefinitions.js} +26 -1
  205. package/lib/gc/gcDefinitions.js.map +1 -0
  206. package/lib/gc/gcHelpers.d.ts +30 -0
  207. package/lib/gc/gcHelpers.d.ts.map +1 -0
  208. package/lib/gc/gcHelpers.js +58 -0
  209. package/lib/gc/gcHelpers.js.map +1 -0
  210. package/lib/gc/gcSummaryStateTracker.d.ts +86 -0
  211. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
  212. package/lib/gc/gcSummaryStateTracker.js +242 -0
  213. package/lib/gc/gcSummaryStateTracker.js.map +1 -0
  214. package/{dist → lib/gc}/gcSweepReadyUsageDetection.d.ts +5 -5
  215. package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  216. package/lib/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +15 -11
  217. package/lib/gc/gcSweepReadyUsageDetection.js.map +1 -0
  218. package/lib/gc/gcUnreferencedStateTracker.d.ts +34 -0
  219. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  220. package/lib/gc/gcUnreferencedStateTracker.js +90 -0
  221. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -0
  222. package/lib/gc/index.d.ts +11 -0
  223. package/lib/gc/index.d.ts.map +1 -0
  224. package/lib/gc/index.js +11 -0
  225. package/lib/gc/index.js.map +1 -0
  226. package/lib/index.d.ts +2 -5
  227. package/lib/index.d.ts.map +1 -1
  228. package/lib/index.js +1 -4
  229. package/lib/index.js.map +1 -1
  230. package/lib/opLifecycle/batchManager.d.ts +2 -13
  231. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  232. package/lib/opLifecycle/batchManager.js +19 -41
  233. package/lib/opLifecycle/batchManager.js.map +1 -1
  234. package/lib/opLifecycle/definitions.d.ts +4 -0
  235. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  236. package/lib/opLifecycle/definitions.js.map +1 -1
  237. package/lib/opLifecycle/index.d.ts.map +1 -1
  238. package/lib/opLifecycle/index.js.map +1 -1
  239. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  240. package/lib/opLifecycle/opCompressor.js +1 -0
  241. package/lib/opLifecycle/opCompressor.js.map +1 -1
  242. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  243. package/lib/opLifecycle/opDecompressor.js +5 -2
  244. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  245. package/lib/opLifecycle/opSplitter.d.ts +1 -1
  246. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  247. package/lib/opLifecycle/opSplitter.js +25 -14
  248. package/lib/opLifecycle/opSplitter.js.map +1 -1
  249. package/lib/opLifecycle/outbox.d.ts +19 -3
  250. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  251. package/lib/opLifecycle/outbox.js +79 -46
  252. package/lib/opLifecycle/outbox.js.map +1 -1
  253. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  254. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  255. package/lib/opProperties.d.ts.map +1 -1
  256. package/lib/opProperties.js +1 -3
  257. package/lib/opProperties.js.map +1 -1
  258. package/lib/packageVersion.d.ts +1 -1
  259. package/lib/packageVersion.js +1 -1
  260. package/lib/packageVersion.js.map +1 -1
  261. package/lib/pendingStateManager.d.ts +8 -2
  262. package/lib/pendingStateManager.d.ts.map +1 -1
  263. package/lib/pendingStateManager.js +21 -13
  264. package/lib/pendingStateManager.js.map +1 -1
  265. package/lib/scheduleManager.d.ts.map +1 -1
  266. package/lib/scheduleManager.js +3 -2
  267. package/lib/scheduleManager.js.map +1 -1
  268. package/lib/serializedSnapshotStorage.d.ts +2 -2
  269. package/lib/serializedSnapshotStorage.d.ts.map +1 -1
  270. package/lib/serializedSnapshotStorage.js +5 -3
  271. package/lib/serializedSnapshotStorage.js.map +1 -1
  272. package/lib/summary/index.d.ts +17 -0
  273. package/lib/summary/index.d.ts.map +1 -0
  274. package/lib/summary/index.js +16 -0
  275. package/lib/summary/index.js.map +1 -0
  276. package/lib/summary/orderedClientElection.d.ts.map +1 -0
  277. package/lib/{orderedClientElection.js → summary/orderedClientElection.js} +10 -4
  278. package/lib/summary/orderedClientElection.js.map +1 -0
  279. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  280. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
  281. package/{dist → lib/summary}/runningSummarizer.d.ts +19 -18
  282. package/lib/summary/runningSummarizer.d.ts.map +1 -0
  283. package/lib/{runningSummarizer.js → summary/runningSummarizer.js} +193 -78
  284. package/lib/summary/runningSummarizer.js.map +1 -0
  285. package/lib/{summarizer.d.ts → summary/summarizer.d.ts} +4 -6
  286. package/lib/summary/summarizer.d.ts.map +1 -0
  287. package/lib/{summarizer.js → summary/summarizer.js} +33 -73
  288. package/lib/summary/summarizer.js.map +1 -0
  289. package/lib/summary/summarizerClientElection.d.ts.map +1 -0
  290. package/lib/summary/summarizerClientElection.js.map +1 -0
  291. package/lib/summary/summarizerHandle.d.ts.map +1 -0
  292. package/lib/summary/summarizerHandle.js.map +1 -0
  293. package/{dist → lib/summary}/summarizerHeuristics.d.ts +1 -1
  294. package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
  295. package/lib/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +6 -9
  296. package/lib/summary/summarizerHeuristics.js.map +1 -0
  297. package/{dist → lib/summary}/summarizerTypes.d.ts +22 -22
  298. package/lib/summary/summarizerTypes.d.ts.map +1 -0
  299. package/lib/summary/summarizerTypes.js.map +1 -0
  300. package/lib/summary/summaryCollection.d.ts.map +1 -0
  301. package/lib/{summaryCollection.js → summary/summaryCollection.js} +18 -8
  302. package/lib/summary/summaryCollection.js.map +1 -0
  303. package/{dist → lib/summary}/summaryFormat.d.ts +1 -40
  304. package/lib/summary/summaryFormat.d.ts.map +1 -0
  305. package/lib/{summaryFormat.js → summary/summaryFormat.js} +20 -20
  306. package/lib/summary/summaryFormat.js.map +1 -0
  307. package/lib/summary/summaryGenerator.d.ts.map +1 -0
  308. package/lib/{summaryGenerator.js → summary/summaryGenerator.js} +33 -15
  309. package/lib/summary/summaryGenerator.js.map +1 -0
  310. package/lib/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
  311. package/lib/summary/summaryManager.d.ts.map +1 -0
  312. package/lib/{summaryManager.js → summary/summaryManager.js} +21 -9
  313. package/lib/summary/summaryManager.js.map +1 -0
  314. package/lib/throttler.d.ts +2 -2
  315. package/lib/throttler.d.ts.map +1 -1
  316. package/lib/throttler.js +4 -4
  317. package/lib/throttler.js.map +1 -1
  318. package/package.json +60 -51
  319. package/prettier.config.cjs +1 -1
  320. package/src/batchTracker.ts +54 -49
  321. package/src/blobManager.ts +825 -674
  322. package/src/connectionTelemetry.ts +280 -249
  323. package/src/containerHandleContext.ts +27 -29
  324. package/src/containerRuntime.ts +3249 -2978
  325. package/src/dataStore.ts +172 -159
  326. package/src/dataStoreContext.ts +1141 -1057
  327. package/src/dataStoreContexts.ts +178 -161
  328. package/src/dataStoreRegistry.ts +25 -20
  329. package/src/dataStores.ts +880 -731
  330. package/src/deltaScheduler.ts +158 -150
  331. package/{garbageCollection.md → src/gc/garbageCollection.md} +16 -3
  332. package/src/gc/garbageCollection.ts +1506 -0
  333. package/src/gc/gcDefinitions.ts +244 -0
  334. package/src/gc/gcHelpers.ts +86 -0
  335. package/src/gc/gcSummaryStateTracker.ts +339 -0
  336. package/src/gc/gcSweepReadyUsageDetection.ts +145 -0
  337. package/src/gc/gcUnreferencedStateTracker.ts +114 -0
  338. package/src/gc/index.ts +40 -0
  339. package/src/index.ts +67 -70
  340. package/src/opLifecycle/README.md +152 -0
  341. package/src/opLifecycle/batchManager.ts +101 -144
  342. package/src/opLifecycle/definitions.ts +33 -29
  343. package/src/opLifecycle/index.ts +5 -5
  344. package/src/opLifecycle/opCompressor.ts +55 -53
  345. package/src/opLifecycle/opDecompressor.ts +100 -81
  346. package/src/opLifecycle/opSplitter.ts +233 -188
  347. package/src/opLifecycle/outbox.ts +251 -195
  348. package/src/opLifecycle/remoteMessageProcessor.ts +62 -62
  349. package/src/opProperties.ts +11 -9
  350. package/src/packageVersion.ts +1 -1
  351. package/src/pendingStateManager.ts +396 -338
  352. package/src/scheduleManager.ts +299 -269
  353. package/src/serializedSnapshotStorage.ts +126 -112
  354. package/src/summary/index.ts +99 -0
  355. package/src/summary/orderedClientElection.ts +564 -0
  356. package/src/summary/runWhileConnectedCoordinator.ts +113 -0
  357. package/src/summary/runningSummarizer.ts +788 -0
  358. package/src/summary/summarizer.ts +386 -0
  359. package/src/summary/summarizerClientElection.ts +139 -0
  360. package/src/{summarizerHandle.ts → summary/summarizerHandle.ts} +11 -9
  361. package/src/summary/summarizerHeuristics.ts +219 -0
  362. package/src/summary/summarizerTypes.ts +521 -0
  363. package/src/summary/summaryCollection.ts +450 -0
  364. package/src/summary/summaryFormat.ts +226 -0
  365. package/src/summary/summaryGenerator.ts +505 -0
  366. package/src/summary/summaryManager.ts +423 -0
  367. package/src/throttler.ts +131 -122
  368. package/tsconfig.esnext.json +6 -6
  369. package/tsconfig.json +9 -13
  370. package/dist/garbageCollection.d.ts.map +0 -1
  371. package/dist/garbageCollection.js.map +0 -1
  372. package/dist/garbageCollectionConstants.d.ts +0 -25
  373. package/dist/garbageCollectionConstants.d.ts.map +0 -1
  374. package/dist/garbageCollectionConstants.js.map +0 -1
  375. package/dist/garbageCollectionTombstoneUtils.d.ts +0 -14
  376. package/dist/garbageCollectionTombstoneUtils.d.ts.map +0 -1
  377. package/dist/garbageCollectionTombstoneUtils.js +0 -23
  378. package/dist/garbageCollectionTombstoneUtils.js.map +0 -1
  379. package/dist/gcSweepReadyUsageDetection.d.ts.map +0 -1
  380. package/dist/gcSweepReadyUsageDetection.js.map +0 -1
  381. package/dist/orderedClientElection.d.ts.map +0 -1
  382. package/dist/orderedClientElection.js.map +0 -1
  383. package/dist/runWhileConnectedCoordinator.d.ts.map +0 -1
  384. package/dist/runWhileConnectedCoordinator.js.map +0 -1
  385. package/dist/runningSummarizer.d.ts.map +0 -1
  386. package/dist/runningSummarizer.js.map +0 -1
  387. package/dist/summarizer.d.ts.map +0 -1
  388. package/dist/summarizer.js.map +0 -1
  389. package/dist/summarizerClientElection.d.ts.map +0 -1
  390. package/dist/summarizerClientElection.js.map +0 -1
  391. package/dist/summarizerHandle.d.ts.map +0 -1
  392. package/dist/summarizerHandle.js.map +0 -1
  393. package/dist/summarizerHeuristics.d.ts.map +0 -1
  394. package/dist/summarizerHeuristics.js.map +0 -1
  395. package/dist/summarizerTypes.d.ts.map +0 -1
  396. package/dist/summarizerTypes.js.map +0 -1
  397. package/dist/summaryCollection.d.ts.map +0 -1
  398. package/dist/summaryCollection.js.map +0 -1
  399. package/dist/summaryFormat.d.ts.map +0 -1
  400. package/dist/summaryFormat.js.map +0 -1
  401. package/dist/summaryGenerator.d.ts.map +0 -1
  402. package/dist/summaryGenerator.js.map +0 -1
  403. package/dist/summaryManager.d.ts.map +0 -1
  404. package/dist/summaryManager.js.map +0 -1
  405. package/lib/garbageCollection.d.ts.map +0 -1
  406. package/lib/garbageCollection.js.map +0 -1
  407. package/lib/garbageCollectionConstants.d.ts +0 -25
  408. package/lib/garbageCollectionConstants.d.ts.map +0 -1
  409. package/lib/garbageCollectionConstants.js.map +0 -1
  410. package/lib/garbageCollectionTombstoneUtils.d.ts +0 -14
  411. package/lib/garbageCollectionTombstoneUtils.d.ts.map +0 -1
  412. package/lib/garbageCollectionTombstoneUtils.js +0 -19
  413. package/lib/garbageCollectionTombstoneUtils.js.map +0 -1
  414. package/lib/gcSweepReadyUsageDetection.d.ts.map +0 -1
  415. package/lib/gcSweepReadyUsageDetection.js.map +0 -1
  416. package/lib/orderedClientElection.d.ts.map +0 -1
  417. package/lib/orderedClientElection.js.map +0 -1
  418. package/lib/runWhileConnectedCoordinator.d.ts.map +0 -1
  419. package/lib/runWhileConnectedCoordinator.js.map +0 -1
  420. package/lib/runningSummarizer.d.ts.map +0 -1
  421. package/lib/runningSummarizer.js.map +0 -1
  422. package/lib/summarizer.d.ts.map +0 -1
  423. package/lib/summarizer.js.map +0 -1
  424. package/lib/summarizerClientElection.d.ts.map +0 -1
  425. package/lib/summarizerClientElection.js.map +0 -1
  426. package/lib/summarizerHandle.d.ts.map +0 -1
  427. package/lib/summarizerHandle.js.map +0 -1
  428. package/lib/summarizerHeuristics.d.ts.map +0 -1
  429. package/lib/summarizerHeuristics.js.map +0 -1
  430. package/lib/summarizerTypes.d.ts.map +0 -1
  431. package/lib/summarizerTypes.js.map +0 -1
  432. package/lib/summaryCollection.d.ts.map +0 -1
  433. package/lib/summaryCollection.js.map +0 -1
  434. package/lib/summaryFormat.d.ts.map +0 -1
  435. package/lib/summaryFormat.js.map +0 -1
  436. package/lib/summaryGenerator.d.ts.map +0 -1
  437. package/lib/summaryGenerator.js.map +0 -1
  438. package/lib/summaryManager.d.ts.map +0 -1
  439. package/lib/summaryManager.js.map +0 -1
  440. package/src/garbageCollection.ts +0 -1800
  441. package/src/garbageCollectionConstants.ts +0 -41
  442. package/src/garbageCollectionTombstoneUtils.ts +0 -28
  443. package/src/gcSweepReadyUsageDetection.ts +0 -139
  444. package/src/orderedClientElection.ts +0 -532
  445. package/src/runWhileConnectedCoordinator.ts +0 -106
  446. package/src/runningSummarizer.ts +0 -610
  447. package/src/summarizer.ts +0 -421
  448. package/src/summarizerClientElection.ts +0 -132
  449. package/src/summarizerHeuristics.ts +0 -222
  450. package/src/summarizerTypes.ts +0 -507
  451. package/src/summaryCollection.ts +0 -421
  452. package/src/summaryFormat.ts +0 -256
  453. package/src/summaryGenerator.ts +0 -450
  454. package/src/summaryManager.ts +0 -394
  455. /package/dist/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  456. /package/dist/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +0 -0
  457. /package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +0 -0
  458. /package/dist/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
  459. /package/dist/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
  460. /package/dist/{summarizerHandle.d.ts → summary/summarizerHandle.d.ts} +0 -0
  461. /package/dist/{summarizerHandle.js → summary/summarizerHandle.js} +0 -0
  462. /package/dist/{summarizerTypes.js → summary/summarizerTypes.js} +0 -0
  463. /package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  464. /package/dist/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
  465. /package/lib/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  466. /package/lib/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +0 -0
  467. /package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +0 -0
  468. /package/lib/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
  469. /package/lib/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
  470. /package/lib/{summarizerHandle.d.ts → summary/summarizerHandle.d.ts} +0 -0
  471. /package/lib/{summarizerHandle.js → summary/summarizerHandle.js} +0 -0
  472. /package/lib/{summarizerTypes.js → summary/summarizerTypes.js} +0 -0
  473. /package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  474. /package/lib/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
@@ -7,9 +7,9 @@ import { ITelemetryLogger } from "@fluidframework/common-definitions";
7
7
  import { ChildLogger, TelemetryLogger } from "@fluidframework/telemetry-utils";
8
8
  import { IDeltaManager } from "@fluidframework/container-definitions";
9
9
  import {
10
- IDocumentMessage,
11
- ISequencedDocumentMessage,
12
- MessageType,
10
+ IDocumentMessage,
11
+ ISequencedDocumentMessage,
12
+ MessageType,
13
13
  } from "@fluidframework/protocol-definitions";
14
14
  import { assert, performance } from "@fluidframework/common-utils";
15
15
 
@@ -26,263 +26,294 @@ export const latencyThreshold = 5000;
26
26
  // 3. Op received from service back (pushed to inbound queue).
27
27
  // 4. Op is processed.
28
28
  interface IOpPerfTelemetryProperties {
29
- /** Measure time between (1) and (2) - Measure time outbound op is sitting in queue due to active batch */
30
- durationOutboundBatching: number; // was durationOutboundQueue in previous versions
31
- /** Measure time between (2) and (3) - Track how long it took for op to be acked by service */
32
- durationNetwork: number; // was durationInboundQueue
33
- /** Measure time between (3) and (4) - Time between DM's inbound "push" event until DM's "op" event */
34
- durationInboundToProcessing: number;
35
- /** Length of the DeltaManager's inbound queue at the time of the DM's inbound "push" event (3) */
36
- lengthInboundQueue: number;
29
+ /** Measure time between (1) and (2) - Measure time outbound op is sitting in queue due to active batch */
30
+ durationOutboundBatching: number; // was durationOutboundQueue in previous versions
31
+ /** Measure time between (2) and (3) - Track how long it took for op to be acked by service */
32
+ durationNetwork: number; // was durationInboundQueue
33
+ /** Measure time between (3) and (4) - Time between DM's inbound "push" event until DM's "op" event */
34
+ durationInboundToProcessing: number;
35
+ /** Length of the DeltaManager's inbound queue at the time of the DM's inbound "push" event (3) */
36
+ lengthInboundQueue: number;
37
37
  }
38
38
 
39
39
  /**
40
40
  * Timings collected at various moments during the op processing.
41
41
  */
42
- interface IOpPerfTimings {
43
- /** Starting time for (1) */
44
- submitOpEventTime: number;
45
- /** Starting time for (2) */
46
- outboundPushEventTime: number;
47
- /** Starting time for (3) */
48
- inboundPushEventTime: number;
42
+ interface IOpPerfTimings {
43
+ /** Starting time for (1) */
44
+ submitOpEventTime: number;
45
+ /** Starting time for (2) */
46
+ outboundPushEventTime: number;
47
+ /** Starting time for (3) */
48
+ inboundPushEventTime: number;
49
49
  }
50
50
 
51
51
  class OpPerfTelemetry {
52
- private pongCount: number = 0;
53
- private pingLatency: number | undefined;
54
-
55
- // Collab window tracking. This is timestamp of %1000 message.
56
- private sequenceNumberForMsnTracking: number | undefined;
57
- private msnTrackingTimestamp: number = 0;
58
- // To track round trip time for every %500 client message.
59
- private clientSequenceNumberForLatencyStatistics: number | undefined;
60
-
61
- private opProcessingTimes: Partial<IOpPerfTimings> = {};
62
-
63
- // Performance Data to be reported for ops round trips and processing.
64
- private opPerfData: Partial<IOpPerfTelemetryProperties> = {};
65
-
66
- private firstConnection = true;
67
- private connectionOpSeqNumber: number | undefined;
68
- private readonly bootTime = performance.now();
69
- private connectionStartTime = 0;
70
- private gap = 0;
71
-
72
- private readonly logger: ITelemetryLogger;
73
-
74
- public constructor(
75
- private clientId: string | undefined,
76
- private readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
77
- logger: ITelemetryLogger) {
78
- this.logger = ChildLogger.create(logger, "OpPerf");
79
-
80
- this.deltaManager.on("pong", (latency) => this.recordPingTime(latency));
81
- this.deltaManager.on("submitOp", (message) => this.beforeOpSubmit(message));
82
-
83
- this.deltaManager.on("op", (message) => this.afterProcessingOp(message));
84
-
85
- this.deltaManager.on("connect", (details, opsBehind) => {
86
- this.clientId = details.clientId;
87
- if (opsBehind !== undefined) {
88
- this.connectionOpSeqNumber = this.deltaManager.lastKnownSeqNumber;
89
- this.gap = opsBehind;
90
- this.connectionStartTime = performance.now();
91
-
92
- // We might be already up-today. If so, report it right away.
93
- if (this.gap <= 0) {
94
- this.reportGettingUpToDate();
95
- }
96
- }
97
- });
98
- this.deltaManager.on("disconnect", () => {
99
- this.sequenceNumberForMsnTracking = undefined;
100
- this.clientSequenceNumberForLatencyStatistics = undefined;
101
- this.opProcessingTimes = {};
102
- this.opPerfData = {};
103
- this.connectionOpSeqNumber = undefined;
104
- this.firstConnection = false;
105
- this.pongCount = 0;
106
- });
107
-
108
- this.deltaManager.outbound.on("push", (messages) => {
109
- for (const msg of messages) {
110
- if (msg.type === MessageType.Operation &&
111
- this.clientSequenceNumberForLatencyStatistics === msg.clientSequenceNumber) {
112
- assert(this.opProcessingTimes.outboundPushEventTime === undefined,
113
- 0x2c8 /* "outboundPushEventTime should be undefined" */);
114
- assert(this.opPerfData.durationNetwork === undefined,
115
- 0x2c9 /* "durationNetwork should be undefined" */);
116
- this.opProcessingTimes.outboundPushEventTime = Date.now();
117
-
118
- assert(this.opPerfData.durationOutboundBatching === undefined,
119
- 0x2ca /* "durationOutboundBatching should be undefined" */);
120
-
121
- assert(this.opProcessingTimes.submitOpEventTime !== undefined,
122
- 0x2cb /* "submitOpEventTime should be undefined" */);
123
-
124
- this.opPerfData.durationOutboundBatching = this.opProcessingTimes.outboundPushEventTime
125
- - this.opProcessingTimes.submitOpEventTime;
126
- }
127
- }
128
- });
129
-
130
- this.deltaManager.inbound.on("push", (message: ISequencedDocumentMessage) => {
131
- if (this.clientId === message.clientId &&
132
- message.type === MessageType.Operation &&
133
- this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber &&
134
- this.opProcessingTimes.outboundPushEventTime !== undefined) {
135
- this.opProcessingTimes.inboundPushEventTime = Date.now();
136
- this.opPerfData.durationNetwork = this.opProcessingTimes.inboundPushEventTime
137
- - this.opProcessingTimes.outboundPushEventTime;
138
- this.opProcessingTimes.outboundPushEventTime = undefined;
139
- this.opPerfData.lengthInboundQueue = this.deltaManager.inbound.length;
140
- }
141
- });
142
-
143
- this.deltaManager.inbound.on("idle", (count: number, duration: number) => {
144
- // Do not want to log zero for sure.
145
- // We are more interested in aggregates, so logging only if we are processing some number of ops
146
- // Cut-off is arbitrary - can be increased or decreased based on amount of data collected and questions we
147
- // want to get answered
148
- // back-compat: Once 0.36 loader version saturates (count & duration args were added there),
149
- // we can remove typeof check.
150
- if (typeof count === "number" && count >= 100) {
151
- this.logger.sendPerformanceEvent({
152
- eventName: "GetDeltas_OpProcessing",
153
- count,
154
- duration,
155
- });
156
- }
157
- });
158
- }
159
-
160
- private reportGettingUpToDate() {
161
- this.connectionOpSeqNumber = undefined;
162
- this.logger.sendPerformanceEvent({
163
- eventName: "ConnectionSpeed",
164
- duration: performance.now() - this.connectionStartTime,
165
- ops: this.gap,
166
- // track time to connect only for first connection.
167
- timeToConnect: this.firstConnection ?
168
- TelemetryLogger.formatTick(this.connectionStartTime - this.bootTime) :
169
- undefined,
170
- firstConnection: this.firstConnection,
171
- });
172
- }
173
-
174
- private recordPingTime(latency: number) {
175
- this.pingLatency = latency;
176
- // logging one in every 1000 pongs, including the first time, if it is a "write" client.
177
- if (this.pongCount % 100 === 0 && this.deltaManager.active) {
178
- this.logger.sendPerformanceEvent({
179
- eventName: "DeltaLatency",
180
- duration: latency,
181
- });
182
- }
183
- this.pongCount++;
184
- }
185
-
186
- private beforeOpSubmit(message: IDocumentMessage) {
187
- // start with first client op and measure latency every 500 client ops
188
- if (this.clientSequenceNumberForLatencyStatistics === undefined &&
189
- message.clientSequenceNumber % 500 === 1) {
190
- assert(this.opProcessingTimes.outboundPushEventTime === undefined,
191
- 0x2cc /* "OpTimeSittingInboundQueue should be undefined" */);
192
- assert(this.opPerfData.durationNetwork === undefined,
193
- 0x2cd /* "durationNetwork should be undefined" */);
194
- this.opProcessingTimes.submitOpEventTime = Date.now();
195
- this.clientSequenceNumberForLatencyStatistics = message.clientSequenceNumber;
196
- }
197
- }
198
-
199
- private afterProcessingOp(message: ISequencedDocumentMessage) {
200
- const sequenceNumber = message.sequenceNumber;
201
-
202
- if (sequenceNumber === this.connectionOpSeqNumber) {
203
- this.reportGettingUpToDate();
204
- }
205
-
206
- // Record collab window max size after every 1000th op.
207
- if (this.sequenceNumberForMsnTracking === undefined && sequenceNumber % 1000 === 0) {
208
- this.sequenceNumberForMsnTracking = sequenceNumber;
209
- this.msnTrackingTimestamp = message.timestamp;
210
- }
211
- if (this.sequenceNumberForMsnTracking !== undefined &&
212
- message.minimumSequenceNumber >= this.sequenceNumberForMsnTracking) {
213
- assert(this.msnTrackingTimestamp !== undefined,
214
- 0x2ce /* "msnTrackingTimestamp should not be undefined" */);
215
- this.logger.sendPerformanceEvent({
216
- eventName: "MsnStatistics",
217
- sequenceNumber,
218
- msnDistance: sequenceNumber - this.sequenceNumberForMsnTracking,
219
- duration: message.timestamp - this.msnTrackingTimestamp,
220
- });
221
- this.sequenceNumberForMsnTracking = undefined;
222
- }
223
-
224
- if (this.clientId === message.clientId &&
225
- this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber) {
226
- assert(this.opProcessingTimes.submitOpEventTime !== undefined,
227
- 0x120 /* "Undefined latency statistics (op send time)" */);
228
- const currentTime = Date.now();
229
-
230
- if (this.opProcessingTimes.inboundPushEventTime !== undefined) {
231
- this.opPerfData.durationInboundToProcessing = currentTime
232
- - this.opProcessingTimes.inboundPushEventTime;
233
- }
234
-
235
- const duration = currentTime - this.opProcessingTimes.submitOpEventTime;
236
-
237
- // One of the core expectations for Fluid service is to be fast.
238
- // When it's not the case, we want to learn about it and be able to investigate, so
239
- // raise awareness.
240
- // This also helps identify cases where it's due to client behavior (sending too many ops)
241
- // that results in overwhelming ordering service and thus starting to see long latencies.
242
- // The threshold could be adjusted, but ideally it stays workload-agnostic, as service
243
- // performance impacts all workloads relying on service.
244
- const category = duration > latencyThreshold ? "error" : "performance";
245
-
246
- this.logger.sendPerformanceEvent({
247
- eventName: "OpRoundtripTime",
248
- sequenceNumber,
249
- referenceSequenceNumber: message.referenceSequenceNumber,
250
- duration,
251
- category,
252
- pingLatency: this.pingLatency,
253
- msnDistance: this.deltaManager.lastSequenceNumber - this.deltaManager.minimumSequenceNumber,
254
- ...this.opPerfData,
255
- });
256
- this.clientSequenceNumberForLatencyStatistics = undefined;
257
- this.opPerfData = {};
258
- }
259
- }
52
+ private pongCount: number = 0;
53
+ private pingLatency: number | undefined;
54
+
55
+ // Collab window tracking. This is timestamp of %1000 message.
56
+ private sequenceNumberForMsnTracking: number | undefined;
57
+ private msnTrackingTimestamp: number = 0;
58
+ // To track round trip time for every %500 client message.
59
+ private clientSequenceNumberForLatencyStatistics: number | undefined;
60
+
61
+ private opProcessingTimes: Partial<IOpPerfTimings> = {};
62
+
63
+ // Performance Data to be reported for ops round trips and processing.
64
+ private opPerfData: Partial<IOpPerfTelemetryProperties> = {};
65
+
66
+ private firstConnection = true;
67
+ private connectionOpSeqNumber: number | undefined;
68
+ private readonly bootTime = performance.now();
69
+ private connectionStartTime = 0;
70
+ private gap = 0;
71
+
72
+ private readonly logger: ITelemetryLogger;
73
+
74
+ public constructor(
75
+ private clientId: string | undefined,
76
+ private readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
77
+ logger: ITelemetryLogger,
78
+ ) {
79
+ this.logger = ChildLogger.create(logger, "OpPerf");
80
+
81
+ this.deltaManager.on("pong", (latency) => this.recordPingTime(latency));
82
+ this.deltaManager.on("submitOp", (message) => this.beforeOpSubmit(message));
83
+
84
+ this.deltaManager.on("op", (message) => this.afterProcessingOp(message));
85
+
86
+ this.deltaManager.on("connect", (details, opsBehind) => {
87
+ this.clientId = details.clientId;
88
+ if (opsBehind !== undefined) {
89
+ this.connectionOpSeqNumber = this.deltaManager.lastKnownSeqNumber;
90
+ this.gap = opsBehind;
91
+ this.connectionStartTime = performance.now();
92
+
93
+ // We might be already up-today. If so, report it right away.
94
+ if (this.gap <= 0) {
95
+ this.reportGettingUpToDate();
96
+ }
97
+ }
98
+ });
99
+ this.deltaManager.on("disconnect", () => {
100
+ this.sequenceNumberForMsnTracking = undefined;
101
+ this.clientSequenceNumberForLatencyStatistics = undefined;
102
+ this.opProcessingTimes = {};
103
+ this.opPerfData = {};
104
+ this.connectionOpSeqNumber = undefined;
105
+ this.firstConnection = false;
106
+ this.pongCount = 0;
107
+ });
108
+
109
+ this.deltaManager.outbound.on("push", (messages) => {
110
+ for (const msg of messages) {
111
+ if (
112
+ msg.type === MessageType.Operation &&
113
+ this.clientSequenceNumberForLatencyStatistics === msg.clientSequenceNumber
114
+ ) {
115
+ assert(
116
+ this.opProcessingTimes.outboundPushEventTime === undefined,
117
+ 0x2c8 /* "outboundPushEventTime should be undefined" */,
118
+ );
119
+ assert(
120
+ this.opPerfData.durationNetwork === undefined,
121
+ 0x2c9 /* "durationNetwork should be undefined" */,
122
+ );
123
+ this.opProcessingTimes.outboundPushEventTime = Date.now();
124
+
125
+ assert(
126
+ this.opPerfData.durationOutboundBatching === undefined,
127
+ 0x2ca /* "durationOutboundBatching should be undefined" */,
128
+ );
129
+
130
+ assert(
131
+ this.opProcessingTimes.submitOpEventTime !== undefined,
132
+ 0x2cb /* "submitOpEventTime should be undefined" */,
133
+ );
134
+
135
+ this.opPerfData.durationOutboundBatching =
136
+ this.opProcessingTimes.outboundPushEventTime -
137
+ this.opProcessingTimes.submitOpEventTime;
138
+ }
139
+ }
140
+ });
141
+
142
+ this.deltaManager.inbound.on("push", (message: ISequencedDocumentMessage) => {
143
+ if (
144
+ this.clientId === message.clientId &&
145
+ message.type === MessageType.Operation &&
146
+ this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber &&
147
+ this.opProcessingTimes.outboundPushEventTime !== undefined
148
+ ) {
149
+ this.opProcessingTimes.inboundPushEventTime = Date.now();
150
+ this.opPerfData.durationNetwork =
151
+ this.opProcessingTimes.inboundPushEventTime -
152
+ this.opProcessingTimes.outboundPushEventTime;
153
+ this.opProcessingTimes.outboundPushEventTime = undefined;
154
+ this.opPerfData.lengthInboundQueue = this.deltaManager.inbound.length;
155
+ }
156
+ });
157
+
158
+ this.deltaManager.inbound.on("idle", (count: number, duration: number) => {
159
+ // Do not want to log zero for sure.
160
+ // We are more interested in aggregates, so logging only if we are processing some number of ops
161
+ // Cut-off is arbitrary - can be increased or decreased based on amount of data collected and questions we
162
+ // want to get answered
163
+ // back-compat: Once 0.36 loader version saturates (count & duration args were added there),
164
+ // we can remove typeof check.
165
+ if (typeof count === "number" && count >= 100) {
166
+ this.logger.sendPerformanceEvent({
167
+ eventName: "GetDeltas_OpProcessing",
168
+ count,
169
+ duration,
170
+ });
171
+ }
172
+ });
173
+ }
174
+
175
+ private reportGettingUpToDate() {
176
+ this.connectionOpSeqNumber = undefined;
177
+ this.logger.sendPerformanceEvent({
178
+ eventName: "ConnectionSpeed",
179
+ duration: performance.now() - this.connectionStartTime,
180
+ ops: this.gap,
181
+ // track time to connect only for first connection.
182
+ timeToConnect: this.firstConnection
183
+ ? TelemetryLogger.formatTick(this.connectionStartTime - this.bootTime)
184
+ : undefined,
185
+ firstConnection: this.firstConnection,
186
+ });
187
+ }
188
+
189
+ private recordPingTime(latency: number) {
190
+ this.pingLatency = latency;
191
+ // logging one in every 1000 pongs, including the first time, if it is a "write" client.
192
+ if (this.pongCount % 100 === 0 && this.deltaManager.active) {
193
+ this.logger.sendPerformanceEvent({
194
+ eventName: "DeltaLatency",
195
+ duration: latency,
196
+ });
197
+ }
198
+ this.pongCount++;
199
+ }
200
+
201
+ private beforeOpSubmit(message: IDocumentMessage) {
202
+ // start with first client op and measure latency every 500 client ops
203
+ if (
204
+ this.clientSequenceNumberForLatencyStatistics === undefined &&
205
+ message.clientSequenceNumber % 500 === 1
206
+ ) {
207
+ assert(
208
+ this.opProcessingTimes.outboundPushEventTime === undefined,
209
+ 0x2cc /* "OpTimeSittingInboundQueue should be undefined" */,
210
+ );
211
+ assert(
212
+ this.opPerfData.durationNetwork === undefined,
213
+ 0x2cd /* "durationNetwork should be undefined" */,
214
+ );
215
+ this.opProcessingTimes.submitOpEventTime = Date.now();
216
+ this.clientSequenceNumberForLatencyStatistics = message.clientSequenceNumber;
217
+ }
218
+ }
219
+
220
+ private afterProcessingOp(message: ISequencedDocumentMessage) {
221
+ const sequenceNumber = message.sequenceNumber;
222
+
223
+ if (sequenceNumber === this.connectionOpSeqNumber) {
224
+ this.reportGettingUpToDate();
225
+ }
226
+
227
+ // Record collab window max size after every 1000th op.
228
+ if (this.sequenceNumberForMsnTracking === undefined && sequenceNumber % 1000 === 0) {
229
+ this.sequenceNumberForMsnTracking = sequenceNumber;
230
+ this.msnTrackingTimestamp = message.timestamp;
231
+ }
232
+ if (
233
+ this.sequenceNumberForMsnTracking !== undefined &&
234
+ message.minimumSequenceNumber >= this.sequenceNumberForMsnTracking
235
+ ) {
236
+ assert(
237
+ this.msnTrackingTimestamp !== undefined,
238
+ 0x2ce /* "msnTrackingTimestamp should not be undefined" */,
239
+ );
240
+ this.logger.sendPerformanceEvent({
241
+ eventName: "MsnStatistics",
242
+ sequenceNumber,
243
+ msnDistance: sequenceNumber - this.sequenceNumberForMsnTracking,
244
+ duration: message.timestamp - this.msnTrackingTimestamp,
245
+ });
246
+ this.sequenceNumberForMsnTracking = undefined;
247
+ }
248
+
249
+ if (
250
+ this.clientId === message.clientId &&
251
+ this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber
252
+ ) {
253
+ assert(
254
+ this.opProcessingTimes.submitOpEventTime !== undefined,
255
+ 0x120 /* "Undefined latency statistics (op send time)" */,
256
+ );
257
+ const currentTime = Date.now();
258
+
259
+ if (this.opProcessingTimes.inboundPushEventTime !== undefined) {
260
+ this.opPerfData.durationInboundToProcessing =
261
+ currentTime - this.opProcessingTimes.inboundPushEventTime;
262
+ }
263
+
264
+ const duration = currentTime - this.opProcessingTimes.submitOpEventTime;
265
+
266
+ // One of the core expectations for Fluid service is to be fast.
267
+ // When it's not the case, we want to learn about it and be able to investigate, so
268
+ // raise awareness.
269
+ // This also helps identify cases where it's due to client behavior (sending too many ops)
270
+ // that results in overwhelming ordering service and thus starting to see long latencies.
271
+ // The threshold could be adjusted, but ideally it stays workload-agnostic, as service
272
+ // performance impacts all workloads relying on service.
273
+ const category = duration > latencyThreshold ? "error" : "performance";
274
+
275
+ this.logger.sendPerformanceEvent({
276
+ eventName: "OpRoundtripTime",
277
+ sequenceNumber,
278
+ referenceSequenceNumber: message.referenceSequenceNumber,
279
+ duration,
280
+ category,
281
+ pingLatency: this.pingLatency,
282
+ msnDistance:
283
+ this.deltaManager.lastSequenceNumber - this.deltaManager.minimumSequenceNumber,
284
+ ...this.opPerfData,
285
+ });
286
+ this.clientSequenceNumberForLatencyStatistics = undefined;
287
+ this.opPerfData = {};
288
+ }
289
+ }
260
290
  }
261
291
  export interface IPerfSignalReport {
262
- /**
263
- * Identifier for the signal being submitted in order to
264
- * allow collection of data around the roundtrip of signal messages.
265
- */
266
- signalSequenceNumber: number;
267
- /**
268
- * Number of signals that were expected but not received.
269
- */
270
- signalsLost: number;
271
-
272
- /**
273
- * Timestamp before submitting the signal we will trace.
274
- */
275
- signalTimestamp: number;
276
-
277
- /**
278
- * Expected Signal Sequence to be received.
279
- */
280
- trackingSignalSequenceNumber: number | undefined;
292
+ /**
293
+ * Identifier for the signal being submitted in order to
294
+ * allow collection of data around the roundtrip of signal messages.
295
+ */
296
+ signalSequenceNumber: number;
297
+ /**
298
+ * Number of signals that were expected but not received.
299
+ */
300
+ signalsLost: number;
301
+
302
+ /**
303
+ * Timestamp before submitting the signal we will trace.
304
+ */
305
+ signalTimestamp: number;
306
+
307
+ /**
308
+ * Expected Signal Sequence to be received.
309
+ */
310
+ trackingSignalSequenceNumber: number | undefined;
281
311
  }
282
312
 
283
313
  export function ReportOpPerfTelemetry(
284
- clientId: string | undefined,
285
- deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
286
- logger: ITelemetryLogger) {
287
- new OpPerfTelemetry(clientId, deltaManager, logger);
314
+ clientId: string | undefined,
315
+ deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
316
+ logger: ITelemetryLogger,
317
+ ) {
318
+ new OpPerfTelemetry(clientId, deltaManager, logger);
288
319
  }
@@ -3,42 +3,40 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import {
7
- IFluidHandleContext,
8
- IRequest,
9
- IResponse,
10
- } from "@fluidframework/core-interfaces";
6
+ import { IFluidHandleContext, IRequest, IResponse } from "@fluidframework/core-interfaces";
11
7
  import { AttachState } from "@fluidframework/container-definitions";
12
8
  import { generateHandleContextPath } from "@fluidframework/runtime-utils";
13
9
  import { ContainerRuntime } from "./containerRuntime";
14
10
 
15
11
  export class ContainerFluidHandleContext implements IFluidHandleContext {
16
- public get IFluidHandleContext() { return this; }
17
- public readonly absolutePath: string;
12
+ public get IFluidHandleContext() {
13
+ return this;
14
+ }
15
+ public readonly absolutePath: string;
18
16
 
19
- /**
20
- * Creates a new ContainerFluidHandleContext.
21
- * @param path - The path to this handle relative to the routeContext.
22
- * @param runtime - The IRuntime object this context represents.
23
- * @param routeContext - The parent IFluidHandleContext that has a route to this handle.
24
- */
25
- constructor(
26
- public readonly path: string,
27
- private readonly runtime: ContainerRuntime,
28
- public readonly routeContext?: IFluidHandleContext,
29
- ) {
30
- this.absolutePath = generateHandleContextPath(path, this.routeContext);
31
- }
17
+ /**
18
+ * Creates a new ContainerFluidHandleContext.
19
+ * @param path - The path to this handle relative to the routeContext.
20
+ * @param runtime - The IRuntime object this context represents.
21
+ * @param routeContext - The parent IFluidHandleContext that has a route to this handle.
22
+ */
23
+ constructor(
24
+ public readonly path: string,
25
+ private readonly runtime: ContainerRuntime,
26
+ public readonly routeContext?: IFluidHandleContext,
27
+ ) {
28
+ this.absolutePath = generateHandleContextPath(path, this.routeContext);
29
+ }
32
30
 
33
- public attachGraph(): void {
34
- throw new Error("can't attach container runtime form within container!");
35
- }
31
+ public attachGraph(): void {
32
+ throw new Error("can't attach container runtime form within container!");
33
+ }
36
34
 
37
- public get isAttached() {
38
- return this.runtime.attachState !== AttachState.Detached;
39
- }
35
+ public get isAttached() {
36
+ return this.runtime.attachState !== AttachState.Detached;
37
+ }
40
38
 
41
- public async resolveHandle(request: IRequest): Promise<IResponse> {
42
- return this.runtime.resolveHandle(request);
43
- }
39
+ public async resolveHandle(request: IRequest): Promise<IResponse> {
40
+ return this.runtime.resolveHandle(request);
41
+ }
44
42
  }