@fluidframework/container-runtime 2.74.0-370705 → 2.80.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 (117) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/container-runtime.test-files.tar +0 -0
  3. package/dist/blobManager/blobManager.d.ts +0 -2
  4. package/dist/blobManager/blobManager.d.ts.map +1 -1
  5. package/dist/blobManager/blobManager.js +4 -5
  6. package/dist/blobManager/blobManager.js.map +1 -1
  7. package/dist/channelCollection.d.ts +3 -3
  8. package/dist/channelCollection.d.ts.map +1 -1
  9. package/dist/channelCollection.js +20 -2
  10. package/dist/channelCollection.js.map +1 -1
  11. package/dist/containerRuntime.d.ts +5 -0
  12. package/dist/containerRuntime.d.ts.map +1 -1
  13. package/dist/containerRuntime.js +13 -7
  14. package/dist/containerRuntime.js.map +1 -1
  15. package/dist/dataStoreContext.d.ts +1 -1
  16. package/dist/dataStoreContext.d.ts.map +1 -1
  17. package/dist/dataStoreContext.js +1 -1
  18. package/dist/dataStoreContext.js.map +1 -1
  19. package/dist/dataStoreContexts.d.ts +56 -9
  20. package/dist/dataStoreContexts.d.ts.map +1 -1
  21. package/dist/dataStoreContexts.js +56 -9
  22. package/dist/dataStoreContexts.js.map +1 -1
  23. package/dist/packageVersion.d.ts +1 -1
  24. package/dist/packageVersion.d.ts.map +1 -1
  25. package/dist/packageVersion.js +1 -1
  26. package/dist/packageVersion.js.map +1 -1
  27. package/dist/runtimeLayerCompatState.d.ts +10 -6
  28. package/dist/runtimeLayerCompatState.d.ts.map +1 -1
  29. package/dist/runtimeLayerCompatState.js +16 -6
  30. package/dist/runtimeLayerCompatState.js.map +1 -1
  31. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  32. package/dist/summary/summarizerClientElection.js +1 -0
  33. package/dist/summary/summarizerClientElection.js.map +1 -1
  34. package/dist/summary/summarizerTypes.d.ts +5 -0
  35. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  36. package/dist/summary/summarizerTypes.js.map +1 -1
  37. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts +3 -1
  38. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
  39. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js +39 -18
  40. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
  41. package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts +1 -1
  42. package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
  43. package/dist/summary/summaryDelayLoadedModule/summarizer.js +13 -11
  44. package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
  45. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +4 -1
  46. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -1
  47. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js +30 -9
  48. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  49. package/dist/summary/summaryManager.d.ts +1 -1
  50. package/dist/summary/summaryManager.d.ts.map +1 -1
  51. package/dist/summary/summaryManager.js +10 -9
  52. package/dist/summary/summaryManager.js.map +1 -1
  53. package/eslint.config.mts +31 -0
  54. package/lib/blobManager/blobManager.d.ts +0 -2
  55. package/lib/blobManager/blobManager.d.ts.map +1 -1
  56. package/lib/blobManager/blobManager.js +4 -5
  57. package/lib/blobManager/blobManager.js.map +1 -1
  58. package/lib/channelCollection.d.ts +3 -3
  59. package/lib/channelCollection.d.ts.map +1 -1
  60. package/lib/channelCollection.js +20 -2
  61. package/lib/channelCollection.js.map +1 -1
  62. package/lib/containerRuntime.d.ts +5 -0
  63. package/lib/containerRuntime.d.ts.map +1 -1
  64. package/lib/containerRuntime.js +13 -7
  65. package/lib/containerRuntime.js.map +1 -1
  66. package/lib/dataStoreContext.d.ts +1 -1
  67. package/lib/dataStoreContext.d.ts.map +1 -1
  68. package/lib/dataStoreContext.js +1 -1
  69. package/lib/dataStoreContext.js.map +1 -1
  70. package/lib/dataStoreContexts.d.ts +56 -9
  71. package/lib/dataStoreContexts.d.ts.map +1 -1
  72. package/lib/dataStoreContexts.js +56 -9
  73. package/lib/dataStoreContexts.js.map +1 -1
  74. package/lib/packageVersion.d.ts +1 -1
  75. package/lib/packageVersion.d.ts.map +1 -1
  76. package/lib/packageVersion.js +1 -1
  77. package/lib/packageVersion.js.map +1 -1
  78. package/lib/runtimeLayerCompatState.d.ts +10 -6
  79. package/lib/runtimeLayerCompatState.d.ts.map +1 -1
  80. package/lib/runtimeLayerCompatState.js +15 -5
  81. package/lib/runtimeLayerCompatState.js.map +1 -1
  82. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  83. package/lib/summary/summarizerClientElection.js +1 -0
  84. package/lib/summary/summarizerClientElection.js.map +1 -1
  85. package/lib/summary/summarizerTypes.d.ts +5 -0
  86. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  87. package/lib/summary/summarizerTypes.js.map +1 -1
  88. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts +3 -1
  89. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
  90. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js +39 -18
  91. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
  92. package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts +1 -1
  93. package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
  94. package/lib/summary/summaryDelayLoadedModule/summarizer.js +13 -11
  95. package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
  96. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +4 -1
  97. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -1
  98. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js +26 -5
  99. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  100. package/lib/summary/summaryManager.d.ts +1 -1
  101. package/lib/summary/summaryManager.d.ts.map +1 -1
  102. package/lib/summary/summaryManager.js +10 -9
  103. package/lib/summary/summaryManager.js.map +1 -1
  104. package/package.json +27 -26
  105. package/src/blobManager/blobManager.ts +3 -7
  106. package/src/channelCollection.ts +29 -5
  107. package/src/containerRuntime.ts +19 -6
  108. package/src/dataStoreContext.ts +2 -2
  109. package/src/dataStoreContexts.ts +56 -9
  110. package/src/packageVersion.ts +1 -1
  111. package/src/runtimeLayerCompatState.ts +25 -9
  112. package/src/summary/summarizerClientElection.ts +1 -0
  113. package/src/summary/summarizerTypes.ts +5 -0
  114. package/src/summary/summaryDelayLoadedModule/runningSummarizer.ts +54 -26
  115. package/src/summary/summaryDelayLoadedModule/summarizer.ts +13 -11
  116. package/src/summary/summaryDelayLoadedModule/summaryGenerator.ts +35 -5
  117. package/src/summary/summaryManager.ts +11 -10
