@fluidframework/container-runtime 2.0.0-dev-rc.5.0.0.263932 → 2.0.0-dev-rc.5.0.0.265721

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 (266) hide show
  1. package/api-report/container-runtime.api.md +31 -40
  2. package/dist/batchTracker.js.map +1 -1
  3. package/dist/blobManager.d.ts +2 -2
  4. package/dist/blobManager.d.ts.map +1 -1
  5. package/dist/blobManager.js +1 -1
  6. package/dist/blobManager.js.map +1 -1
  7. package/dist/channelCollection.d.ts +2 -2
  8. package/dist/channelCollection.d.ts.map +1 -1
  9. package/dist/channelCollection.js +3 -3
  10. package/dist/channelCollection.js.map +1 -1
  11. package/dist/connectionTelemetry.js.map +1 -1
  12. package/dist/containerHandleContext.d.ts +2 -1
  13. package/dist/containerHandleContext.d.ts.map +1 -1
  14. package/dist/containerHandleContext.js.map +1 -1
  15. package/dist/containerRuntime.d.ts +10 -17
  16. package/dist/containerRuntime.d.ts.map +1 -1
  17. package/dist/containerRuntime.js +62 -104
  18. package/dist/containerRuntime.js.map +1 -1
  19. package/dist/dataStore.d.ts.map +1 -1
  20. package/dist/dataStore.js.map +1 -1
  21. package/dist/dataStoreContext.d.ts +6 -6
  22. package/dist/dataStoreContext.d.ts.map +1 -1
  23. package/dist/dataStoreContext.js +3 -3
  24. package/dist/dataStoreContext.js.map +1 -1
  25. package/dist/dataStoreContexts.js.map +1 -1
  26. package/dist/dataStoreRegistry.js.map +1 -1
  27. package/dist/deltaManagerProxies.js.map +1 -1
  28. package/dist/deltaScheduler.js.map +1 -1
  29. package/dist/gc/garbageCollection.d.ts +1 -2
  30. package/dist/gc/garbageCollection.d.ts.map +1 -1
  31. package/dist/gc/garbageCollection.js +1 -1
  32. package/dist/gc/garbageCollection.js.map +1 -1
  33. package/dist/gc/gcConfigs.d.ts.map +1 -1
  34. package/dist/gc/gcConfigs.js +14 -19
  35. package/dist/gc/gcConfigs.js.map +1 -1
  36. package/dist/gc/gcDefinitions.d.ts +4 -22
  37. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  38. package/dist/gc/gcDefinitions.js +3 -3
  39. package/dist/gc/gcDefinitions.js.map +1 -1
  40. package/dist/gc/gcHelpers.d.ts +1 -2
  41. package/dist/gc/gcHelpers.d.ts.map +1 -1
  42. package/dist/gc/gcHelpers.js.map +1 -1
  43. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  44. package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
  45. package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -1
  46. package/dist/gc/gcSummaryDefinitions.js.map +1 -1
  47. package/dist/gc/gcSummaryStateTracker.d.ts +1 -1
  48. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  49. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  50. package/dist/gc/gcTelemetry.d.ts +1 -1
  51. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  52. package/dist/gc/gcTelemetry.js +2 -2
  53. package/dist/gc/gcTelemetry.js.map +1 -1
  54. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  55. package/dist/gc/index.d.ts +1 -1
  56. package/dist/gc/index.d.ts.map +1 -1
  57. package/dist/gc/index.js +2 -2
  58. package/dist/gc/index.js.map +1 -1
  59. package/dist/index.d.ts +1 -1
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js.map +1 -1
  62. package/dist/legacy.d.ts +1 -1
  63. package/dist/opLifecycle/batchManager.js.map +1 -1
  64. package/dist/opLifecycle/opCompressor.js.map +1 -1
  65. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  66. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  67. package/dist/opLifecycle/opSplitter.js.map +1 -1
  68. package/dist/opLifecycle/outbox.d.ts +1 -0
  69. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  70. package/dist/opLifecycle/outbox.js +2 -16
  71. package/dist/opLifecycle/outbox.js.map +1 -1
  72. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  73. package/dist/packageVersion.d.ts +1 -1
  74. package/dist/packageVersion.js +1 -1
  75. package/dist/packageVersion.js.map +1 -1
  76. package/dist/pendingStateManager.js.map +1 -1
  77. package/dist/scheduleManager.js.map +1 -1
  78. package/dist/storageServiceWithAttachBlobs.js.map +1 -1
  79. package/dist/summary/documentSchema.js +1 -1
  80. package/dist/summary/documentSchema.js.map +1 -1
  81. package/dist/summary/index.d.ts +1 -1
  82. package/dist/summary/index.d.ts.map +1 -1
  83. package/dist/summary/index.js.map +1 -1
  84. package/dist/summary/orderedClientElection.d.ts +3 -1
  85. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  86. package/dist/summary/orderedClientElection.js +35 -13
  87. package/dist/summary/orderedClientElection.js.map +1 -1
  88. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  89. package/dist/summary/runningSummarizer.d.ts +0 -5
  90. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  91. package/dist/summary/runningSummarizer.js +19 -104
  92. package/dist/summary/runningSummarizer.js.map +1 -1
  93. package/dist/summary/summarizer.d.ts +1 -1
  94. package/dist/summary/summarizer.d.ts.map +1 -1
  95. package/dist/summary/summarizer.js +4 -1
  96. package/dist/summary/summarizer.js.map +1 -1
  97. package/dist/summary/summarizerClientElection.js.map +1 -1
  98. package/dist/summary/summarizerHeuristics.js.map +1 -1
  99. package/dist/summary/summarizerNode/summarizerNode.d.ts +1 -2
  100. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  101. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  102. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  103. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -2
  104. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  105. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  106. package/dist/summary/summarizerTypes.d.ts +15 -26
  107. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  108. package/dist/summary/summarizerTypes.js.map +1 -1
  109. package/dist/summary/summaryCollection.js +2 -2
  110. package/dist/summary/summaryCollection.js.map +1 -1
  111. package/dist/summary/summaryFormat.d.ts +1 -1
  112. package/dist/summary/summaryFormat.d.ts.map +1 -1
  113. package/dist/summary/summaryFormat.js.map +1 -1
  114. package/dist/summary/summaryGenerator.d.ts +7 -8
  115. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  116. package/dist/summary/summaryGenerator.js +23 -18
  117. package/dist/summary/summaryGenerator.js.map +1 -1
  118. package/dist/summary/summaryManager.js.map +1 -1
  119. package/dist/throttler.js.map +1 -1
  120. package/lib/batchTracker.js.map +1 -1
  121. package/lib/blobManager.d.ts +2 -2
  122. package/lib/blobManager.d.ts.map +1 -1
  123. package/lib/blobManager.js +1 -1
  124. package/lib/blobManager.js.map +1 -1
  125. package/lib/channelCollection.d.ts +2 -2
  126. package/lib/channelCollection.d.ts.map +1 -1
  127. package/lib/channelCollection.js +3 -3
  128. package/lib/channelCollection.js.map +1 -1
  129. package/lib/connectionTelemetry.js.map +1 -1
  130. package/lib/containerHandleContext.d.ts +2 -1
  131. package/lib/containerHandleContext.d.ts.map +1 -1
  132. package/lib/containerHandleContext.js.map +1 -1
  133. package/lib/containerRuntime.d.ts +10 -17
  134. package/lib/containerRuntime.d.ts.map +1 -1
  135. package/lib/containerRuntime.js +62 -104
  136. package/lib/containerRuntime.js.map +1 -1
  137. package/lib/dataStore.d.ts.map +1 -1
  138. package/lib/dataStore.js.map +1 -1
  139. package/lib/dataStoreContext.d.ts +6 -6
  140. package/lib/dataStoreContext.d.ts.map +1 -1
  141. package/lib/dataStoreContext.js +3 -3
  142. package/lib/dataStoreContext.js.map +1 -1
  143. package/lib/dataStoreContexts.js.map +1 -1
  144. package/lib/dataStoreRegistry.js.map +1 -1
  145. package/lib/deltaManagerProxies.js.map +1 -1
  146. package/lib/deltaScheduler.js.map +1 -1
  147. package/lib/gc/garbageCollection.d.ts +1 -2
  148. package/lib/gc/garbageCollection.d.ts.map +1 -1
  149. package/lib/gc/garbageCollection.js +1 -1
  150. package/lib/gc/garbageCollection.js.map +1 -1
  151. package/lib/gc/gcConfigs.d.ts.map +1 -1
  152. package/lib/gc/gcConfigs.js +15 -20
  153. package/lib/gc/gcConfigs.js.map +1 -1
  154. package/lib/gc/gcDefinitions.d.ts +4 -22
  155. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  156. package/lib/gc/gcDefinitions.js +2 -2
  157. package/lib/gc/gcDefinitions.js.map +1 -1
  158. package/lib/gc/gcHelpers.d.ts +1 -2
  159. package/lib/gc/gcHelpers.d.ts.map +1 -1
  160. package/lib/gc/gcHelpers.js.map +1 -1
  161. package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  162. package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
  163. package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -1
  164. package/lib/gc/gcSummaryDefinitions.js.map +1 -1
  165. package/lib/gc/gcSummaryStateTracker.d.ts +1 -1
  166. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  167. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  168. package/lib/gc/gcTelemetry.d.ts +1 -1
  169. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  170. package/lib/gc/gcTelemetry.js +2 -2
  171. package/lib/gc/gcTelemetry.js.map +1 -1
  172. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  173. package/lib/gc/index.d.ts +1 -1
  174. package/lib/gc/index.d.ts.map +1 -1
  175. package/lib/gc/index.js +1 -1
  176. package/lib/gc/index.js.map +1 -1
  177. package/lib/index.d.ts +1 -1
  178. package/lib/index.d.ts.map +1 -1
  179. package/lib/index.js.map +1 -1
  180. package/lib/legacy.d.ts +1 -1
  181. package/lib/opLifecycle/batchManager.js.map +1 -1
  182. package/lib/opLifecycle/opCompressor.js.map +1 -1
  183. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  184. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  185. package/lib/opLifecycle/opSplitter.js.map +1 -1
  186. package/lib/opLifecycle/outbox.d.ts +1 -0
  187. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  188. package/lib/opLifecycle/outbox.js +2 -16
  189. package/lib/opLifecycle/outbox.js.map +1 -1
  190. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  191. package/lib/packageVersion.d.ts +1 -1
  192. package/lib/packageVersion.js +1 -1
  193. package/lib/packageVersion.js.map +1 -1
  194. package/lib/pendingStateManager.js.map +1 -1
  195. package/lib/scheduleManager.js.map +1 -1
  196. package/lib/storageServiceWithAttachBlobs.js.map +1 -1
  197. package/lib/summary/documentSchema.js +1 -1
  198. package/lib/summary/documentSchema.js.map +1 -1
  199. package/lib/summary/index.d.ts +1 -1
  200. package/lib/summary/index.d.ts.map +1 -1
  201. package/lib/summary/index.js.map +1 -1
  202. package/lib/summary/orderedClientElection.d.ts +3 -1
  203. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  204. package/lib/summary/orderedClientElection.js +35 -13
  205. package/lib/summary/orderedClientElection.js.map +1 -1
  206. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  207. package/lib/summary/runningSummarizer.d.ts +0 -5
  208. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  209. package/lib/summary/runningSummarizer.js +20 -105
  210. package/lib/summary/runningSummarizer.js.map +1 -1
  211. package/lib/summary/summarizer.d.ts +1 -1
  212. package/lib/summary/summarizer.d.ts.map +1 -1
  213. package/lib/summary/summarizer.js +4 -1
  214. package/lib/summary/summarizer.js.map +1 -1
  215. package/lib/summary/summarizerClientElection.js.map +1 -1
  216. package/lib/summary/summarizerHeuristics.js.map +1 -1
  217. package/lib/summary/summarizerNode/summarizerNode.d.ts +1 -2
  218. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  219. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  220. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  221. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -2
  222. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  223. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  224. package/lib/summary/summarizerTypes.d.ts +15 -26
  225. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  226. package/lib/summary/summarizerTypes.js.map +1 -1
  227. package/lib/summary/summaryCollection.js +2 -2
  228. package/lib/summary/summaryCollection.js.map +1 -1
  229. package/lib/summary/summaryFormat.d.ts +1 -1
  230. package/lib/summary/summaryFormat.d.ts.map +1 -1
  231. package/lib/summary/summaryFormat.js +1 -1
  232. package/lib/summary/summaryFormat.js.map +1 -1
  233. package/lib/summary/summaryGenerator.d.ts +7 -8
  234. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  235. package/lib/summary/summaryGenerator.js +23 -18
  236. package/lib/summary/summaryGenerator.js.map +1 -1
  237. package/lib/summary/summaryManager.js.map +1 -1
  238. package/lib/throttler.js.map +1 -1
  239. package/package.json +59 -22
  240. package/src/blobManager.ts +3 -3
  241. package/src/channelCollection.ts +5 -7
  242. package/src/containerHandleContext.ts +2 -1
  243. package/src/containerRuntime.ts +72 -121
  244. package/src/dataStore.ts +2 -1
  245. package/src/dataStoreContext.ts +7 -8
  246. package/src/gc/garbageCollection.md +0 -8
  247. package/src/gc/garbageCollection.ts +2 -1
  248. package/src/gc/gcConfigs.ts +12 -19
  249. package/src/gc/gcDefinitions.ts +5 -23
  250. package/src/gc/gcHelpers.ts +1 -1
  251. package/src/gc/gcSummaryDefinitions.ts +1 -1
  252. package/src/gc/gcSummaryStateTracker.ts +1 -1
  253. package/src/gc/gcTelemetry.ts +1 -1
  254. package/src/gc/index.ts +1 -1
  255. package/src/index.ts +1 -1
  256. package/src/opLifecycle/outbox.ts +2 -26
  257. package/src/packageVersion.ts +1 -1
  258. package/src/summary/index.ts +1 -1
  259. package/src/summary/orderedClientElection.ts +82 -11
  260. package/src/summary/runningSummarizer.ts +29 -113
  261. package/src/summary/summarizer.ts +5 -2
  262. package/src/summary/summarizerNode/summarizerNode.ts +0 -2
  263. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +1 -3
  264. package/src/summary/summarizerTypes.ts +21 -27
  265. package/src/summary/summaryFormat.ts +5 -2
  266. package/src/summary/summaryGenerator.ts +49 -26
