@fluidframework/container-runtime 1.2.2 → 2.0.0-internal.1.0.0.82159

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 (135) hide show
  1. package/dist/blobManager.d.ts +81 -25
  2. package/dist/blobManager.d.ts.map +1 -1
  3. package/dist/blobManager.js +301 -100
  4. package/dist/blobManager.js.map +1 -1
  5. package/dist/containerRuntime.d.ts +65 -11
  6. package/dist/containerRuntime.d.ts.map +1 -1
  7. package/dist/containerRuntime.js +101 -82
  8. package/dist/containerRuntime.js.map +1 -1
  9. package/dist/dataStore.d.ts +1 -1
  10. package/dist/dataStore.d.ts.map +1 -1
  11. package/dist/dataStore.js +32 -26
  12. package/dist/dataStore.js.map +1 -1
  13. package/dist/dataStoreContext.d.ts +3 -4
  14. package/dist/dataStoreContext.d.ts.map +1 -1
  15. package/dist/dataStoreContext.js +16 -23
  16. package/dist/dataStoreContext.js.map +1 -1
  17. package/dist/dataStores.d.ts +5 -2
  18. package/dist/dataStores.d.ts.map +1 -1
  19. package/dist/dataStores.js +11 -3
  20. package/dist/dataStores.js.map +1 -1
  21. package/dist/garbageCollection.d.ts.map +1 -1
  22. package/dist/garbageCollection.js +17 -12
  23. package/dist/garbageCollection.js.map +1 -1
  24. package/dist/opProperties.d.ts +7 -0
  25. package/dist/opProperties.d.ts.map +1 -0
  26. package/dist/opProperties.js +20 -0
  27. package/dist/opProperties.js.map +1 -0
  28. package/dist/packageVersion.d.ts +1 -1
  29. package/dist/packageVersion.d.ts.map +1 -1
  30. package/dist/packageVersion.js +1 -1
  31. package/dist/packageVersion.js.map +1 -1
  32. package/dist/runningSummarizer.d.ts +14 -4
  33. package/dist/runningSummarizer.d.ts.map +1 -1
  34. package/dist/runningSummarizer.js +68 -26
  35. package/dist/runningSummarizer.js.map +1 -1
  36. package/dist/summarizer.d.ts +0 -2
  37. package/dist/summarizer.d.ts.map +1 -1
  38. package/dist/summarizer.js +1 -12
  39. package/dist/summarizer.js.map +1 -1
  40. package/dist/summarizerHeuristics.d.ts +26 -4
  41. package/dist/summarizerHeuristics.d.ts.map +1 -1
  42. package/dist/summarizerHeuristics.js +95 -18
  43. package/dist/summarizerHeuristics.js.map +1 -1
  44. package/dist/summarizerTypes.d.ts +30 -10
  45. package/dist/summarizerTypes.d.ts.map +1 -1
  46. package/dist/summarizerTypes.js.map +1 -1
  47. package/dist/summaryCollection.js +1 -1
  48. package/dist/summaryCollection.js.map +1 -1
  49. package/dist/summaryFormat.d.ts +0 -5
  50. package/dist/summaryFormat.d.ts.map +1 -1
  51. package/dist/summaryFormat.js.map +1 -1
  52. package/dist/summaryGenerator.d.ts +1 -0
  53. package/dist/summaryGenerator.d.ts.map +1 -1
  54. package/dist/summaryGenerator.js +11 -9
  55. package/dist/summaryGenerator.js.map +1 -1
  56. package/lib/blobManager.d.ts +81 -25
  57. package/lib/blobManager.d.ts.map +1 -1
  58. package/lib/blobManager.js +302 -101
  59. package/lib/blobManager.js.map +1 -1
  60. package/lib/containerRuntime.d.ts +65 -11
  61. package/lib/containerRuntime.d.ts.map +1 -1
  62. package/lib/containerRuntime.js +103 -84
  63. package/lib/containerRuntime.js.map +1 -1
  64. package/lib/dataStore.d.ts +1 -1
  65. package/lib/dataStore.d.ts.map +1 -1
  66. package/lib/dataStore.js +32 -26
  67. package/lib/dataStore.js.map +1 -1
  68. package/lib/dataStoreContext.d.ts +3 -4
  69. package/lib/dataStoreContext.d.ts.map +1 -1
  70. package/lib/dataStoreContext.js +17 -24
  71. package/lib/dataStoreContext.js.map +1 -1
  72. package/lib/dataStores.d.ts +5 -2
  73. package/lib/dataStores.d.ts.map +1 -1
  74. package/lib/dataStores.js +11 -3
  75. package/lib/dataStores.js.map +1 -1
  76. package/lib/garbageCollection.d.ts.map +1 -1
  77. package/lib/garbageCollection.js +17 -12
  78. package/lib/garbageCollection.js.map +1 -1
  79. package/lib/opProperties.d.ts +7 -0
  80. package/lib/opProperties.d.ts.map +1 -0
  81. package/lib/opProperties.js +16 -0
  82. package/lib/opProperties.js.map +1 -0
  83. package/lib/packageVersion.d.ts +1 -1
  84. package/lib/packageVersion.d.ts.map +1 -1
  85. package/lib/packageVersion.js +1 -1
  86. package/lib/packageVersion.js.map +1 -1
  87. package/lib/runningSummarizer.d.ts +14 -4
  88. package/lib/runningSummarizer.d.ts.map +1 -1
  89. package/lib/runningSummarizer.js +68 -26
  90. package/lib/runningSummarizer.js.map +1 -1
  91. package/lib/summarizer.d.ts +0 -2
  92. package/lib/summarizer.d.ts.map +1 -1
  93. package/lib/summarizer.js +1 -12
  94. package/lib/summarizer.js.map +1 -1
  95. package/lib/summarizerHeuristics.d.ts +26 -4
  96. package/lib/summarizerHeuristics.d.ts.map +1 -1
  97. package/lib/summarizerHeuristics.js +95 -18
  98. package/lib/summarizerHeuristics.js.map +1 -1
  99. package/lib/summarizerTypes.d.ts +30 -10
  100. package/lib/summarizerTypes.d.ts.map +1 -1
  101. package/lib/summarizerTypes.js.map +1 -1
  102. package/lib/summaryCollection.js +1 -1
  103. package/lib/summaryCollection.js.map +1 -1
  104. package/lib/summaryFormat.d.ts +0 -5
  105. package/lib/summaryFormat.d.ts.map +1 -1
  106. package/lib/summaryFormat.js.map +1 -1
  107. package/lib/summaryGenerator.d.ts +1 -0
  108. package/lib/summaryGenerator.d.ts.map +1 -1
  109. package/lib/summaryGenerator.js +11 -9
  110. package/lib/summaryGenerator.js.map +1 -1
  111. package/package.json +45 -20
  112. package/src/blobManager.ts +360 -119
  113. package/src/containerRuntime.ts +203 -103
  114. package/src/dataStore.ts +53 -38
  115. package/src/dataStoreContext.ts +16 -23
  116. package/src/dataStores.ts +14 -3
  117. package/src/garbageCollection.ts +13 -7
  118. package/src/opProperties.ts +19 -0
  119. package/src/packageVersion.ts +1 -1
  120. package/src/runningSummarizer.ts +75 -22
  121. package/src/summarizer.ts +1 -18
  122. package/src/summarizerHeuristics.ts +133 -19
  123. package/src/summarizerTypes.ts +37 -10
  124. package/src/summaryCollection.ts +1 -1
  125. package/src/summaryFormat.ts +0 -6
  126. package/src/summaryGenerator.ts +40 -22
  127. package/dist/opTelemetry.d.ts +0 -22
  128. package/dist/opTelemetry.d.ts.map +0 -1
  129. package/dist/opTelemetry.js +0 -59
  130. package/dist/opTelemetry.js.map +0 -1
  131. package/lib/opTelemetry.d.ts +0 -22
  132. package/lib/opTelemetry.d.ts.map +0 -1
  133. package/lib/opTelemetry.js +0 -55
  134. package/lib/opTelemetry.js.map +0 -1
  135. package/src/opTelemetry.ts +0 -71
@@ -15,8 +15,10 @@ var __rest = (this && this.__rest) || function (s, e) {
15
15
  };
16
16
  import { assert, delay, Deferred, PromiseTimer } from "@fluidframework/common-utils";
17
17
  import { UsageError } from "@fluidframework/container-utils";
18
+ import { isRuntimeMessage } from "@fluidframework/driver-utils";
18
19
  import { MessageType, } from "@fluidframework/protocol-definitions";
19
20
  import { ChildLogger } from "@fluidframework/telemetry-utils";
21
+ import { opSize } from "./opProperties";
20
22
  import { SummarizeHeuristicRunner } from "./summarizerHeuristics";
21
23
  import { raceTimer, SummarizeResultBuilder, SummaryGenerator, } from "./summaryGenerator";
22
24
  const maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes
@@ -28,7 +30,7 @@ const maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes
28
30
  * This object is created and controlled by Summarizer object.
29
31
  */