@@ -301,7 +301,7 @@ export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements
301
301
  this.runtime,
302
302
  );
303
303
  this.runningSummarizer = runningSummarizer;
304
- this.setupForwardedEvents();
304
+ this.setupForwardedEvents(runningSummarizer);
305
305
  this.starting = false;
306
306
  return runningSummarizer;
307
307
  }
@@ -399,24 +399,26 @@ export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements
399
399
  this._heuristicData?.recordAttempt(summaryRefSeqNum);
400
400
  }
401
401
 
402
- private readonly forwardedEvents = new Map<string, () => void>();
402
+ private readonly forwardedEventsCleanup: (() => void)[] = [];
403
403
 
404
- private setupForwardedEvents(): void {
405
- for (const event of ["summarize", "summarizeAllAttemptsFailed"]) {
404
+ private setupForwardedEvents(runningSummarizer: RunningSummarizer): void {
405
+ for (const event of [
406
+ "summarize",
407
+ "summarizeAllAttemptsFailed",
408
+ "summarizeTimeout",
409
+ ] as const) {
406
410
  const listener = (...args: unknown[]): void => {
407
411
  this.emit(event, ...args);
408
412
  };
409
- // TODO: better typing here
410
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
411
- this.runningSummarizer?.on(event as any, listener);
412
- this.forwardedEvents.set(event, listener);
413
+ runningSummarizer.on(event, listener);
414
+ this.forwardedEventsCleanup.push(() => runningSummarizer.off(event, listener));
413
415
  }
414
416
  }
415
417
 
416
418
  private cleanupForwardedEvents(): void {
417
- for (const [event, listener] of this.forwardedEvents.entries()) {
418
- this.runningSummarizer?.off(event, listener);
419
+ for (const cleanup of this.forwardedEventsCleanup) {
420
+ cleanup();
419
421
  }
420
- this.forwardedEvents.clear();
422
+ this.forwardedEventsCleanup.length = 0;
421
423
  }
422
424
  }
@@ -3,9 +3,12 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import { TypedEventEmitter } from "@fluid-internal/client-utils";
7
+ import type { ISummarizerEvents } from "@fluidframework/container-runtime-definitions/internal";
6
8
  import { assert, type IPromiseTimer, Timer } from "@fluidframework/core-utils/internal";
7
9
  import { DriverErrorTypes, MessageType } from "@fluidframework/driver-definitions/internal";
8
10
  import { getRetryDelaySecondsFromError } from "@fluidframework/driver-utils/internal";
11
+ import { TelemetryContext } from "@fluidframework/runtime-utils/internal";
9
12
  import {
10
13
  isFluidError,
11
14
  type ITelemetryLoggerExt,
@@ -40,8 +43,9 @@ const maxSummarizeTimeoutCount = 5; // Double and resend 5 times
40
43
  /**
41
44
  * This class generates and tracks a summary attempt.
42
45
  */
43
- export class SummaryGenerator {
46
+ export class SummaryGenerator extends TypedEventEmitter<ISummarizerEvents> {
44
47
  private readonly summarizeTimer: Timer;
48
+ private activeTelemetryContext?: TelemetryContext;
45
49
  constructor(
46
50
  private readonly pendingAckTimer: IPromiseTimer,
47
51
  private readonly heuristicData: ISummarizeHeuristicData,
@@ -55,6 +59,7 @@ export class SummaryGenerator {
55
59
  private readonly summaryWatcher: Pick<IClientSummaryWatcher, "watchSummary">,
56
60
  private readonly logger: ITelemetryLoggerExt,
57
61
  ) {
62
+ super();
58
63
  this.summarizeTimer = new Timer(maxSummarizeTimeoutTime, () =>
59
64
  this.summarizeTimerHandler(maxSummarizeTimeoutTime, 1),
60
65
  );
@@ -85,7 +90,16 @@ export class SummaryGenerator {
85
90
  submitSummaryOptions: ISubmitSummaryOptions,
86
91
  resultsBuilder: SummarizeResultBuilder,
87
92
  ): Promise<void> {
88
- const { summaryLogger, cancellationToken, ...summarizeOptions } = submitSummaryOptions;
93
+ const {
94
+ summaryLogger,
95
+ cancellationToken,
96
+ telemetryContext = new TelemetryContext(),
97
+ ...summarizeOptions
98
+ } = submitSummaryOptions;
99
+
100
+ telemetryContext.setCurrentSummarizeStep("submitSummary");
101
+ const submitOptions = { ...submitSummaryOptions, telemetryContext };
102
+ this.activeTelemetryContext = telemetryContext;
89
103
 
90
104
  // Note: timeSinceLastAttempt and timeSinceLastSummary for the
91
105
  // first summary are basically the time since the summarizer was loaded.
@@ -97,6 +111,8 @@ export class SummaryGenerator {
97
111
  fullTree: summarizeOptions.fullTree ?? false,
98
112
  timeSinceLastAttempt,
99
113
  timeSinceLastSummary,
114
+ nonRuntimeOpsSinceLastSummary: this.heuristicData.numNonRuntimeOps,
115
+ runtimeOpsSinceLastSummary: this.heuristicData.numRuntimeOps,
100
116
  };
101
117
 
102
118
  const summarizeEvent = PerformanceEvent.start(
@@ -148,10 +164,12 @@ export class SummaryGenerator {
148
164
  // Wait to generate and send summary
149
165
  this.summarizeTimer.start();
150
166
  try {
167
+ telemetryContext.setCurrentSummarizeStep("generateSummary");
151
168
  // Need to save refSeqNum before we record new attempt (happens as part of submitSummaryCallback)
152
169
  const lastAttemptRefSeqNum = this.heuristicData.lastAttempt.refSequenceNumber;
153
170
 
154
- summaryData = await this.submitSummaryCallback(submitSummaryOptions);
171
+ summaryData = await this.submitSummaryCallback(submitOptions);
172
+ telemetryContext.setCurrentSummarizeStep("submitSummaryOp");
155
173
 
156
174
  // Cumulatively add telemetry properties based on how far generateSummary went.
157
175
  const referenceSequenceNumber = summaryData.referenceSequenceNumber;
@@ -189,6 +207,7 @@ export class SummaryGenerator {
189
207
  * exceed the number of ops since last summary + number of data store whose reference state changed.
190
208
  */
191
209
  if (submitSummaryOptions.fullTree !== true) {
210
+ telemetryContext.setCurrentSummarizeStep("watchSummary");
192
211
  const { summarizedDataStoreCount, gcStateUpdatedDataStoreCount = 0 } =
193
212
  summaryData.summaryStats;
194
213
  if (
@@ -227,6 +246,8 @@ export class SummaryGenerator {
227
246
  this.summarizeTimer.clear();
228
247
  }
229
248
 
249
+ telemetryContext.setCurrentSummarizeStep("waitForSummaryAck");
250
+
230
251
  try {
231
252
  const pendingTimeoutP = this.pendingAckTimer.start();
232
253
  const summary = this.summaryWatcher.watchSummary(summaryData.clientSequenceNumber);
@@ -300,6 +321,7 @@ export class SummaryGenerator {
300
321
  ...summarizeTelemetryProps,
301
322
  };
302
323
  if (ackNackOp.type === MessageType.SummaryAck) {
324
+ telemetryContext.setCurrentSummarizeStep("ackReceived");
303
325
  this.heuristicData.markLastAttemptAsSuccessful();
304
326
  this.successfulSummaryCallback();
305
327
  summarizeEvent.end({
@@ -324,6 +346,7 @@ export class SummaryGenerator {
324
346
  } else {
325
347
  // Check for retryDelay in summaryNack response.
326
348
  assert(ackNackOp.type === MessageType.SummaryNack, 0x274 /* "type check" */);
349
+ telemetryContext.setCurrentSummarizeStep("nackReceived");
327
350
  const summaryNack = ackNackOp.contents;
328
351
  const errorMessage = summaryNack?.message;
329
352
  const retryAfterSeconds = summaryNack?.retryAfter;
@@ -350,6 +373,7 @@ export class SummaryGenerator {
350
373
  }
351
374
  } finally {
352
375
  this.pendingAckTimer.clear();
376
+ this.activeTelemetryContext = undefined;
353
377
  }
354
378
  }
355
379
 
@@ -390,8 +414,6 @@ export class SummaryGenerator {
390
414
  clientSequenceNumber: summaryData.clientSequenceNumber,
391
415
  hasMissingOpData: this.heuristicData.hasMissingOpData,
392
416
  opsSizesSinceLastSummary: this.heuristicData.totalOpsSize,
393
- nonRuntimeOpsSinceLastSummary: this.heuristicData.numNonRuntimeOps,
394
- runtimeOpsSinceLastSummary: this.heuristicData.numRuntimeOps,
395
417
  };
396
418
  }
397
419
 
@@ -408,6 +430,13 @@ export class SummaryGenerator {
408
430
  eventName: "SummarizeTimeout",
409
431
  timeoutTime: time,
410
432
  timeoutCount: count,
433
+ currentSummarizeStep: this.activeTelemetryContext?.getCurrentSummarizeStep(),
434
+ });
435
+ this.emit("summarizeTimeout", {
436
+ timeoutCount: count,
437
+ currentSummarizeStep: this.activeTelemetryContext?.getCurrentSummarizeStep(),
438
+ numUnsummarizedRuntimeOps: this.heuristicData.numRuntimeOps,
439
+ numUnsummarizedNonRuntimeOps: this.heuristicData.numNonRuntimeOps,
411
440
  });
412
441
  if (count < maxSummarizeTimeoutCount) {
413
442
  // Double and start a new timer
@@ -420,5 +449,6 @@ export class SummaryGenerator {
420
449
 
421
450
  public dispose(): void {
422
451
  this.summarizeTimer.clear();
452
+ this.activeTelemetryContext = undefined;
423
453
  }
424
454
  }
@@ -274,7 +274,7 @@ export class SummaryManager
274
274
 
275
275
  const summarizer = await this.createSummarizerFn();
276
276
  this.summarizer = summarizer;
277
- this.setupForwardedEvents();
277
+ this.setupForwardedEvents(summarizer);
278
278
 
279
279
  // Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore
280
280
  // If we can't run the LastSummary, simply return as to avoid paying the cost of launching
@@ -456,31 +456,32 @@ export class SummaryManager
456
456
  this._disposed = true;
457
457
  }
458
458
 
459
- private readonly forwardedEvents = new Map<string, () => void>();
459
+ private readonly forwardedEventsCleanup: (() => void)[] = [];
460
460
 
461
- private setupForwardedEvents(): void {
461
+ private setupForwardedEvents(summarizer: ISummarizer): void {
462
462
  for (const event of [
463
463
  "summarize",
464
464
  "summarizeAllAttemptsFailed",
465
465
  "summarizerStop",
466
466
  "summarizerStart",
467
467
  "summarizerStartupFailed",
468
- ]) {
468
+ "summarizeTimeout",
469
+ ] as const) {
469
470
  const listener = (...args: unknown[]): void => {
470
471
  this.emit(event, ...args);
471
472
  };
472
473
  // TODO: better typing here
473
474
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
474
- this.summarizer?.on(event as any, listener);
475
- this.forwardedEvents.set(event, listener);
475
+ summarizer.on(event as any, listener);
476
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
477
+ this.forwardedEventsCleanup.push(() => summarizer.off(event as any, listener));
476
478
  }
477
479
  }
478
480
 
479
481
  private cleanupForwardedEvents(): void {
480
- for (const [event, listener] of this.forwardedEvents.entries()) {
481
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
482
- this.summarizer?.off(event as any, listener);
482
+ for (const cleanup of this.forwardedEventsCleanup) {
483
+ cleanup();
483
484
  }
484
- this.forwardedEvents.clear();
485
+ this.forwardedEventsCleanup.length = 0;
485
486
  }
486
487
  }