@fluidframework/container-runtime 2.11.0 → 2.13.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 (119) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/api-report/container-runtime.legacy.alpha.api.md +17 -15
  3. package/container-runtime.test-files.tar +0 -0
  4. package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
  5. package/dist/channelCollection.js.map +1 -1
  6. package/dist/containerRuntime.d.ts +38 -5
  7. package/dist/containerRuntime.d.ts.map +1 -1
  8. package/dist/containerRuntime.js +28 -7
  9. package/dist/containerRuntime.js.map +1 -1
  10. package/dist/gc/garbageCollection.d.ts.map +1 -1
  11. package/dist/gc/garbageCollection.js.map +1 -1
  12. package/dist/gc/gcConfigs.js +1 -1
  13. package/dist/gc/gcConfigs.js.map +1 -1
  14. package/dist/gc/gcHelpers.js.map +1 -1
  15. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/opLifecycle/opDecompressor.js +0 -1
  20. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  21. package/dist/opLifecycle/opSplitter.js +0 -1
  22. package/dist/opLifecycle/opSplitter.js.map +1 -1
  23. package/dist/packageVersion.d.ts +1 -1
  24. package/dist/packageVersion.js +1 -1
  25. package/dist/packageVersion.js.map +1 -1
  26. package/dist/pendingStateManager.d.ts +4 -0
  27. package/dist/pendingStateManager.d.ts.map +1 -1
  28. package/dist/pendingStateManager.js +31 -1
  29. package/dist/pendingStateManager.js.map +1 -1
  30. package/dist/scheduleManager.js +0 -2
  31. package/dist/scheduleManager.js.map +1 -1
  32. package/dist/summary/runWhileConnectedCoordinator.d.ts +2 -1
  33. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  34. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  35. package/dist/summary/runningSummarizer.d.ts +8 -1
  36. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  37. package/dist/summary/runningSummarizer.js +70 -8
  38. package/dist/summary/runningSummarizer.js.map +1 -1
  39. package/dist/summary/summarizer.d.ts +5 -2
  40. package/dist/summary/summarizer.d.ts.map +1 -1
  41. package/dist/summary/summarizer.js +39 -6
  42. package/dist/summary/summarizer.js.map +1 -1
  43. package/dist/summary/summarizerTypes.d.ts +8 -4
  44. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  45. package/dist/summary/summarizerTypes.js.map +1 -1
  46. package/dist/summary/summaryCollection.js +0 -2
  47. package/dist/summary/summaryCollection.js.map +1 -1
  48. package/dist/summary/summaryManager.d.ts +5 -2
  49. package/dist/summary/summaryManager.d.ts.map +1 -1
  50. package/dist/summary/summaryManager.js +23 -6
  51. package/dist/summary/summaryManager.js.map +1 -1
  52. package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
  53. package/lib/channelCollection.js.map +1 -1
  54. package/lib/containerRuntime.d.ts +38 -5
  55. package/lib/containerRuntime.d.ts.map +1 -1
  56. package/lib/containerRuntime.js +28 -7
  57. package/lib/containerRuntime.js.map +1 -1
  58. package/lib/gc/garbageCollection.d.ts.map +1 -1
  59. package/lib/gc/garbageCollection.js.map +1 -1
  60. package/lib/gc/gcConfigs.js +1 -1
  61. package/lib/gc/gcConfigs.js.map +1 -1
  62. package/lib/gc/gcHelpers.js.map +1 -1
  63. package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  64. package/lib/index.d.ts +1 -1
  65. package/lib/index.d.ts.map +1 -1
  66. package/lib/index.js.map +1 -1
  67. package/lib/opLifecycle/opDecompressor.js +0 -1
  68. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  69. package/lib/opLifecycle/opSplitter.js +0 -1
  70. package/lib/opLifecycle/opSplitter.js.map +1 -1
  71. package/lib/packageVersion.d.ts +1 -1
  72. package/lib/packageVersion.js +1 -1
  73. package/lib/packageVersion.js.map +1 -1
  74. package/lib/pendingStateManager.d.ts +4 -0
  75. package/lib/pendingStateManager.d.ts.map +1 -1
  76. package/lib/pendingStateManager.js +29 -0
  77. package/lib/pendingStateManager.js.map +1 -1
  78. package/lib/scheduleManager.js +0 -2
  79. package/lib/scheduleManager.js.map +1 -1
  80. package/lib/summary/runWhileConnectedCoordinator.d.ts +2 -1
  81. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  82. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  83. package/lib/summary/runningSummarizer.d.ts +8 -1
  84. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  85. package/lib/summary/runningSummarizer.js +70 -8
  86. package/lib/summary/runningSummarizer.js.map +1 -1
  87. package/lib/summary/summarizer.d.ts +5 -2
  88. package/lib/summary/summarizer.d.ts.map +1 -1
  89. package/lib/summary/summarizer.js +39 -6
  90. package/lib/summary/summarizer.js.map +1 -1
  91. package/lib/summary/summarizerTypes.d.ts +8 -4
  92. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  93. package/lib/summary/summarizerTypes.js.map +1 -1
  94. package/lib/summary/summaryCollection.js +0 -2
  95. package/lib/summary/summaryCollection.js.map +1 -1
  96. package/lib/summary/summaryManager.d.ts +5 -2
  97. package/lib/summary/summaryManager.d.ts.map +1 -1
  98. package/lib/summary/summaryManager.js +23 -6
  99. package/lib/summary/summaryManager.js.map +1 -1
  100. package/package.json +20 -20
  101. package/src/blobManager/blobManagerSnapSum.ts +1 -1
  102. package/src/channelCollection.ts +1 -1
  103. package/src/containerRuntime.ts +84 -24
  104. package/src/gc/garbageCollection.ts +2 -1
  105. package/src/gc/gcConfigs.ts +1 -1
  106. package/src/gc/gcHelpers.ts +2 -2
  107. package/src/gc/gcReferenceGraphAlgorithm.ts +1 -1
  108. package/src/index.ts +1 -0
  109. package/src/opLifecycle/opDecompressor.ts +1 -1
  110. package/src/opLifecycle/opSplitter.ts +1 -1
  111. package/src/packageVersion.ts +1 -1
  112. package/src/pendingStateManager.ts +38 -0
  113. package/src/scheduleManager.ts +2 -2
  114. package/src/summary/runWhileConnectedCoordinator.ts +2 -5
  115. package/src/summary/runningSummarizer.ts +82 -11
  116. package/src/summary/summarizer.ts +49 -10
  117. package/src/summary/summarizerTypes.ts +11 -4
  118. package/src/summary/summaryCollection.ts +2 -2
  119. package/src/summary/summaryManager.ts +30 -10