package/src/index.ts CHANGED
@@ -97,7 +97,7 @@ export {
97
97
  ICancellableSummarizerController,
98
98
  SubmitSummaryFailureData,
99
99
  SummaryStage,
100
- IRetriableFailureResult,
100
+ IRetriableFailureError,
101
101
  ISummarizeEventProps,
102
102
  IdCompressorMode,
103
103
  IDocumentSchema,
@@ -201,32 +201,7 @@ export class Outbox {
201
201
  public submitIdAllocation(message: BatchMessage) {
202
202
  this.maybeFlushPartialBatch();
203
203
 
204
- if (
205
- !this.idAllocationBatch.push(
206
- message,
207
- this.isContextReentrant(),
208
- this.params.getCurrentSequenceNumbers().clientSequenceNumber,
209
- )
210
- ) {
211
- // BatchManager has two limits - soft limit & hard limit. Soft limit is only engaged
212
- // when queue is not empty.
213
- // Flush queue & retry. Failure on retry would mean - single message is bigger than hard limit
214
- this.flushInternal(this.idAllocationBatch);
215
-
216
- this.addMessageToBatchManager(this.idAllocationBatch, message);
217
- }
218
-
219
- // If compression is enabled, we will always successfully receive
220
- // attach ops and compress then send them at the next JS turn, regardless
221
- // of the overall size of the accumulated ops in the batch.
222
- // However, it is more efficient to flush these ops faster, preferably
223
- // after they reach a size which would benefit from compression.
224
- if (
225
- this.idAllocationBatch.contentSizeInBytes >=
226
- this.params.config.compressionOptions.minimumBatchSizeInBytes
227
- ) {
228
- this.flushInternal(this.idAllocationBatch);
229
- }
204
+ this.addMessageToBatchManager(this.idAllocationBatch, message);
230
205
  }
231
206
 
232
207
  private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage) {
@@ -434,6 +409,7 @@ export class Outbox {
434
409
  const mainBatch: IBatchCheckpoint = this.mainBatch.checkpoint();
435
410
  return {
436
411
  mainBatch,
412
+ idAllocationBatch: this.idAllocationBatch.checkpoint(),
437
413
  blobAttachBatch: this.blobAttachBatch.checkpoint(),
438
414
  };
439
415
  }
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.0.0-dev-rc.5.0.0.263932";
9
+ export const pkgVersion = "2.0.0-dev-rc.5.0.0.265721";
@@ -63,7 +63,7 @@ export {
63
63
  SummarizeResultPart,
64
64
  SubmitSummaryFailureData,
65
65
  SummaryStage,
66
- IRetriableFailureResult,
66
+ IRetriableFailureError,
67
67
  ISummarizeEventProps,
68
68
  } from "./summarizerTypes.js";
69
69
  export {
@@ -351,6 +351,7 @@ export class OrderedClientElection
351
351
  /** Serialized state from summary or current sequence number at time of load if new. */
352
352
  initialState: ISerializedElection | number,
353
353
  private readonly isEligibleFn: (c: ITrackedClient) => boolean,
354
+ private readonly recordPerformanceEvents: boolean = false,
354
355
  ) {
355
356
  super();
356
357
  let initialClient: ILinkedClient | undefined;
@@ -410,17 +411,42 @@ export class OrderedClientElection
410
411
  * Note that this function does no eligibility or suitability checks. If we get here, then
411
412
  * we will set _electedClient, and we will set _electedParent if this is an interactive client.
412
413
  */
413
- private tryElectingClient(client: ILinkedClient | undefined, sequenceNumber: number): void {
414
+ private tryElectingClient(
415
+ client: ILinkedClient | undefined,
416
+ sequenceNumber: number,
417
+ reason: string,
418
+ ): void {
419
+ this.sendPerformanceEvent(
420
+ "TryElectingClient",
421
+ client,
422
+ sequenceNumber,
423
+ false /* forceSend */,
424
+ reason,
425
+ );
414
426
  let change = false;
415
427
  const isSummarizerClient = client?.client.details.type === summarizerClientType;
416
428
  const prevClient = this._electedClient;
417
429
  if (this._electedClient !== client) {
430
+ this.sendPerformanceEvent(
431
+ "ClientElected",
432
+ client,
433
+ sequenceNumber,
434
+ true /* forceSend */,
435
+ reason,
436
+ );
418
437
  // Changing the elected client. Record the sequence number and note that we have to fire an event.
419
438
  this._electionSequenceNumber = sequenceNumber;
420
439
  this._electedClient = client;
421
440
  change = true;
422
441
  }
423
442
  if (this._electedParent !== client && !isSummarizerClient) {
443
+ this.sendPerformanceEvent(
444
+ "InteractiveClientElected",
445
+ client,
446
+ sequenceNumber,
447
+ true /* forceSend */,
448
+ reason,
449
+ );
424
450
  // Changing the elected parent as well.
425
451
  this._electedParent = client;
426
452
  change = true;
@@ -430,8 +456,26 @@ export class OrderedClientElection
430
456
  }
431
457
  }
432
458
 
433
- private tryElectingParent(client: ILinkedClient | undefined, sequenceNumber: number): void {
459
+ private tryElectingParent(
460
+ client: ILinkedClient | undefined,
461
+ sequenceNumber: number,
462
+ reason: string,
463
+ ): void {
464
+ this.sendPerformanceEvent(
465
+ "TryElectingParent",
466
+ client,
467
+ sequenceNumber,
468
+ false /* forceSend */,
469
+ reason,
470
+ );
434
471
  if (this._electedParent !== client) {
472
+ this.sendPerformanceEvent(
473
+ "ParentElected",
474
+ client,
475
+ sequenceNumber,
476
+ true /* forceSend */,
477
+ reason,
478
+ );
435
479
  this._electedParent = client;
436
480
  this.emit("election", this._electedClient, sequenceNumber, this._electedClient);
437
481
  }
@@ -462,6 +506,7 @@ export class OrderedClientElection
462
506
  * @param sequenceNumber - sequence number when client was added
463
507
  */
464
508
  private addClient(client: ILinkedClient, sequenceNumber: number): void {
509
+ this.sendPerformanceEvent("AddClient", client, sequenceNumber);
465
510
  if (this.isEligibleFn(client)) {
466
511
  this._eligibleCount++;
467
512
  const newClientIsSummarizer = client.client.details.type === summarizerClientType;
@@ -472,10 +517,10 @@ export class OrderedClientElection
472
517
  this._electedClient === undefined ||
473
518
  (!electedClientIsSummarizer && newClientIsSummarizer)
474
519
  ) {
475
- this.tryElectingClient(client, sequenceNumber);
520
+ this.tryElectingClient(client, sequenceNumber, "AddClient");
476
521
  } else if (this._electedParent === undefined && !newClientIsSummarizer) {
477
522
  // This is an odd case. If the _electedClient is set, the _electedParent should be as well.
478
- this.tryElectingParent(client, sequenceNumber);
523
+ this.tryElectingParent(client, sequenceNumber, "AddClient");
479
524
  }
480
525
  }
481
526
  }
@@ -487,6 +532,7 @@ export class OrderedClientElection
487
532
  * @param sequenceNumber - sequence number when client was removed
488
533
  */
489
534
  private removeClient(client: ILinkedClient, sequenceNumber: number): void {
535
+ this.sendPerformanceEvent("RemoveClient", client, sequenceNumber);
490
536
  if (this.isEligibleFn(client)) {
491
537
  this._eligibleCount--;
492
538
  if (this._electedClient === client) {
@@ -497,14 +543,18 @@ export class OrderedClientElection
497
543
  if (this._electedClient.client.details.type !== summarizerClientType) {
498
544
  throw new UsageError("Elected client should be a summarizer client 1");
499
545
  }
500
- this.tryElectingClient(this._electedParent, sequenceNumber);
546
+ this.tryElectingClient(
547
+ this._electedParent,
548
+ sequenceNumber,
549
+ "RemoveSummarizerClient",
550
+ );
501
551
  } else {
502
552
  // 2. The _electedClient is an interactive client that has left the quorum.
503
553
  // Automatically shift to next oldest client.
504
554
  const nextClient =
505
555
  this.findFirstEligibleParent(this._electedParent?.youngerClient) ??
506
556
  this.findFirstEligibleParent(this.orderedClientCollection.oldestClient);
507
- this.tryElectingClient(nextClient, sequenceNumber);
557
+ this.tryElectingClient(nextClient, sequenceNumber, "RemoveClient");
508
558
  }
509
559
  } else if (this._electedParent === client) {
510
560
  // Removing the _electedParent (but not _electedClient).
@@ -516,7 +566,7 @@ export class OrderedClientElection
516
566
  const nextParent =
517
567
  this.findFirstEligibleParent(this._electedParent?.youngerClient) ??
518
568
  this.findFirstEligibleParent(this.orderedClientCollection.oldestClient);
519
- this.tryElectingParent(nextParent, sequenceNumber);
569
+ this.tryElectingParent(nextParent, sequenceNumber, "RemoveClient");
520
570
  }
521
571
  }
522
572
  }
@@ -534,11 +584,11 @@ export class OrderedClientElection
534
584
  this.findFirstEligibleParent(this._electedParent?.youngerClient) ??
535
585
  this.findFirstEligibleParent(this.orderedClientCollection.oldestClient);
536
586
  if (this._electedClient === undefined || this._electedClient === this._electedParent) {
537
- this.tryElectingClient(nextClient, sequenceNumber);
587
+ this.tryElectingClient(nextClient, sequenceNumber, "IncrementElectedClient");
538
588
  } else {
539
589
  // The _electedClient is a summarizer and should not be replaced until it leaves the quorum.
540
590
  // Changing the _electedParent will stop the summarizer.
541
- this.tryElectingParent(nextClient, sequenceNumber);
591
+ this.tryElectingParent(nextClient, sequenceNumber, "IncrementElectedClient");
542
592
  }
543
593
  }
544
594
 
@@ -549,11 +599,11 @@ export class OrderedClientElection
549
599
  public resetElectedClient(sequenceNumber: number): void {
550
600
  const firstClient = this.findFirstEligibleParent(this.orderedClientCollection.oldestClient);
551
601
  if (this._electedClient === undefined || this._electedClient === this._electedParent) {
552
- this.tryElectingClient(firstClient, sequenceNumber);
602
+ this.tryElectingClient(firstClient, sequenceNumber, "ResetElectedClient");
553
603
  } else {
554
604
  // The _electedClient is a summarizer and should not be replaced until it leaves the quorum.
555
605
  // Changing the _electedParent will stop the summarizer.
556
- this.tryElectingParent(firstClient, sequenceNumber);
606
+ this.tryElectingParent(firstClient, sequenceNumber, "ResetElectedClient");
557
607
  }
558
608
  }
559
609
 
@@ -571,4 +621,25 @@ export class OrderedClientElection
571
621
  electedParentId: this.electedParent?.clientId,
572
622
  };
573
623
  }
624
+
625
+ private sendPerformanceEvent(
626
+ eventName: string,
627
+ client: ILinkedClient | undefined,
628
+ sequenceNumber: number,
629
+ forceSend: boolean = false,
630
+ reason?: string,
631
+ ) {
632
+ if (this.recordPerformanceEvents || forceSend) {
633
+ this.logger.sendPerformanceEvent({
634
+ eventName,
635
+ clientId: client?.clientId,
636
+ sequenceNumber,
637
+ electedClientId: this.electedClient?.clientId,
638
+ electedParentId: this.electedParent?.clientId,
639
+ isEligible: client !== undefined ? this.isEligibleFn(client) : false,
640
+ isSummarizerClient: client?.client.details.type === summarizerClientType,
641
+ reason,
642
+ });
643
+ }
644
+ }
574
645
  }
