@fluidframework/container-runtime 2.0.0-internal.3.1.0 → 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 (351) hide show
  1. package/dist/blobManager.d.ts +6 -0
  2. package/dist/blobManager.d.ts.map +1 -1
  3. package/dist/blobManager.js +31 -6
  4. package/dist/blobManager.js.map +1 -1
  5. package/dist/containerRuntime.d.ts +17 -15
  6. package/dist/containerRuntime.d.ts.map +1 -1
  7. package/dist/containerRuntime.js +158 -121
  8. package/dist/containerRuntime.js.map +1 -1
  9. package/dist/dataStoreContext.d.ts +21 -12
  10. package/dist/dataStoreContext.d.ts.map +1 -1
  11. package/dist/dataStoreContext.js +76 -50
  12. package/dist/dataStoreContext.js.map +1 -1
  13. package/dist/dataStores.d.ts +9 -10
  14. package/dist/dataStores.d.ts.map +1 -1
  15. package/dist/dataStores.js +42 -49
  16. package/dist/dataStores.js.map +1 -1
  17. package/dist/{garbageCollection.d.ts → gc/garbageCollection.d.ts} +5 -200
  18. package/dist/gc/garbageCollection.d.ts.map +1 -0
  19. package/dist/{garbageCollection.js → gc/garbageCollection.js} +77 -353
  20. package/dist/gc/garbageCollection.js.map +1 -0
  21. package/dist/gc/gcDefinitions.d.ts +189 -0
  22. package/dist/gc/gcDefinitions.d.ts.map +1 -0
  23. package/dist/{garbageCollectionConstants.js → gc/gcDefinitions.js} +24 -2
  24. package/dist/gc/gcDefinitions.js.map +1 -0
  25. package/{lib/garbageCollectionHelpers.d.ts → dist/gc/gcHelpers.d.ts} +5 -1
  26. package/dist/gc/gcHelpers.d.ts.map +1 -0
  27. package/dist/{garbageCollectionHelpers.js → gc/gcHelpers.js} +27 -7
  28. package/dist/gc/gcHelpers.js.map +1 -0
  29. package/dist/gc/gcSummaryStateTracker.d.ts +86 -0
  30. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -0
  31. package/dist/gc/gcSummaryStateTracker.js +246 -0
  32. package/dist/gc/gcSummaryStateTracker.js.map +1 -0
  33. package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  34. package/dist/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +2 -2
  35. package/dist/gc/gcSweepReadyUsageDetection.js.map +1 -0
  36. package/dist/gc/gcUnreferencedStateTracker.d.ts +34 -0
  37. package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  38. package/dist/gc/gcUnreferencedStateTracker.js +94 -0
  39. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -0
  40. package/dist/gc/index.d.ts +11 -0
  41. package/dist/gc/index.d.ts.map +1 -0
  42. package/dist/gc/index.js +40 -0
  43. package/dist/gc/index.js.map +1 -0
  44. package/dist/index.d.ts +2 -5
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +6 -9
  47. package/dist/index.js.map +1 -1
  48. package/dist/opLifecycle/batchManager.d.ts +2 -13
  49. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  50. package/dist/opLifecycle/batchManager.js +7 -36
  51. package/dist/opLifecycle/batchManager.js.map +1 -1
  52. package/dist/opLifecycle/definitions.d.ts +4 -0
  53. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  54. package/dist/opLifecycle/definitions.js.map +1 -1
  55. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  56. package/dist/opLifecycle/opCompressor.js +1 -0
  57. package/dist/opLifecycle/opCompressor.js.map +1 -1
  58. package/dist/opLifecycle/opSplitter.d.ts +1 -1
  59. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  60. package/dist/opLifecycle/opSplitter.js +20 -12
  61. package/dist/opLifecycle/opSplitter.js.map +1 -1
  62. package/dist/opLifecycle/outbox.d.ts +19 -3
  63. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  64. package/dist/opLifecycle/outbox.js +59 -28
  65. package/dist/opLifecycle/outbox.js.map +1 -1
  66. package/dist/packageVersion.d.ts +1 -1
  67. package/dist/packageVersion.js +1 -1
  68. package/dist/packageVersion.js.map +1 -1
  69. package/dist/pendingStateManager.d.ts +1 -2
  70. package/dist/pendingStateManager.d.ts.map +1 -1
  71. package/dist/pendingStateManager.js +14 -9
  72. package/dist/pendingStateManager.js.map +1 -1
  73. package/dist/summary/index.d.ts +17 -0
  74. package/dist/summary/index.d.ts.map +1 -0
  75. package/dist/summary/index.js +47 -0
  76. package/dist/summary/index.js.map +1 -0
  77. package/dist/summary/orderedClientElection.d.ts.map +1 -0
  78. package/dist/summary/orderedClientElection.js.map +1 -0
  79. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  80. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -0
  81. package/{lib → dist/summary}/runningSummarizer.d.ts +19 -18
  82. package/dist/summary/runningSummarizer.d.ts.map +1 -0
  83. package/dist/{runningSummarizer.js → summary/runningSummarizer.js} +158 -56
  84. package/dist/summary/runningSummarizer.js.map +1 -0
  85. package/dist/{summarizer.d.ts → summary/summarizer.d.ts} +2 -4
  86. package/dist/summary/summarizer.d.ts.map +1 -0
  87. package/dist/{summarizer.js → summary/summarizer.js} +1 -61
  88. package/dist/summary/summarizer.js.map +1 -0
  89. package/dist/summary/summarizerClientElection.d.ts.map +1 -0
  90. package/dist/summary/summarizerClientElection.js.map +1 -0
  91. package/dist/summary/summarizerHandle.d.ts.map +1 -0
  92. package/dist/summary/summarizerHandle.js.map +1 -0
  93. package/dist/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +1 -1
  94. package/dist/summary/summarizerHeuristics.d.ts.map +1 -0
  95. package/dist/summary/summarizerHeuristics.js.map +1 -0
  96. package/{lib → dist/summary}/summarizerTypes.d.ts +1 -1
  97. package/dist/summary/summarizerTypes.d.ts.map +1 -0
  98. package/dist/summary/summarizerTypes.js.map +1 -0
  99. package/dist/summary/summaryCollection.d.ts.map +1 -0
  100. package/dist/summary/summaryCollection.js.map +1 -0
  101. package/{lib → dist/summary}/summaryFormat.d.ts +1 -43
  102. package/dist/summary/summaryFormat.d.ts.map +1 -0
  103. package/dist/{summaryFormat.js → summary/summaryFormat.js} +1 -10
  104. package/dist/summary/summaryFormat.js.map +1 -0
  105. package/dist/summary/summaryGenerator.d.ts.map +1 -0
  106. package/dist/{summaryGenerator.js → summary/summaryGenerator.js} +1 -2
  107. package/dist/summary/summaryGenerator.js.map +1 -0
  108. package/dist/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
  109. package/dist/summary/summaryManager.d.ts.map +1 -0
  110. package/dist/summary/summaryManager.js.map +1 -0
  111. package/lib/blobManager.d.ts +6 -0
  112. package/lib/blobManager.d.ts.map +1 -1
  113. package/lib/blobManager.js +28 -3
  114. package/lib/blobManager.js.map +1 -1
  115. package/lib/containerRuntime.d.ts +17 -15
  116. package/lib/containerRuntime.d.ts.map +1 -1
  117. package/lib/containerRuntime.js +127 -90
  118. package/lib/containerRuntime.js.map +1 -1
  119. package/lib/dataStoreContext.d.ts +21 -12
  120. package/lib/dataStoreContext.d.ts.map +1 -1
  121. package/lib/dataStoreContext.js +64 -38
  122. package/lib/dataStoreContext.js.map +1 -1
  123. package/lib/dataStores.d.ts +9 -10
  124. package/lib/dataStores.d.ts.map +1 -1
  125. package/lib/dataStores.js +33 -40
  126. package/lib/dataStores.js.map +1 -1
  127. package/lib/{garbageCollection.d.ts → gc/garbageCollection.d.ts} +5 -200
  128. package/lib/gc/garbageCollection.d.ts.map +1 -0
  129. package/lib/{garbageCollection.js → gc/garbageCollection.js} +44 -319
  130. package/lib/gc/garbageCollection.js.map +1 -0
  131. package/lib/gc/gcDefinitions.d.ts +189 -0
  132. package/lib/gc/gcDefinitions.d.ts.map +1 -0
  133. package/lib/{garbageCollectionConstants.js → gc/gcDefinitions.js} +23 -1
  134. package/lib/gc/gcDefinitions.js.map +1 -0
  135. package/{dist/garbageCollectionHelpers.d.ts → lib/gc/gcHelpers.d.ts} +5 -1
  136. package/lib/gc/gcHelpers.d.ts.map +1 -0
  137. package/lib/{garbageCollectionHelpers.js → gc/gcHelpers.js} +20 -2
  138. package/lib/gc/gcHelpers.js.map +1 -0
  139. package/lib/gc/gcSummaryStateTracker.d.ts +86 -0
  140. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -0
  141. package/lib/gc/gcSummaryStateTracker.js +242 -0
  142. package/lib/gc/gcSummaryStateTracker.js.map +1 -0
  143. package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +1 -0
  144. package/lib/{gcSweepReadyUsageDetection.js → gc/gcSweepReadyUsageDetection.js} +1 -1
  145. package/lib/gc/gcSweepReadyUsageDetection.js.map +1 -0
  146. package/lib/gc/gcUnreferencedStateTracker.d.ts +34 -0
  147. package/lib/gc/gcUnreferencedStateTracker.d.ts.map +1 -0
  148. package/lib/gc/gcUnreferencedStateTracker.js +90 -0
  149. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -0
  150. package/lib/gc/index.d.ts +11 -0
  151. package/lib/gc/index.d.ts.map +1 -0
  152. package/lib/gc/index.js +11 -0
  153. package/lib/gc/index.js.map +1 -0
  154. package/lib/index.d.ts +2 -5
  155. package/lib/index.d.ts.map +1 -1
  156. package/lib/index.js +1 -4
  157. package/lib/index.js.map +1 -1
  158. package/lib/opLifecycle/batchManager.d.ts +2 -13
  159. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  160. package/lib/opLifecycle/batchManager.js +7 -36
  161. package/lib/opLifecycle/batchManager.js.map +1 -1
  162. package/lib/opLifecycle/definitions.d.ts +4 -0
  163. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  164. package/lib/opLifecycle/definitions.js.map +1 -1
  165. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  166. package/lib/opLifecycle/opCompressor.js +1 -0
  167. package/lib/opLifecycle/opCompressor.js.map +1 -1
  168. package/lib/opLifecycle/opSplitter.d.ts +1 -1
  169. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  170. package/lib/opLifecycle/opSplitter.js +20 -12
  171. package/lib/opLifecycle/opSplitter.js.map +1 -1
  172. package/lib/opLifecycle/outbox.d.ts +19 -3
  173. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  174. package/lib/opLifecycle/outbox.js +60 -29
  175. package/lib/opLifecycle/outbox.js.map +1 -1
  176. package/lib/packageVersion.d.ts +1 -1
  177. package/lib/packageVersion.js +1 -1
  178. package/lib/packageVersion.js.map +1 -1
  179. package/lib/pendingStateManager.d.ts +1 -2
  180. package/lib/pendingStateManager.d.ts.map +1 -1
  181. package/lib/pendingStateManager.js +14 -9
  182. package/lib/pendingStateManager.js.map +1 -1
  183. package/lib/summary/index.d.ts +17 -0
  184. package/lib/summary/index.d.ts.map +1 -0
  185. package/lib/summary/index.js +16 -0
  186. package/lib/summary/index.js.map +1 -0
  187. package/lib/summary/orderedClientElection.d.ts.map +1 -0
  188. package/lib/summary/orderedClientElection.js.map +1 -0
  189. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -0
  190. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -0
  191. package/{dist → lib/summary}/runningSummarizer.d.ts +19 -18
  192. package/lib/summary/runningSummarizer.d.ts.map +1 -0
  193. package/lib/{runningSummarizer.js → summary/runningSummarizer.js} +159 -57
  194. package/lib/summary/runningSummarizer.js.map +1 -0
  195. package/lib/{summarizer.d.ts → summary/summarizer.d.ts} +2 -4
  196. package/lib/summary/summarizer.d.ts.map +1 -0
  197. package/lib/{summarizer.js → summary/summarizer.js} +3 -63
  198. package/lib/summary/summarizer.js.map +1 -0
  199. package/lib/summary/summarizerClientElection.d.ts.map +1 -0
  200. package/lib/summary/summarizerClientElection.js.map +1 -0
  201. package/lib/summary/summarizerHandle.d.ts.map +1 -0
  202. package/lib/summary/summarizerHandle.js.map +1 -0
  203. package/lib/{summarizerHeuristics.d.ts → summary/summarizerHeuristics.d.ts} +1 -1
  204. package/lib/summary/summarizerHeuristics.d.ts.map +1 -0
  205. package/lib/summary/summarizerHeuristics.js.map +1 -0
  206. package/{dist → lib/summary}/summarizerTypes.d.ts +1 -1
  207. package/lib/summary/summarizerTypes.d.ts.map +1 -0
  208. package/lib/summary/summarizerTypes.js.map +1 -0
  209. package/lib/summary/summaryCollection.d.ts.map +1 -0
  210. package/lib/summary/summaryCollection.js.map +1 -0
  211. package/{dist → lib/summary}/summaryFormat.d.ts +1 -43
  212. package/lib/summary/summaryFormat.d.ts.map +1 -0
  213. package/lib/{summaryFormat.js → summary/summaryFormat.js} +0 -8
  214. package/lib/summary/summaryFormat.js.map +1 -0
  215. package/lib/summary/summaryGenerator.d.ts.map +1 -0
  216. package/lib/{summaryGenerator.js → summary/summaryGenerator.js} +1 -2
  217. package/lib/summary/summaryGenerator.js.map +1 -0
  218. package/lib/{summaryManager.d.ts → summary/summaryManager.d.ts} +1 -1
  219. package/lib/summary/summaryManager.d.ts.map +1 -0
  220. package/lib/summary/summaryManager.js.map +1 -0
  221. package/package.json +125 -122
  222. package/src/blobManager.ts +33 -3
  223. package/src/containerRuntime.ts +178 -106
  224. package/src/dataStoreContext.ts +90 -49
  225. package/src/dataStores.ts +44 -51
  226. package/{garbageCollection.md → src/gc/garbageCollection.md} +2 -2
  227. package/src/{garbageCollection.ts → gc/garbageCollection.ts} +90 -560
  228. package/src/gc/gcDefinitions.ts +244 -0
  229. package/src/{garbageCollectionHelpers.ts → gc/gcHelpers.ts} +26 -1
  230. package/src/gc/gcSummaryStateTracker.ts +339 -0
  231. package/src/{gcSweepReadyUsageDetection.ts → gc/gcSweepReadyUsageDetection.ts} +1 -1
  232. package/src/gc/gcUnreferencedStateTracker.ts +114 -0
  233. package/src/gc/index.ts +40 -0
  234. package/src/index.ts +10 -14
  235. package/src/opLifecycle/batchManager.ts +7 -54
  236. package/src/opLifecycle/definitions.ts +4 -0
  237. package/src/opLifecycle/opCompressor.ts +1 -0
  238. package/src/opLifecycle/opSplitter.ts +33 -14
  239. package/src/opLifecycle/outbox.ts +84 -38
  240. package/src/packageVersion.ts +1 -1
  241. package/src/pendingStateManager.ts +26 -14
  242. package/src/summary/index.ts +99 -0
  243. package/src/{runningSummarizer.ts → summary/runningSummarizer.ts} +279 -139
  244. package/src/{summarizer.ts → summary/summarizer.ts} +5 -76
  245. package/src/{summarizerHeuristics.ts → summary/summarizerHeuristics.ts} +1 -1
  246. package/src/{summarizerTypes.ts → summary/summarizerTypes.ts} +1 -1
  247. package/src/{summaryFormat.ts → summary/summaryFormat.ts} +1 -53
  248. package/src/{summaryGenerator.ts → summary/summaryGenerator.ts} +9 -9
  249. package/src/{summaryManager.ts → summary/summaryManager.ts} +1 -1
  250. package/dist/garbageCollection.d.ts.map +0 -1
  251. package/dist/garbageCollection.js.map +0 -1
  252. package/dist/garbageCollectionConstants.d.ts +0 -26
  253. package/dist/garbageCollectionConstants.d.ts.map +0 -1
  254. package/dist/garbageCollectionConstants.js.map +0 -1
  255. package/dist/garbageCollectionHelpers.d.ts.map +0 -1
  256. package/dist/garbageCollectionHelpers.js.map +0 -1
  257. package/dist/gcSweepReadyUsageDetection.d.ts.map +0 -1
  258. package/dist/gcSweepReadyUsageDetection.js.map +0 -1
  259. package/dist/orderedClientElection.d.ts.map +0 -1
  260. package/dist/orderedClientElection.js.map +0 -1
  261. package/dist/runWhileConnectedCoordinator.d.ts.map +0 -1
  262. package/dist/runWhileConnectedCoordinator.js.map +0 -1
  263. package/dist/runningSummarizer.d.ts.map +0 -1
  264. package/dist/runningSummarizer.js.map +0 -1
  265. package/dist/summarizer.d.ts.map +0 -1
  266. package/dist/summarizer.js.map +0 -1
  267. package/dist/summarizerClientElection.d.ts.map +0 -1
  268. package/dist/summarizerClientElection.js.map +0 -1
  269. package/dist/summarizerHandle.d.ts.map +0 -1
  270. package/dist/summarizerHandle.js.map +0 -1
  271. package/dist/summarizerHeuristics.d.ts.map +0 -1
  272. package/dist/summarizerHeuristics.js.map +0 -1
  273. package/dist/summarizerTypes.d.ts.map +0 -1
  274. package/dist/summarizerTypes.js.map +0 -1
  275. package/dist/summaryCollection.d.ts.map +0 -1
  276. package/dist/summaryCollection.js.map +0 -1
  277. package/dist/summaryFormat.d.ts.map +0 -1
  278. package/dist/summaryFormat.js.map +0 -1
  279. package/dist/summaryGenerator.d.ts.map +0 -1
  280. package/dist/summaryGenerator.js.map +0 -1
  281. package/dist/summaryManager.d.ts.map +0 -1
  282. package/dist/summaryManager.js.map +0 -1
  283. package/lib/garbageCollection.d.ts.map +0 -1
  284. package/lib/garbageCollection.js.map +0 -1
  285. package/lib/garbageCollectionConstants.d.ts +0 -26
  286. package/lib/garbageCollectionConstants.d.ts.map +0 -1
  287. package/lib/garbageCollectionConstants.js.map +0 -1
  288. package/lib/garbageCollectionHelpers.d.ts.map +0 -1
  289. package/lib/garbageCollectionHelpers.js.map +0 -1
  290. package/lib/gcSweepReadyUsageDetection.d.ts.map +0 -1
  291. package/lib/gcSweepReadyUsageDetection.js.map +0 -1
  292. package/lib/orderedClientElection.d.ts.map +0 -1
  293. package/lib/orderedClientElection.js.map +0 -1
  294. package/lib/runWhileConnectedCoordinator.d.ts.map +0 -1
  295. package/lib/runWhileConnectedCoordinator.js.map +0 -1
  296. package/lib/runningSummarizer.d.ts.map +0 -1
  297. package/lib/runningSummarizer.js.map +0 -1
  298. package/lib/summarizer.d.ts.map +0 -1
  299. package/lib/summarizer.js.map +0 -1
  300. package/lib/summarizerClientElection.d.ts.map +0 -1
  301. package/lib/summarizerClientElection.js.map +0 -1
  302. package/lib/summarizerHandle.d.ts.map +0 -1
  303. package/lib/summarizerHandle.js.map +0 -1
  304. package/lib/summarizerHeuristics.d.ts.map +0 -1
  305. package/lib/summarizerHeuristics.js.map +0 -1
  306. package/lib/summarizerTypes.d.ts.map +0 -1
  307. package/lib/summarizerTypes.js.map +0 -1
  308. package/lib/summaryCollection.d.ts.map +0 -1
  309. package/lib/summaryCollection.js.map +0 -1
  310. package/lib/summaryFormat.d.ts.map +0 -1
  311. package/lib/summaryFormat.js.map +0 -1
  312. package/lib/summaryGenerator.d.ts.map +0 -1
  313. package/lib/summaryGenerator.js.map +0 -1
  314. package/lib/summaryManager.d.ts.map +0 -1
  315. package/lib/summaryManager.js.map +0 -1
  316. package/src/garbageCollectionConstants.ts +0 -44
  317. /package/dist/{gcSweepReadyUsageDetection.d.ts → gc/gcSweepReadyUsageDetection.d.ts} +0 -0
  318. /package/dist/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  319. /package/dist/{orderedClientElection.js → summary/orderedClientElection.js} +0 -0
  320. /package/dist/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +0 -0
  321. /package/dist/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +0 -0
  322. /package/dist/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
  323. /package/dist/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
  324. /package/dist/{summarizerHandle.d.ts → summary/summarizerHandle.d.ts} +0 -0
  325. /package/dist/{summarizerHandle.js → summary/summarizerHandle.js} +0 -0
  326. /package/dist/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +0 -0
  327. /package/dist/{summarizerTypes.js → summary/summarizerTypes.js} +0 -0
  328. /package/dist/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  329. /package/dist/{summaryCollection.js → summary/summaryCollection.js} +0 -0
  330. /package/dist/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
  331. /package/dist/{summaryManager.js → summary/summaryManager.js} +0 -0
  332. /package/lib/{gcSweepReadyUsageDetection.d.ts → gc/gcSweepReadyUsageDetection.d.ts} +0 -0
  333. /package/lib/{orderedClientElection.d.ts → summary/orderedClientElection.d.ts} +0 -0
  334. /package/lib/{orderedClientElection.js → summary/orderedClientElection.js} +0 -0
  335. /package/lib/{runWhileConnectedCoordinator.d.ts → summary/runWhileConnectedCoordinator.d.ts} +0 -0
  336. /package/lib/{runWhileConnectedCoordinator.js → summary/runWhileConnectedCoordinator.js} +0 -0
  337. /package/lib/{summarizerClientElection.d.ts → summary/summarizerClientElection.d.ts} +0 -0
  338. /package/lib/{summarizerClientElection.js → summary/summarizerClientElection.js} +0 -0
  339. /package/lib/{summarizerHandle.d.ts → summary/summarizerHandle.d.ts} +0 -0
  340. /package/lib/{summarizerHandle.js → summary/summarizerHandle.js} +0 -0
  341. /package/lib/{summarizerHeuristics.js → summary/summarizerHeuristics.js} +0 -0
  342. /package/lib/{summarizerTypes.js → summary/summarizerTypes.js} +0 -0
  343. /package/lib/{summaryCollection.d.ts → summary/summaryCollection.d.ts} +0 -0
  344. /package/lib/{summaryCollection.js → summary/summaryCollection.js} +0 -0
  345. /package/lib/{summaryGenerator.d.ts → summary/summaryGenerator.d.ts} +0 -0
  346. /package/lib/{summaryManager.js → summary/summaryManager.js} +0 -0
  347. /package/src/{orderedClientElection.ts → summary/orderedClientElection.ts} +0 -0
  348. /package/src/{runWhileConnectedCoordinator.ts → summary/runWhileConnectedCoordinator.ts} +0 -0
  349. /package/src/{summarizerClientElection.ts → summary/summarizerClientElection.ts} +0 -0
  350. /package/src/{summarizerHandle.ts → summary/summarizerHandle.ts} +0 -0
  351. /package/src/{summaryCollection.ts → summary/summaryCollection.ts} +0 -0