@@ -4,6 +4,12 @@
4
4
  */
5
5
 
6
6
  import { TypedEventEmitter } from "@fluid-internal/client-utils";
7
+ import type {
8
+ ISummarizeEventProps,
9
+ ISummarizerEvents,
10
+ ISummarizerObservabilityProps,
11
+ SummarizerStopReason,
12
+ } from "@fluidframework/container-runtime-definitions/internal";
7
13
  import { IDisposable, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
8
14
  import { assert, Deferred, PromiseTimer, delay } from "@fluidframework/core-utils/internal";
9
15
  import {
@@ -29,18 +35,15 @@ import {
29
35
  IOnDemandSummarizeOptions,
30
36
  IRefreshSummaryAckOptions,
31
37
  ISubmitSummaryOptions,
32
- ISummarizeEventProps,
33
38
  ISummarizeHeuristicData,
34
39
  ISummarizeHeuristicRunner,
35
40
  ISummarizeOptions,
36
41
  ISummarizeResults,
37
42
  ISummarizeRunnerTelemetry,
38
43
  ISummarizeTelemetryProperties,
39
- ISummarizerEvents,
40
44
  ISummarizerRuntime,
41
45
  ISummaryCancellationToken,
42
46
  SubmitSummaryResult,
43
- SummarizerStopReason,
44
47
  type IRetriableFailureError,
45
48
  } from "./summarizerTypes.js";
46
49
  import {
@@ -189,6 +192,13 @@ export class RunningSummarizer
189
192
  /** The maximum number of summary attempts to do when submit summary fails. */
190
193
  private readonly maxAttemptsForSubmitFailures: number;
191
194
 
195
+ /**
196
+ * These are necessary to store outside of methods because of the logic around runnning a lastSummary.
197
+ * We want the lastSummary to also be captured as "all attempts failed".
198
+ */
199
+ private lastSummarizeFailureEventProps: Omit<ISummarizeEventProps, "result"> | undefined =
200
+ undefined;
201
+
192
202
  private constructor(
193
203
  baseLogger: ITelemetryBaseLogger,
194
204
  private readonly summaryWatcher: IClientSummaryWatcher,
@@ -492,6 +502,8 @@ export class RunningSummarizer
492
502
  // summarizeProps
493
503
  { summarizeReason: "lastSummary" },
494
504
  {},
505
+ undefined,
506
+ true /* isLastSummary */,
495
507
  );
496
508
  }
497
509
  }
@@ -502,6 +514,15 @@ export class RunningSummarizer
502
514
  // submit summary. We should reconsider this flow and make summarizer move to exit faster.
503
515
  // This resolves when the current pending summary gets an ack or fails.
504
516
  await this.summarizingLock;
517
+
518
+ if (this.lastSummarizeFailureEventProps !== undefined) {
519
+ this.emit("summarizeAllAttemptsFailed", {
520
+ ...this.lastSummarizeFailureEventProps,
521
+ numUnsummarizedRuntimeOps: this.heuristicData.numRuntimeOps,
522
+ numUnsummarizedNonRuntimeOps: this.heuristicData.numNonRuntimeOps,
523
+ });
524
+ }
525
+ this.lastSummarizeFailureEventProps = undefined;
505
526
  }