30
32
  export class RunningSummarizer {
31
- constructor(baseLogger, summaryWatcher, configuration, submitSummaryCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback) {
33
+ constructor(baseLogger, summaryWatcher, configuration, submitSummaryCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback, runtime) {
32
34
  this.summaryWatcher = summaryWatcher;
33
35
  this.configuration = configuration;
34
36
  this.submitSummaryCallback = submitSummaryCallback;
@@ -37,11 +39,13 @@ export class RunningSummarizer {
37
39
  this.summaryCollection = summaryCollection;
38
40
  this.cancellationToken = cancellationToken;
39
41
  this.stopSummarizerCallback = stopSummarizerCallback;
42
+ this.runtime = runtime;
40
43
  this.stopping = false;
41
44
  this._disposed = false;
42
45
  this.tryWhileSummarizing = false;
43
46
  this.summarizeCount = 0;
44
47
  this.totalSuccessfulAttempts = 0;
48
+ this.initialized = false;
45
49
  /**
46
50
  * RunningSummarizer's logger includes the sequenced index of the current summary on each event.
47
51
  * If some other Summarizer code wants that event on their logs they can get it here,
@@ -51,6 +55,8 @@ export class RunningSummarizer {
51
55
  this.tryGetCorrelatedLogger = (summaryOpRefSeq) => this.heuristicData.lastAttempt.refSequenceNumber === summaryOpRefSeq
52
56
  ? this.logger
53
57
  : undefined;
58
+ /** We only want a single heuristic runner micro-task (will provide better optimized grouping of ops) */
59
+ this.heuristicRunnerMicroTaskExists = false;
54
60
  const telemetryProps = {
55
61
  summarizeCount: () => this.summarizeCount,
56
62
  summarizerSuccessfulAttempts: () => this.totalSuccessfulAttempts,
@@ -92,18 +98,39 @@ export class RunningSummarizer {
92
98
  }
93
99
  });
94
100
  this.generator = new SummaryGenerator(this.pendingAckTimer, this.heuristicData, this.submitSummaryCallback, this.raiseSummarizingError, () => { this.totalSuccessfulAttempts++; }, this.summaryWatcher, this.logger);
101
+ // Listen for ops
102
+ this.runtime.deltaManager.on("op", (op) => { this.handleOp(op); });
95
103
  }
96
- static async start(logger, summaryWatcher, configuration, submitSummaryCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback) {
97
- var _a;
98
- const summarizer = new RunningSummarizer(logger, summaryWatcher, configuration, submitSummaryCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback);
104
+ static async start(logger, summaryWatcher, configuration, submitSummaryCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback, runtime) {
105
+ var _a, _b;
106
+ const summarizer = new RunningSummarizer(logger, summaryWatcher, configuration, submitSummaryCallback, heuristicData, raiseSummarizingError, summaryCollection, cancellationToken, stopSummarizerCallback, runtime);
99
107
  await summarizer.waitStart();
100
- // Run the heuristics after starting
101
- (_a = summarizer.heuristicRunner) === null || _a === void 0 ? void 0 : _a.run();
108
+ // Update heuristic counts
109
+ // By the time we get here, there are potentially ops missing from the heuristic summary counts
110
+ // Examples of where this could happen:
111
+ // 1. Op is processed during the time that we are initiating the RunningSummarizer instance but before we
112
+ // listen for the op events (will get missed by the handlers in the current workflow)
113
+ // 2. Op was sequenced after the last time we summarized (op sequence number > summarize ref sequence number)
114
+ const diff = runtime.deltaManager.lastSequenceNumber - (heuristicData.lastSuccessfulSummary.refSequenceNumber
115
+ + heuristicData.numNonRuntimeOps
116
+ + heuristicData.numRuntimeOps);
117
+ heuristicData.hasMissingOpData = diff > 0;
118
+ if (heuristicData.hasMissingOpData) {
119
+ // Split the diff 50-50 and increment the counts appropriately
120
+ heuristicData.numNonRuntimeOps += Math.ceil(diff / 2);
121
+ heuristicData.numRuntimeOps += Math.floor(diff / 2);
122
+ }
123
+ // Update last seq number (in case the handlers haven't processed anything yet)
124
+ heuristicData.lastOpSequenceNumber = runtime.deltaManager.lastSequenceNumber;
125
+ // Start heuristics
126
+ (_a = summarizer.heuristicRunner) === null || _a === void 0 ? void 0 : _a.start();
127
+ (_b = summarizer.heuristicRunner) === null || _b === void 0 ? void 0 : _b.run();
102
128
  return summarizer;
103
129
  }
104
130
  get disposed() { return this._disposed; }
105
131
  dispose() {
106
132
  var _a;
133
+ this.runtime.deltaManager.off("op", (op) => { this.handleOp(op); });
107
134
  this.summaryWatcher.dispose();
108
135
  (_a = this.heuristicRunner) === null || _a === void 0 ? void 0 : _a.dispose();
109
136
  this.heuristicRunner = undefined;
@@ -113,29 +140,43 @@ export class RunningSummarizer {
113
140
  this._disposed = true;
114
141
  this.stopping = true;
115
142
  }
116
- handleSystemOp(op) {
117
- switch (op.type) {
118
- case MessageType.ClientLeave:
119
- case MessageType.ClientJoin:
120
- case MessageType.Propose: {
121
- // Synchronously handle quorum ops like regular ops
122
- this.handleOp(undefined, op);
123
- return;
124
- }
125
- default: {
126
- return;
127
- }
143
+ handleOp(op) {
144
+ this.heuristicData.lastOpSequenceNumber = op.sequenceNumber;
145
+ if (op.type !== MessageType.Summarize && isRuntimeMessage(op)) {
146
+ this.heuristicData.numRuntimeOps++;
128
147
  }
129
- }
130
- handleOp(error, { sequenceNumber, type, clientId, contents }) {
131
- var _a;
132
- if (error !== undefined) {
133
- return;
148
+ else {
149
+ this.heuristicData.numNonRuntimeOps++;
134
150
  }
135
- this.heuristicData.lastOpSequenceNumber = sequenceNumber;
151
+ this.heuristicData.totalOpsSize += opSize(op);
136
152
  // Check for enqueued on-demand summaries; Intentionally do nothing otherwise
137
- if (!this.tryRunEnqueuedSummary()) {
138
- (_a = this.heuristicRunner) === null || _a === void 0 ? void 0 : _a.run();
153
+ if (this.initialized
154
+ && this.opCanTriggerSummary(op)
155
+ && !this.tryRunEnqueuedSummary()
156
+ && !this.heuristicRunnerMicroTaskExists) {
157
+ this.heuristicRunnerMicroTaskExists = true;
158
+ Promise.resolve().then(() => {
159
+ var _a;
160
+ (_a = this.heuristicRunner) === null || _a === void 0 ? void 0 : _a.run();
161
+ }).finally(() => {
162
+ this.heuristicRunnerMicroTaskExists = false;
163
+ });
164
+ }
165
+ }
166
+ /**
167
+ * Can the given op trigger a summary?
168
+ * # Currently only prevents summaries for Summarize and SummaryAck ops
169
+ * @param op - op to check
170
+ * @returns true if this type of op can trigger a summary
171
+ */
172
+ opCanTriggerSummary(op) {
173
+ switch (op.type) {
174
+ case MessageType.Summarize:
175
+ case MessageType.SummaryAck:
176
+ case MessageType.SummaryNack:
177
+ return false;
178
+ default:
179
+ return true;
139
180
  }
140
181
  }
141
182
  async waitStop(allowLastSummary) {
@@ -177,6 +218,7 @@ export class RunningSummarizer {
177
218
  summarySequenceNumber: waitStartResult.value.summaryOp.sequenceNumber,
178
219
  });
179
220
  }
221
+ this.initialized = true;
180
222
  }
181
223
  /**
182
224
  * Runs single summary action that prevents any other concurrent actions.
@@ -1 +1 @@
1
- {"version":3,"file":"runningSummarizer.js","sourceRoot":"","sources":["../src/runningSummarizer.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, delay, Deferred, PromiseTimer } from \"@fluidframework/common-utils\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport {\n ISequencedDocumentMessage,\n MessageType,\n} from \"@fluidframework/protocol-definitions\";\nimport { ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport {\n ISummaryConfiguration,\n} from \"./containerRuntime\";\nimport { SummarizeHeuristicRunner } from \"./summarizerHeuristics\";\nimport {\n IEnqueueSummarizeOptions,\n ISummarizeOptions,\n ISummarizeHeuristicData,\n ISummarizeHeuristicRunner,\n IOnDemandSummarizeOptions,\n EnqueueSummarizeResult,\n SummarizerStopReason,\n ISubmitSummaryOptions,\n SubmitSummaryResult,\n ISummaryCancellationToken,\n ISummarizeResults,\n ISummarizeTelemetryProperties,\n ISummarizeRunnerTelemetry,\n} from \"./summarizerTypes\";\nimport { IClientSummaryWatcher, SummaryCollection } from \"./summaryCollection\";\nimport {\n raceTimer,\n SummarizeReason,\n SummarizeResultBuilder,\n SummaryGenerator,\n} from \"./summaryGenerator\";\n\nconst maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes\n\n/**\n * An instance of RunningSummarizer manages the heuristics for summarizing.\n * Until disposed, the instance of RunningSummarizer can assume that it is\n * in a state of running, meaning it is connected and initialized. It keeps\n * track of summaries that it is generating as they are broadcast and acked/nacked.\n * This object is created and controlled by Summarizer object.\n */\nexport class RunningSummarizer implements IDisposable {\n public static async start(\n logger: ITelemetryLogger,\n summaryWatcher: IClientSummaryWatcher,\n configuration: ISummaryConfiguration,\n submitSummaryCallback: (options: ISubmitSummaryOptions) => Promise<SubmitSummaryResult>,\n heuristicData: ISummarizeHeuristicData,\n raiseSummarizingError: (errorMessage: string) => void,\n summaryCollection: SummaryCollection,\n cancellationToken: ISummaryCancellationToken,\n stopSummarizerCallback: (reason: SummarizerStopReason) => void,\n ): Promise<RunningSummarizer> {\n const summarizer = new RunningSummarizer(\n logger,\n summaryWatcher,\n configuration,\n submitSummaryCallback,\n heuristicData,\n raiseSummarizingError,\n summaryCollection,\n cancellationToken,\n stopSummarizerCallback);\n\n await summarizer.waitStart();\n\n // Run the heuristics after starting\n summarizer.heuristicRunner?.run();\n return summarizer;\n }\n\n public get disposed() { return this._disposed; }\n\n private stopping = false;\n private _disposed = false;\n private summarizingLock: Promise<void> | undefined;\n private tryWhileSummarizing = false;\n private readonly pendingAckTimer: PromiseTimer;\n private heuristicRunner?: ISummarizeHeuristicRunner;\n private readonly generator: SummaryGenerator;\n private readonly logger: ITelemetryLogger;\n private enqueuedSummary: {\n reason: SummarizeReason;\n afterSequenceNumber: number;\n options: ISummarizeOptions;\n readonly resultsBuilder: SummarizeResultBuilder;\n } | undefined;\n private summarizeCount = 0;\n private totalSuccessfulAttempts = 0;\n\n private constructor(\n baseLogger: ITelemetryLogger,\n private readonly summaryWatcher: IClientSummaryWatcher,\n private readonly configuration: ISummaryConfiguration,\n private readonly submitSummaryCallback: (options: ISubmitSummaryOptions) => Promise<SubmitSummaryResult>,\n private readonly heuristicData: ISummarizeHeuristicData,\n private readonly raiseSummarizingError: (errorMessage: string) => void,\n private readonly summaryCollection: SummaryCollection,\n private readonly cancellationToken: ISummaryCancellationToken,\n private readonly stopSummarizerCallback: (reason: SummarizerStopReason) => void,\n ) {\n const telemetryProps: ISummarizeRunnerTelemetry = {\n summarizeCount: () => this.summarizeCount,\n summarizerSuccessfulAttempts: () => this.totalSuccessfulAttempts,\n };\n\n this.logger = ChildLogger.create(\n baseLogger, \"Running\",\n {\n all: telemetryProps,\n },\n );\n\n if (configuration.state !== \"disableHeuristics\") {\n assert(this.configuration.state === \"enabled\", 0x2ea /* \"Configuration state should be enabled\" */);\n this.heuristicRunner = new SummarizeHeuristicRunner(\n heuristicData,\n this.configuration,\n (reason) => this.trySummarize(reason),\n this.logger);\n }\n\n assert(\n this.configuration.state !== \"disabled\",\n 0x2eb /* \"Summary not supported with configuration disabled\" */,\n );\n\n // Cap the maximum amount of time client will wait for a summarize op ack to maxSummarizeAckWaitTime\n // configuration.maxAckWaitTime is composed from defaults, server values, and runtime overrides\n\n const maxAckWaitTime = Math.min(this.configuration.maxAckWaitTime, maxSummarizeAckWaitTime);\n\n this.pendingAckTimer = new PromiseTimer(\n maxAckWaitTime,\n () => {\n // pre-0.58 error message: summaryAckWaitTimeout\n this.raiseSummarizingError(\"Pending summary ack not received in time\");\n // Note: summarizeCount (from ChildLogger definition) may be 0,\n // since this code path is hit when RunningSummarizer first starts up,\n // before this instance has kicked off a new summarize run.\n this.logger.sendErrorEvent({\n eventName: \"SummaryAckWaitTimeout\",\n maxAckWaitTime,\n referenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,\n summarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,\n timePending: Date.now() - this.heuristicData.lastAttempt.summaryTime,\n });\n });\n // Set up pending ack timeout by op timestamp differences for previous summaries.\n summaryCollection.setPendingAckTimerTimeoutCallback(maxAckWaitTime, () => {\n if (this.pendingAckTimer.hasTimer) {\n this.logger.sendTelemetryEvent({\n eventName: \"MissingSummaryAckFoundByOps\",\n referenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,\n summarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,\n });\n this.pendingAckTimer.clear();\n }\n });\n\n this.generator = new SummaryGenerator(\n this.pendingAckTimer,\n this.heuristicData,\n this.submitSummaryCallback,\n this.raiseSummarizingError,\n () => { this.totalSuccessfulAttempts++; },\n this.summaryWatcher,\n this.logger,\n );\n }\n\n public dispose(): void {\n this.summaryWatcher.dispose();\n this.heuristicRunner?.dispose();\n this.heuristicRunner = undefined;\n this.generator.dispose();\n this.pendingAckTimer.clear();\n this.disposeEnqueuedSummary();\n this._disposed = true;\n this.stopping = true;\n }\n\n /**\n * RunningSummarizer's logger includes the sequenced index of the current summary on each event.\n * If some other Summarizer code wants that event on their logs they can get it here,\n * but only if they're logging about that same summary.\n * @param summaryOpRefSeq - RefSeq number of the summary op, to ensure the log correlation will be correct\n */\n public tryGetCorrelatedLogger = (summaryOpRefSeq) =>\n this.heuristicData.lastAttempt.refSequenceNumber === summaryOpRefSeq\n ? this.logger\n : undefined;\n\n public handleSystemOp(op: ISequencedDocumentMessage) {\n switch (op.type) {\n case MessageType.ClientLeave:\n case MessageType.ClientJoin:\n case MessageType.Propose: {\n // Synchronously handle quorum ops like regular ops\n this.handleOp(undefined, op);\n return;\n }\n default: {\n return;\n }\n }\n }\n\n public handleOp(error: any, { sequenceNumber, type, clientId, contents }: ISequencedDocumentMessage) {\n if (error !== undefined) {\n return;\n }\n this.heuristicData.lastOpSequenceNumber = sequenceNumber;\n\n // Check for enqueued on-demand summaries; Intentionally do nothing otherwise\n if (!this.tryRunEnqueuedSummary()) {\n this.heuristicRunner?.run();\n }\n }\n\n public async waitStop(allowLastSummary: boolean): Promise<void> {\n if (this.stopping) {\n return;\n }\n\n this.stopping = true;\n\n this.disposeEnqueuedSummary();\n\n // This will try to run lastSummary if needed.\n if (allowLastSummary && this.heuristicRunner?.shouldRunLastSummary()) {\n if (this.summarizingLock === undefined) {\n this.trySummarizeOnce(\n // summarizeProps\n { reason: \"lastSummary\" },\n // ISummarizeOptions, using defaults: { refreshLatestAck: false, fullTree: false }\n {});\n }\n }\n\n // Note that trySummarizeOnce() call above returns right away, without waiting.\n // So we need to wait for its completion, otherwise it would be destroyed right away.\n // That said, if summary lock was taken upfront, this wait might wait on multiple retries to\n // submit summary. We should reconsider this flow and make summarizer move to exit faster.\n // This resolves when the current pending summary gets an ack or fails.\n await this.summarizingLock;\n }\n\n private async waitStart() {\n // Wait no longer than ack timeout for all pending\n const waitStartResult = await raceTimer(\n this.summaryWatcher.waitFlushed(),\n this.pendingAckTimer.start(),\n );\n this.pendingAckTimer.clear();\n\n // Remove pending ack wait timeout by op timestamp comparison, because\n // it has race conditions with summaries submitted by this same client.\n this.summaryCollection.unsetPendingAckTimerTimeoutCallback();\n\n if (waitStartResult.result === \"done\" && waitStartResult.value !== undefined) {\n this.heuristicData.updateWithLastSummaryAckInfo({\n refSequenceNumber: waitStartResult.value.summaryOp.referenceSequenceNumber,\n // This will be the Summarizer starting point so only use timestamps from client's machine.\n summaryTime: Date.now(),\n summarySequenceNumber: waitStartResult.value.summaryOp.sequenceNumber,\n });\n }\n }\n\n /**\n * Runs single summary action that prevents any other concurrent actions.\n * Assumes that caller checked upfront for lack of concurrent action (this.summarizingLock)\n * before calling this API. I.e. caller is responsible for either erroring out or waiting on this promise.\n * @param action - action to perform.\n * @returns - result of action.\n */\n private async lockedSummaryAction<T>(action: () => Promise<T>) {\n assert(this.summarizingLock === undefined, 0x25b /* \"Caller is responsible for checking lock\" */);\n\n const summarizingLock = new Deferred<void>();\n this.summarizingLock = summarizingLock.promise;\n\n this.summarizeCount++;\n\n return action().finally(() => {\n summarizingLock.resolve();\n this.summarizingLock = undefined;\n\n const retry = this.tryWhileSummarizing;\n this.tryWhileSummarizing = false;\n\n // After summarizing, we should check to see if we need to summarize again.\n // Rerun the heuristics and check for enqueued summaries.\n if (!this.stopping && !this.tryRunEnqueuedSummary() && retry) {\n this.heuristicRunner?.run();\n }\n });\n }\n\n /**\n * Runs single summarize attempt\n * @param summarizeProps - props to log with each telemetry event associated with this attempt\n * @param options - summary options\n * @param cancellationToken - cancellation token to use to be able to cancel this summary, if needed\n * @param resultsBuilder - optional, result builder to use.\n * @returns ISummarizeResult - result of running a summary.\n */\n private trySummarizeOnce(\n summarizeProps: ISummarizeTelemetryProperties,\n options: ISummarizeOptions,\n cancellationToken = this.cancellationToken,\n resultsBuilder = new SummarizeResultBuilder()): ISummarizeResults {\n this.lockedSummaryAction(async () => {\n const summarizeResult = this.generator.summarize(\n summarizeProps,\n options,\n cancellationToken,\n resultsBuilder);\n // ensure we wait till the end of the process\n return summarizeResult.receivedSummaryAckOrNack;\n }).catch((error) => {\n // SummaryGenerator.summarize() does not throw exceptions - it converts them to failed result\n // on resultsBuilder\n // We do not care about exceptions on receivedSummaryAckOrNack - caller should check results\n // and take a appropriate action.\n });\n\n return resultsBuilder.build();\n }\n\n /** Heuristics summarize attempt. */\n private trySummarize(\n reason: SummarizeReason,\n cancellationToken = this.cancellationToken): void {\n if (this.summarizingLock !== undefined) {\n // lockedSummaryAction() will retry heuristic-based summary at the end of current attempt\n // if it's still needed\n this.tryWhileSummarizing = true;\n return;\n }\n\n this.lockedSummaryAction(async () => {\n const attempts: (ISummarizeOptions & { delaySeconds?: number; })[] = [\n { refreshLatestAck: false, fullTree: false },\n { refreshLatestAck: true, fullTree: false },\n { refreshLatestAck: true, fullTree: false, delaySeconds: 2 * 60 },\n { refreshLatestAck: true, fullTree: true, delaySeconds: 10 * 60 },\n ];\n let overrideDelaySeconds: number | undefined;\n let summaryAttempts = 0;\n let summaryAttemptsPerPhase = 0;\n\n let lastResult: { message: string; error: any; } | undefined;\n\n for (let summaryAttemptPhase = 0; summaryAttemptPhase < attempts.length;) {\n if (this.cancellationToken.cancelled) {\n return;\n }\n\n // We only want to attempt 1 summary when reason is \"lastSummary\"\n if (++summaryAttempts > 1 && reason === \"lastSummary\") {\n return;\n }\n\n summaryAttemptsPerPhase++;\n\n const { delaySeconds: regularDelaySeconds = 0, ...options } = attempts[summaryAttemptPhase];\n const delaySeconds = overrideDelaySeconds ?? regularDelaySeconds;\n\n const summarizeProps: ISummarizeTelemetryProperties = {\n reason,\n summaryAttempts,\n summaryAttemptsPerPhase,\n summaryAttemptPhase: summaryAttemptPhase + 1, // make everything 1-based\n ...options,\n };\n\n if (delaySeconds > 0) {\n this.logger.sendPerformanceEvent({\n eventName: \"SummarizeAttemptDelay\",\n duration: delaySeconds,\n summaryNackDelay: overrideDelaySeconds !== undefined,\n ...summarizeProps,\n });\n await delay(delaySeconds * 1000);\n }\n // Note: no need to account for cancellationToken.waitCancelled here, as\n // this is accounted SummaryGenerator.summarizeCore that controls receivedSummaryAckOrNack.\n const resultSummarize = this.generator.summarize(summarizeProps, options, cancellationToken);\n const result = await resultSummarize.receivedSummaryAckOrNack;\n\n if (result.success) {\n return;\n }\n // Check for retryDelay that can come from summaryNack or upload summary flow.\n // Retry the same step only once per retryAfter response.\n overrideDelaySeconds = result.retryAfterSeconds;\n if (overrideDelaySeconds === undefined || summaryAttemptsPerPhase > 1) {\n summaryAttemptPhase++;\n summaryAttemptsPerPhase = 0;\n }\n lastResult = result;\n }\n\n // If all attempts failed, log error (with last attempt info) and close the summarizer container\n this.logger.sendErrorEvent({\n eventName: \"FailToSummarize\",\n reason,\n message: lastResult?.message,\n }, lastResult?.error);\n\n this.stopSummarizerCallback(\"failToSummarize\");\n }).catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"UnexpectedSummarizeError\" }, error);\n });\n }\n\n /** {@inheritdoc (ISummarizer:interface).summarizeOnDemand} */\n public summarizeOnDemand(\n resultsBuilder: SummarizeResultBuilder = new SummarizeResultBuilder(),\n {\n reason,\n ...options\n }: IOnDemandSummarizeOptions): ISummarizeResults {\n if (this.stopping) {\n resultsBuilder.fail(\"RunningSummarizer stopped or disposed\", undefined);\n return resultsBuilder.build();\n }\n // Check for concurrent summary attempts. If one is found,\n // return a promise that caller can await before trying again.\n if (this.summarizingLock !== undefined) {\n // The heuristics are blocking concurrent summarize attempts.\n throw new UsageError(\"Attempted to run an already-running summarizer on demand\");\n }\n const result = this.trySummarizeOnce(\n { reason: `onDemand/${reason}` },\n options,\n this.cancellationToken,\n resultsBuilder);\n return result;\n }\n\n /** {@inheritdoc (ISummarizer:interface).enqueueSummarize} */\n public enqueueSummarize({\n reason,\n afterSequenceNumber = 0,\n override = false,\n ...options\n }: IEnqueueSummarizeOptions): EnqueueSummarizeResult {\n const onDemandReason = `enqueue;${reason}` as const;\n let overridden = false;\n if (this.enqueuedSummary !== undefined) {\n if (!override) {\n return { alreadyEnqueued: true };\n }\n // Override existing enqueued summarize attempt.\n this.enqueuedSummary.resultsBuilder.fail(\n \"Aborted; overridden by another enqueue summarize attempt\",\n undefined,\n );\n this.enqueuedSummary = undefined;\n overridden = true;\n }\n this.enqueuedSummary = {\n reason: onDemandReason,\n afterSequenceNumber,\n options,\n resultsBuilder: new SummarizeResultBuilder(),\n };\n const results = this.enqueuedSummary.resultsBuilder.build();\n this.tryRunEnqueuedSummary();\n return overridden ? {\n ...results,\n alreadyEnqueued: true,\n overridden: true,\n } : results;\n }\n\n private tryRunEnqueuedSummary() {\n if (this.stopping) {\n this.disposeEnqueuedSummary();\n return false;\n }\n if (\n this.enqueuedSummary === undefined\n || this.heuristicData.lastOpSequenceNumber < this.enqueuedSummary.afterSequenceNumber\n || this.summarizingLock !== undefined\n ) {\n // If no enqueued summary is ready or a summary is already in progress, take no action.\n return false;\n }\n const { reason, resultsBuilder, options } = this.enqueuedSummary;\n // Set to undefined first, so that subsequent enqueue attempt while summarize will occur later.\n this.enqueuedSummary = undefined;\n this.trySummarizeOnce(\n { reason: `enqueuedSummary/${reason}` },\n options,\n this.cancellationToken,\n resultsBuilder);\n return true;\n }\n\n private disposeEnqueuedSummary() {\n if (this.enqueuedSummary !== undefined) {\n this.enqueuedSummary.resultsBuilder.fail(\"RunningSummarizer stopped or disposed\", undefined);\n this.enqueuedSummary = undefined;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"runningSummarizer.js","sourceRoot":"","sources":["../src/runningSummarizer.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, delay, Deferred, PromiseTimer } from \"@fluidframework/common-utils\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport { isRuntimeMessage } from \"@fluidframework/driver-utils\";\nimport {\n ISequencedDocumentMessage,\n MessageType,\n} from \"@fluidframework/protocol-definitions\";\nimport { ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport {\n ISummaryConfiguration,\n} from \"./containerRuntime\";\nimport { opSize } from \"./opProperties\";\nimport { SummarizeHeuristicRunner } from \"./summarizerHeuristics\";\nimport {\n IEnqueueSummarizeOptions,\n ISummarizeOptions,\n ISummarizeHeuristicData,\n ISummarizeHeuristicRunner,\n IOnDemandSummarizeOptions,\n EnqueueSummarizeResult,\n SummarizerStopReason,\n ISubmitSummaryOptions,\n SubmitSummaryResult,\n ISummaryCancellationToken,\n ISummarizeResults,\n ISummarizeTelemetryProperties,\n ISummarizerRuntime,\n ISummarizeRunnerTelemetry,\n} from \"./summarizerTypes\";\nimport { IClientSummaryWatcher, SummaryCollection } from \"./summaryCollection\";\nimport {\n raceTimer,\n SummarizeReason,\n SummarizeResultBuilder,\n SummaryGenerator,\n} from \"./summaryGenerator\";\n\nconst maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes\n\n/**\n * An instance of RunningSummarizer manages the heuristics for summarizing.\n * Until disposed, the instance of RunningSummarizer can assume that it is\n * in a state of running, meaning it is connected and initialized. It keeps\n * track of summaries that it is generating as they are broadcast and acked/nacked.\n * This object is created and controlled by Summarizer object.\n */\nexport class RunningSummarizer implements IDisposable {\n public static async start(\n logger: ITelemetryLogger,\n summaryWatcher: IClientSummaryWatcher,\n configuration: ISummaryConfiguration,\n submitSummaryCallback: (options: ISubmitSummaryOptions) => Promise<SubmitSummaryResult>,\n heuristicData: ISummarizeHeuristicData,\n raiseSummarizingError: (errorMessage: string) => void,\n summaryCollection: SummaryCollection,\n cancellationToken: ISummaryCancellationToken,\n stopSummarizerCallback: (reason: SummarizerStopReason) => void,\n runtime: ISummarizerRuntime,\n ): Promise<RunningSummarizer> {\n const summarizer = new RunningSummarizer(\n logger,\n summaryWatcher,\n configuration,\n submitSummaryCallback,\n heuristicData,\n raiseSummarizingError,\n summaryCollection,\n cancellationToken,\n stopSummarizerCallback,\n runtime);\n\n await summarizer.waitStart();\n\n // Update heuristic counts\n // By the time we get here, there are potentially ops missing from the heuristic summary counts\n // Examples of where this could happen:\n // 1. Op is processed during the time that we are initiating the RunningSummarizer instance but before we\n // listen for the op events (will get missed by the handlers in the current workflow)\n // 2. Op was sequenced after the last time we summarized (op sequence number > summarize ref sequence number)\n const diff = runtime.deltaManager.lastSequenceNumber - (\n heuristicData.lastSuccessfulSummary.refSequenceNumber\n + heuristicData.numNonRuntimeOps\n + heuristicData.numRuntimeOps);\n heuristicData.hasMissingOpData = diff > 0;\n\n if (heuristicData.hasMissingOpData) {\n // Split the diff 50-50 and increment the counts appropriately\n heuristicData.numNonRuntimeOps += Math.ceil(diff / 2);\n heuristicData.numRuntimeOps += Math.floor(diff / 2);\n }\n\n // Update last seq number (in case the handlers haven't processed anything yet)\n heuristicData.lastOpSequenceNumber = runtime.deltaManager.lastSequenceNumber;\n\n // Start heuristics\n summarizer.heuristicRunner?.start();\n summarizer.heuristicRunner?.run();\n\n return summarizer;\n }\n\n public get disposed() { return this._disposed; }\n\n private stopping = false;\n private _disposed = false;\n private summarizingLock: Promise<void> | undefined;\n private tryWhileSummarizing = false;\n private readonly pendingAckTimer: PromiseTimer;\n private heuristicRunner?: ISummarizeHeuristicRunner;\n private readonly generator: SummaryGenerator;\n private readonly logger: ITelemetryLogger;\n private enqueuedSummary: {\n reason: SummarizeReason;\n afterSequenceNumber: number;\n options: ISummarizeOptions;\n readonly resultsBuilder: SummarizeResultBuilder;\n } | undefined;\n private summarizeCount = 0;\n private totalSuccessfulAttempts = 0;\n private initialized = false;\n\n private constructor(\n baseLogger: ITelemetryLogger,\n private readonly summaryWatcher: IClientSummaryWatcher,\n private readonly configuration: ISummaryConfiguration,\n private readonly submitSummaryCallback: (options: ISubmitSummaryOptions) => Promise<SubmitSummaryResult>,\n private readonly heuristicData: ISummarizeHeuristicData,\n private readonly raiseSummarizingError: (errorMessage: string) => void,\n private readonly summaryCollection: SummaryCollection,\n private readonly cancellationToken: ISummaryCancellationToken,\n private readonly stopSummarizerCallback: (reason: SummarizerStopReason) => void,\n private readonly runtime: ISummarizerRuntime,\n ) {\n const telemetryProps: ISummarizeRunnerTelemetry = {\n summarizeCount: () => this.summarizeCount,\n summarizerSuccessfulAttempts: () => this.totalSuccessfulAttempts,\n };\n\n this.logger = ChildLogger.create(\n baseLogger, \"Running\",\n {\n all: telemetryProps,\n },\n );\n\n if (configuration.state !== \"disableHeuristics\") {\n assert(this.configuration.state === \"enabled\", 0x2ea /* \"Configuration state should be enabled\" */);\n this.heuristicRunner = new SummarizeHeuristicRunner(\n heuristicData,\n this.configuration,\n (reason) => this.trySummarize(reason),\n this.logger);\n }\n\n assert(\n this.configuration.state !== \"disabled\",\n 0x2eb /* \"Summary not supported with configuration disabled\" */,\n );\n\n // Cap the maximum amount of time client will wait for a summarize op ack to maxSummarizeAckWaitTime\n // configuration.maxAckWaitTime is composed from defaults, server values, and runtime overrides\n\n const maxAckWaitTime = Math.min(this.configuration.maxAckWaitTime, maxSummarizeAckWaitTime);\n\n this.pendingAckTimer = new PromiseTimer(\n maxAckWaitTime,\n () => {\n // pre-0.58 error message: summaryAckWaitTimeout\n this.raiseSummarizingError(\"Pending summary ack not received in time\");\n // Note: summarizeCount (from ChildLogger definition) may be 0,\n // since this code path is hit when RunningSummarizer first starts up,\n // before this instance has kicked off a new summarize run.\n this.logger.sendErrorEvent({\n eventName: \"SummaryAckWaitTimeout\",\n maxAckWaitTime,\n referenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,\n summarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,\n timePending: Date.now() - this.heuristicData.lastAttempt.summaryTime,\n });\n });\n // Set up pending ack timeout by op timestamp differences for previous summaries.\n summaryCollection.setPendingAckTimerTimeoutCallback(maxAckWaitTime, () => {\n if (this.pendingAckTimer.hasTimer) {\n this.logger.sendTelemetryEvent({\n eventName: \"MissingSummaryAckFoundByOps\",\n referenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,\n summarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,\n });\n this.pendingAckTimer.clear();\n }\n });\n\n this.generator = new SummaryGenerator(\n this.pendingAckTimer,\n this.heuristicData,\n this.submitSummaryCallback,\n this.raiseSummarizingError,\n () => { this.totalSuccessfulAttempts++; },\n this.summaryWatcher,\n this.logger,\n );\n\n // Listen for ops\n this.runtime.deltaManager.on(\"op\", (op) => { this.handleOp(op); });\n }\n\n public dispose(): void {\n this.runtime.deltaManager.off(\"op\", (op) => { this.handleOp(op); });\n this.summaryWatcher.dispose();\n this.heuristicRunner?.dispose();\n this.heuristicRunner = undefined;\n this.generator.dispose();\n this.pendingAckTimer.clear();\n this.disposeEnqueuedSummary();\n this._disposed = true;\n this.stopping = true;\n }\n\n /**\n * RunningSummarizer's logger includes the sequenced index of the current summary on each event.\n * If some other Summarizer code wants that event on their logs they can get it here,\n * but only if they're logging about that same summary.\n * @param summaryOpRefSeq - RefSeq number of the summary op, to ensure the log correlation will be correct\n */\n public tryGetCorrelatedLogger = (summaryOpRefSeq) =>\n this.heuristicData.lastAttempt.refSequenceNumber === summaryOpRefSeq\n ? this.logger\n : undefined;\n\n /** We only want a single heuristic runner micro-task (will provide better optimized grouping of ops) */\n private heuristicRunnerMicroTaskExists = false;\n\n public handleOp(op: ISequencedDocumentMessage) {\n this.heuristicData.lastOpSequenceNumber = op.sequenceNumber;\n\n if (op.type !== MessageType.Summarize && isRuntimeMessage(op)) {\n this.heuristicData.numRuntimeOps++;\n } else {\n this.heuristicData.numNonRuntimeOps++;\n }\n\n this.heuristicData.totalOpsSize += opSize(op);\n\n // Check for enqueued on-demand summaries; Intentionally do nothing otherwise\n if (this.initialized\n && this.opCanTriggerSummary(op)\n && !this.tryRunEnqueuedSummary()\n && !this.heuristicRunnerMicroTaskExists) {\n this.heuristicRunnerMicroTaskExists = true;\n Promise.resolve().then(() => {\n this.heuristicRunner?.run();\n }).finally(() => {\n this.heuristicRunnerMicroTaskExists = false;\n });\n }\n }\n\n /**\n * Can the given op trigger a summary?\n * # Currently only prevents summaries for Summarize and SummaryAck ops\n * @param op - op to check\n * @returns true if this type of op can trigger a summary\n */\n private opCanTriggerSummary(op: ISequencedDocumentMessage): boolean {\n switch (op.type) {\n case MessageType.Summarize:\n case MessageType.SummaryAck:\n case MessageType.SummaryNack:\n return false;\n default:\n return true;\n }\n }\n\n public async waitStop(allowLastSummary: boolean): Promise<void> {\n if (this.stopping) {\n return;\n }\n\n this.stopping = true;\n\n this.disposeEnqueuedSummary();\n\n // This will try to run lastSummary if needed.\n if (allowLastSummary && this.heuristicRunner?.shouldRunLastSummary()) {\n if (this.summarizingLock === undefined) {\n this.trySummarizeOnce(\n // summarizeProps\n { reason: \"lastSummary\" },\n // ISummarizeOptions, using defaults: { refreshLatestAck: false, fullTree: false }\n {});\n }\n }\n\n // Note that trySummarizeOnce() call above returns right away, without waiting.\n // So we need to wait for its completion, otherwise it would be destroyed right away.\n // That said, if summary lock was taken upfront, this wait might wait on multiple retries to\n // submit summary. We should reconsider this flow and make summarizer move to exit faster.\n // This resolves when the current pending summary gets an ack or fails.\n await this.summarizingLock;\n }\n\n private async waitStart() {\n // Wait no longer than ack timeout for all pending\n const waitStartResult = await raceTimer(\n this.summaryWatcher.waitFlushed(),\n this.pendingAckTimer.start(),\n );\n this.pendingAckTimer.clear();\n\n // Remove pending ack wait timeout by op timestamp comparison, because\n // it has race conditions with summaries submitted by this same client.\n this.summaryCollection.unsetPendingAckTimerTimeoutCallback();\n\n if (waitStartResult.result === \"done\" && waitStartResult.value !== undefined) {\n this.heuristicData.updateWithLastSummaryAckInfo({\n refSequenceNumber: waitStartResult.value.summaryOp.referenceSequenceNumber,\n // This will be the Summarizer starting point so only use timestamps from client's machine.\n summaryTime: Date.now(),\n summarySequenceNumber: waitStartResult.value.summaryOp.sequenceNumber,\n });\n }\n this.initialized = true;\n }\n\n /**\n * Runs single summary action that prevents any other concurrent actions.\n * Assumes that caller checked upfront for lack of concurrent action (this.summarizingLock)\n * before calling this API. I.e. caller is responsible for either erroring out or waiting on this promise.\n * @param action - action to perform.\n * @returns - result of action.\n */\n private async lockedSummaryAction<T>(action: () => Promise<T>) {\n assert(this.summarizingLock === undefined, 0x25b /* \"Caller is responsible for checking lock\" */);\n\n const summarizingLock = new Deferred<void>();\n this.summarizingLock = summarizingLock.promise;\n\n this.summarizeCount++;\n\n return action().finally(() => {\n summarizingLock.resolve();\n this.summarizingLock = undefined;\n\n const retry = this.tryWhileSummarizing;\n this.tryWhileSummarizing = false;\n\n // After summarizing, we should check to see if we need to summarize again.\n // Rerun the heuristics and check for enqueued summaries.\n if (!this.stopping && !this.tryRunEnqueuedSummary() && retry) {\n this.heuristicRunner?.run();\n }\n });\n }\n\n /**\n * Runs single summarize attempt\n * @param summarizeProps - props to log with each telemetry event associated with this attempt\n * @param options - summary options\n * @param cancellationToken - cancellation token to use to be able to cancel this summary, if needed\n * @param resultsBuilder - optional, result builder to use.\n * @returns ISummarizeResult - result of running a summary.\n */\n private trySummarizeOnce(\n summarizeProps: ISummarizeTelemetryProperties,\n options: ISummarizeOptions,\n cancellationToken = this.cancellationToken,\n resultsBuilder = new SummarizeResultBuilder()): ISummarizeResults {\n this.lockedSummaryAction(async () => {\n const summarizeResult = this.generator.summarize(\n summarizeProps,\n options,\n cancellationToken,\n resultsBuilder);\n // ensure we wait till the end of the process\n return summarizeResult.receivedSummaryAckOrNack;\n }).catch((error) => {\n // SummaryGenerator.summarize() does not throw exceptions - it converts them to failed result\n // on resultsBuilder\n // We do not care about exceptions on receivedSummaryAckOrNack - caller should check results\n // and take a appropriate action.\n });\n\n return resultsBuilder.build();\n }\n\n /** Heuristics summarize attempt. */\n private trySummarize(\n reason: SummarizeReason,\n cancellationToken = this.cancellationToken): void {\n if (this.summarizingLock !== undefined) {\n // lockedSummaryAction() will retry heuristic-based summary at the end of current attempt\n // if it's still needed\n this.tryWhileSummarizing = true;\n return;\n }\n\n this.lockedSummaryAction(async () => {\n const attempts: (ISummarizeOptions & { delaySeconds?: number; })[] = [\n { refreshLatestAck: false, fullTree: false },\n { refreshLatestAck: true, fullTree: false },\n { refreshLatestAck: true, fullTree: false, delaySeconds: 2 * 60 },\n { refreshLatestAck: true, fullTree: true, delaySeconds: 10 * 60 },\n ];\n let overrideDelaySeconds: number | undefined;\n let summaryAttempts = 0;\n let summaryAttemptsPerPhase = 0;\n\n let lastResult: { message: string; error: any; } | undefined;\n\n for (let summaryAttemptPhase = 0; summaryAttemptPhase < attempts.length;) {\n if (this.cancellationToken.cancelled) {\n return;\n }\n\n // We only want to attempt 1 summary when reason is \"lastSummary\"\n if (++summaryAttempts > 1 && reason === \"lastSummary\") {\n return;\n }\n\n summaryAttemptsPerPhase++;\n\n const { delaySeconds: regularDelaySeconds = 0, ...options } = attempts[summaryAttemptPhase];\n const delaySeconds = overrideDelaySeconds ?? regularDelaySeconds;\n\n const summarizeProps: ISummarizeTelemetryProperties = {\n reason,\n summaryAttempts,\n summaryAttemptsPerPhase,\n summaryAttemptPhase: summaryAttemptPhase + 1, // make everything 1-based\n ...options,\n };\n\n if (delaySeconds > 0) {\n this.logger.sendPerformanceEvent({\n eventName: \"SummarizeAttemptDelay\",\n duration: delaySeconds,\n summaryNackDelay: overrideDelaySeconds !== undefined,\n ...summarizeProps,\n });\n await delay(delaySeconds * 1000);\n }\n // Note: no need to account for cancellationToken.waitCancelled here, as\n // this is accounted SummaryGenerator.summarizeCore that controls receivedSummaryAckOrNack.\n const resultSummarize = this.generator.summarize(summarizeProps, options, cancellationToken);\n const result = await resultSummarize.receivedSummaryAckOrNack;\n\n if (result.success) {\n return;\n }\n // Check for retryDelay that can come from summaryNack or upload summary flow.\n // Retry the same step only once per retryAfter response.\n overrideDelaySeconds = result.retryAfterSeconds;\n if (overrideDelaySeconds === undefined || summaryAttemptsPerPhase > 1) {\n summaryAttemptPhase++;\n summaryAttemptsPerPhase = 0;\n }\n lastResult = result;\n }\n\n // If all attempts failed, log error (with last attempt info) and close the summarizer container\n this.logger.sendErrorEvent({\n eventName: \"FailToSummarize\",\n reason,\n message: lastResult?.message,\n }, lastResult?.error);\n\n this.stopSummarizerCallback(\"failToSummarize\");\n }).catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"UnexpectedSummarizeError\" }, error);\n });\n }\n\n /** {@inheritdoc (ISummarizer:interface).summarizeOnDemand} */\n public summarizeOnDemand(\n resultsBuilder: SummarizeResultBuilder = new SummarizeResultBuilder(),\n {\n reason,\n ...options\n }: IOnDemandSummarizeOptions): ISummarizeResults {\n if (this.stopping) {\n resultsBuilder.fail(\"RunningSummarizer stopped or disposed\", undefined);\n return resultsBuilder.build();\n }\n // Check for concurrent summary attempts. If one is found,\n // return a promise that caller can await before trying again.\n if (this.summarizingLock !== undefined) {\n // The heuristics are blocking concurrent summarize attempts.\n throw new UsageError(\"Attempted to run an already-running summarizer on demand\");\n }\n const result = this.trySummarizeOnce(\n { reason: `onDemand/${reason}` },\n options,\n this.cancellationToken,\n resultsBuilder);\n return result;\n }\n\n /** {@inheritdoc (ISummarizer:interface).enqueueSummarize} */\n public enqueueSummarize({\n reason,\n afterSequenceNumber = 0,\n override = false,\n ...options\n }: IEnqueueSummarizeOptions): EnqueueSummarizeResult {\n const onDemandReason = `enqueue;${reason}` as const;\n let overridden = false;\n if (this.enqueuedSummary !== undefined) {\n if (!override) {\n return { alreadyEnqueued: true };\n }\n // Override existing enqueued summarize attempt.\n this.enqueuedSummary.resultsBuilder.fail(\n \"Aborted; overridden by another enqueue summarize attempt\",\n undefined,\n );\n this.enqueuedSummary = undefined;\n overridden = true;\n }\n this.enqueuedSummary = {\n reason: onDemandReason,\n afterSequenceNumber,\n options,\n resultsBuilder: new SummarizeResultBuilder(),\n };\n const results = this.enqueuedSummary.resultsBuilder.build();\n this.tryRunEnqueuedSummary();\n return overridden ? {\n ...results,\n alreadyEnqueued: true,\n overridden: true,\n } : results;\n }\n\n private tryRunEnqueuedSummary() {\n if (this.stopping) {\n this.disposeEnqueuedSummary();\n return false;\n }\n if (\n this.enqueuedSummary === undefined\n || this.heuristicData.lastOpSequenceNumber < this.enqueuedSummary.afterSequenceNumber\n || this.summarizingLock !== undefined\n ) {\n // If no enqueued summary is ready or a summary is already in progress, take no action.\n return false;\n }\n const { reason, resultsBuilder, options } = this.enqueuedSummary;\n // Set to undefined first, so that subsequent enqueue attempt while summarize will occur later.\n this.enqueuedSummary = undefined;\n this.trySummarizeOnce(\n { reason: `enqueuedSummary/${reason}` },\n options,\n this.cancellationToken,\n resultsBuilder);\n return true;\n }\n\n private disposeEnqueuedSummary() {\n if (this.enqueuedSummary !== undefined) {\n this.enqueuedSummary.resultsBuilder.fail(\"RunningSummarizer stopped or disposed\", undefined);\n this.enqueuedSummary = undefined;\n }\n }\n}\n"]}
@@ -42,8 +42,6 @@ export declare class Summarizer extends EventEmitter implements ISummarizer {
42
42
  get ISummarizer(): this;
43
43
  private readonly logger;
44
44
  private runningSummarizer?;
45
- private systemOpListener?;
46
- private opListener?;
47
45
  private _disposed;
48
46
  private starting;
49
47
  private readonly innerHandle;
@@ -1 +1 @@
1
- {"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../src/summarizer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../src/summarizer.ts"],"names":[],"mappings":"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"}
package/lib/summarizer.js CHANGED
@@ -253,7 +253,7 @@ export class Summarizer extends EventEmitter {
253
253
  if (!this._disposed) {
254
254
  this.logger.sendErrorEvent({ eventName: "summarizingError" }, createSummarizingWarning(errorMessage, true));
255
255
  }
256
- }, this.summaryCollection, runCoordinator /* cancellationToken */, (reason) => runCoordinator.stop(reason));
256
+ }, this.summaryCollection, runCoordinator /* cancellationToken */, (reason) => runCoordinator.stop(reason), /* stopSummarizerCallback */ this.runtime);
257
257
  this.runningSummarizer = runningSummarizer;
258
258
  this.starting = false;
259
259
  // Handle summary acks
@@ -261,11 +261,6 @@ export class Summarizer extends EventEmitter {
261
261
  this.handleSummaryAcks().catch((error) => {
262
262
  this.logger.sendErrorEvent({ eventName: "HandleSummaryAckFatalError" }, error);
263
263
  });
264
- // Listen for ops
265
- this.systemOpListener = (op) => runningSummarizer.handleSystemOp(op);
266
- this.runtime.deltaManager.inbound.on("op", this.systemOpListener);
267
- this.opListener = (error, op) => runningSummarizer.handleOp(error, op);
268
- this.runtime.on("batchEnd", this.opListener);
269
264
  return runningSummarizer;
270
265
  }
271
266
  /**
@@ -282,12 +277,6 @@ export class Summarizer extends EventEmitter {
282
277
  this.runningSummarizer.dispose();
283
278
  this.runningSummarizer = undefined;
284
279
  }
285
- if (this.systemOpListener) {
286
- this.runtime.deltaManager.inbound.off("op", this.systemOpListener);
287
- }
288
- if (this.opListener) {
289
- this.runtime.removeListener("batchEnd", this.opListener);
290
- }
291
280
  }
292
281
  async handleSummaryAcks() {
293
282
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../src/summarizer.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { EventEmitter } from \"events\";\nimport { Deferred } from \"@fluidframework/common-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ILoader, LoaderHeader } from \"@fluidframework/container-definitions\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport { DriverHeader } from \"@fluidframework/driver-definitions\";\nimport { requestFluidObject } from \"@fluidframework/runtime-utils\";\nimport { ChildLogger, IFluidErrorBase, LoggingError, wrapErrorAndLog } from \"@fluidframework/telemetry-utils\";\nimport {\n FluidObject,\n IFluidHandleContext,\n IFluidHandle,\n IRequest,\n} from \"@fluidframework/core-interfaces\";\nimport {\n ISequencedDocumentMessage,\n} from \"@fluidframework/protocol-definitions\";\nimport { ISummaryConfiguration } from \"./containerRuntime\";\nimport { ICancellableSummarizerController } from \"./runWhileConnectedCoordinator\";\nimport { summarizerClientType } from \"./summarizerClientElection\";\nimport { SummaryCollection } from \"./summaryCollection\";\nimport { SummarizerHandle } from \"./summarizerHandle\";\nimport { RunningSummarizer } from \"./runningSummarizer\";\nimport {\n ISummarizer,\n ISummarizerInternalsProvider,\n ISummarizerRuntime,\n ISummarizingWarning,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nimport { SummarizeHeuristicData } from \"./summarizerHeuristics\";\nimport { SummarizeResultBuilder } from \"./summaryGenerator\";\nimport { IConnectableRuntime } from \".\";\n\nconst summarizingError = \"summarizingError\";\n\nexport class SummarizingWarning extends LoggingError implements ISummarizingWarning, IFluidErrorBase {\n readonly errorType = summarizingError;\n readonly canRetry = true;\n\n constructor(\n errorMessage: string,\n readonly logged: boolean = false,\n ) {\n super(errorMessage);\n }\n\n static wrap(error: any, logged: boolean = false, logger: ITelemetryLogger) {\n const newErrorFn = (errMsg: string) => new SummarizingWarning(errMsg, logged);\n return wrapErrorAndLog<SummarizingWarning>(error, newErrorFn, logger);\n }\n}\n\nexport const createSummarizingWarning =\n (errorMessage: string, logged: boolean) => new SummarizingWarning(errorMessage, logged);\n\n/**\n * Summarizer is responsible for coordinating when to generate and send summaries.\n * It is the main entry point for summary work.\n * It is created only by summarizing container (i.e. one with clientType === \"summarizer\")\n */\nexport class Summarizer extends EventEmitter implements ISummarizer {\n public get IFluidLoadable() { return this; }\n public get ISummarizer() { return this; }\n\n private readonly logger: ITelemetryLogger;\n private runningSummarizer?: RunningSummarizer;\n private systemOpListener?: (op: ISequencedDocumentMessage) => void;\n private opListener?: (error: any, op: ISequencedDocumentMessage) => void;\n private _disposed: boolean = false;\n private starting: boolean = false;\n\n private readonly innerHandle: IFluidHandle<this>;\n\n public get handle(): IFluidHandle<this> { return this.innerHandle; }\n private readonly stopDeferred = new Deferred<SummarizerStopReason>();\n\n constructor(\n url: string,\n /** Reference to runtime that created this object.\n * i.e. runtime with clientType === \"summarizer\"\n */\n private readonly runtime: ISummarizerRuntime,\n private readonly configurationGetter: () => ISummaryConfiguration,\n /** Represents an object that can generate summary.\n * In practical terms, it's same runtime (this.runtime) with clientType === \"summarizer\".\n */\n private readonly internalsProvider: ISummarizerInternalsProvider,\n handleContext: IFluidHandleContext,\n public readonly summaryCollection: SummaryCollection,\n private readonly runCoordinatorCreateFn:\n (runtime: IConnectableRuntime) => Promise<ICancellableSummarizerController>,\n ) {\n super();\n this.logger = ChildLogger.create(this.runtime.logger, \"Summarizer\");\n this.innerHandle = new SummarizerHandle(this, url, handleContext);\n }\n\n /**\n * Creates a Summarizer and its underlying client.\n * Note that different implementations of ILoader will handle the URL differently.\n * ILoader provided by a ContainerRuntime is a RelativeLoader, which will treat URL's\n * starting with \"/\" as relative to the Container. The general ILoader\n * interface will expect an absolute URL and will not handle \"/\".\n * @param loader - the loader that resolves the request\n * @param url - the URL used to resolve the container\n */\n public static async create(\n loader: ILoader,\n url: string): Promise<ISummarizer> {\n const request: IRequest = {\n headers: {\n [LoaderHeader.cache]: false,\n [LoaderHeader.clientDetails]: {\n capabilities: { interactive: false },\n type: summarizerClientType,\n },\n [DriverHeader.summarizingClient]: true,\n [LoaderHeader.reconnect]: false,\n },\n url,\n };\n\n const resolvedContainer = await loader.resolve(request);\n const fluidObject =\n await requestFluidObject<FluidObject<ISummarizer>>(resolvedContainer, { url: \"_summarizer\" });\n if (fluidObject.ISummarizer === undefined) {\n throw new UsageError(\"Fluid object does not implement ISummarizer\");\n }\n return fluidObject.ISummarizer;\n }\n\n public async run(onBehalfOf: string): Promise<SummarizerStopReason> {\n try {\n return await this.runCore(onBehalfOf);\n } catch (error) {\n this.stop(\"summarizerException\");\n throw SummarizingWarning.wrap(error, false /* logged */, this.logger);\n } finally {\n this.close();\n }\n }\n\n /**\n * Stops the summarizer from running. This will complete\n * the run promise, and also close the container.\n * @param reason - reason code for stopping\n */\n public stop(reason: SummarizerStopReason) {\n this.stopDeferred.resolve(reason);\n }\n\n public close() {\n // This will result in \"summarizerClientDisconnected\" stop reason recorded in telemetry,\n // unless stop() was called earlier\n this.dispose();\n this.runtime.closeFn();\n }\n\n private async runCore(onBehalfOf: string): Promise<SummarizerStopReason> {\n const runCoordinator: ICancellableSummarizerController = await this.runCoordinatorCreateFn(this.runtime);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopP = Promise.race([runCoordinator.waitCancelled, this.stopDeferred.promise]);\n void stopP.then((reason) => {\n this.logger.sendTelemetryEvent({\n eventName: \"StoppingSummarizer\",\n onBehalfOf,\n reason,\n });\n });\n\n if (runCoordinator.cancelled) {\n return runCoordinator.waitCancelled;\n }\n\n const runningSummarizer = await this.start(onBehalfOf, runCoordinator);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopReason = await stopP;\n\n // There are two possible approaches here:\n // 1. Propagate cancellation from this.stopDeferred to runCoordinator. This will ensure that we move to the exit\n // faster, including breaking out of the RunningSummarizer.trySummarize() faster.\n // We could create new coordinator and pass it to waitStop() -> trySummarizeOnce(\"lastSummary\") flow.\n // The con of this approach is that we might cancel active summary, and lastSummary will fail because it\n // did not wait for ack/nack from previous summary. Plus we disregard any 429 kind of info from service\n // that way (i.e. trySummarize() loop might have been waiting for 5 min because storage told us so).\n // In general, it's more wasted resources.\n // 2. We can not do it and make waitStop() do last summary only if there was no active summary. This ensures\n // that client behaves properly (from server POV) and we do not waste resources. But, it may mean we wait\n // substantially longer for trySummarize() retries to play out and thus this summary loop may run into\n // conflict with new summarizer client starting on different client.\n // As of now, #2 is implemented. It's more forward looking, as issue #7279 suggests changing design for new\n // summarizer client to not be created until current summarizer fully moves to exit, and that would reduce\n // cons of #2 substantially.\n\n // Cleanup after running\n await runningSummarizer.waitStop(\n !runCoordinator.cancelled && Summarizer.stopReasonCanRunLastSummary(stopReason));\n\n // Propagate reason and ensure that if someone is waiting for cancellation token, they are moving to exit\n runCoordinator.stop(stopReason);\n\n return stopReason;\n }\n\n /**\n * Should we try to run a last summary for the given stop reason?\n * Currently only allows \"parentNotConnected\"\n * @param stopReason - SummarizerStopReason\n * @returns - true if the stop reason can run a last summary\n */\n public static stopReasonCanRunLastSummary(stopReason: SummarizerStopReason): boolean {\n return stopReason === \"parentNotConnected\";\n }\n\n /**\n * Put the summarizer in a started state, including creating and initializing the RunningSummarizer.\n * The start request can come either from the SummaryManager (in the auto-summarize case) or from the user\n * (in the on-demand case).\n * @param onBehalfOf - ID of the client that requested that the summarizer start\n * @param runCoordinator - cancellation token\n * @param newConfig - Summary configuration to override the existing config when invoking the RunningSummarizer.\n * @returns - Promise that is fulfilled when the RunningSummarizer is ready\n */\n private async start(\n onBehalfOf: string,\n runCoordinator: ICancellableSummarizerController): Promise<RunningSummarizer> {\n if (this.runningSummarizer) {\n if (this.runningSummarizer.disposed) {\n throw new UsageError(\"Starting a disposed summarizer\");\n }\n return this.runningSummarizer;\n }\n if (this.starting) {\n throw new UsageError(\"Attempting to start a summarizer that is already starting\");\n }\n this.starting = true;\n // Initialize values and first ack (time is not exact)\n this.logger.sendTelemetryEvent({\n eventName: \"RunningSummarizer\",\n onBehalfOf,\n initSummarySeqNumber: this.runtime.deltaManager.initialSequenceNumber,\n config: JSON.stringify(this.configurationGetter()),\n });\n\n // Summarizing container ID (with clientType === \"summarizer\")\n const clientId = this.runtime.clientId;\n if (clientId === undefined) {\n throw new UsageError(\"clientId should be defined if connected.\");\n }\n\n const runningSummarizer = await RunningSummarizer.start(\n this.logger,\n this.summaryCollection.createWatcher(clientId),\n this.configurationGetter(),\n async (...args) => this.internalsProvider.submitSummary(...args), // submitSummaryCallback\n new SummarizeHeuristicData(\n this.runtime.deltaManager.lastSequenceNumber,\n { /** summary attempt baseline for heuristics */\n refSequenceNumber: this.runtime.deltaManager.initialSequenceNumber,\n summaryTime: Date.now(),\n } as const,\n ),\n (errorMessage: string) => {\n if (!this._disposed) {\n this.logger.sendErrorEvent({ eventName: \"summarizingError\" },\n createSummarizingWarning(errorMessage, true));\n }\n },\n this.summaryCollection,\n runCoordinator /* cancellationToken */,\n (reason) => runCoordinator.stop(reason), /* stopSummarizerCallback */\n );\n this.runningSummarizer = runningSummarizer;\n this.starting = false;\n\n // Handle summary acks\n // Note: no exceptions are thrown from handleSummaryAcks handler as it handles all exceptions\n this.handleSummaryAcks().catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"HandleSummaryAckFatalError\" }, error);\n });\n\n // Listen for ops\n this.systemOpListener = (op: ISequencedDocumentMessage) => runningSummarizer.handleSystemOp(op);\n this.runtime.deltaManager.inbound.on(\"op\", this.systemOpListener);\n\n this.opListener = (error: any, op: ISequencedDocumentMessage) => runningSummarizer.handleOp(error, op);\n this.runtime.on(\"batchEnd\", this.opListener);\n\n return runningSummarizer;\n }\n\n /**\n * Disposes of resources after running. This cleanup will\n * clear any outstanding timers and reset some of the state\n * properties.\n * Called by ContainerRuntime when it is disposed, as well as at the end the run().\n */\n public dispose() {\n // Given that the call can come from own ContainerRuntime, ensure that we stop all the processes.\n this.stop(\"summarizerClientDisconnected\");\n\n this._disposed = true;\n if (this.runningSummarizer) {\n this.runningSummarizer.dispose();\n this.runningSummarizer = undefined;\n }\n if (this.systemOpListener) {\n this.runtime.deltaManager.inbound.off(\"op\", this.systemOpListener);\n }\n if (this.opListener) {\n this.runtime.removeListener(\"batchEnd\", this.opListener);\n }\n }\n\n public readonly summarizeOnDemand: ISummarizer[\"summarizeOnDemand\"] = (...args) => {\n try {\n if (this._disposed || this.runningSummarizer?.disposed) {\n throw new UsageError(\"Summarizer is already disposed.\");\n }\n if (this.runtime.summarizerClientId !== undefined &&\n this.runtime.summarizerClientId !== this.runtime.clientId) {\n // If there is an elected summarizer, and it's not this one, don't allow on-demand summary.\n // This is to prevent the on-demand summary and heuristic-based summary from stepping on\n // each other.\n throw new UsageError(\"On-demand summary attempted while an elected summarizer is present\");\n }\n const builder = new SummarizeResultBuilder();\n if (this.runningSummarizer) {\n // Summarizer is already running. Go ahead and start.\n return this.runningSummarizer.summarizeOnDemand(builder, ...args);\n }\n\n // Summarizer isn't running, so we need to start it, which is an async operation.\n // Manage the promise related to creating the cancellation token here.\n // The promises related to starting, summarizing,\n // and submitting are communicated to the caller through the results builder.\n const coordinatorCreateP = this.runCoordinatorCreateFn(this.runtime);\n\n coordinatorCreateP.then((runCoordinator) => {\n // Successully created the cancellation token. Start the summarizer.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const startP = this.start(this.runtime.clientId!, runCoordinator);\n startP.then(async (runningSummarizer) => {\n // Successfully started the summarizer. Run it.\n runningSummarizer.summarizeOnDemand(builder, ...args);\n // Wait for a command to stop or loss of connectivity before tearing down the summarizer and client.\n const stopReason = await Promise.race([this.stopDeferred.promise, runCoordinator.waitCancelled]);\n await runningSummarizer.waitStop(false);\n runCoordinator.stop(stopReason);\n this.close();\n }).catch((reason) => {\n builder.fail(\"Failed to start summarizer\", reason);\n });\n }).catch((reason) => {\n builder.fail(\"Failed to create cancellation token\", reason);\n });\n\n return builder.build();\n } catch (error) {\n throw SummarizingWarning.wrap(error, false /* logged */, this.logger);\n }\n };\n\n public readonly enqueueSummarize: ISummarizer[\"enqueueSummarize\"] = (...args) => {\n if (this._disposed || this.runningSummarizer === undefined || this.runningSummarizer.disposed) {\n throw new UsageError(\"Summarizer is not running or already disposed.\");\n }\n return this.runningSummarizer.enqueueSummarize(...args);\n };\n\n private async handleSummaryAcks() {\n let refSequenceNumber = this.runtime.deltaManager.initialSequenceNumber;\n while (this.runningSummarizer) {\n const summaryLogger = this.runningSummarizer.tryGetCorrelatedLogger(refSequenceNumber) ?? this.logger;\n try {\n const ack = await this.summaryCollection.waitSummaryAck(refSequenceNumber);\n refSequenceNumber = ack.summaryOp.referenceSequenceNumber;\n\n await this.internalsProvider.refreshLatestSummaryAck(\n ack.summaryOp.contents.handle,\n ack.summaryAck.contents.handle,\n refSequenceNumber,\n summaryLogger,\n );\n } catch (error) {\n summaryLogger.sendErrorEvent({\n eventName: \"HandleSummaryAckError\",\n referenceSequenceNumber: refSequenceNumber,\n }, error);\n }\n refSequenceNumber++;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../src/summarizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAExD,OAAO,EAAW,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,WAAW,EAAmB,YAAY,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAS9G,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAQxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAE5C,MAAM,OAAO,kBAAmB,SAAQ,YAAY;IAIhD,YACI,YAAoB,EACX,SAAkB,KAAK;QAEhC,KAAK,CAAC,YAAY,CAAC,CAAC;QAFX,WAAM,GAAN,MAAM,CAAiB;QAL3B,cAAS,GAAG,gBAAgB,CAAC;QAC7B,aAAQ,GAAG,IAAI,CAAC;IAOzB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,KAAU,EAAE,SAAkB,KAAK,EAAE,MAAwB;QACrE,MAAM,UAAU,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC,IAAI,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9E,OAAO,eAAe,CAAqB,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAC1E,CAAC;CACJ;AAED,MAAM,CAAC,MAAM,wBAAwB,GACjC,CAAC,YAAoB,EAAE,MAAe,EAAE,EAAE,CAAC,IAAI,kBAAkB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;AAE5F;;;;GAIG;AACH,MAAM,OAAO,UAAW,SAAQ,YAAY;IAcxC,YACI,GAAW;IACX;;OAEG;IACc,OAA2B,EAC3B,mBAAgD;IACjE;;MAEE;IACe,iBAA+C,EAChE,aAAkC,EAClB,iBAAoC,EACnC,sBAC8D;QAE/E,KAAK,EAAE,CAAC;QAXS,YAAO,GAAP,OAAO,CAAoB;QAC3B,wBAAmB,GAAnB,mBAAmB,CAA6B;QAIhD,sBAAiB,GAAjB,iBAAiB,CAA8B;QAEhD,sBAAiB,GAAjB,iBAAiB,CAAmB;QACnC,2BAAsB,GAAtB,sBAAsB,CACwC;QAtB3E,cAAS,GAAY,KAAK,CAAC;QAC3B,aAAQ,GAAY,KAAK,CAAC;QAKjB,iBAAY,GAAG,IAAI,QAAQ,EAAwB,CAAC;QAsOrD,sBAAiB,GAAqC,CAAC,GAAG,IAAI,EAAE,EAAE;;YAC9E,IAAI;gBACA,IAAI,IAAI,CAAC,SAAS,KAAI,MAAA,IAAI,CAAC,iBAAiB,0CAAE,QAAQ,CAAA,EAAE;oBACpD,MAAM,IAAI,UAAU,CAAC,iCAAiC,CAAC,CAAC;iBAC3D;gBACD,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,KAAK,SAAS;oBAC7C,IAAI,CAAC,OAAO,CAAC,kBAAkB,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE;oBAC3D,2FAA2F;oBAC3F,wFAAwF;oBACxF,cAAc;oBACd,MAAM,IAAI,UAAU,CAAC,oEAAoE,CAAC,CAAC;iBAC9F;gBACD,MAAM,OAAO,GAAG,IAAI,sBAAsB,EAAE,CAAC;gBAC7C,IAAI,IAAI,CAAC,iBAAiB,EAAE;oBACxB,qDAAqD;oBACrD,OAAO,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;iBACrE;gBAED,iFAAiF;gBACjF,sEAAsE;gBACtE,iDAAiD;gBACjD,6EAA6E;gBAC7E,MAAM,kBAAkB,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAErE,kBAAkB,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,EAAE;oBACvC,oEAAoE;oBACpE,oEAAoE;oBACpE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAS,EAAE,cAAc,CAAC,CAAC;oBAClE,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,iBAAiB,EAAE,EAAE;wBACpC,+CAA+C;wBAC/C,iBAAiB,CAAC,iBAAiB,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;wBACtD,oGAAoG;wBACpG,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC;wBACjG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;wBACxC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;wBAChC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACjB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE;wBAChB,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,MAAM,CAAC,CAAC;oBACvD,CAAC,CAAC,CAAC;gBACP,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE;oBAChB,OAAO,CAAC,IAAI,CAAC,qCAAqC,EAAE,MAAM,CAAC,CAAC;gBAChE,CAAC,CAAC,CAAC;gBAEH,OAAO,OAAO,CAAC,KAAK,EAAE,CAAC;aAC1B;YAAC,OAAO,KAAK,EAAE;gBACZ,MAAM,kBAAkB,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;aACzE;QACL,CAAC,CAAC;QAEc,qBAAgB,GAAoC,CAAC,GAAG,IAAI,EAAE,EAAE;YAC5E,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS,IAAI,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE;gBAC3F,MAAM,IAAI,UAAU,CAAC,gDAAgD,CAAC,CAAC;aAC1E;YACD,OAAO,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5D,CAAC,CAAC;QAzQE,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACpE,IAAI,CAAC,WAAW,GAAG,IAAI,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;IACtE,CAAC;IAhCD,IAAW,cAAc,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAC5C,IAAW,WAAW,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IASzC,IAAW,MAAM,KAAyB,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAwBpE;;;;;;;;OAQG;IACI,MAAM,CAAC,KAAK,CAAC,MAAM,CACtB,MAAe,EACf,GAAW;QACX,MAAM,OAAO,GAAa;YACtB,OAAO,EAAE;gBACL,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,KAAK;gBAC3B,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE;oBAC1B,YAAY,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;oBACpC,IAAI,EAAE,oBAAoB;iBAC7B;gBACD,CAAC,YAAY,CAAC,iBAAiB,CAAC,EAAE,IAAI;gBACtC,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,KAAK;aAClC;YACD,GAAG;SACN,CAAC;QAEF,MAAM,iBAAiB,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,WAAW,GACb,MAAM,kBAAkB,CAA2B,iBAAiB,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC;QAClG,IAAI,WAAW,CAAC,WAAW,KAAK,SAAS,EAAE;YACvC,MAAM,IAAI,UAAU,CAAC,6CAA6C,CAAC,CAAC;SACvE;QACD,OAAO,WAAW,CAAC,WAAW,CAAC;IACnC,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,UAAkB;QAC/B,IAAI;YACA,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;SACzC;QAAC,OAAO,KAAK,EAAE;YACZ,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YACjC,MAAM,kBAAkB,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;SACzE;gBAAS;YACN,IAAI,CAAC,KAAK,EAAE,CAAC;SAChB;IACL,CAAC;IAED;;;;OAIG;IACI,IAAI,CAAC,MAA4B;QACpC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAEM,KAAK;QACR,wFAAwF;QACxF,mCAAmC;QACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,UAAkB;QACpC,MAAM,cAAc,GAAqC,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEzG,sEAAsE;QACtE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;QACtF,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACvB,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;gBAC3B,SAAS,EAAE,oBAAoB;gBAC/B,UAAU;gBACV,MAAM;aACT,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,IAAI,cAAc,CAAC,SAAS,EAAE;YAC1B,OAAO,cAAc,CAAC,aAAa,CAAC;SACvC;QAED,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAEvE,sEAAsE;QACtE,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC;QAE/B,0CAA0C;QAC1C,gHAAgH;QAChH,oFAAoF;QACpF,wGAAwG;QACxG,2GAA2G;QAC3G,0GAA0G;QAC1G,uGAAuG;QACvG,6CAA6C;QAC7C,4GAA4G;QAC5G,4GAA4G;QAC5G,yGAAyG;QACzG,uEAAuE;QACvE,2GAA2G;QAC3G,0GAA0G;QAC1G,4BAA4B;QAE5B,wBAAwB;QACxB,MAAM,iBAAiB,CAAC,QAAQ,CAC5B,CAAC,cAAc,CAAC,SAAS,IAAI,UAAU,CAAC,2BAA2B,CAAC,UAAU,CAAC,CAAC,CAAC;QAErF,yGAAyG;QACzG,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEhC,OAAO,UAAU,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,2BAA2B,CAAC,UAAgC;QACtE,OAAO,UAAU,KAAK,oBAAoB,CAAC;IAC/C,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK,CAAC,KAAK,CACf,UAAkB,EAClB,cAAgD;QAChD,IAAI,IAAI,CAAC,iBAAiB,EAAE;YACxB,IAAI,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE;gBACjC,MAAM,IAAI,UAAU,CAAC,gCAAgC,CAAC,CAAC;aAC1D;YACD,OAAO,IAAI,CAAC,iBAAiB,CAAC;SACjC;QACD,IAAI,IAAI,CAAC,QAAQ,EAAE;YACf,MAAM,IAAI,UAAU,CAAC,2DAA2D,CAAC,CAAC;SACrF;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,sDAAsD;QACtD,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAC3B,SAAS,EAAE,mBAAmB;YAC9B,UAAU;YACV,oBAAoB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,qBAAqB;YACrE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;SACrD,CAAC,CAAC;QAEH,8DAA8D;QAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QACvC,IAAI,QAAQ,KAAK,SAAS,EAAE;YACxB,MAAM,IAAI,UAAU,CAAC,0CAA0C,CAAC,CAAC;SACpE;QAED,MAAM,iBAAiB,GAAG,MAAM,iBAAiB,CAAC,KAAK,CACnD,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,QAAQ,CAAC,EAC9C,IAAI,CAAC,mBAAmB,EAAE,EAC1B,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,EAAE,wBAAwB;QAC1F,IAAI,sBAAsB,CACtB,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,kBAAkB,EAC5C;YACI,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,qBAAqB;YAClE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;SACjB,CACb,EACD,CAAC,YAAoB,EAAE,EAAE;YACrB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;gBACjB,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,EACxD,wBAAwB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC;aACrD;QACL,CAAC,EACD,IAAI,CAAC,iBAAiB,EACtB,cAAc,CAAC,uBAAuB,EACtC,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,4BAA4B,CACrE,IAAI,CAAC,OAAO,CACf,CAAC;QACF,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAEtB,sBAAsB;QACtB,6FAA6F;QAC7F,IAAI,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACrC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,4BAA4B,EAAE,EAAE,KAAK,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC;QAEH,OAAO,iBAAiB,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACI,OAAO;QACV,iGAAiG;QACjG,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAE1C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,IAAI,CAAC,iBAAiB,EAAE;YACxB,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;SACtC;IACL,CAAC;IA0DO,KAAK,CAAC,iBAAiB;;QAC3B,IAAI,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC;QACxE,OAAO,IAAI,CAAC,iBAAiB,EAAE;YAC3B,MAAM,aAAa,GAAG,MAAA,IAAI,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,mCAAI,IAAI,CAAC,MAAM,CAAC;YACtG,IAAI;gBACA,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;gBAC3E,iBAAiB,GAAG,GAAG,CAAC,SAAS,CAAC,uBAAuB,CAAC;gBAE1D,MAAM,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,CAChD,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAC7B,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,EAC9B,iBAAiB,EACjB,aAAa,CAChB,CAAC;aACL;YAAC,OAAO,KAAK,EAAE;gBACZ,aAAa,CAAC,cAAc,CAAC;oBACzB,SAAS,EAAE,uBAAuB;oBAClC,uBAAuB,EAAE,iBAAiB;iBAC7C,EAAE,KAAK,CAAC,CAAC;aACb;YACD,iBAAiB,EAAE,CAAC;SACvB;IACL,CAAC;CACJ","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { EventEmitter } from \"events\";\nimport { Deferred } from \"@fluidframework/common-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ILoader, LoaderHeader } from \"@fluidframework/container-definitions\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport { DriverHeader } from \"@fluidframework/driver-definitions\";\nimport { requestFluidObject } from \"@fluidframework/runtime-utils\";\nimport { ChildLogger, IFluidErrorBase, LoggingError, wrapErrorAndLog } from \"@fluidframework/telemetry-utils\";\nimport {\n FluidObject,\n IFluidHandleContext,\n IFluidHandle,\n IRequest,\n} from \"@fluidframework/core-interfaces\";\nimport { ISummaryConfiguration } from \"./containerRuntime\";\nimport { ICancellableSummarizerController } from \"./runWhileConnectedCoordinator\";\nimport { summarizerClientType } from \"./summarizerClientElection\";\nimport { SummaryCollection } from \"./summaryCollection\";\nimport { SummarizerHandle } from \"./summarizerHandle\";\nimport { RunningSummarizer } from \"./runningSummarizer\";\nimport {\n ISummarizer,\n ISummarizerInternalsProvider,\n ISummarizerRuntime,\n ISummarizingWarning,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nimport { SummarizeHeuristicData } from \"./summarizerHeuristics\";\nimport { SummarizeResultBuilder } from \"./summaryGenerator\";\nimport { IConnectableRuntime } from \".\";\n\nconst summarizingError = \"summarizingError\";\n\nexport class SummarizingWarning extends LoggingError implements ISummarizingWarning, IFluidErrorBase {\n readonly errorType = summarizingError;\n readonly canRetry = true;\n\n constructor(\n errorMessage: string,\n readonly logged: boolean = false,\n ) {\n super(errorMessage);\n }\n\n static wrap(error: any, logged: boolean = false, logger: ITelemetryLogger) {\n const newErrorFn = (errMsg: string) => new SummarizingWarning(errMsg, logged);\n return wrapErrorAndLog<SummarizingWarning>(error, newErrorFn, logger);\n }\n}\n\nexport const createSummarizingWarning =\n (errorMessage: string, logged: boolean) => new SummarizingWarning(errorMessage, logged);\n\n/**\n * Summarizer is responsible for coordinating when to generate and send summaries.\n * It is the main entry point for summary work.\n * It is created only by summarizing container (i.e. one with clientType === \"summarizer\")\n */\nexport class Summarizer extends EventEmitter implements ISummarizer {\n public get IFluidLoadable() { return this; }\n public get ISummarizer() { return this; }\n\n private readonly logger: ITelemetryLogger;\n private runningSummarizer?: RunningSummarizer;\n private _disposed: boolean = false;\n private starting: boolean = false;\n\n private readonly innerHandle: IFluidHandle<this>;\n\n public get handle(): IFluidHandle<this> { return this.innerHandle; }\n private readonly stopDeferred = new Deferred<SummarizerStopReason>();\n\n constructor(\n url: string,\n /** Reference to runtime that created this object.\n * i.e. runtime with clientType === \"summarizer\"\n */\n private readonly runtime: ISummarizerRuntime,\n private readonly configurationGetter: () => ISummaryConfiguration,\n /** Represents an object that can generate summary.\n * In practical terms, it's same runtime (this.runtime) with clientType === \"summarizer\".\n */\n private readonly internalsProvider: ISummarizerInternalsProvider,\n handleContext: IFluidHandleContext,\n public readonly summaryCollection: SummaryCollection,\n private readonly runCoordinatorCreateFn:\n (runtime: IConnectableRuntime) => Promise<ICancellableSummarizerController>,\n ) {\n super();\n this.logger = ChildLogger.create(this.runtime.logger, \"Summarizer\");\n this.innerHandle = new SummarizerHandle(this, url, handleContext);\n }\n\n /**\n * Creates a Summarizer and its underlying client.\n * Note that different implementations of ILoader will handle the URL differently.\n * ILoader provided by a ContainerRuntime is a RelativeLoader, which will treat URL's\n * starting with \"/\" as relative to the Container. The general ILoader\n * interface will expect an absolute URL and will not handle \"/\".\n * @param loader - the loader that resolves the request\n * @param url - the URL used to resolve the container\n */\n public static async create(\n loader: ILoader,\n url: string): Promise<ISummarizer> {\n const request: IRequest = {\n headers: {\n [LoaderHeader.cache]: false,\n [LoaderHeader.clientDetails]: {\n capabilities: { interactive: false },\n type: summarizerClientType,\n },\n [DriverHeader.summarizingClient]: true,\n [LoaderHeader.reconnect]: false,\n },\n url,\n };\n\n const resolvedContainer = await loader.resolve(request);\n const fluidObject =\n await requestFluidObject<FluidObject<ISummarizer>>(resolvedContainer, { url: \"_summarizer\" });\n if (fluidObject.ISummarizer === undefined) {\n throw new UsageError(\"Fluid object does not implement ISummarizer\");\n }\n return fluidObject.ISummarizer;\n }\n\n public async run(onBehalfOf: string): Promise<SummarizerStopReason> {\n try {\n return await this.runCore(onBehalfOf);\n } catch (error) {\n this.stop(\"summarizerException\");\n throw SummarizingWarning.wrap(error, false /* logged */, this.logger);\n } finally {\n this.close();\n }\n }\n\n /**\n * Stops the summarizer from running. This will complete\n * the run promise, and also close the container.\n * @param reason - reason code for stopping\n */\n public stop(reason: SummarizerStopReason) {\n this.stopDeferred.resolve(reason);\n }\n\n public close() {\n // This will result in \"summarizerClientDisconnected\" stop reason recorded in telemetry,\n // unless stop() was called earlier\n this.dispose();\n this.runtime.closeFn();\n }\n\n private async runCore(onBehalfOf: string): Promise<SummarizerStopReason> {\n const runCoordinator: ICancellableSummarizerController = await this.runCoordinatorCreateFn(this.runtime);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopP = Promise.race([runCoordinator.waitCancelled, this.stopDeferred.promise]);\n void stopP.then((reason) => {\n this.logger.sendTelemetryEvent({\n eventName: \"StoppingSummarizer\",\n onBehalfOf,\n reason,\n });\n });\n\n if (runCoordinator.cancelled) {\n return runCoordinator.waitCancelled;\n }\n\n const runningSummarizer = await this.start(onBehalfOf, runCoordinator);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopReason = await stopP;\n\n // There are two possible approaches here:\n // 1. Propagate cancellation from this.stopDeferred to runCoordinator. This will ensure that we move to the exit\n // faster, including breaking out of the RunningSummarizer.trySummarize() faster.\n // We could create new coordinator and pass it to waitStop() -> trySummarizeOnce(\"lastSummary\") flow.\n // The con of this approach is that we might cancel active summary, and lastSummary will fail because it\n // did not wait for ack/nack from previous summary. Plus we disregard any 429 kind of info from service\n // that way (i.e. trySummarize() loop might have been waiting for 5 min because storage told us so).\n // In general, it's more wasted resources.\n // 2. We can not do it and make waitStop() do last summary only if there was no active summary. This ensures\n // that client behaves properly (from server POV) and we do not waste resources. But, it may mean we wait\n // substantially longer for trySummarize() retries to play out and thus this summary loop may run into\n // conflict with new summarizer client starting on different client.\n // As of now, #2 is implemented. It's more forward looking, as issue #7279 suggests changing design for new\n // summarizer client to not be created until current summarizer fully moves to exit, and that would reduce\n // cons of #2 substantially.\n\n // Cleanup after running\n await runningSummarizer.waitStop(\n !runCoordinator.cancelled && Summarizer.stopReasonCanRunLastSummary(stopReason));\n\n // Propagate reason and ensure that if someone is waiting for cancellation token, they are moving to exit\n runCoordinator.stop(stopReason);\n\n return stopReason;\n }\n\n /**\n * Should we try to run a last summary for the given stop reason?\n * Currently only allows \"parentNotConnected\"\n * @param stopReason - SummarizerStopReason\n * @returns - true if the stop reason can run a last summary\n */\n public static stopReasonCanRunLastSummary(stopReason: SummarizerStopReason): boolean {\n return stopReason === \"parentNotConnected\";\n }\n\n /**\n * Put the summarizer in a started state, including creating and initializing the RunningSummarizer.\n * The start request can come either from the SummaryManager (in the auto-summarize case) or from the user\n * (in the on-demand case).\n * @param onBehalfOf - ID of the client that requested that the summarizer start\n * @param runCoordinator - cancellation token\n * @param newConfig - Summary configuration to override the existing config when invoking the RunningSummarizer.\n * @returns - Promise that is fulfilled when the RunningSummarizer is ready\n */\n private async start(\n onBehalfOf: string,\n runCoordinator: ICancellableSummarizerController): Promise<RunningSummarizer> {\n if (this.runningSummarizer) {\n if (this.runningSummarizer.disposed) {\n throw new UsageError(\"Starting a disposed summarizer\");\n }\n return this.runningSummarizer;\n }\n if (this.starting) {\n throw new UsageError(\"Attempting to start a summarizer that is already starting\");\n }\n this.starting = true;\n // Initialize values and first ack (time is not exact)\n this.logger.sendTelemetryEvent({\n eventName: \"RunningSummarizer\",\n onBehalfOf,\n initSummarySeqNumber: this.runtime.deltaManager.initialSequenceNumber,\n config: JSON.stringify(this.configurationGetter()),\n });\n\n // Summarizing container ID (with clientType === \"summarizer\")\n const clientId = this.runtime.clientId;\n if (clientId === undefined) {\n throw new UsageError(\"clientId should be defined if connected.\");\n }\n\n const runningSummarizer = await RunningSummarizer.start(\n this.logger,\n this.summaryCollection.createWatcher(clientId),\n this.configurationGetter(),\n async (...args) => this.internalsProvider.submitSummary(...args), // submitSummaryCallback\n new SummarizeHeuristicData(\n this.runtime.deltaManager.lastSequenceNumber,\n { /** summary attempt baseline for heuristics */\n refSequenceNumber: this.runtime.deltaManager.initialSequenceNumber,\n summaryTime: Date.now(),\n } as const,\n ),\n (errorMessage: string) => {\n if (!this._disposed) {\n this.logger.sendErrorEvent({ eventName: \"summarizingError\" },\n createSummarizingWarning(errorMessage, true));\n }\n },\n this.summaryCollection,\n runCoordinator /* cancellationToken */,\n (reason) => runCoordinator.stop(reason), /* stopSummarizerCallback */\n this.runtime,\n );\n this.runningSummarizer = runningSummarizer;\n this.starting = false;\n\n // Handle summary acks\n // Note: no exceptions are thrown from handleSummaryAcks handler as it handles all exceptions\n this.handleSummaryAcks().catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"HandleSummaryAckFatalError\" }, error);\n });\n\n return runningSummarizer;\n }\n\n /**\n * Disposes of resources after running. This cleanup will\n * clear any outstanding timers and reset some of the state\n * properties.\n * Called by ContainerRuntime when it is disposed, as well as at the end the run().\n */\n public dispose() {\n // Given that the call can come from own ContainerRuntime, ensure that we stop all the processes.\n this.stop(\"summarizerClientDisconnected\");\n\n this._disposed = true;\n if (this.runningSummarizer) {\n this.runningSummarizer.dispose();\n this.runningSummarizer = undefined;\n }\n }\n\n public readonly summarizeOnDemand: ISummarizer[\"summarizeOnDemand\"] = (...args) => {\n try {\n if (this._disposed || this.runningSummarizer?.disposed) {\n throw new UsageError(\"Summarizer is already disposed.\");\n }\n if (this.runtime.summarizerClientId !== undefined &&\n this.runtime.summarizerClientId !== this.runtime.clientId) {\n // If there is an elected summarizer, and it's not this one, don't allow on-demand summary.\n // This is to prevent the on-demand summary and heuristic-based summary from stepping on\n // each other.\n throw new UsageError(\"On-demand summary attempted while an elected summarizer is present\");\n }\n const builder = new SummarizeResultBuilder();\n if (this.runningSummarizer) {\n // Summarizer is already running. Go ahead and start.\n return this.runningSummarizer.summarizeOnDemand(builder, ...args);\n }\n\n // Summarizer isn't running, so we need to start it, which is an async operation.\n // Manage the promise related to creating the cancellation token here.\n // The promises related to starting, summarizing,\n // and submitting are communicated to the caller through the results builder.\n const coordinatorCreateP = this.runCoordinatorCreateFn(this.runtime);\n\n coordinatorCreateP.then((runCoordinator) => {\n // Successully created the cancellation token. Start the summarizer.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const startP = this.start(this.runtime.clientId!, runCoordinator);\n startP.then(async (runningSummarizer) => {\n // Successfully started the summarizer. Run it.\n runningSummarizer.summarizeOnDemand(builder, ...args);\n // Wait for a command to stop or loss of connectivity before tearing down the summarizer and client.\n const stopReason = await Promise.race([this.stopDeferred.promise, runCoordinator.waitCancelled]);\n await runningSummarizer.waitStop(false);\n runCoordinator.stop(stopReason);\n this.close();\n }).catch((reason) => {\n builder.fail(\"Failed to start summarizer\", reason);\n });\n }).catch((reason) => {\n builder.fail(\"Failed to create cancellation token\", reason);\n });\n\n return builder.build();\n } catch (error) {\n throw SummarizingWarning.wrap(error, false /* logged */, this.logger);\n }\n };\n\n public readonly enqueueSummarize: ISummarizer[\"enqueueSummarize\"] = (...args) => {\n if (this._disposed || this.runningSummarizer === undefined || this.runningSummarizer.disposed) {\n throw new UsageError(\"Summarizer is not running or already disposed.\");\n }\n return this.runningSummarizer.enqueueSummarize(...args);\n };\n\n private async handleSummaryAcks() {\n let refSequenceNumber = this.runtime.deltaManager.initialSequenceNumber;\n while (this.runningSummarizer) {\n const summaryLogger = this.runningSummarizer.tryGetCorrelatedLogger(refSequenceNumber) ?? this.logger;\n try {\n const ack = await this.summaryCollection.waitSummaryAck(refSequenceNumber);\n refSequenceNumber = ack.summaryOp.referenceSequenceNumber;\n\n await this.internalsProvider.refreshLatestSummaryAck(\n ack.summaryOp.contents.handle,\n ack.summaryAck.contents.handle,\n refSequenceNumber,\n summaryLogger,\n );\n } catch (error) {\n summaryLogger.sendErrorEvent({\n eventName: \"HandleSummaryAckError\",\n referenceSequenceNumber: refSequenceNumber,\n }, error);\n }\n refSequenceNumber++;\n }\n }\n}\n"]}
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
6
6
  import { ISummaryConfigurationHeuristics } from "./containerRuntime";
7
- import { ISummarizeHeuristicData, ISummarizeHeuristicRunner, ISummarizeAttempt } from "./summarizerTypes";
7
+ import { ISummarizeHeuristicData, ISummarizeHeuristicRunner, ISummarizeAttempt, ISummaryHeuristicStrategy } from "./summarizerTypes";
8
8
  import { SummarizeReason } from "./summaryGenerator";
9
9
  /** Simple implementation of class for tracking summarize heuristic data. */
10
10
  export declare class SummarizeHeuristicData implements ISummarizeHeuristicData {
@@ -13,6 +13,26 @@ export declare class SummarizeHeuristicData implements ISummarizeHeuristicData {
13
13
  get lastAttempt(): ISummarizeAttempt;
14
14
  protected _lastSuccessfulSummary: Readonly<ISummarizeAttempt>;
15
15
  get lastSuccessfulSummary(): Readonly<ISummarizeAttempt>;
16
+ numNonRuntimeOps: number;
17
+ totalOpsSize: number;
18
+ hasMissingOpData: boolean;
19
+ /**
20
+ * Cumulative size in bytes of all the ops at the beginning of the summarization attempt.
21
+ * Is used to adjust totalOpsSize appropriately after successful summarization.
22
+ */
23
+ /** */
24
+ private totalOpsSizeBefore;
25
+ /**
26
+ * Number of system ops at beginning of attempting to summarize.
27
+ * Is used to adjust numSystemOps appropriately after successful summarization.
28
+ */
29
+ private numSystemOpsBefore;
30
+ numRuntimeOps: number;
31
+ /**
32
+ * Number of non-system ops at beginning of attempting to summarize.
33
+ * Is used to adjust numNonSystemOps appropriately after successful summarization.
34
+ */
35
+ private numNonSystemOpsBefore;
16
36
  constructor(lastOpSequenceNumber: number,
17
37
  /** Baseline attempt data used for comparisons with subsequent attempts/calculations. */
18
38
  attemptBaseline: ISummarizeAttempt);
@@ -26,12 +46,14 @@ export declare class SummarizeHeuristicData implements ISummarizeHeuristicData {
26
46
  export declare class SummarizeHeuristicRunner implements ISummarizeHeuristicRunner {
27
47
  private readonly heuristicData;
28
48
  private readonly configuration;
29
- private readonly trySummarize;
30
49
  private readonly logger;
50
+ private readonly summarizeStrategies;
31
51
  private readonly idleTimer;
32
- private readonly minOpsForLastSummaryAttempt;
33
- constructor(heuristicData: ISummarizeHeuristicData, configuration: ISummaryConfigurationHeuristics, trySummarize: (reason: SummarizeReason) => void, logger: ITelemetryLogger);
52
+ private readonly runSummarize;
53
+ constructor(heuristicData: ISummarizeHeuristicData, configuration: ISummaryConfigurationHeuristics, trySummarize: (reason: SummarizeReason) => void, logger: ITelemetryLogger, summarizeStrategies?: ISummaryHeuristicStrategy[]);
54
+ get idleTime(): number;
34
55
  get opsSinceLastAck(): number;
56
+ start(): void;
35
57
  run(): void;
36
58
  shouldRunLastSummary(): boolean;
37
59
  dispose(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"summarizerHeuristics.d.ts","sourceRoot":"","sources":["../src/summarizerHeuristics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AAErE,OAAO,EACH,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,4EAA4E;AAC5E,qBAAa,sBAAuB,YAAW,uBAAuB;IAYvD,oBAAoB,EAAE,MAAM;IAXvC,SAAS,CAAC,YAAY,EAAE,iBAAiB,CAAC;IAC1C,IAAW,WAAW,IAAI,iBAAiB,CAE1C;IAED,SAAS,CAAC,sBAAsB,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC9D,IAAW,qBAAqB,IAAI,QAAQ,CAAC,iBAAiB,CAAC,CAE9D;gBAGU,oBAAoB,EAAE,MAAM;IACnC,wFAAwF;IACxF,eAAe,EAAE,iBAAiB;IAM/B,4BAA4B,CAAC,WAAW,EAAE,QAAQ,CAAC,iBAAiB,CAAC;IAKrE,aAAa,CAAC,iBAAiB,CAAC,EAAE,MAAM;IAOxC,2BAA2B;CAGrC;AAED;;GAEG;AACH,qBAAa,wBAAyB,YAAW,yBAAyB;IAKlE,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAP3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAS;gBAGhC,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,+BAA+B,EAC9C,YAAY,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,EAC/C,MAAM,EAAE,gBAAgB;IAQ7C,IAAW,eAAe,IAAI,MAAM,CAEnC;IAEM,GAAG;IAcH,oBAAoB,IAAI,OAAO;IAa/B,OAAO;CAGjB"}
1
+ {"version":3,"file":"summarizerHeuristics.d.ts","sourceRoot":"","sources":["../src/summarizerHeuristics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EACH,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,yBAAyB,EAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,4EAA4E;AAC5E,qBAAa,sBAAuB,YAAW,uBAAuB;IAoCvD,oBAAoB,EAAE,MAAM;IAnCvC,SAAS,CAAC,YAAY,EAAE,iBAAiB,CAAC;IAC1C,IAAW,WAAW,IAAI,iBAAiB,CAE1C;IAED,SAAS,CAAC,sBAAsB,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAC9D,IAAW,qBAAqB,IAAI,QAAQ,CAAC,iBAAiB,CAAC,CAE9D;IAEM,gBAAgB,EAAE,MAAM,CAAK;IAC7B,YAAY,EAAE,MAAM,CAAK;IACzB,gBAAgB,EAAE,OAAO,CAAS;IAEzC;;;OAGG;IACF,MAAM;IACP,OAAO,CAAC,kBAAkB,CAAa;IAEvC;;;OAGG;IACH,OAAO,CAAC,kBAAkB,CAAa;IAEhC,aAAa,EAAE,MAAM,CAAK;IACjC;;;OAGG;IACH,OAAO,CAAC,qBAAqB,CAAa;gBAG/B,oBAAoB,EAAE,MAAM;IACnC,wFAAwF;IACxF,eAAe,EAAE,iBAAiB;IAM/B,4BAA4B,CAAC,WAAW,EAAE,QAAQ,CAAC,iBAAiB,CAAC;IAKrE,aAAa,CAAC,iBAAiB,CAAC,EAAE,MAAM;IAWxC,2BAA2B;CAYrC;AAED;;GAEG;AACH,qBAAa,wBAAyB,YAAW,yBAAyB;IAKlE,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAE9B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IARxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoC;gBAG5C,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,+BAA+B,EAC/D,YAAY,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,EAC9B,MAAM,EAAE,gBAAgB,EACxB,mBAAmB,GAAE,yBAAyB,EAA2C;IAiB9G,IAAW,QAAQ,IAAI,MAAM,CAiB5B;IAED,IAAW,eAAe,IAAI,MAAM,CAEnC;IAEM,KAAK;IAIL,GAAG;IAUH,oBAAoB,IAAI,OAAO;IAa/B,OAAO;CAGjB"}