@@ -38,9 +38,11 @@ import {
38
38
  ISummaryCancellationToken,
39
39
  SubmitSummaryResult,
40
40
  SummarizerStopReason,
41
+ type IRetriableFailureError,
41
42
  } from "./summarizerTypes.js";
42
43
  import { IAckedSummary, IClientSummaryWatcher, SummaryCollection } from "./summaryCollection.js";
43
44
  import {
45
+ RetriableSummaryError,
44
46
  SummarizeReason,
45
47
  SummarizeResultBuilder,
46
48
  SummaryGenerator,
@@ -474,7 +476,6 @@ export class RunningSummarizer extends TypedEventEmitter<ISummarizerEvents> impl
474
476
  this.trySummarizeOnce(
475
477
  // summarizeProps
476
478
  { summarizeReason: "lastSummary" },
477
- // ISummarizeOptions, using defaults: { refreshLatestAck: false, fullTree: false }
478
479
  {},
479
480
  );
480
481
  }
@@ -627,9 +628,7 @@ export class RunningSummarizer extends TypedEventEmitter<ISummarizerEvents> impl
627
628
  this.beforeSummaryAction();
628
629
  },
629
630
  async () => {
630
- return this.mc.config.getBoolean("Fluid.Summarizer.UseDynamicRetries")
631
- ? this.trySummarizeWithRetries(reason)
632
- : this.trySummarizeWithStaticAttempts(reason);
631
+ return this.trySummarizeWithRetries(reason);
633
632
  },