506
527
 
507
528
  private async waitStart() {
@@ -579,12 +600,14 @@ export class RunningSummarizer
579
600
  * @param options - summary options
580
601
  * @param cancellationToken - cancellation token to use to be able to cancel this summary, if needed
581
602
  * @param resultsBuilder - optional, result builder to use.
603
+ * @param isLastSummary - optional, is the call to this method for a last summary when shutting down the summarizer?
582
604
  * @returns ISummarizeResult - result of running a summary.
583
605
  */
584
606
  private trySummarizeOnce(
585
607
  summarizeProps: ISummarizeTelemetryProperties,
586
608
  options: ISummarizeOptions,
587
609
  resultsBuilder = new SummarizeResultBuilder(),
610
+ isLastSummary = false,
588
611
  ): ISummarizeResults {
589
612
  this.lockedSummaryAction(
590
613
  () => {
@@ -604,7 +627,28 @@ export class RunningSummarizer
604
627
  const summarizeResult = this.generator.summarize(summaryOptions, resultsBuilder);
605
628
  // ensure we wait till the end of the process
606
629
  const result = await summarizeResult.receivedSummaryAckOrNack;
607
- if (!result.success) {
630
+
631
+ if (result.success) {
632
+ this.emit("summarize", {
633
+ result: "success",
634
+ currentAttempt: 1,
635
+ maxAttempts: 1,
636
+ numUnsummarizedRuntimeOps: this.heuristicData.numRuntimeOps,
637
+ numUnsummarizedNonRuntimeOps: this.heuristicData.numNonRuntimeOps,
638
+ isLastSummary,
639
+ });
640
+ this.lastSummarizeFailureEventProps = undefined;
641
+ } else {
642
+ this.emit("summarize", {
643
+ result: "failure",
644
+ currentAttempt: 1,
645
+ maxAttempts: 1,
646
+ error: result.error,
647
+ failureMessage: result.message,
648
+ numUnsummarizedRuntimeOps: this.heuristicData.numRuntimeOps,
649
+ numUnsummarizedNonRuntimeOps: this.heuristicData.numNonRuntimeOps,
650
+ isLastSummary,
651
+ });
608
652
  this.mc.logger.sendErrorEvent(
609
653
  {
610
654
  eventName: "SummarizeFailed",
@@ -613,6 +657,14 @@ export class RunningSummarizer
613
657
  },
614
658
  result.error,
615
659
  );
660
+ if (isLastSummary) {
661
+ this.lastSummarizeFailureEventProps = {
662
+ currentAttempt: (this.lastSummarizeFailureEventProps?.currentAttempt ?? 0) + 1,
663
+ maxAttempts: (this.lastSummarizeFailureEventProps?.currentAttempt ?? 0) + 1,
664
+ error: result.error,
665
+ failureMessage: result.message,
666
+ };
667
+ }
616
668
  }
617
669
  },
618
670
  () => {
@@ -701,6 +753,7 @@ export class RunningSummarizer
701
753
  let status: "success" | "failure" | "canceled" = "success";
702
754
  let results: ISummarizeResults | undefined;
703
755
  let error: IRetriableFailureError | undefined;
756
+ let failureMessage: string | undefined;
704
757
  do {
705
758
  currentAttempt++;
706
759
  if (this.cancellationToken.cancelled) {
@@ -731,12 +784,16 @@ export class RunningSummarizer
731
784
  // Emit "summarize" event for this failed attempt.
732
785
  status = "failure";
733
786
  error = ackNackResult.error;
787
+ failureMessage = ackNackResult.message;
734
788
  retryAfterSeconds = error.retryAfterSeconds;
735
- const eventProps: ISummarizeEventProps = {
789
+ const eventProps: ISummarizeEventProps & ISummarizerObservabilityProps = {
736
790
  result: status,
737
791
  currentAttempt,
738
792
  maxAttempts,
739
793
  error,
794
+ failureMessage,
795
+ numUnsummarizedRuntimeOps: this.heuristicData.numRuntimeOps,
796
+ numUnsummarizedNonRuntimeOps: this.heuristicData.numNonRuntimeOps,
740
797
  };
741
798
  this.emit("summarize", eventProps);
742
799
 
@@ -761,7 +818,13 @@ export class RunningSummarizer
761
818
 
762
819
  // If the attempt was successful, emit "summarize" event and return. A failed attempt may be retried below.
763
820
  if (status !== "failure") {
764
- this.emit("summarize", { result: status, currentAttempt, maxAttempts });
821
+ this.emit("summarize", {
822
+ result: status,
823
+ currentAttempt,
824
+ maxAttempts,
825
+ numUnsummarizedRuntimeOps: this.heuristicData.numRuntimeOps,
826
+ numUnsummarizedNonRuntimeOps: this.heuristicData.numNonRuntimeOps,
827
+ });
765
828
  return results;
766
829
  }
767
830
 
@@ -772,14 +835,16 @@ export class RunningSummarizer
772
835
  // Ack / nack is the final step, so if it succeeds we're done.
773
836
  const ackNackResult = await summarizeResult.receivedSummaryAckOrNack;
774
837
  status = ackNackResult.success ? "success" : "failure";
775
- if (!ackNackResult.success) {
776
- error = ackNackResult.error;
777
- }
778
- const eventProps: ISummarizeEventProps = {
838
+ error = ackNackResult.success ? undefined : ackNackResult.error;
839
+ failureMessage = ackNackResult.success ? undefined : ackNackResult.message;
840
+ const eventProps: ISummarizeEventProps & ISummarizerObservabilityProps = {
779
841
  result: status,
780
842
  currentAttempt,
781
843
  maxAttempts,
782
- error: ackNackResult.success ? undefined : ackNackResult.error,
844
+ error,
845
+ failureMessage,
846
+ numUnsummarizedRuntimeOps: this.heuristicData.numRuntimeOps,
847
+ numUnsummarizedNonRuntimeOps: this.heuristicData.numNonRuntimeOps,
783
848
  };
784
849
  this.emit("summarize", eventProps);
785
850
  results = summarizeResult;
@@ -795,6 +860,12 @@ export class RunningSummarizer
795
860
  },
796
861
  error,
797
862
  );
863
+ this.lastSummarizeFailureEventProps = {
864
+ currentAttempt,
865
+ maxAttempts,
866
+ error,
867
+ failureMessage,
868
+ };
798
869
  this.stopSummarizerCallback("failToSummarize");
799
870
  }
800
871
  return results;
@@ -4,6 +4,10 @@
4
4
  */
5
5
 
6
6
  import { TypedEventEmitter } from "@fluid-internal/client-utils";
7
+ import type {
8
+ ISummarizerEvents,
9
+ SummarizerStopReason,
10
+ } from "@fluidframework/container-runtime-definitions/internal";
7
11
  import { IFluidHandleContext } from "@fluidframework/core-interfaces/internal";
8
12
  import { Deferred } from "@fluidframework/core-utils/internal";
9
13
  import {
@@ -25,15 +29,12 @@ import {
25
29
  IConnectableRuntime,
26
30
  IEnqueueSummarizeOptions,
27
31
  IOnDemandSummarizeOptions,
28
- ISummarizeEventProps,
29
32
  ISummarizeHeuristicData,
30
33
  ISummarizeResults,
31
34
  ISummarizer,
32
- ISummarizerEvents,
33
35
  ISummarizerInternalsProvider,
34
36
  ISummarizerRuntime,
35
37
  ISummarizingWarning,
36
- SummarizerStopReason,
37
38
  } from "./summarizerTypes.js";
38
39
  import { SummaryCollection } from "./summaryCollection.js";
39
40
  import { SummarizeResultBuilder } from "./summaryGenerator.js";
@@ -107,9 +108,21 @@ export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements
107
108
 
108
109
  public async run(onBehalfOf: string): Promise<SummarizerStopReason> {
109
110
  try {
110
- return await this.runCore(onBehalfOf);
111
+ const stopReason = await this.runCore(onBehalfOf);
112
+ this.emit("summarizerStop", {
113
+ stopReason,
114
+ numUnsummarizedRuntimeOps: this._heuristicData?.numRuntimeOps,
115
+ numUnsummarizedNonRuntimeOps: this._heuristicData?.numNonRuntimeOps,
116
+ });
117
+ return stopReason;
111
118
  } catch (error) {
112
119
  this.stop("summarizerException");
120
+ this.emit("summarizerStop", {
121
+ stopReason: "summarizerException",
122
+ error,
123
+ numUnsummarizedRuntimeOps: this._heuristicData?.numRuntimeOps,
124
+ numUnsummarizedNonRuntimeOps: this._heuristicData?.numNonRuntimeOps,
125
+ });
113
126
  throw SummarizingWarning.wrap(error, false /* logged */, this.logger);
114
127
  } finally {
115
128
  this.close();
@@ -148,9 +161,20 @@ export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements
148
161
  });
149
162
 
150
163
  if (runCoordinator.cancelled) {
164
+ this.emit("summarizerStartupFailed", {
165
+ reason: await runCoordinator.waitCancelled,
166
+ numUnsummarizedRuntimeOps: this._heuristicData?.numRuntimeOps,
167
+ numUnsummarizedNonRuntimeOps: this._heuristicData?.numNonRuntimeOps,
168
+ });
151
169
  return runCoordinator.waitCancelled;
152
170
  }
153
171
 
172
+ this.emit("summarizerStart", {
173
+ onBehalfOf,
174
+ numUnsummarizedRuntimeOps: this._heuristicData?.numRuntimeOps,
175
+ numUnsummarizedNonRuntimeOps: this._heuristicData?.numNonRuntimeOps,
176
+ });
177
+
154
178
  const runningSummarizer = await this.start(onBehalfOf, runCoordinator);
155
179
 
156
180
  // Wait for either external signal to cancel, or loss of connectivity.
@@ -254,15 +278,11 @@ export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements
254
278
  this.runtime,
255
279
  );
256
280
  this.runningSummarizer = runningSummarizer;
257
- this.runningSummarizer.on("summarize", this.handleSummarizeEvent);
281
+ this.setupForwardedEvents();
258
282
  this.starting = false;
259
283
  return runningSummarizer;
260
284
  }
261
285
 
262
- private readonly handleSummarizeEvent = (eventProps: ISummarizeEventProps) => {
263
- this.emit("summarize", eventProps);
264
- };
265
-
266
286
  /**
267
287
  * Disposes of resources after running. This cleanup will
268
288
  * clear any outstanding timers and reset some of the state
@@ -275,7 +295,7 @@ export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements
275
295
 
276
296
  this._disposed = true;
277
297
  if (this.runningSummarizer) {
278
- this.runningSummarizer.off("summarize", this.handleSummarizeEvent);
298
+ this.cleanupForwardedEvents();
279
299
  this.runningSummarizer.dispose();
280
300
  this.runningSummarizer = undefined;
281
301
  }
@@ -355,4 +375,23 @@ export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements
355
375
  public recordSummaryAttempt?(summaryRefSeqNum?: number) {
356
376
  this._heuristicData?.recordAttempt(summaryRefSeqNum);
357
377
  }
378
+
379
+ private readonly forwardedEvents = new Map<any, () => void>();
380
+
381
+ private setupForwardedEvents() {
382
+ ["summarize", "summarizeAllAttemptsFailed"].forEach((event) => {
383
+ const listener = (...args: any[]) => {
384
+ this.emit(event, ...args);
385
+ };
386
+ this.runningSummarizer?.on(event as any, listener);
387
+ this.forwardedEvents.set(event, listener);
388
+ });
389
+ }
390
+
391
+ private cleanupForwardedEvents() {
392
+ this.forwardedEvents.forEach((listener, event) =>
393
+ this.runningSummarizer?.off(event, listener),
394
+ );
395
+ this.forwardedEvents.clear();
396
+ }
358
397
  }
@@ -7,6 +7,10 @@ import {
7
7
  IDeltaManager,
8
8
  ContainerWarning,
9
9
  } from "@fluidframework/container-definitions/internal";
10
+ import type {
11
+ ISummarizerEvents as NewISummarizerEvents,
12
+ SummarizerStopReason as NewSummarizerStopReason,
13
+ } from "@fluidframework/container-runtime-definitions/internal";
10
14
  import {
11
15
  IEvent,
12
16
  IEventProvider,
@@ -54,7 +58,7 @@ export interface ICancellationToken<T> {
54
58
  * @legacy
55
59
  * @alpha
56
60
  */
57
- export type ISummaryCancellationToken = ICancellationToken<SummarizerStopReason>;
61
+ export type ISummaryCancellationToken = ICancellationToken<NewSummarizerStopReason>;
58
62
 
59
63
  /**
60
64
  * Data required to update internal tracking state after receiving a Summary Ack.
@@ -397,6 +401,7 @@ export type EnqueueSummarizeResult =
397
401
  /**
398
402
  * @legacy
399
403
  * @alpha
404
+ * @deprecated Use SummarizerStopReason from the "\@fluidframework/container-runtime-definitions" package
400
405
  */
401
406
  export type SummarizerStopReason =
402
407
  /** Summarizer client failed to summarize in all attempts. */
@@ -427,6 +432,7 @@ export type SummarizerStopReason =
427
432
  /**
428
433
  * @legacy
429
434
  * @alpha
435
+ * @deprecated Use ISummarizeEventProps from the "\@fluidframework/container-runtime-definitions" package
430
436
  */
431
437
  export interface ISummarizeEventProps {
432
438
  result: "success" | "failure" | "canceled";
@@ -438,6 +444,7 @@ export interface ISummarizeEventProps {
438
444
  /**
439
445
  * @legacy
440
446
  * @alpha
447
+ * @deprecated Use ISummarizerEvents from the "\@fluidframework/container-runtime-definitions" package
441
448
  */
442
449
  export interface ISummarizerEvents extends IEvent {
443
450
  (event: "summarize", listener: (props: ISummarizeEventProps) => void);
@@ -447,7 +454,7 @@ export interface ISummarizerEvents extends IEvent {
447
454
  * @legacy
448
455
  * @alpha
449
456
  */
450
- export interface ISummarizer extends IEventProvider<ISummarizerEvents> {
457
+ export interface ISummarizer extends IEventProvider<NewISummarizerEvents> {
451
458
  /**
452
459
  * Allows {@link ISummarizer} to be used with our {@link @fluidframework/core-interfaces#FluidObject} pattern.
453
460
  */
@@ -458,12 +465,12 @@ export interface ISummarizer extends IEventProvider<ISummarizerEvents> {
458
465
  * Summarizer will finish current processes, which may take a while.
459
466
  * For example, summarizer may complete last summary before exiting.
460
467
  */
461
- stop(reason: SummarizerStopReason): void;
468
+ stop(reason: NewSummarizerStopReason): void;
462
469
 
463
470
  /* Closes summarizer. Any pending processes (summary in flight) are abandoned. */
464
471
  close(): void;
465
472
 
466
- run(onBehalfOf: string): Promise<SummarizerStopReason>;
473
+ run(onBehalfOf: string): Promise<NewSummarizerStopReason>;
467
474
 
468
475
  /**
469
476
  * Attempts to generate a summary on demand. If already running, takes no action.
@@ -83,7 +83,7 @@ class Summary implements ISummary {
83
83
  }
84
84
  public static createFromOp(op: ISummaryOpMessage) {
85
85
  // TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
86
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
86
+
87
87
  const summary = new Summary(op.clientId as string, op.clientSequenceNumber);
88
88
  summary.broadcast(op);
89
89
  return summary;
@@ -408,7 +408,7 @@ export class SummaryCollection extends TypedEventEmitter<ISummaryCollectionOpEve
408
408
 
409
409
  // Check if summary already being watched, broadcast if so
410
410
  // TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
411
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
411
+
412
412
  const watcher = this.summaryWatchers.get(op.clientId as string);
413
413
  if (watcher) {
414
414
  summary = watcher.tryGetSummary(op.clientSequenceNumber);
@@ -4,6 +4,10 @@
4
4
  */
5
5
 
6
6
  import { TypedEventEmitter } from "@fluid-internal/client-utils";
7
+ import type {
8
+ ISummarizerEvents,
9
+ SummarizerStopReason,
10
+ } from "@fluidframework/container-runtime-definitions/internal";
7
11
  import {
8
12
  IDisposable,
9
13
  IEvent,
@@ -26,11 +30,8 @@ import {
26
30
  EnqueueSummarizeResult,
27
31
  IEnqueueSummarizeOptions,
28
32
  IOnDemandSummarizeOptions,
29
- ISummarizeEventProps,
30
33
  ISummarizeResults,
31
34
  ISummarizer,
32
- ISummarizerEvents,
33
- SummarizerStopReason,
34
35
  } from "./summarizerTypes.js";
35
36
  import { SummaryCollection } from "./summaryCollection.js";
36
37
 
@@ -165,10 +166,6 @@ export class SummaryManager
165
166
  this.refreshSummarizer();
166
167
  };
167
168
 
168
- private readonly handleSummarizeEvent = (eventProps: ISummarizeEventProps) => {
169
- this.emit("summarize", eventProps);
170
- };
171
-
172
169
  private static readonly isStartingOrRunning = (state: SummaryManagerState) =>
173
170
  state === SummaryManagerState.Starting || state === SummaryManagerState.Running;
174
171
 
@@ -271,7 +268,7 @@ export class SummaryManager
271
268
 
272
269
  const summarizer = await this.createSummarizerFn();
273
270
  this.summarizer = summarizer;
274
- this.summarizer.on("summarize", this.handleSummarizeEvent);
271
+ this.setupForwardedEvents();
275
272
 
276
273
  // Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore
277
274
  // If we can't run the LastSummary, simply return as to avoid paying the cost of launching
@@ -345,7 +342,7 @@ export class SummaryManager
345
342
  assert(this.state !== SummaryManagerState.Off, 0x264 /* "Expected: Not Off" */);
346
343
  this.state = SummaryManagerState.Off;
347
344
 
348
- this.summarizer?.off("summarize", this.handleSummarizeEvent);
345
+ this.cleanupForwardedEvents();
349
346
  this.summarizer?.close();
350
347
  this.summarizer = undefined;
351
348
 
@@ -448,7 +445,30 @@ export class SummaryManager
448
445
  this.clientElection.off("electedSummarizerChanged", this.refreshSummarizer);
449
446
  this.connectedState.off("connected", this.handleConnected);
450
447
  this.connectedState.off("disconnected", this.handleDisconnected);
451
- this.summarizer?.off("summarize", this.handleSummarizeEvent);
448
+ this.cleanupForwardedEvents();
452
449
  this._disposed = true;
453
450
  }
451
+
452
+ private readonly forwardedEvents = new Map<any, () => void>();
453
+
454
+ private setupForwardedEvents() {
455
+ [
456
+ "summarize",
457
+ "summarizeAllAttemptsFailed",
458
+ "summarizerStop",
459
+ "summarizerStart",
460
+ "summarizerStartupFailed",
461
+ ].forEach((event) => {
462
+ const listener = (...args: any[]) => {
463
+ this.emit(event, ...args);
464
+ };
465
+ this.summarizer?.on(event as any, listener);
466
+ this.forwardedEvents.set(event, listener);
467
+ });
468
+ }
469
+
470
+ private cleanupForwardedEvents() {
471
+ this.forwardedEvents.forEach((listener, event) => this.summarizer?.off(event, listener));
472
+ this.forwardedEvents.clear();
473
+ }
454
474
  }