@fluidframework/container-runtime 2.0.0-dev.6.4.0.191515 → 2.0.0-dev.7.2.0.203917

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 (335) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/api-extractor.json +1 -1
  3. package/api-report/container-runtime.api.md +864 -0
  4. package/dist/blobManager.d.ts +4 -4
  5. package/dist/blobManager.d.ts.map +1 -1
  6. package/dist/blobManager.js +55 -71
  7. package/dist/blobManager.js.map +1 -1
  8. package/dist/connectionTelemetry.d.ts.map +1 -1
  9. package/dist/connectionTelemetry.js +75 -42
  10. package/dist/connectionTelemetry.js.map +1 -1
  11. package/dist/container-runtime-alpha.d.ts +1742 -0
  12. package/dist/container-runtime-beta.d.ts +1742 -0
  13. package/dist/container-runtime-public.d.ts +1742 -0
  14. package/dist/container-runtime-untrimmed.d.ts +1803 -0
  15. package/dist/containerHandleContext.js +3 -3
  16. package/dist/containerHandleContext.js.map +1 -1
  17. package/dist/containerRuntime.d.ts +88 -98
  18. package/dist/containerRuntime.d.ts.map +1 -1
  19. package/dist/containerRuntime.js +466 -453
  20. package/dist/containerRuntime.js.map +1 -1
  21. package/dist/dataStore.js +11 -11
  22. package/dist/dataStore.js.map +1 -1
  23. package/dist/dataStoreContext.d.ts +2 -4
  24. package/dist/dataStoreContext.d.ts.map +1 -1
  25. package/dist/dataStoreContext.js +60 -59
  26. package/dist/dataStoreContext.js.map +1 -1
  27. package/dist/dataStoreRegistry.d.ts +3 -0
  28. package/dist/dataStoreRegistry.d.ts.map +1 -1
  29. package/dist/dataStoreRegistry.js +6 -3
  30. package/dist/dataStoreRegistry.js.map +1 -1
  31. package/dist/dataStores.js +1 -1
  32. package/dist/dataStores.js.map +1 -1
  33. package/dist/deltaManagerProxyBase.js +4 -4
  34. package/dist/deltaManagerProxyBase.js.map +1 -1
  35. package/dist/deltaManagerSummarizerProxy.js +6 -6
  36. package/dist/deltaManagerSummarizerProxy.js.map +1 -1
  37. package/dist/deltaScheduler.js.map +1 -1
  38. package/dist/error.d.ts.map +1 -1
  39. package/dist/error.js.map +1 -1
  40. package/dist/gc/garbageCollection.d.ts.map +1 -1
  41. package/dist/gc/garbageCollection.js +23 -24
  42. package/dist/gc/garbageCollection.js.map +1 -1
  43. package/dist/gc/gcConfigs.js +1 -1
  44. package/dist/gc/gcConfigs.js.map +1 -1
  45. package/dist/gc/gcDefinitions.d.ts +34 -24
  46. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  47. package/dist/gc/gcDefinitions.js +10 -7
  48. package/dist/gc/gcDefinitions.js.map +1 -1
  49. package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
  50. package/dist/gc/gcSummaryDefinitions.js.map +1 -1
  51. package/dist/gc/gcTelemetry.d.ts +2 -2
  52. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  53. package/dist/gc/gcTelemetry.js +5 -5
  54. package/dist/gc/gcTelemetry.js.map +1 -1
  55. package/dist/gc/gcUnreferencedStateTracker.js +3 -3
  56. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  57. package/dist/gc/index.d.ts +1 -1
  58. package/dist/gc/index.d.ts.map +1 -1
  59. package/dist/gc/index.js +3 -3
  60. package/dist/gc/index.js.map +1 -1
  61. package/dist/id-compressor/appendOnlySortedMap.js.map +1 -1
  62. package/dist/id-compressor/idCompressor.js.map +1 -1
  63. package/dist/id-compressor/identifiers.d.ts +3 -3
  64. package/dist/id-compressor/identifiers.d.ts.map +1 -1
  65. package/dist/id-compressor/utilities.d.ts +3 -0
  66. package/dist/id-compressor/utilities.d.ts.map +1 -1
  67. package/dist/id-compressor/utilities.js +3 -0
  68. package/dist/id-compressor/utilities.js.map +1 -1
  69. package/dist/index.d.ts +5 -3
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +6 -2
  72. package/dist/index.js.map +1 -1
  73. package/dist/messageTypes.d.ts +137 -0
  74. package/dist/messageTypes.d.ts.map +1 -0
  75. package/dist/messageTypes.js +32 -0
  76. package/dist/messageTypes.js.map +1 -0
  77. package/dist/opLifecycle/batchManager.js +6 -6
  78. package/dist/opLifecycle/batchManager.js.map +1 -1
  79. package/dist/opLifecycle/definitions.d.ts +7 -3
  80. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  81. package/dist/opLifecycle/definitions.js.map +1 -1
  82. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  83. package/dist/opLifecycle/opDecompressor.js +0 -4
  84. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  85. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  86. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  87. package/dist/opLifecycle/opSplitter.js +3 -3
  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 +7 -2
  91. package/dist/opLifecycle/outbox.js.map +1 -1
  92. package/dist/opLifecycle/remoteMessageProcessor.d.ts +17 -3
  93. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  94. package/dist/opLifecycle/remoteMessageProcessor.js +38 -25
  95. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  96. package/dist/packageVersion.d.ts +1 -1
  97. package/dist/packageVersion.js +1 -1
  98. package/dist/packageVersion.js.map +1 -1
  99. package/dist/pendingStateManager.d.ts +4 -20
  100. package/dist/pendingStateManager.d.ts.map +1 -1
  101. package/dist/pendingStateManager.js +36 -46
  102. package/dist/pendingStateManager.js.map +1 -1
  103. package/dist/scheduleManager.js +6 -2
  104. package/dist/scheduleManager.js.map +1 -1
  105. package/dist/summary/orderedClientElection.d.ts +7 -4
  106. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  107. package/dist/summary/orderedClientElection.js +54 -54
  108. package/dist/summary/orderedClientElection.js.map +1 -1
  109. package/dist/summary/runWhileConnectedCoordinator.d.ts +5 -0
  110. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  111. package/dist/summary/runWhileConnectedCoordinator.js +7 -6
  112. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  113. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  114. package/dist/summary/runningSummarizer.js +40 -38
  115. package/dist/summary/runningSummarizer.js.map +1 -1
  116. package/dist/summary/summarizer.d.ts +2 -0
  117. package/dist/summary/summarizer.d.ts.map +1 -1
  118. package/dist/summary/summarizer.js +18 -8
  119. package/dist/summary/summarizer.js.map +1 -1
  120. package/dist/summary/summarizerClientElection.js +6 -6
  121. package/dist/summary/summarizerClientElection.js.map +1 -1
  122. package/dist/summary/summarizerHeuristics.js +9 -9
  123. package/dist/summary/summarizerHeuristics.js.map +1 -1
  124. package/dist/summary/summarizerNode/summarizerNode.d.ts +1 -1
  125. package/dist/summary/summarizerNode/summarizerNode.js +8 -8
  126. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  127. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
  128. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  129. package/dist/summary/summarizerNode/summarizerNodeUtils.js +3 -3
  130. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  131. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -2
  132. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  133. package/dist/summary/summarizerTypes.d.ts +107 -22
  134. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  135. package/dist/summary/summarizerTypes.js.map +1 -1
  136. package/dist/summary/summaryCollection.d.ts +18 -2
  137. package/dist/summary/summaryCollection.d.ts.map +1 -1
  138. package/dist/summary/summaryCollection.js +23 -21
  139. package/dist/summary/summaryCollection.js.map +1 -1
  140. package/dist/summary/summaryFormat.d.ts +15 -6
  141. package/dist/summary/summaryFormat.d.ts.map +1 -1
  142. package/dist/summary/summaryFormat.js.map +1 -1
  143. package/dist/summary/summaryGenerator.d.ts +3 -3
  144. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  145. package/dist/summary/summaryGenerator.js.map +1 -1
  146. package/dist/summary/summaryManager.d.ts +2 -2
  147. package/dist/summary/summaryManager.d.ts.map +1 -1
  148. package/dist/summary/summaryManager.js +10 -10
  149. package/dist/summary/summaryManager.js.map +1 -1
  150. package/dist/throttler.js +16 -16
  151. package/dist/throttler.js.map +1 -1
  152. package/dist/tsdoc-metadata.json +1 -1
  153. package/lib/blobManager.d.ts +4 -4
  154. package/lib/blobManager.d.ts.map +1 -1
  155. package/lib/blobManager.js +56 -72
  156. package/lib/blobManager.js.map +1 -1
  157. package/lib/connectionTelemetry.d.ts.map +1 -1
  158. package/lib/connectionTelemetry.js +76 -43
  159. package/lib/connectionTelemetry.js.map +1 -1
  160. package/lib/containerHandleContext.js +3 -3
  161. package/lib/containerHandleContext.js.map +1 -1
  162. package/lib/containerRuntime.d.ts +88 -98
  163. package/lib/containerRuntime.d.ts.map +1 -1
  164. package/lib/containerRuntime.js +424 -416
  165. package/lib/containerRuntime.js.map +1 -1
  166. package/lib/dataStore.js +11 -11
  167. package/lib/dataStore.js.map +1 -1
  168. package/lib/dataStoreContext.d.ts +2 -4
  169. package/lib/dataStoreContext.d.ts.map +1 -1
  170. package/lib/dataStoreContext.js +60 -59
  171. package/lib/dataStoreContext.js.map +1 -1
  172. package/lib/dataStoreRegistry.d.ts +3 -0
  173. package/lib/dataStoreRegistry.d.ts.map +1 -1
  174. package/lib/dataStoreRegistry.js +6 -3
  175. package/lib/dataStoreRegistry.js.map +1 -1
  176. package/lib/dataStores.js +1 -1
  177. package/lib/dataStores.js.map +1 -1
  178. package/lib/deltaManagerProxyBase.js +4 -4
  179. package/lib/deltaManagerProxyBase.js.map +1 -1
  180. package/lib/deltaManagerSummarizerProxy.js +6 -6
  181. package/lib/deltaManagerSummarizerProxy.js.map +1 -1
  182. package/lib/deltaScheduler.js.map +1 -1
  183. package/lib/error.d.ts.map +1 -1
  184. package/lib/error.js.map +1 -1
  185. package/lib/gc/garbageCollection.d.ts.map +1 -1
  186. package/lib/gc/garbageCollection.js +23 -24
  187. package/lib/gc/garbageCollection.js.map +1 -1
  188. package/lib/gc/gcConfigs.js +2 -2
  189. package/lib/gc/gcConfigs.js.map +1 -1
  190. package/lib/gc/gcDefinitions.d.ts +34 -24
  191. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  192. package/lib/gc/gcDefinitions.js +9 -6
  193. package/lib/gc/gcDefinitions.js.map +1 -1
  194. package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
  195. package/lib/gc/gcSummaryDefinitions.js.map +1 -1
  196. package/lib/gc/gcTelemetry.d.ts +2 -2
  197. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  198. package/lib/gc/gcTelemetry.js +5 -5
  199. package/lib/gc/gcTelemetry.js.map +1 -1
  200. package/lib/gc/gcUnreferencedStateTracker.js +3 -3
  201. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  202. package/lib/gc/index.d.ts +1 -1
  203. package/lib/gc/index.d.ts.map +1 -1
  204. package/lib/gc/index.js +1 -1
  205. package/lib/gc/index.js.map +1 -1
  206. package/lib/id-compressor/appendOnlySortedMap.js.map +1 -1
  207. package/lib/id-compressor/idCompressor.js.map +1 -1
  208. package/lib/id-compressor/identifiers.d.ts +3 -3
  209. package/lib/id-compressor/identifiers.d.ts.map +1 -1
  210. package/lib/id-compressor/utilities.d.ts +3 -0
  211. package/lib/id-compressor/utilities.d.ts.map +1 -1
  212. package/lib/id-compressor/utilities.js +3 -0
  213. package/lib/id-compressor/utilities.js.map +1 -1
  214. package/lib/index.d.ts +5 -3
  215. package/lib/index.d.ts.map +1 -1
  216. package/lib/index.js +3 -1
  217. package/lib/index.js.map +1 -1
  218. package/lib/messageTypes.d.ts +137 -0
  219. package/lib/messageTypes.d.ts.map +1 -0
  220. package/lib/messageTypes.js +29 -0
  221. package/lib/messageTypes.js.map +1 -0
  222. package/lib/opLifecycle/batchManager.js +6 -6
  223. package/lib/opLifecycle/batchManager.js.map +1 -1
  224. package/lib/opLifecycle/definitions.d.ts +7 -3
  225. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  226. package/lib/opLifecycle/definitions.js.map +1 -1
  227. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  228. package/lib/opLifecycle/opDecompressor.js +0 -4
  229. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  230. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  231. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  232. package/lib/opLifecycle/opSplitter.js +1 -1
  233. package/lib/opLifecycle/opSplitter.js.map +1 -1
  234. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  235. package/lib/opLifecycle/outbox.js +7 -2
  236. package/lib/opLifecycle/outbox.js.map +1 -1
  237. package/lib/opLifecycle/remoteMessageProcessor.d.ts +17 -3
  238. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  239. package/lib/opLifecycle/remoteMessageProcessor.js +37 -24
  240. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  241. package/lib/packageVersion.d.ts +1 -1
  242. package/lib/packageVersion.js +1 -1
  243. package/lib/packageVersion.js.map +1 -1
  244. package/lib/pendingStateManager.d.ts +4 -20
  245. package/lib/pendingStateManager.d.ts.map +1 -1
  246. package/lib/pendingStateManager.js +35 -45
  247. package/lib/pendingStateManager.js.map +1 -1
  248. package/lib/scheduleManager.js +6 -2
  249. package/lib/scheduleManager.js.map +1 -1
  250. package/lib/summary/orderedClientElection.d.ts +7 -4
  251. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  252. package/lib/summary/orderedClientElection.js +54 -54
  253. package/lib/summary/orderedClientElection.js.map +1 -1
  254. package/lib/summary/runWhileConnectedCoordinator.d.ts +5 -0
  255. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  256. package/lib/summary/runWhileConnectedCoordinator.js +7 -6
  257. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  258. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  259. package/lib/summary/runningSummarizer.js +40 -38
  260. package/lib/summary/runningSummarizer.js.map +1 -1
  261. package/lib/summary/summarizer.d.ts +2 -0
  262. package/lib/summary/summarizer.d.ts.map +1 -1
  263. package/lib/summary/summarizer.js +19 -9
  264. package/lib/summary/summarizer.js.map +1 -1
  265. package/lib/summary/summarizerClientElection.js +6 -6
  266. package/lib/summary/summarizerClientElection.js.map +1 -1
  267. package/lib/summary/summarizerHeuristics.js +9 -9
  268. package/lib/summary/summarizerHeuristics.js.map +1 -1
  269. package/lib/summary/summarizerNode/summarizerNode.d.ts +1 -1
  270. package/lib/summary/summarizerNode/summarizerNode.js +8 -8
  271. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  272. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
  273. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  274. package/lib/summary/summarizerNode/summarizerNodeUtils.js +3 -3
  275. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  276. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -2
  277. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  278. package/lib/summary/summarizerTypes.d.ts +107 -22
  279. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  280. package/lib/summary/summarizerTypes.js.map +1 -1
  281. package/lib/summary/summaryCollection.d.ts +18 -2
  282. package/lib/summary/summaryCollection.d.ts.map +1 -1
  283. package/lib/summary/summaryCollection.js +23 -21
  284. package/lib/summary/summaryCollection.js.map +1 -1
  285. package/lib/summary/summaryFormat.d.ts +15 -6
  286. package/lib/summary/summaryFormat.d.ts.map +1 -1
  287. package/lib/summary/summaryFormat.js.map +1 -1
  288. package/lib/summary/summaryGenerator.d.ts +3 -3
  289. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  290. package/lib/summary/summaryGenerator.js.map +1 -1
  291. package/lib/summary/summaryManager.d.ts +2 -2
  292. package/lib/summary/summaryManager.d.ts.map +1 -1
  293. package/lib/summary/summaryManager.js +9 -9
  294. package/lib/summary/summaryManager.js.map +1 -1
  295. package/lib/throttler.js +16 -16
  296. package/lib/throttler.js.map +1 -1
  297. package/package.json +27 -28
  298. package/src/blobManager.ts +64 -77
  299. package/src/connectionTelemetry.ts +97 -52
  300. package/src/containerRuntime.ts +337 -341
  301. package/src/dataStore.ts +3 -3
  302. package/src/dataStoreContext.ts +7 -7
  303. package/src/dataStoreRegistry.ts +3 -0
  304. package/src/dataStores.ts +1 -1
  305. package/src/error.ts +4 -1
  306. package/src/gc/garbageCollection.ts +12 -11
  307. package/src/gc/gcConfigs.ts +3 -3
  308. package/src/gc/gcDefinitions.ts +35 -25
  309. package/src/gc/gcSummaryDefinitions.ts +1 -1
  310. package/src/gc/gcTelemetry.ts +6 -5
  311. package/src/gc/index.ts +2 -2
  312. package/src/id-compressor/utilities.ts +3 -0
  313. package/src/index.ts +21 -5
  314. package/src/messageTypes.ts +228 -0
  315. package/src/opLifecycle/README.md +93 -68
  316. package/src/opLifecycle/definitions.ts +5 -1
  317. package/src/opLifecycle/opDecompressor.ts +0 -8
  318. package/src/opLifecycle/opGroupingManager.ts +2 -4
  319. package/src/opLifecycle/opSplitter.ts +2 -2
  320. package/src/opLifecycle/outbox.ts +3 -0
  321. package/src/opLifecycle/remoteMessageProcessor.ts +54 -33
  322. package/src/packageVersion.ts +1 -1
  323. package/src/pendingStateManager.ts +31 -52
  324. package/src/scheduleManager.ts +2 -0
  325. package/src/summary/orderedClientElection.ts +4 -1
  326. package/src/summary/runWhileConnectedCoordinator.ts +5 -1
  327. package/src/summary/runningSummarizer.ts +3 -1
  328. package/src/summary/summarizer.ts +21 -7
  329. package/src/summary/summarizerNode/summarizerNode.ts +1 -1
  330. package/src/summary/summarizerTypes.ts +96 -11
  331. package/src/summary/summaryCollection.ts +19 -1
  332. package/src/summary/summaryFormat.ts +11 -1
  333. package/src/summary/summaryGenerator.ts +3 -3
  334. package/src/summary/summaryManager.ts +2 -2
  335. package/src/gc/gcEarlyAdoption.md +0 -145