634
633
  () => {
635
634
  this.afterSummaryAction();
@@ -639,92 +638,6 @@ export class RunningSummarizer extends TypedEventEmitter<ISummarizerEvents> impl
639
638
  });
640
639
  }
641
640
 
642
- /**
643
- * Tries to summarize 2 times with pre-defined summary options. If an attempt fails with "retryAfterSeconds"
644
- * param, that attempt is tried once more.
645
- */
646
- private async trySummarizeWithStaticAttempts(reason: SummarizeReason) {
647
- const attemptOptions: ISummarizeOptions[] = [
648
- { refreshLatestAck: false, fullTree: false },
649
- { refreshLatestAck: true, fullTree: false },
650
- ];
651
- let summaryAttempts = 0;
652
- let summaryAttemptsPerPhase = 0;
653
- let summaryAttemptPhase = 0;
654
- let error: any;
655
- while (summaryAttemptPhase < attemptOptions.length) {
656
- if (this.cancellationToken.cancelled) {
657
- return;
658
- }
659
-
660
- // We only want to attempt 1 summary when reason is "lastSummary"
661
- if (++summaryAttempts > 1 && reason === "lastSummary") {
662
- return;
663
- }
664
-
665
- summaryAttemptsPerPhase++;
666
-
667
- const summarizeOptions = attemptOptions[summaryAttemptPhase];
668
- const summarizeProps: ISummarizeTelemetryProperties = {
669
- summarizeReason: reason,
670
- summaryAttempts,
671
- summaryAttemptsPerPhase,
672
- summaryAttemptPhase: summaryAttemptPhase + 1, // make everything 1-based
673
- ...summarizeOptions,
674
- };
675
- const summaryLogger = createChildLogger({
676
- logger: this.mc.logger,
677
- properties: { all: summarizeProps },
678
- });
679
- const summaryOptions: ISubmitSummaryOptions = {
680
- ...summarizeOptions,
681
- summaryLogger,
682
- cancellationToken: this.cancellationToken,
683
- latestSummaryRefSeqNum: this.heuristicData.lastSuccessfulSummary.refSequenceNumber,
684
- };
685
-
686
- // Note: no need to account for cancellationToken.waitCancelled here, as
687
- // this is accounted SummaryGenerator.summarizeCore that controls receivedSummaryAckOrNack.
688
- const resultSummarize = this.generator.summarize(summaryOptions);
689
- const ackNackResult = await resultSummarize.receivedSummaryAckOrNack;
690
- if (ackNackResult.success) {
691
- return;
692
- }
693
-
694
- error = ackNackResult.error;
695
-
696
- // Check for retryDelay that can come from summaryNack, upload summary or submit summary flows.
697
- // Retry the same step only once per retryAfter response.
698
- const submitResult = await resultSummarize.summarySubmitted;
699
- const delaySeconds = !submitResult.success
700
- ? submitResult.data?.retryAfterSeconds
701
- : ackNackResult.data?.retryAfterSeconds;
702
- if (delaySeconds === undefined || summaryAttemptsPerPhase > 1) {
703
- summaryAttemptPhase++;
704
- summaryAttemptsPerPhase = 0;
705
- }
706
-
707
- if (delaySeconds !== undefined) {
708
- this.mc.logger.sendPerformanceEvent({
709
- eventName: "SummarizeAttemptDelay",
710
- duration: delaySeconds,
711
- summaryNackDelay: ackNackResult.data?.retryAfterSeconds !== undefined,
712
- ...summarizeProps,
713
- });
714
- await delay(delaySeconds * 1000);
715
- }
716
- }
717
- this.mc.logger.sendErrorEvent(
718
- {
719
- eventName: "SummarizeFailed",
720
- maxAttempts: attemptOptions.length,
721
- summaryAttempts: summaryAttemptPhase,
722
- },
723
- error,
724
- );
725
- this.stopSummarizerCallback("failToSummarize");
726
- }
727
-
728
641
  /**
729
642
  * Tries to summarize with retries where retry is based on the failure params.
730
643
  * For example, summarization may be retried for failures with "retryAfterSeconds" param.
@@ -773,7 +686,7 @@ export class RunningSummarizer extends TypedEventEmitter<ISummarizerEvents> impl
773
686
  let done = false;
774
687
  let status: "success" | "failure" | "canceled" = "success";
775
688
  let results: ISummarizeResults | undefined;
776
- let error: any;
689
+ let error: IRetriableFailureError | undefined;
777
690
  do {
778
691
  currentAttempt++;
779
692
  if (this.cancellationToken.cancelled) {
@@ -793,22 +706,18 @@ export class RunningSummarizer extends TypedEventEmitter<ISummarizerEvents> impl
793
706
  break;
794
707
  }
795
708
 
796
- // Update max attempts and retry params from the failure result.
797
- // If submit summary failed, use the params from "summarySubmitted" result. Else, use the params
798
- // from "receivedSummaryAckOrNack" result.
709
+ // Update max attempts from the failure result.
710
+ // If submit summary failed, use maxAttemptsForSubmitFailures. Else use the defaultMaxAttempts.
799
711
  // Note: Check "summarySubmitted" result first because if it fails, ack nack would fail as well.
800
712
  const submitSummaryResult = await results.summarySubmitted;
801
- if (!submitSummaryResult.success) {
802
- maxAttempts = this.maxAttemptsForSubmitFailures;
803
- retryAfterSeconds = submitSummaryResult.data?.retryAfterSeconds;
804
- } else {
805
- maxAttempts = defaultMaxAttempts;
806
- retryAfterSeconds = ackNackResult.data?.retryAfterSeconds;
807
- }
713
+ maxAttempts = !submitSummaryResult.success
714
+ ? this.maxAttemptsForSubmitFailures
715
+ : defaultMaxAttempts;
808
716
 
809
717
  // Emit "summarize" event for this failed attempt.
810
718
  status = "failure";
811
719
  error = ackNackResult.error;
720
+ retryAfterSeconds = error.retryAfterSeconds;
812
721
  const eventProps: ISummarizeEventProps = {
813
722
  result: status,
814
723
  currentAttempt,
@@ -817,27 +726,26 @@ export class RunningSummarizer extends TypedEventEmitter<ISummarizerEvents> impl
817
726
  };
818
727
  this.emit("summarize", eventProps);
819
728
 
820
- // If the failure doesn't have "retryAfterSeconds" or the max number of attempts have been done, we're done.
729
+ // Break if the failure doesn't have "retryAfterSeconds" or we are one less from max number of attempts.
730
+ // Note that the final attempt if "retryAfterSeconds" does exist happens outside of the do..while loop.
821
731
  if (retryAfterSeconds === undefined || currentAttempt >= maxAttempts - 1) {
822
732
  done = true;
823
733
  }
824
734
 
825
- // If the failure has "retryAfterSeconds", add a delay of that time. In this case, a final attempt will
826
- // take place and we need to wait for "retryAfterSeconds" before that.
827
- if (retryAfterSeconds !== undefined) {
735
+ // If the failure has "retryAfterSeconds", add a delay of that time before starting the next attempt.
736
+ if (retryAfterSeconds !== undefined && retryAfterSeconds > 0) {
828
737
  this.mc.logger.sendPerformanceEvent({
829
738
  eventName: "SummarizeAttemptDelay",
830
- duration: retryAfterSeconds,
831
- summaryNackDelay: ackNackResult.data?.retryAfterSeconds !== undefined,
739
+ duration: retryAfterSeconds * 1000,
740
+ summaryNackDelay: ackNackResult.data !== undefined, // This will only be defined only for nack failures.
832
741
  stage: submitSummaryResult.data?.stage,
833
- dynamicRetries: true, // To differentiate this telemetry from regular retry logic
834
742
  ...attemptResult.summarizeProps,
835
743
  });
836
744
  await delay(retryAfterSeconds * 1000);
837
745
  }
838
746
  } while (!done);
839
747
 
840
- // If summarize attempt did not fail, emit "summarize" event and return. A failed attempt may be retried below.
748
+ // If the attempt was successful, emit "summarize" event and return. A failed attempt may be retried below.
841
749
  if (status !== "failure") {
842
750
  this.emit("summarize", { result: status, currentAttempt, maxAttempts });
843
751
  return results;
@@ -888,7 +796,10 @@ export class RunningSummarizer extends TypedEventEmitter<ISummarizerEvents> impl
888
796
  ) {
889
797
  const results = await this.trySummarizeWithRetries(reason);
890
798
  if (results === undefined) {
891
- resultsBuilder.fail("Summarization was canceled", undefined);
799
+ resultsBuilder.fail(
800
+ "Summarization was canceled",
801
+ new RetriableSummaryError("Summarization was canceled"),
802
+ );
892
803
  return resultsBuilder.build();
893
804
  }
894
805
  const submitResult = await results.summarySubmitted;
@@ -906,7 +817,10 @@ export class RunningSummarizer extends TypedEventEmitter<ISummarizerEvents> impl
906
817
  resultsBuilder: SummarizeResultBuilder = new SummarizeResultBuilder(),
907
818
  ): ISummarizeResults {
908
819
  if (this.stopping) {
909
- resultsBuilder.fail("RunningSummarizer stopped or disposed", undefined);
820
+ resultsBuilder.fail(
821
+ "RunningSummarizer stopped or disposed",
822
+ new RetriableSummaryError("RunningSummarizer stopped or disposed"),
823
+ );
910
824
  return resultsBuilder.build();
911
825
  }
912
826
  // Check for concurrent summary attempts. If one is found,
@@ -944,7 +858,9 @@ export class RunningSummarizer extends TypedEventEmitter<ISummarizerEvents> impl
944
858
  // Override existing enqueued summarize attempt.
945
859
  this.enqueuedSummary.resultsBuilder.fail(
946
860
  "Aborted; overridden by another enqueue summarize attempt",
947
- undefined,
861
+ new RetriableSummaryError(
862
+ "Summary was overridden by another enqueue summarize attempt",
863
+ ),
948
864
  );
949
865
  this.enqueuedSummary = undefined;
950
866
  overridden = true;
@@ -995,7 +911,7 @@ export class RunningSummarizer extends TypedEventEmitter<ISummarizerEvents> impl
995
911
  if (this.enqueuedSummary !== undefined) {
996
912
  this.enqueuedSummary.resultsBuilder.fail(
997
913
  "RunningSummarizer stopped or disposed",
998
- undefined,
914
+ new RetriableSummaryError("RunningSummarizer stopped or disposed"),
999
915
  );
1000
916
  this.enqueuedSummary = undefined;
1001
917
  }
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { TypedEventEmitter } from "@fluid-internal/client-utils";
7
- import { IFluidHandleContext } from "@fluidframework/core-interfaces";
7
+ import { IFluidHandleContext } from "@fluidframework/core-interfaces/internal";
8
8
  import { Deferred } from "@fluidframework/core-utils/internal";
9
9
  import {
10
10
  IFluidErrorBase,
@@ -98,7 +98,10 @@ export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements
98
98
  ) => Promise<ICancellableSummarizerController>,
99
99
  ) {
100
100
  super();
101
- this.logger = createChildLogger({ logger: this.runtime.logger, namespace: "Summarizer" });
101
+ this.logger = createChildLogger({
102
+ logger: this.runtime.baseLogger,
103
+ namespace: "Summarizer",
104
+ });
102
105
  }
103
106
 
104
107
  public async run(onBehalfOf: string): Promise<SummarizerStopReason> {
@@ -13,8 +13,6 @@ import {
13
13
  import {
14
14
  IExperimentalIncrementalSummaryContext,
15
15
  ITelemetryContext,
16
- } from "@fluidframework/runtime-definitions";
17
- import {
18
16
  CreateChildSummarizerNodeParam,
19
17
  CreateSummarizerNodeSource,
20
18
  ISummarizeResult,
@@ -7,10 +7,8 @@ import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
7
7
  import { assert, LazyPromise } from "@fluidframework/core-utils/internal";
8
8
  import {
9
9
  IExperimentalIncrementalSummaryContext,
10
- IGarbageCollectionData,
11
10
  ITelemetryContext,
12
- } from "@fluidframework/runtime-definitions";
13
- import {
11
+ IGarbageCollectionData,
14
12
  CreateChildSummarizerNodeParam,
15
13
  IGarbageCollectionDetailsBase,
16
14
  ISummarizeInternalResult,
@@ -4,13 +4,18 @@
4
4
  */