@@ -6,11 +6,17 @@
6
6
  import { IDisposable, ITelemetryLogger } from "@fluidframework/common-definitions";
7
7
  import { assert, delay, Deferred, PromiseTimer } from "@fluidframework/common-utils";
8
8
  import { UsageError } from "@fluidframework/container-utils";
9
+ import { DriverErrorType } from "@fluidframework/driver-definitions";
9
10
  import { isRuntimeMessage } from "@fluidframework/driver-utils";
10
11
  import { ISequencedDocumentMessage, MessageType } from "@fluidframework/protocol-definitions";
11
- import { ChildLogger } from "@fluidframework/telemetry-utils";
12
- import { ISummaryConfiguration } from "./containerRuntime";
13
- import { opSize } from "./opProperties";
12
+ import {
13
+ ChildLogger,
14
+ isFluidError,
15
+ loggerToMonitoringContext,
16
+ MonitoringContext,
17
+ } from "@fluidframework/telemetry-utils";
18
+ import { ISummaryConfiguration } from "../containerRuntime";
19
+ import { opSize } from "../opProperties";
14
20
  import { SummarizeHeuristicRunner } from "./summarizerHeuristics";
15
21
  import {
16
22
  IEnqueueSummarizeOptions,
@@ -27,8 +33,9 @@ import {
27
33
  ISummarizeTelemetryProperties,
28
34
  ISummarizerRuntime,
29
35
  ISummarizeRunnerTelemetry,
36
+ IRefreshSummaryAckOptions,
30
37
  } from "./summarizerTypes";
31
- import { IClientSummaryWatcher, SummaryCollection } from "./summaryCollection";
38
+ import { IAckedSummary, IClientSummaryWatcher, SummaryCollection } from "./summaryCollection";
32
39
  import {
33
40
  raceTimer,
34
41
  SummarizeReason,
@@ -38,6 +45,7 @@ import {
38
45
 
39
46
  const maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes
40
47
 
48
+ const defaultNumberSummarizationAttempts = 2; // only up to 2 attempts
41
49
  /**
42
50
  * An instance of RunningSummarizer manages the heuristics for summarizing.
43
51
  * Until disposed, the instance of RunningSummarizer can assume that it is
@@ -51,6 +59,7 @@ export class RunningSummarizer implements IDisposable {
51
59
  summaryWatcher: IClientSummaryWatcher,
52
60
  configuration: ISummaryConfiguration,
53
61
  submitSummaryCallback: (options: ISubmitSummaryOptions) => Promise<SubmitSummaryResult>,
62
+ refreshLatestSummaryAckCallback: (options: IRefreshSummaryAckOptions) => Promise<void>,
54
63
  heuristicData: ISummarizeHeuristicData,
55
64
  raiseSummarizingError: (errorMessage: string) => void,
56
65
  summaryCollection: SummaryCollection,
@@ -63,6 +72,7 @@ export class RunningSummarizer implements IDisposable {
63
72
  summaryWatcher,
64
73
  configuration,
65
74
  submitSummaryCallback,
75
+ refreshLatestSummaryAckCallback,
66
76
  heuristicData,
67
77
  raiseSummarizingError,
68
78
  summaryCollection,
@@ -71,8 +81,18 @@ export class RunningSummarizer implements IDisposable {
71
81
  runtime,
72
82
  );
73
83
 
84
+ // Before doing any heuristics or proceeding with its refreshing, if there is a summary ack received while
85
+ // this summarizer catches up, let's refresh state before proceeding with the summarization.
86
+ const lastAckRefSeq = await summarizer.handleSummaryAck();
87
+
74
88
  await summarizer.waitStart();
75
89
 
90
+ // Handle summary acks asynchronously
91
+ // Note: no exceptions are thrown from processIncomingSummaryAcks handler as it handles all exceptions
92
+ summarizer.processIncomingSummaryAcks(lastAckRefSeq).catch((error) => {
93
+ logger.sendErrorEvent({ eventName: "HandleSummaryAckFatalError" }, error);
94
+ });
95
+
76
96
  // Update heuristic counts
77
97
  // By the time we get here, there are potentially ops missing from the heuristic summary counts
78
98
  // Examples of where this could happen:
@@ -108,12 +128,12 @@ export class RunningSummarizer implements IDisposable {
108
128
  private stopping = false;
109
129
  private _disposed = false;
110
130
  private summarizingLock: Promise<void> | undefined;
111
- private refreshSummaryAckLock: Promise<void> | undefined;
112
131
  private tryWhileSummarizing = false;
113
132
  private readonly pendingAckTimer: PromiseTimer;
114
133
  private heuristicRunner?: ISummarizeHeuristicRunner;
115
134
  private readonly generator: SummaryGenerator;
116
- private readonly logger: ITelemetryLogger;
135
+ private readonly mc: MonitoringContext;
136
+
117
137
  private enqueuedSummary:
118
138
  | {
119
139
  reason: SummarizeReason;
@@ -133,6 +153,9 @@ export class RunningSummarizer implements IDisposable {
133
153
  private readonly submitSummaryCallback: (
134
154
  options: ISubmitSummaryOptions,
135
155
  ) => Promise<SubmitSummaryResult>,
156
+ private readonly refreshLatestSummaryAckCallback: (
157
+ options: IRefreshSummaryAckOptions,
158
+ ) => Promise<void>,
136
159
  private readonly heuristicData: ISummarizeHeuristicData,
137
160
  private readonly raiseSummarizingError: (errorMessage: string) => void,
138
161
  private readonly summaryCollection: SummaryCollection,
@@ -145,9 +168,11 @@ export class RunningSummarizer implements IDisposable {
145
168
  summarizerSuccessfulAttempts: () => this.totalSuccessfulAttempts,
146
169
  };
147
170
 
148
- this.logger = ChildLogger.create(baseLogger, "Running", {
149
- all: telemetryProps,
150
- });
171
+ this.mc = loggerToMonitoringContext(
172
+ ChildLogger.create(baseLogger, "Running", {
173
+ all: telemetryProps,
174
+ }),
175
+ );
151
176
 
152
177
  if (configuration.state !== "disableHeuristics") {
153
178
  assert(
@@ -158,7 +183,7 @@ export class RunningSummarizer implements IDisposable {
158
183
  heuristicData,
159
184
  this.configuration,
160
185
  (reason) => this.trySummarize(reason),
161
- this.logger,
186
+ this.mc.logger,
162
187
  );
163
188
  }
164
189
 
@@ -178,7 +203,7 @@ export class RunningSummarizer implements IDisposable {
178
203
  // Note: summarizeCount (from ChildLogger definition) may be 0,
179
204
  // since this code path is hit when RunningSummarizer first starts up,
180
205
  // before this instance has kicked off a new summarize run.
181
- this.logger.sendErrorEvent({
206
+ this.mc.logger.sendErrorEvent({
182
207
  eventName: "SummaryAckWaitTimeout",
183
208
  maxAckWaitTime,
184
209
  referenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,
@@ -189,7 +214,7 @@ export class RunningSummarizer implements IDisposable {
189
214
  // Set up pending ack timeout by op timestamp differences for previous summaries.
190
215
  summaryCollection.setPendingAckTimerTimeoutCallback(maxAckWaitTime, () => {
191
216
  if (this.pendingAckTimer.hasTimer) {
192
- this.logger.sendTelemetryEvent({
217
+ this.mc.logger.sendTelemetryEvent({
193
218
  eventName: "MissingSummaryAckFoundByOps",
194
219
  referenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,
195
220
  summarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,
@@ -207,7 +232,7 @@ export class RunningSummarizer implements IDisposable {
207
232
  this.totalSuccessfulAttempts++;
208
233
  },
209
234
  this.summaryWatcher,
210
- this.logger,
235
+ this.mc.logger,
211
236
  );
212
237
 
213
238
  // Listen for ops
@@ -216,6 +241,109 @@ export class RunningSummarizer implements IDisposable {
216
241
  });
217
242
  }
218
243
 
244
+ private async handleSummaryAck(): Promise<number> {
245
+ const lastAck: IAckedSummary | undefined = this.summaryCollection.latestAck;
246
+ let refSequenceNumber = -1;
247
+ // In case we haven't received the lastestAck yet, just return.
248
+ if (lastAck !== undefined) {
249
+ refSequenceNumber = lastAck.summaryOp.referenceSequenceNumber;
250
+ const summaryLogger = this.tryGetCorrelatedLogger(refSequenceNumber) ?? this.mc.logger;
251
+ try {
252
+ const summaryOpHandle = lastAck.summaryOp.contents.handle;
253
+ const summaryAckHandle = lastAck.summaryAck.contents.handle;
254
+ while (this.summarizingLock !== undefined) {
255
+ summaryLogger.sendTelemetryEvent({
256
+ eventName: "RefreshAttemptWithSummarizerRunning",
257
+ referenceSequenceNumber: refSequenceNumber,
258
+ proposalHandle: summaryOpHandle,
259
+ ackHandle: summaryAckHandle,
260
+ });
261
+ await this.summarizingLock;
262
+ }
263
+
264
+ // Make sure we block any summarizer from being executed/enqueued while
265
+ // executing the refreshLatestSummaryAck.
266
+ // https://dev.azure.com/fluidframework/internal/_workitems/edit/779
267
+ await this.lockedSummaryAction(
268
+ () => {},
269
+ async () =>
270
+ this.refreshLatestSummaryAckCallback({
271
+ proposalHandle: summaryOpHandle,
272
+ ackHandle: summaryAckHandle,
273
+ summaryRefSeq: refSequenceNumber,
274
+ summaryLogger,
275
+ }).catch(async (error) => {
276
+ // If the error is 404, so maybe the fetched version no longer exists on server. We just
277
+ // ignore this error in that case, as that means we will have another summaryAck for the
278
+ // latest version with which we will refresh the state. However in case of single commit
279
+ // summary, we might me missing a summary ack, so in that case we are still fine as the
280
+ // code in `submitSummary` function in container runtime, will refresh the latest state
281
+ // by calling `refreshLatestSummaryAckFromServer` and we will be fine.
282
+ if (
283
+ isFluidError(error) &&
284
+ error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError
285
+ ) {
286
+ summaryLogger.sendTelemetryEvent(
287
+ {
288
+ eventName: "HandleSummaryAckErrorIgnored",
289
+ referenceSequenceNumber: refSequenceNumber,
290
+ proposalHandle: summaryOpHandle,
291
+ ackHandle: summaryAckHandle,
292
+ },
293
+ error,
294
+ );
295
+ } else {
296
+ throw error;
297
+ }
298
+ }),
299
+ () => {},
300
+ );
301
+ } catch (error) {
302
+ summaryLogger.sendErrorEvent(
303
+ {
304
+ eventName: "HandleLastSummaryAckError",
305
+ referenceSequenceNumber: refSequenceNumber,
306
+ handle: lastAck?.summaryOp?.contents?.handle,
307
+ ackHandle: lastAck?.summaryAck?.contents?.handle,
308
+ },
309
+ error,
310
+ );
311
+ }
312
+ refSequenceNumber++;
313
+ }
314
+ return refSequenceNumber;
315
+ }
316
+
317
+ /**
318
+ * Responsible for receiving and processing all the summaryAcks.
319
+ * In case there was a summary ack processed by the running summarizer before processIncomingSummaryAcks is called,
320
+ * it will wait for the summary ack that is newer than the one indicated by the lastAckRefSeq.
321
+ * @param lastAckRefSeq - Identifies the minimum reference sequence number the summarizer needs to wait for.
322
+ * In case of a negative number, the summarizer will wait for ANY summary ack that is greater than the deltaManager's initial sequence number,
323
+ * and, in case of a positive one, it will wait for a summary ack that is greater than this current reference sequence number.
324
+ */
325
+ private async processIncomingSummaryAcks(lastAckRefSeq: number) {
326
+ let refSequenceNumber =
327
+ lastAckRefSeq > 0 ? lastAckRefSeq : this.runtime.deltaManager.initialSequenceNumber;
328
+ while (!this.disposed) {
329
+ const summaryLogger = this.tryGetCorrelatedLogger(refSequenceNumber) ?? this.mc.logger;
330
+
331
+ // Initialize ack with undefined if exception happens inside of waitSummaryAck on second iteration,
332
+ // we record undefined, not previous handles.
333
+ await this.summaryCollection.waitSummaryAck(refSequenceNumber);
334
+
335
+ summaryLogger.sendTelemetryEvent({
336
+ eventName: "processIncomingSummaryAcks",
337
+ referenceSequenceNumber: refSequenceNumber,
338
+ lastAckRefSeq,
339
+ });
340
+
341
+ refSequenceNumber = await this.handleSummaryAck();
342
+ // A valid Summary Ack must have been processed.
343
+ assert(refSequenceNumber >= 0, 0x58f /* Invalid ref sequence number */);
344
+ }
345
+ }
346
+
219
347
  public dispose(): void {
220
348
  this.runtime.deltaManager.off("op", (op) => {
221
349
  this.handleOp(op);
@@ -238,7 +366,7 @@ export class RunningSummarizer implements IDisposable {
238
366
  */
239
367
  public tryGetCorrelatedLogger = (summaryOpRefSeq) =>
240
368
  this.heuristicData.lastAttempt.refSequenceNumber === summaryOpRefSeq
241
- ? this.logger
369
+ ? this.mc.logger
242
370
  : undefined;
243
371
 
244
372
  /** We only want a single heuristic runner micro-task (will provide better optimized grouping of ops) */
@@ -353,41 +481,35 @@ export class RunningSummarizer implements IDisposable {
353
481
  this.initialized = true;
354
482
  }
355
483
 
356
- /**
357
- * Blocks a new summarizer from running in case RefreshSummaryAck is being processed.
358
- * Assumes that caller checked upfront for lack of concurrent action (this.refreshSummaryAckLock)
359
- * before calling this API. I.e. caller is responsible for either erroring out or waiting on this promise.
360
- * Note: The refreshSummaryAckLock makes sure no summarizer gets enqueued or processed
361
- * until the refresh has completed. One can't rely uniquely on the summarizingLock as the
362
- * refreshLatestSummaryAck also happens during the time summarizingLock !== undefined.
363
- * Ex. Summarizer submits a summay + op and then waits for the Summary Ack to proceed
364
- * with the refreshLatestSummaryAck and complete the summary.
365
- * @param action - action to perform.
366
- * @returns - result of action.
367
- */
368
- public async lockedRefreshSummaryAckAction<T>(action: () => Promise<T>) {
369
- assert(
370
- this.refreshSummaryAckLock === undefined,
371
- 0x396 /* Refresh Summary Ack - Caller is responsible for checking lock */,
372
- );
484
+ private beforeSummaryAction() {
485
+ this.summarizeCount++;
486
+ }
373
487
 
374
- const refreshSummaryAckLock = new Deferred<void>();
375
- this.refreshSummaryAckLock = refreshSummaryAckLock.promise;
488
+ private afterSummaryAction() {
489
+ const retry = this.tryWhileSummarizing;
490
+ this.tryWhileSummarizing = false;
376
491
 
377
- return action().finally(() => {
378
- refreshSummaryAckLock.resolve();
379
- this.refreshSummaryAckLock = undefined;
380
- });
492
+ // After summarizing, we should check to see if we need to summarize again.
493
+ // Rerun the heuristics and check for enqueued summaries.
494
+ if (!this.stopping && !this.tryRunEnqueuedSummary() && retry) {
495
+ this.heuristicRunner?.run();
496
+ }
381
497
  }
382
498
 
383
499
  /**
384
500
  * Runs single summary action that prevents any other concurrent actions.
385
501
  * Assumes that caller checked upfront for lack of concurrent action (this.summarizingLock)
386
502
  * before calling this API. I.e. caller is responsible for either erroring out or waiting on this promise.
503
+ * @param before - set of instructions to run before running the action.
387
504
  * @param action - action to perform.
505
+ * @param after - set of instructions to run after running the action.
388
506
  * @returns - result of action.
389
507
  */
390
- private async lockedSummaryAction<T>(action: () => Promise<T>) {
508
+ private async lockedSummaryAction<T>(
509
+ before: () => void,
510
+ action: () => Promise<T>,
511
+ after: () => void,
512
+ ) {
391
513
  assert(
392
514
  this.summarizingLock === undefined,
393
515
  0x25b /* "Caller is responsible for checking lock" */,
@@ -396,22 +518,12 @@ export class RunningSummarizer implements IDisposable {
396
518
  const summarizingLock = new Deferred<void>();
397
519
  this.summarizingLock = summarizingLock.promise;
398
520
 
399
- this.summarizeCount++;
400
- // Make sure the RefreshLatestSummaryAck is not being executed.
401
- await this.refreshSummaryAckLock;
521
+ before();
402
522
 
403
523
  return action().finally(() => {
404
524
  summarizingLock.resolve();
405
525
  this.summarizingLock = undefined;
406
-
407
- const retry = this.tryWhileSummarizing;
408
- this.tryWhileSummarizing = false;
409
-
410
- // After summarizing, we should check to see if we need to summarize again.
411
- // Rerun the heuristics and check for enqueued summaries.
412
- if (!this.stopping && !this.tryRunEnqueuedSummary() && retry) {
413
- this.heuristicRunner?.run();
414
- }
526
+ after();
415
527
  });
416
528
  }
417
529
 
@@ -429,16 +541,24 @@ export class RunningSummarizer implements IDisposable {
429
541
  cancellationToken = this.cancellationToken,
430
542
  resultsBuilder = new SummarizeResultBuilder(),
431
543
  ): ISummarizeResults {
432
- this.lockedSummaryAction(async () => {
433
- const summarizeResult = this.generator.summarize(
434
- summarizeProps,
435
- options,
436
- cancellationToken,
437
- resultsBuilder,
438
- );
439
- // ensure we wait till the end of the process
440
- return summarizeResult.receivedSummaryAckOrNack;
441
- }).catch((error) => {
544
+ this.lockedSummaryAction(
545
+ () => {
546
+ this.beforeSummaryAction();
547
+ },
548
+ async () => {
549
+ const summarizeResult = this.generator.summarize(
550
+ summarizeProps,
551
+ options,
552
+ cancellationToken,
553
+ resultsBuilder,
554
+ );
555
+ // ensure we wait till the end of the process
556
+ return summarizeResult.receivedSummaryAckOrNack;
557
+ },
558
+ () => {
559
+ this.afterSummaryAction();
560
+ },
561
+ ).catch((error) => {
442
562
  // SummaryGenerator.summarize() does not throw exceptions - it converts them to failed result
443
563
  // on resultsBuilder
444
564
  // We do not care about exceptions on receivedSummaryAckOrNack - caller should check results
@@ -460,91 +580,111 @@ export class RunningSummarizer implements IDisposable {
460
580
  return;
461
581
  }
462
582
 
463
- this.lockedSummaryAction(async () => {
464
- const attempts: (ISummarizeOptions & { delaySeconds?: number })[] = [
465
- { refreshLatestAck: false, fullTree: false },
466
- { refreshLatestAck: true, fullTree: false },
467
- { refreshLatestAck: true, fullTree: false, delaySeconds: 2 * 60 },
468
- { refreshLatestAck: true, fullTree: true, delaySeconds: 10 * 60 },
469
- ];
470
- let overrideDelaySeconds: number | undefined;
471
- let summaryAttempts = 0;
472
- let summaryAttemptsPerPhase = 0;
473
-
474
- let lastResult: { message: string; error: any } | undefined;
475
-
476
- for (let summaryAttemptPhase = 0; summaryAttemptPhase < attempts.length; ) {
477
- if (this.cancellationToken.cancelled) {
478
- return;
479
- }
480
-
481
- // We only want to attempt 1 summary when reason is "lastSummary"
482
- if (++summaryAttempts > 1 && reason === "lastSummary") {
483
- return;
484
- }
485
-
486
- summaryAttemptsPerPhase++;
487
-
488
- const { delaySeconds: regularDelaySeconds = 0, ...options } =
489
- attempts[summaryAttemptPhase];
490
- const delaySeconds = overrideDelaySeconds ?? regularDelaySeconds;
491
-
492
- const summarizeProps: ISummarizeTelemetryProperties = {
493
- reason,
494
- summaryAttempts,
495
- summaryAttemptsPerPhase,
496
- summaryAttemptPhase: summaryAttemptPhase + 1, // make everything 1-based
497
- ...options,
498
- };
499
-
500
- if (delaySeconds > 0) {
501
- this.logger.sendPerformanceEvent({
502
- eventName: "SummarizeAttemptDelay",
503
- duration: delaySeconds,
504
- summaryNackDelay: overrideDelaySeconds !== undefined,
505
- ...summarizeProps,
583
+ this.lockedSummaryAction(
584
+ () => {
585
+ this.beforeSummaryAction();
586
+ },
587
+ async () => {
588
+ const attempts: (ISummarizeOptions & { delaySeconds?: number })[] = [
589
+ { refreshLatestAck: false, fullTree: false },
590
+ { refreshLatestAck: true, fullTree: false },
591
+ { refreshLatestAck: true, fullTree: false, delaySeconds: 2 * 60 },
592
+ { refreshLatestAck: true, fullTree: true, delaySeconds: 10 * 60 },
593
+ ];
594
+ let overrideDelaySeconds: number | undefined;
595
+ let summaryAttempts = 0;
596
+ let summaryAttemptsPerPhase = 0;
597
+ // Reducing the default number of attempts to defaultNumberofSummarizationAttempts.
598
+ let totalAttempts =
599
+ this.mc.config.getNumber("Fluid.Summarizer.Attempts") ??
600
+ defaultNumberSummarizationAttempts;
601
+
602
+ if (totalAttempts > attempts.length) {
603
+ this.mc.logger.sendTelemetryEvent({
604
+ eventName: "InvalidSummarizerAttempts",
605
+ attempts: totalAttempts,
506
606
  });
507
- await delay(delaySeconds * 1000);
607
+ totalAttempts = defaultNumberSummarizationAttempts;
608
+ } else if (totalAttempts < 1) {
609
+ throw new UsageError("Invalid number of attempts.");
508
610
  }
509
611
 
510
- // Make sure the refresh Summary Ack is not being executed.
511
- await this.refreshSummaryAckLock;
512
-
513
- // Note: no need to account for cancellationToken.waitCancelled here, as
514
- // this is accounted SummaryGenerator.summarizeCore that controls receivedSummaryAckOrNack.
515
- const resultSummarize = this.generator.summarize(
516
- summarizeProps,
517
- options,
518
- cancellationToken,
519
- );
520
- const result = await resultSummarize.receivedSummaryAckOrNack;
521
-
522
- if (result.success) {
523
- return;
524
- }
525
- // Check for retryDelay that can come from summaryNack or upload summary flow.
526
- // Retry the same step only once per retryAfter response.
527
- overrideDelaySeconds = result.retryAfterSeconds;
528
- if (overrideDelaySeconds === undefined || summaryAttemptsPerPhase > 1) {
529
- summaryAttemptPhase++;
530
- summaryAttemptsPerPhase = 0;
612
+ let lastResult: { message: string; error: any } | undefined;
613
+
614
+ for (let summaryAttemptPhase = 0; summaryAttemptPhase < totalAttempts; ) {
615
+ if (this.cancellationToken.cancelled) {
616
+ return;
617
+ }
618
+
619
+ // We only want to attempt 1 summary when reason is "lastSummary"
620
+ if (++summaryAttempts > 1 && reason === "lastSummary") {
621
+ return;
622
+ }
623
+
624
+ summaryAttemptsPerPhase++;
625
+
626
+ const { delaySeconds: regularDelaySeconds = 0, ...options } =
627
+ attempts[summaryAttemptPhase];
628
+
629
+ const summarizeProps: ISummarizeTelemetryProperties = {
630
+ reason,
631
+ summaryAttempts,
632
+ summaryAttemptsPerPhase,
633
+ summaryAttemptPhase: summaryAttemptPhase + 1, // make everything 1-based
634
+ ...options,
635
+ };
636
+
637
+ // Note: no need to account for cancellationToken.waitCancelled here, as
638
+ // this is accounted SummaryGenerator.summarizeCore that controls receivedSummaryAckOrNack.
639
+ const resultSummarize = this.generator.summarize(
640
+ summarizeProps,
641
+ options,
642
+ cancellationToken,
643
+ );
644
+ const result = await resultSummarize.receivedSummaryAckOrNack;
645
+
646
+ if (result.success) {
647
+ return;
648
+ }
649
+ // Check for retryDelay that can come from summaryNack or upload summary flow.
650
+ // Retry the same step only once per retryAfter response.
651
+ overrideDelaySeconds = result.retryAfterSeconds;
652
+ if (overrideDelaySeconds === undefined || summaryAttemptsPerPhase > 1) {
653
+ summaryAttemptPhase++;
654
+ summaryAttemptsPerPhase = 0;
655
+ }
656
+ lastResult = result;
657
+
658
+ const delaySeconds = overrideDelaySeconds ?? regularDelaySeconds;
659
+
660
+ if (delaySeconds > 0) {
661
+ this.mc.logger.sendPerformanceEvent({
662
+ eventName: "SummarizeAttemptDelay",
663
+ duration: delaySeconds,
664
+ summaryNackDelay: overrideDelaySeconds !== undefined,
665
+ ...summarizeProps,
666
+ });
667
+ await delay(delaySeconds * 1000);
668
+ }
531
669
  }
532
- lastResult = result;
533
- }
534
670
 
535
- // If all attempts failed, log error (with last attempt info) and close the summarizer container
536
- this.logger.sendErrorEvent(
537
- {
538
- eventName: "FailToSummarize",
539
- reason,
540
- message: lastResult?.message,
541
- },
542
- lastResult?.error,
543
- );
671
+ // If all attempts failed, log error (with last attempt info) and close the summarizer container
672
+ this.mc.logger.sendErrorEvent(
673
+ {
674
+ eventName: "FailToSummarize",
675
+ reason,
676
+ message: lastResult?.message,
677
+ },
678
+ lastResult?.error,
679
+ );
544
680
 
545
- this.stopSummarizerCallback("failToSummarize");
546
- }).catch((error) => {
547
- this.logger.sendErrorEvent({ eventName: "UnexpectedSummarizeError" }, error);
681
+ this.stopSummarizerCallback("failToSummarize");
682
+ },
683
+ () => {
684
+ this.afterSummaryAction();
685
+ },
686
+ ).catch((error) => {
687
+ this.mc.logger.sendErrorEvent({ eventName: "UnexpectedSummarizeError" }, error);
548
688
  });
549
689
  }
550
690