@@ -4,8 +4,11 @@
4
4
  */
5
5
 
6
6
  import {
7
+ IEventSampler,
8
+ ISampledTelemetryLogger,
7
9
  ITelemetryLoggerExt,
8
10
  createChildLogger,
11
+ createSampledLogger,
9
12
  formatTick,
10
13
  } from "@fluidframework/telemetry-utils";
11
14
  import { IDeltaManager } from "@fluidframework/container-definitions";
@@ -53,7 +56,6 @@ interface IOpPerfTimings {
53
56
  }
54
57
 
55
58
  class OpPerfTelemetry {
56
- private pongCount: number = 0;
57
59
  private pingLatency: number | undefined;
58
60
 
59
61
  // Collab window tracking. This is timestamp of %1000 message.
@@ -61,11 +63,14 @@ class OpPerfTelemetry {
61
63
  private msnTrackingTimestamp: number = 0;
62
64
  // To track round trip time for every %500 client message.
63
65
  private clientSequenceNumberForLatencyStatistics: number | undefined;
64
-
65
- private opProcessingTimes: Partial<IOpPerfTimings> = {};
66
-
67
66
  // Performance Data to be reported for ops round trips and processing.
68
- private opPerfData: Partial<IOpPerfTelemetryProperties> = {};
67
+ private readonly latencyStatistics = new Map<
68
+ number,
69
+ {
70
+ opProcessingTimes: Partial<IOpPerfTimings>;
71
+ opPerfData: Partial<IOpPerfTelemetryProperties>;
72
+ }
73
+ >();
69
74
 
70
75
  private firstConnection = true;
71
76
  private connectionOpSeqNumber: number | undefined;
@@ -75,6 +80,12 @@ class OpPerfTelemetry {
75
80
 
76
81
  private readonly logger: ITelemetryLoggerExt;
77
82
 
83
+ private static readonly OP_LATENCY_SAMPLE_RATE = 500;
84
+ private readonly opLatencyLogger: ISampledTelemetryLogger;
85
+
86
+ private static readonly DELTA_LATENCY_SAMPLE_RATE = 100;
87
+ private readonly deltaLatencyLogger: ISampledTelemetryLogger;
88
+
78
89
  public constructor(
79
90
  private clientId: string | undefined,
80
91
  private readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
@@ -82,6 +93,28 @@ class OpPerfTelemetry {
82
93
  ) {
83
94
  this.logger = createChildLogger({ logger, namespace: "OpPerf" });
84
95
 
96
+ const deltaLatencyEventSampler: IEventSampler = (() => {
97
+ let eventCount = -1;
98
+ return {
99
+ sample: () => {
100
+ eventCount++;
101
+ const shouldSample =
102
+ eventCount % OpPerfTelemetry.DELTA_LATENCY_SAMPLE_RATE === 0;
103
+ if (shouldSample) {
104
+ eventCount = 0;
105
+ }
106
+ return shouldSample;
107
+ },
108
+ };
109
+ })();
110
+
111
+ this.deltaLatencyLogger = createSampledLogger(logger, deltaLatencyEventSampler);
112
+
113
+ // The SampledLogger here is used get access to the isSamplingDisabled property dervied from
114
+ // telemetry config properties. The actual sampling logic for op messages happens outside this SampledLogger
115
+ // due to complexity of the different asynchronus scenarios of the op message lifecycle.
116
+ this.opLatencyLogger = createSampledLogger(logger);
117
+
85
118
  this.deltaManager.on("pong", (latency) => this.recordPingTime(latency));
86
119
  this.deltaManager.on("submitOp", (message) => this.beforeOpSubmit(message));
87
120
 
@@ -103,42 +136,47 @@ class OpPerfTelemetry {
103
136
  this.deltaManager.on("disconnect", () => {
104
137
  this.sequenceNumberForMsnTracking = undefined;
105
138
  this.clientSequenceNumberForLatencyStatistics = undefined;
106
- this.opProcessingTimes = {};
107
- this.opPerfData = {};
108
139
  this.connectionOpSeqNumber = undefined;
109
140
  this.firstConnection = false;
110
- this.pongCount = 0;
141
+ this.latencyStatistics.clear();
111
142
  });
112
143
 
113
144
  this.deltaManager.outbound.on("push", (messages) => {
114
145
  for (const msg of messages) {
115
146
  if (
116
147
  msg.type === MessageType.Operation &&
117
- this.clientSequenceNumberForLatencyStatistics === msg.clientSequenceNumber
148
+ (this.opLatencyLogger.isSamplingDisabled ||
149
+ this.clientSequenceNumberForLatencyStatistics === msg.clientSequenceNumber)
118
150
  ) {
151
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
152
+ const latencyStats = this.latencyStatistics.get(msg.clientSequenceNumber)!;
153
+ assert(
154
+ latencyStats !== undefined,
155
+ 0x7c2 /* Latency stats for op should exist */,
156
+ );
119
157
  assert(
120
- this.opProcessingTimes.outboundPushEventTime === undefined,
158
+ latencyStats.opProcessingTimes.outboundPushEventTime === undefined,
121
159
  0x2c8 /* "outboundPushEventTime should be undefined" */,
122
160
  );
123
161
  assert(
124
- this.opPerfData.durationNetwork === undefined,
162
+ latencyStats.opPerfData.durationNetwork === undefined,
125
163
  0x2c9 /* "durationNetwork should be undefined" */,
126
164
  );
127
- this.opProcessingTimes.outboundPushEventTime = Date.now();
165
+ latencyStats.opProcessingTimes.outboundPushEventTime = Date.now();
128
166
 
129
167
  assert(
130
- this.opPerfData.durationOutboundBatching === undefined,
168
+ latencyStats.opPerfData.durationOutboundBatching === undefined,
131
169
  0x2ca /* "durationOutboundBatching should be undefined" */,
132
170
  );
133
171
 
134
172
  assert(
135
- this.opProcessingTimes.submitOpEventTime !== undefined,
173
+ latencyStats.opProcessingTimes.submitOpEventTime !== undefined,
136
174
  0x2cb /* "submitOpEventTime should be undefined" */,
137
175
  );
138
176
 
139
- this.opPerfData.durationOutboundBatching =
140
- this.opProcessingTimes.outboundPushEventTime -
141
- this.opProcessingTimes.submitOpEventTime;
177
+ latencyStats.opPerfData.durationOutboundBatching =
178
+ latencyStats.opProcessingTimes.outboundPushEventTime -
179
+ latencyStats.opProcessingTimes.submitOpEventTime;
142
180
  }
143
181
  }
144
182
  });
@@ -147,15 +185,20 @@ class OpPerfTelemetry {
147
185
  if (
148
186
  this.clientId === message.clientId &&
149
187
  message.type === MessageType.Operation &&
150
- this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber &&
151
- this.opProcessingTimes.outboundPushEventTime !== undefined
188
+ (this.opLatencyLogger.isSamplingDisabled ||
189
+ this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber)
152
190
  ) {
153
- this.opProcessingTimes.inboundPushEventTime = Date.now();
154
- this.opPerfData.durationNetwork =
155
- this.opProcessingTimes.inboundPushEventTime -
156
- this.opProcessingTimes.outboundPushEventTime;
157
- this.opProcessingTimes.outboundPushEventTime = undefined;
158
- this.opPerfData.lengthInboundQueue = this.deltaManager.inbound.length;
191
+ // We do an explicit check for undefined right after this
192
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
193
+ const latencyStats = this.latencyStatistics.get(message.clientSequenceNumber)!;
194
+ assert(latencyStats !== undefined, 0x7c3 /* Latency stats for op should exist */);
195
+ if (latencyStats.opProcessingTimes.outboundPushEventTime !== undefined) {
196
+ latencyStats.opProcessingTimes.inboundPushEventTime = Date.now();
197
+ latencyStats.opPerfData.durationNetwork =
198
+ latencyStats.opProcessingTimes.inboundPushEventTime -
199
+ latencyStats.opProcessingTimes.outboundPushEventTime;
200
+ latencyStats.opPerfData.lengthInboundQueue = this.deltaManager.inbound.length;
201
+ }
159
202
  }
160
203
  });
161
204
 
@@ -201,32 +244,33 @@ class OpPerfTelemetry {
201
244
  });
202
245
  }
203
246
 
204
- // logging one in every 100 pongs, including the first time, if it is a "write" client.
205
- if (this.pongCount % 100 === 0 && this.deltaManager.active) {
206
- this.logger.sendPerformanceEvent({
247
+ // logging one in every DELTA_LATENCY_SAMPLE_RATE pongs, including the first time, if it is a "write" client.
248
+ if (this.deltaManager.active) {
249
+ this.deltaLatencyLogger.sendPerformanceEvent({
207
250
  eventName: "DeltaLatency",
208
251
  duration: latency,
209
252
  });
210
253
  }
211
- this.pongCount++;
212
254
  }
213
255
 
214
256
  private beforeOpSubmit(message: IDocumentMessage) {
215
257
  // start with first client op and measure latency every 500 client ops
216
258
  if (
217
- this.clientSequenceNumberForLatencyStatistics === undefined &&
218
- message.clientSequenceNumber % 500 === 1
259
+ this.opLatencyLogger.isSamplingDisabled ||
260
+ (this.clientSequenceNumberForLatencyStatistics === undefined &&
261
+ message.clientSequenceNumber % OpPerfTelemetry.OP_LATENCY_SAMPLE_RATE === 1)
219
262
  ) {
220
263
  assert(
221
- this.opProcessingTimes.outboundPushEventTime === undefined,
222
- 0x2cc /* "OpTimeSittingInboundQueue should be undefined" */,
223
- );
224
- assert(
225
- this.opPerfData.durationNetwork === undefined,
226
- 0x2cd /* "durationNetwork should be undefined" */,
264
+ this.latencyStatistics.get(message.clientSequenceNumber) === undefined,
265
+ 0x7c4 /* Existing op perf data for client sequence number */,
227
266
  );
228
- this.opProcessingTimes.submitOpEventTime = Date.now();
229
267
  this.clientSequenceNumberForLatencyStatistics = message.clientSequenceNumber;
268
+ this.latencyStatistics.set(message.clientSequenceNumber, {
269
+ opProcessingTimes: {
270
+ submitOpEventTime: Date.now(),
271
+ },
272
+ opPerfData: {},
273
+ });
230
274
  }
231
275
  }
232
276
 
@@ -261,20 +305,23 @@ class OpPerfTelemetry {
261
305
 
262
306
  if (
263
307
  this.clientId === message.clientId &&
264
- this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber
308
+ (this.opLatencyLogger.isSamplingDisabled ||
309
+ this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber)
265
310
  ) {
311
+ // We do an explicit check for undefined right after this
312
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
313
+ const latencyData = this.latencyStatistics.get(message.clientSequenceNumber)!;
314
+ assert(latencyData !== undefined, 0x7c5 /* Undefined latency statistics for op */);
266
315
  assert(
267
- this.opProcessingTimes.submitOpEventTime !== undefined,
268
- 0x120 /* "Undefined latency statistics (op send time)" */,
316
+ latencyData.opProcessingTimes.submitOpEventTime !== undefined,
317
+ 0x120 /* "Undefined latency statistics for op (op send time)" */,
269
318
  );
270
319
  const currentTime = Date.now();
271
-
272
- if (this.opProcessingTimes.inboundPushEventTime !== undefined) {
273
- this.opPerfData.durationInboundToProcessing =
274
- currentTime - this.opProcessingTimes.inboundPushEventTime;
320
+ if (latencyData.opProcessingTimes.inboundPushEventTime !== undefined) {
321
+ latencyData.opPerfData.durationInboundToProcessing =
322
+ currentTime - latencyData.opProcessingTimes.inboundPushEventTime;
275
323
  }
276
-
277
- const duration = currentTime - this.opProcessingTimes.submitOpEventTime;
324
+ const duration = currentTime - latencyData.opProcessingTimes.submitOpEventTime;
278
325
 
279
326
  // One of the core expectations for Fluid service is to be fast.
280
327
  // When it's not the case, we want to learn about it and be able to investigate, so
@@ -284,8 +331,7 @@ class OpPerfTelemetry {
284
331
  // The threshold could be adjusted, but ideally it stays workload-agnostic, as service
285
332
  // performance impacts all workloads relying on service.
286
333
  const category = duration > latencyThreshold ? "error" : "performance";
287
-
288
- this.logger.sendPerformanceEvent({
334
+ this.opLatencyLogger.sendPerformanceEvent({
289
335
  eventName: "OpRoundtripTime",
290
336
  sequenceNumber,
291
337
  referenceSequenceNumber: message.referenceSequenceNumber,
@@ -294,11 +340,10 @@ class OpPerfTelemetry {
294
340
  pingLatency: this.pingLatency,
295
341
  msnDistance:
296
342
  this.deltaManager.lastSequenceNumber - this.deltaManager.minimumSequenceNumber,
297
- ...this.opPerfData,
343
+ ...latencyData.opPerfData,
298
344
  });
299
345
  this.clientSequenceNumberForLatencyStatistics = undefined;
300
- this.opPerfData = {};
301
- this.opProcessingTimes = {};
346
+ this.latencyStatistics.delete(message.clientSequenceNumber);
302
347
  }
303
348
  }
304
349
  }