5
5
 
6
6
  import { IDeltaManager, ContainerWarning } from "@fluidframework/container-definitions/internal";
7
- import { IEvent, IEventProvider, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
7
+ import {
8
+ IEvent,
9
+ IEventProvider,
10
+ ITelemetryBaseProperties,
11
+ ITelemetryBaseLogger,
12
+ } from "@fluidframework/core-interfaces";
8
13
  import {
9
14
  IDocumentMessage,
10
15
  ISequencedDocumentMessage,
11
16
  ISummaryTree,
12
17
  } from "@fluidframework/protocol-definitions";
13
- import { ISummaryStats } from "@fluidframework/runtime-definitions";
18
+ import { ISummaryStats } from "@fluidframework/runtime-definitions/internal";
14
19
  import {
15
20
  ITelemetryLoggerExt,
16
21
  ITelemetryLoggerPropertyBag,
@@ -90,7 +95,7 @@ export interface IConnectableRuntime {
90
95
  * @alpha
91
96
  */
92
97
  export interface ISummarizerRuntime extends IConnectableRuntime {
93
- readonly logger: ITelemetryLoggerExt;
98
+ readonly baseLogger: ITelemetryBaseLogger;
94
99
  /** clientId of parent (non-summarizing) container that owns summarizer container */
95
100
  readonly summarizerClientId: string | undefined;
96
101
  readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
@@ -113,13 +118,6 @@ export interface ISummarizerRuntime extends IConnectableRuntime {
113
118
  export interface ISummarizeOptions {
114
119
  /** True to generate the full tree with no handle reuse optimizations; defaults to false */
115
120
  readonly fullTree?: boolean;
116
- /**
117
- * True to ask the server what the latest summary is first; defaults to false
118
- *
119
- * @deprecated Summarize will not refresh latest snapshot state anymore. Instead it updates the cache and closes.
120
- * It's expected a new summarizer client will be created, likely by the same parent.
121
- */
122
- readonly refreshLatestAck?: boolean;
123
121
  }
124
122
 
125
123
  /**
@@ -183,14 +181,22 @@ export interface IGeneratedSummaryStats extends ISummaryStats {
183
181
  readonly summaryNumber: number;
184
182
  }
185
183
 
184
+ /**
185
+ * Type for summarization failures that are retriable.
186
+ * @alpha
187
+ */
188
+ export interface IRetriableFailureError extends Error {
189
+ readonly retryAfterSeconds?: number;
190
+ }
191
+
186
192
  /**
187
193
  * Base results for all submitSummary attempts.
188
194
  * @alpha
189
195
  */
190
196
  export interface IBaseSummarizeResult {
191
197
  readonly stage: "base";
192
- /** Error object related to failed summarize attempt. */
193
- readonly error: Error | undefined;
198
+ /** Retriable error object related to failed summarize attempt. */
199
+ readonly error: IRetriableFailureError | undefined;
194
200
  /** Reference sequence number as of the generate summary attempt. */
195
201
  readonly referenceSequenceNumber: number;
196
202
  readonly minimumSequenceNumber: number;
@@ -265,19 +271,11 @@ export type SubmitSummaryResult =
265
271
  */
266
272
  export type SummaryStage = SubmitSummaryResult["stage"] | "unknown";
267
273
 
268
- /**
269
- * Type for summarization failures that are retriable.
270
- * @alpha
271
- */
272
- export interface IRetriableFailureResult {
273
- readonly retryAfterSeconds?: number;
274
- }
275
-
276
274
  /**
277
275
  * The data in summarizer result when submit summary stage fails.
278
276
  * @alpha
279
277
  */
280
- export interface SubmitSummaryFailureData extends IRetriableFailureResult {
278
+ export interface SubmitSummaryFailureData {
281
279
  stage: SummaryStage;
282
280
  }
283
281
 
@@ -300,7 +298,7 @@ export interface IAckSummaryResult {
300
298
  /**
301
299
  * @alpha
302
300
  */
303
- export interface INackSummaryResult extends IRetriableFailureResult {
301
+ export interface INackSummaryResult {
304
302
  readonly summaryNackOp: ISummaryNackMessage;
305
303
  readonly ackNackDuration: number;
306
304
  }
@@ -317,7 +315,7 @@ export type SummarizeResultPart<TSuccess, TFailure = undefined> =
317
315
  success: false;
318
316
  data: TFailure | undefined;
319
317
  message: string;
320
- error: any;
318
+ error: IRetriableFailureError;
321
319
  };
322
320
 
323
321
  /**
@@ -535,10 +533,6 @@ type ISummarizeTelemetryRequiredProperties =
535
533
  type ISummarizeTelemetryOptionalProperties =
536
534
  /** Number of attempts within the last time window, used for calculating the throttle delay. */
537
535
  | "summaryAttempts"
538
- /** Number of attempts within the current phase (currently capped at 2 ) */
539
- | "summaryAttemptsPerPhase"
540
- /** One-based count of phases we've attempted (used to index into an array of ISummarizeOptions */
541
- | "summaryAttemptPhase"
542
536
  /** Summarization may be attempted multiple times. This tells whether this is the final summarization attempt */
543
537
  | "finalAttempt"
544
538
  | keyof ISummarizeOptions;
@@ -14,8 +14,11 @@ import {
14
14
  ISnapshotTree,
15
15
  SummaryType,
16
16
  } from "@fluidframework/protocol-definitions";
17
- import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
18
- import { channelsTreeName, gcTreeKey } from "@fluidframework/runtime-definitions/internal";
17
+ import {
18
+ ISummaryTreeWithStats,
19
+ channelsTreeName,
20
+ gcTreeKey,
21
+ } from "@fluidframework/runtime-definitions/internal";
19
22
 
20
23
  import { IGCMetadata } from "../gc/index.js";
21
24