@fluidframework/container-runtime 2.0.0-dev-rc.4.0.0.261659 → 2.0.0-dev-rc.5.0.0.265721
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/api-report/container-runtime.api.md +60 -29
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +9 -9
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +3 -5
- package/dist/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +8 -6
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +22 -11
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerHandleContext.d.ts +2 -1
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +14 -24
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +125 -140
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +13 -10
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +21 -8
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/{deltaManagerSummarizerProxy.d.ts → deltaManagerProxies.d.ts} +28 -3
- package/dist/deltaManagerProxies.d.ts.map +1 -0
- package/dist/{deltaManagerSummarizerProxy.js → deltaManagerProxies.js} +38 -2
- package/dist/deltaManagerProxies.js.map +1 -0
- package/dist/deltaScheduler.d.ts +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +1 -2
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +1 -1
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +14 -19
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +4 -22
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +3 -3
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +1 -2
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
- package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
- package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -1
- package/dist/gc/gcSummaryDefinitions.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +2 -2
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/dist/gc/index.d.ts +1 -1
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +2 -2
- package/dist/gc/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +6 -1
- package/dist/messageTypes.d.ts +5 -2
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +4 -0
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +1 -0
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +7 -20
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +6 -0
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +10 -1
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js.map +1 -1
- package/dist/storageServiceWithAttachBlobs.js.map +1 -1
- package/dist/summary/documentSchema.js +2 -2
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/index.d.ts +2 -2
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +4 -2
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +35 -13
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +0 -5
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +28 -113
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +1 -1
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +4 -1
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +1 -2
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -2
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +16 -28
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +1 -1
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +2 -2
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +26 -6
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +7 -8
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +30 -25
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.js +5 -5
- package/dist/summary/summaryManager.js.map +1 -1
- package/dist/throttler.js.map +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +9 -9
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +4 -6
- package/lib/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +8 -6
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +23 -12
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerHandleContext.d.ts +2 -1
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +14 -24
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +125 -140
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +13 -10
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +23 -10
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/{deltaManagerSummarizerProxy.d.ts → deltaManagerProxies.d.ts} +28 -3
- package/lib/deltaManagerProxies.d.ts.map +1 -0
- package/lib/{deltaManagerSummarizerProxy.js → deltaManagerProxies.js} +36 -1
- package/lib/deltaManagerProxies.js.map +1 -0
- package/lib/deltaScheduler.d.ts +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +1 -2
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +1 -1
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +15 -20
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +4 -22
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +2 -2
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +1 -2
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -1
- package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
- package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -1
- package/lib/gc/gcSummaryDefinitions.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +2 -2
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
- package/lib/gc/index.d.ts +1 -1
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -1
- package/lib/gc/index.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +6 -1
- package/lib/messageTypes.d.ts +5 -2
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +4 -0
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +1 -0
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +7 -20
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +6 -0
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +10 -1
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js.map +1 -1
- package/lib/storageServiceWithAttachBlobs.js.map +1 -1
- package/lib/summary/documentSchema.js +2 -2
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/index.d.ts +2 -2
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +4 -2
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +35 -13
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +0 -5
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +21 -106
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +1 -1
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +4 -1
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +1 -2
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +1 -2
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +16 -28
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +1 -1
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +2 -2
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +26 -6
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +1 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +7 -8
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +24 -19
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.js +1 -1
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/throttler.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/package.json +65 -26
- package/src/blobManager.ts +14 -13
- package/src/channelCollection.ts +34 -20
- package/src/connectionTelemetry.ts +1 -1
- package/src/containerHandleContext.ts +2 -1
- package/src/containerRuntime.ts +161 -170
- package/src/dataStore.ts +3 -2
- package/src/dataStoreContext.ts +62 -23
- package/src/{deltaManagerSummarizerProxy.ts → deltaManagerProxies.ts} +55 -3
- package/src/deltaScheduler.ts +1 -1
- package/src/gc/garbageCollection.md +0 -8
- package/src/gc/garbageCollection.ts +2 -1
- package/src/gc/gcConfigs.ts +12 -19
- package/src/gc/gcDefinitions.ts +5 -23
- package/src/gc/gcHelpers.ts +1 -1
- package/src/gc/gcSummaryDefinitions.ts +1 -1
- package/src/gc/gcSummaryStateTracker.ts +1 -1
- package/src/gc/gcTelemetry.ts +1 -1
- package/src/gc/index.ts +1 -1
- package/src/index.ts +6 -1
- package/src/messageTypes.ts +4 -2
- package/src/opLifecycle/batchManager.ts +5 -0
- package/src/opLifecycle/outbox.ts +7 -30
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +11 -1
- package/src/scheduleManager.ts +1 -1
- package/src/summary/documentSchema.ts +1 -1
- package/src/summary/index.ts +5 -1
- package/src/summary/orderedClientElection.ts +83 -12
- package/src/summary/runningSummarizer.ts +30 -114
- package/src/summary/summarizer.ts +5 -2
- package/src/summary/summarizerNode/summarizerNode.ts +0 -2
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +1 -3
- package/src/summary/summarizerTypes.ts +22 -29
- package/src/summary/summaryCollection.ts +1 -1
- package/src/summary/summaryFormat.ts +35 -6
- package/src/summary/summaryGenerator.ts +50 -27
- package/src/summary/summaryManager.ts +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts.map +0 -1
- package/dist/deltaManagerSummarizerProxy.js.map +0 -1
- package/lib/deltaManagerSummarizerProxy.d.ts.map +0 -1
- package/lib/deltaManagerSummarizerProxy.js.map +0 -1
|
@@ -7,9 +7,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.RunningSummarizer = exports.defaultMaxAttemptsForSubmitFailures = exports.defaultMaxAttempts = void 0;
|
|
8
8
|
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
9
|
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
10
|
-
const
|
|
10
|
+
const internal_2 = require("@fluidframework/driver-definitions/internal");
|
|
11
11
|
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
|
|
12
|
-
const
|
|
12
|
+
const internal_3 = require("@fluidframework/telemetry-utils/internal");
|
|
13
13
|
const opProperties_js_1 = require("../opProperties.js");
|
|
14
14
|
const summarizerHeuristics_js_1 = require("./summarizerHeuristics.js");
|
|
15
15
|
const summaryGenerator_js_1 = require("./summaryGenerator.js");
|
|
@@ -50,7 +50,7 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
50
50
|
// Process summary acks asynchronously
|
|
51
51
|
// Note: no exceptions are thrown from processIncomingSummaryAcks handler as it handles all exceptions
|
|
52
52
|
summarizer.processIncomingSummaryAcks(nextReferenceSequenceNumber).catch((error) => {
|
|
53
|
-
(0,
|
|
53
|
+
(0, internal_3.createChildLogger)({ logger }).sendErrorEvent({ eventName: "HandleSummaryAckFatalError" }, error);
|
|
54
54
|
});
|
|
55
55
|
// Update heuristic counts
|
|
56
56
|
// By the time we get here, there are potentially ops missing from the heuristic summary counts
|
|
@@ -104,8 +104,8 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
104
104
|
// code in `submitSummary` function in container runtime, will refresh the latest state
|
|
105
105
|
// by calling `prefetchLatestSummaryThenClose`. We will load the next summarizer from the
|
|
106
106
|
// updated state and be fine.
|
|
107
|
-
const isIgnoredError = (0,
|
|
108
|
-
error.errorType ===
|
|
107
|
+
const isIgnoredError = (0, internal_3.isFluidError)(error) &&
|
|
108
|
+
error.errorType === internal_2.DriverErrorTypes.fileNotFoundOrAccessDeniedError;
|
|
109
109
|
options.summaryLogger.sendTelemetryEvent({
|
|
110
110
|
eventName: isIgnoredError
|
|
111
111
|
? "HandleSummaryAckErrorIgnored"
|
|
@@ -131,7 +131,7 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
131
131
|
summarizeCount: () => this.summarizeCount,
|
|
132
132
|
summarizerSuccessfulAttempts: () => this.totalSuccessfulAttempts,
|
|
133
133
|
};
|
|
134
|
-
this.mc = (0,
|
|
134
|
+
this.mc = (0, internal_3.createChildMonitoringContext)({
|
|
135
135
|
logger: baseLogger,
|
|
136
136
|
namespace: "Running",
|
|
137
137
|
properties: {
|
|
@@ -307,9 +307,7 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
307
307
|
if (this.summarizingLock === undefined) {
|
|
308
308
|
this.trySummarizeOnce(
|
|
309
309
|
// summarizeProps
|
|
310
|
-
{ summarizeReason: "lastSummary" },
|
|
311
|
-
// ISummarizeOptions, using defaults: { refreshLatestAck: false, fullTree: false }
|
|
312
|
-
{});
|
|
310
|
+
{ summarizeReason: "lastSummary" }, {});
|
|
313
311
|
}
|
|
314
312
|
}
|
|
315
313
|
// Note that trySummarizeOnce() call above returns right away, without waiting.
|
|
@@ -380,7 +378,7 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
380
378
|
this.lockedSummaryAction(() => {
|
|
381
379
|
this.beforeSummaryAction();
|
|
382
380
|
}, async () => {
|
|
383
|
-
const summaryLogger = (0,
|
|
381
|
+
const summaryLogger = (0, internal_3.createChildLogger)({
|
|
384
382
|
logger: this.mc.logger,
|
|
385
383
|
properties: { all: summarizeProps },
|
|
386
384
|
});
|
|
@@ -421,90 +419,13 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
421
419
|
this.lockedSummaryAction(() => {
|
|
422
420
|
this.beforeSummaryAction();
|
|
423
421
|
}, async () => {
|
|
424
|
-
return this.
|
|
425
|
-
? this.trySummarizeWithRetries(reason)
|
|
426
|
-
: this.trySummarizeWithStaticAttempts(reason);
|
|
422
|
+
return this.trySummarizeWithRetries(reason);
|
|
427
423
|
}, () => {
|
|
428
424
|
this.afterSummaryAction();
|
|
429
425
|
}).catch((error) => {
|
|
430
426
|
this.mc.logger.sendErrorEvent({ eventName: "UnexpectedSummarizeError" }, error);
|
|
431
427
|
});
|
|
432
428
|
}
|
|
433
|
-
/**
|
|
434
|
-
* Tries to summarize 2 times with pre-defined summary options. If an attempt fails with "retryAfterSeconds"
|
|
435
|
-
* param, that attempt is tried once more.
|
|
436
|
-
*/
|
|
437
|
-
async trySummarizeWithStaticAttempts(reason) {
|
|
438
|
-
const attemptOptions = [
|
|
439
|
-
{ refreshLatestAck: false, fullTree: false },
|
|
440
|
-
{ refreshLatestAck: true, fullTree: false },
|
|
441
|
-
];
|
|
442
|
-
let summaryAttempts = 0;
|
|
443
|
-
let summaryAttemptsPerPhase = 0;
|
|
444
|
-
let summaryAttemptPhase = 0;
|
|
445
|
-
let error;
|
|
446
|
-
while (summaryAttemptPhase < attemptOptions.length) {
|
|
447
|
-
if (this.cancellationToken.cancelled) {
|
|
448
|
-
return;
|
|
449
|
-
}
|
|
450
|
-
// We only want to attempt 1 summary when reason is "lastSummary"
|
|
451
|
-
if (++summaryAttempts > 1 && reason === "lastSummary") {
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
summaryAttemptsPerPhase++;
|
|
455
|
-
const summarizeOptions = attemptOptions[summaryAttemptPhase];
|
|
456
|
-
const summarizeProps = {
|
|
457
|
-
summarizeReason: reason,
|
|
458
|
-
summaryAttempts,
|
|
459
|
-
summaryAttemptsPerPhase,
|
|
460
|
-
summaryAttemptPhase: summaryAttemptPhase + 1,
|
|
461
|
-
...summarizeOptions,
|
|
462
|
-
};
|
|
463
|
-
const summaryLogger = (0, internal_2.createChildLogger)({
|
|
464
|
-
logger: this.mc.logger,
|
|
465
|
-
properties: { all: summarizeProps },
|
|
466
|
-
});
|
|
467
|
-
const summaryOptions = {
|
|
468
|
-
...summarizeOptions,
|
|
469
|
-
summaryLogger,
|
|
470
|
-
cancellationToken: this.cancellationToken,
|
|
471
|
-
latestSummaryRefSeqNum: this.heuristicData.lastSuccessfulSummary.refSequenceNumber,
|
|
472
|
-
};
|
|
473
|
-
// Note: no need to account for cancellationToken.waitCancelled here, as
|
|
474
|
-
// this is accounted SummaryGenerator.summarizeCore that controls receivedSummaryAckOrNack.
|
|
475
|
-
const resultSummarize = this.generator.summarize(summaryOptions);
|
|
476
|
-
const ackNackResult = await resultSummarize.receivedSummaryAckOrNack;
|
|
477
|
-
if (ackNackResult.success) {
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
error = ackNackResult.error;
|
|
481
|
-
// Check for retryDelay that can come from summaryNack, upload summary or submit summary flows.
|
|
482
|
-
// Retry the same step only once per retryAfter response.
|
|
483
|
-
const submitResult = await resultSummarize.summarySubmitted;
|
|
484
|
-
const delaySeconds = !submitResult.success
|
|
485
|
-
? submitResult.data?.retryAfterSeconds
|
|
486
|
-
: ackNackResult.data?.retryAfterSeconds;
|
|
487
|
-
if (delaySeconds === undefined || summaryAttemptsPerPhase > 1) {
|
|
488
|
-
summaryAttemptPhase++;
|
|
489
|
-
summaryAttemptsPerPhase = 0;
|
|
490
|
-
}
|
|
491
|
-
if (delaySeconds !== undefined) {
|
|
492
|
-
this.mc.logger.sendPerformanceEvent({
|
|
493
|
-
eventName: "SummarizeAttemptDelay",
|
|
494
|
-
duration: delaySeconds,
|
|
495
|
-
summaryNackDelay: ackNackResult.data?.retryAfterSeconds !== undefined,
|
|
496
|
-
...summarizeProps,
|
|
497
|
-
});
|
|
498
|
-
await (0, internal_1.delay)(delaySeconds * 1000);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
this.mc.logger.sendErrorEvent({
|
|
502
|
-
eventName: "SummarizeFailed",
|
|
503
|
-
maxAttempts: attemptOptions.length,
|
|
504
|
-
summaryAttempts: summaryAttemptPhase,
|
|
505
|
-
}, error);
|
|
506
|
-
this.stopSummarizerCallback("failToSummarize");
|
|
507
|
-
}
|
|
508
429
|
/**
|
|
509
430
|
* Tries to summarize with retries where retry is based on the failure params.
|
|
510
431
|
* For example, summarization may be retried for failures with "retryAfterSeconds" param.
|
|
@@ -521,7 +442,7 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
521
442
|
...summarizeOptions,
|
|
522
443
|
finalAttempt,
|
|
523
444
|
};
|
|
524
|
-
const summaryLogger = (0,
|
|
445
|
+
const summaryLogger = (0, internal_3.createChildLogger)({
|
|
525
446
|
logger: this.mc.logger,
|
|
526
447
|
properties: { all: summarizeProps },
|
|
527
448
|
});
|
|
@@ -567,22 +488,17 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
567
488
|
done = true;
|
|
568
489
|
break;
|
|
569
490
|
}
|
|
570
|
-
// Update max attempts
|
|
571
|
-
// If submit summary failed, use
|
|
572
|
-
// from "receivedSummaryAckOrNack" result.
|
|
491
|
+
// Update max attempts from the failure result.
|
|
492
|
+
// If submit summary failed, use maxAttemptsForSubmitFailures. Else use the defaultMaxAttempts.
|
|
573
493
|
// Note: Check "summarySubmitted" result first because if it fails, ack nack would fail as well.
|
|
574
494
|
const submitSummaryResult = await results.summarySubmitted;
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
}
|
|
579
|
-
else {
|
|
580
|
-
maxAttempts = exports.defaultMaxAttempts;
|
|
581
|
-
retryAfterSeconds = ackNackResult.data?.retryAfterSeconds;
|
|
582
|
-
}
|
|
495
|
+
maxAttempts = !submitSummaryResult.success
|
|
496
|
+
? this.maxAttemptsForSubmitFailures
|
|
497
|
+
: exports.defaultMaxAttempts;
|
|
583
498
|
// Emit "summarize" event for this failed attempt.
|
|
584
499
|
status = "failure";
|
|
585
500
|
error = ackNackResult.error;
|
|
501
|
+
retryAfterSeconds = error.retryAfterSeconds;
|
|
586
502
|
const eventProps = {
|
|
587
503
|
result: status,
|
|
588
504
|
currentAttempt,
|
|
@@ -590,25 +506,24 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
590
506
|
error,
|
|
591
507
|
};
|
|
592
508
|
this.emit("summarize", eventProps);
|
|
593
|
-
//
|
|
509
|
+
// Break if the failure doesn't have "retryAfterSeconds" or we are one less from max number of attempts.
|
|
510
|
+
// Note that the final attempt if "retryAfterSeconds" does exist happens outside of the do..while loop.
|
|
594
511
|
if (retryAfterSeconds === undefined || currentAttempt >= maxAttempts - 1) {
|
|
595
512
|
done = true;
|
|
596
513
|
}
|
|
597
|
-
// If the failure has "retryAfterSeconds", add a delay of that time
|
|
598
|
-
|
|
599
|
-
if (retryAfterSeconds !== undefined) {
|
|
514
|
+
// If the failure has "retryAfterSeconds", add a delay of that time before starting the next attempt.
|
|
515
|
+
if (retryAfterSeconds !== undefined && retryAfterSeconds > 0) {
|
|
600
516
|
this.mc.logger.sendPerformanceEvent({
|
|
601
517
|
eventName: "SummarizeAttemptDelay",
|
|
602
|
-
duration: retryAfterSeconds,
|
|
603
|
-
summaryNackDelay: ackNackResult.data
|
|
518
|
+
duration: retryAfterSeconds * 1000,
|
|
519
|
+
summaryNackDelay: ackNackResult.data !== undefined, // This will only be defined only for nack failures.
|
|
604
520
|
stage: submitSummaryResult.data?.stage,
|
|
605
|
-
dynamicRetries: true,
|
|
606
521
|
...attemptResult.summarizeProps,
|
|
607
522
|
});
|
|
608
523
|
await (0, internal_1.delay)(retryAfterSeconds * 1000);
|
|
609
524
|
}
|
|
610
525
|
} while (!done);
|
|
611
|
-
// If
|
|
526
|
+
// If the attempt was successful, emit "summarize" event and return. A failed attempt may be retried below.
|
|
612
527
|
if (status !== "failure") {
|
|
613
528
|
this.emit("summarize", { result: status, currentAttempt, maxAttempts });
|
|
614
529
|
return results;
|
|
@@ -650,7 +565,7 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
650
565
|
async summarizeOnDemandWithRetries(reason, resultsBuilder) {
|
|
651
566
|
const results = await this.trySummarizeWithRetries(reason);
|
|
652
567
|
if (results === undefined) {
|
|
653
|
-
resultsBuilder.fail("Summarization was canceled",
|
|
568
|
+
resultsBuilder.fail("Summarization was canceled", new summaryGenerator_js_1.RetriableSummaryError("Summarization was canceled"));
|
|
654
569
|
return resultsBuilder.build();
|
|
655
570
|
}
|
|
656
571
|
const submitResult = await results.summarySubmitted;
|
|
@@ -664,14 +579,14 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
664
579
|
/** {@inheritdoc (ISummarizer:interface).summarizeOnDemand} */
|
|
665
580
|
summarizeOnDemand(options, resultsBuilder = new summaryGenerator_js_1.SummarizeResultBuilder()) {
|
|
666
581
|
if (this.stopping) {
|
|
667
|
-
resultsBuilder.fail("RunningSummarizer stopped or disposed",
|
|
582
|
+
resultsBuilder.fail("RunningSummarizer stopped or disposed", new summaryGenerator_js_1.RetriableSummaryError("RunningSummarizer stopped or disposed"));
|
|
668
583
|
return resultsBuilder.build();
|
|
669
584
|
}
|
|
670
585
|
// Check for concurrent summary attempts. If one is found,
|
|
671
586
|
// return a promise that caller can await before trying again.
|
|
672
587
|
if (this.summarizingLock !== undefined) {
|
|
673
588
|
// The heuristics are blocking concurrent summarize attempts.
|
|
674
|
-
throw new
|
|
589
|
+
throw new internal_3.UsageError("Attempted to run an already-running summarizer on demand");
|
|
675
590
|
}
|
|
676
591
|
const { reason, ...summarizeOptions } = options;
|
|
677
592
|
if (options.retryOnFailure === true) {
|
|
@@ -693,7 +608,7 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
693
608
|
return { alreadyEnqueued: true };
|
|
694
609
|
}
|
|
695
610
|
// Override existing enqueued summarize attempt.
|
|
696
|
-
this.enqueuedSummary.resultsBuilder.fail("Aborted; overridden by another enqueue summarize attempt",
|
|
611
|
+
this.enqueuedSummary.resultsBuilder.fail("Aborted; overridden by another enqueue summarize attempt", new summaryGenerator_js_1.RetriableSummaryError("Summary was overridden by another enqueue summarize attempt"));
|
|
697
612
|
this.enqueuedSummary = undefined;
|
|
698
613
|
overridden = true;
|
|
699
614
|
}
|
|
@@ -732,7 +647,7 @@ class RunningSummarizer extends client_utils_1.TypedEventEmitter {
|
|
|
732
647
|
}
|
|
733
648
|
disposeEnqueuedSummary() {
|
|
734
649
|
if (this.enqueuedSummary !== undefined) {
|
|
735
|
-
this.enqueuedSummary.resultsBuilder.fail("RunningSummarizer stopped or disposed",
|
|
650
|
+
this.enqueuedSummary.resultsBuilder.fail("RunningSummarizer stopped or disposed", new summaryGenerator_js_1.RetriableSummaryError("RunningSummarizer stopped or disposed"));
|
|
736
651
|
this.enqueuedSummary = undefined;
|
|
737
652
|
}
|
|
738
653
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runningSummarizer.js","sourceRoot":"","sources":["../../src/summary/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 { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport { IDisposable, ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert, Deferred, PromiseTimer, delay } from \"@fluidframework/core-utils/internal\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport {\n\tMonitoringContext,\n\tUsageError,\n\tcreateChildLogger,\n\tcreateChildMonitoringContext,\n\tisFluidError,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { ISummaryConfiguration } from \"../containerRuntime.js\";\nimport { opSize } from \"../opProperties.js\";\n\nimport { SummarizeHeuristicRunner } from \"./summarizerHeuristics.js\";\nimport {\n\tEnqueueSummarizeResult,\n\tIEnqueueSummarizeOptions,\n\tIOnDemandSummarizeOptions,\n\tIRefreshSummaryAckOptions,\n\tISubmitSummaryOptions,\n\tISummarizeEventProps,\n\tISummarizeHeuristicData,\n\tISummarizeHeuristicRunner,\n\tISummarizeOptions,\n\tISummarizeResults,\n\tISummarizeRunnerTelemetry,\n\tISummarizeTelemetryProperties,\n\tISummarizerEvents,\n\tISummarizerRuntime,\n\tISummaryCancellationToken,\n\tSubmitSummaryResult,\n\tSummarizerStopReason,\n} from \"./summarizerTypes.js\";\nimport { IAckedSummary, IClientSummaryWatcher, SummaryCollection } from \"./summaryCollection.js\";\nimport {\n\tSummarizeReason,\n\tSummarizeResultBuilder,\n\tSummaryGenerator,\n\traceTimer,\n} from \"./summaryGenerator.js\";\n\nconst maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes\n\n/**\n * The maximum number of summarization attempts that will be done by default in case of failures\n * that can be retried.\n */\nexport const defaultMaxAttempts = 2;\n/**\n * The default value for maximum number of summarization attempts that will be done for summarization failures where\n * submit fails and the failure can be retried.\n */\nexport const defaultMaxAttemptsForSubmitFailures = 5;\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 extends TypedEventEmitter<ISummarizerEvents> implements IDisposable {\n\tpublic static async start(\n\t\tlogger: ITelemetryBaseLogger,\n\t\tsummaryWatcher: IClientSummaryWatcher,\n\t\tconfiguration: ISummaryConfiguration,\n\t\tsubmitSummaryCallback: (options: ISubmitSummaryOptions) => Promise<SubmitSummaryResult>,\n\t\trefreshLatestSummaryAckCallback: (options: IRefreshSummaryAckOptions) => Promise<void>,\n\t\theuristicData: ISummarizeHeuristicData,\n\t\tsummaryCollection: SummaryCollection,\n\t\tcancellationToken: ISummaryCancellationToken,\n\t\tstopSummarizerCallback: (reason: SummarizerStopReason) => void,\n\t\truntime: ISummarizerRuntime,\n\t): Promise<RunningSummarizer> {\n\t\tconst summarizer = new RunningSummarizer(\n\t\t\tlogger,\n\t\t\tsummaryWatcher,\n\t\t\tconfiguration,\n\t\t\tsubmitSummaryCallback,\n\t\t\trefreshLatestSummaryAckCallback,\n\t\t\theuristicData,\n\t\t\tsummaryCollection,\n\t\t\tcancellationToken,\n\t\t\tstopSummarizerCallback,\n\t\t\truntime,\n\t\t);\n\n\t\t// If there have been any acks newer that the one this client loaded from until now, process them before\n\t\t// starting the running summarizer which will trigger summary heuristics.\n\t\t// This is done primarily to handle scenarios where the summarizer loads from a cached snapshot and there\n\t\t// is newer one available. The ack for the newer summary is processed before summarizing because otherwise\n\t\t// that summary would fail as it has an older parent.\n\t\tlet nextReferenceSequenceNumber = runtime.deltaManager.initialSequenceNumber + 1;\n\t\tconst latestAck = summaryCollection.latestAck;\n\t\tif (\n\t\t\tlatestAck !== undefined &&\n\t\t\tlatestAck.summaryOp.referenceSequenceNumber >= nextReferenceSequenceNumber\n\t\t) {\n\t\t\tawait summarizer.handleSummaryAck(latestAck);\n\t\t\tnextReferenceSequenceNumber = latestAck.summaryOp.referenceSequenceNumber + 1;\n\t\t}\n\n\t\tawait summarizer.waitStart();\n\n\t\t// Process summary acks asynchronously\n\t\t// Note: no exceptions are thrown from processIncomingSummaryAcks handler as it handles all exceptions\n\t\tsummarizer.processIncomingSummaryAcks(nextReferenceSequenceNumber).catch((error) => {\n\t\t\tcreateChildLogger({ logger }).sendErrorEvent(\n\t\t\t\t{ eventName: \"HandleSummaryAckFatalError\" },\n\t\t\t\terror,\n\t\t\t);\n\t\t});\n\n\t\t// Update heuristic counts\n\t\t// By the time we get here, there are potentially ops missing from the heuristic summary counts\n\t\t// Examples of where this could happen:\n\t\t// 1. Op is processed during the time that we are initiating the RunningSummarizer instance but before we\n\t\t// listen for the op events (will get missed by the handlers in the current workflow)\n\t\t// 2. Op was sequenced after the last time we summarized (op sequence number > summarize ref sequence number)\n\t\tconst diff =\n\t\t\truntime.deltaManager.lastSequenceNumber -\n\t\t\t(heuristicData.lastSuccessfulSummary.refSequenceNumber +\n\t\t\t\theuristicData.numNonRuntimeOps +\n\t\t\t\theuristicData.numRuntimeOps);\n\t\theuristicData.hasMissingOpData = diff > 0;\n\n\t\tif (heuristicData.hasMissingOpData) {\n\t\t\t// Split the diff 50-50 and increment the counts appropriately\n\t\t\theuristicData.numNonRuntimeOps += Math.ceil(diff / 2);\n\t\t\theuristicData.numRuntimeOps += Math.floor(diff / 2);\n\t\t}\n\n\t\t// Update last seq number (in case the handlers haven't processed anything yet)\n\t\theuristicData.lastOpSequenceNumber = runtime.deltaManager.lastSequenceNumber;\n\n\t\t// Start heuristics\n\t\tsummarizer.heuristicRunner?.start();\n\t\tsummarizer.heuristicRunner?.run();\n\n\t\treturn summarizer;\n\t}\n\n\tpublic get disposed() {\n\t\treturn this._disposed;\n\t}\n\tprivate stopping = false;\n\tprivate _disposed = false;\n\tprivate summarizingLock: Promise<void> | undefined;\n\tprivate tryWhileSummarizing = false;\n\tprivate readonly pendingAckTimer: PromiseTimer;\n\tprivate heuristicRunner?: ISummarizeHeuristicRunner;\n\tprivate readonly generator: SummaryGenerator;\n\tprivate readonly mc: MonitoringContext;\n\n\tprivate enqueuedSummary:\n\t\t| {\n\t\t\t\treason: SummarizeReason;\n\t\t\t\tafterSequenceNumber: number;\n\t\t\t\tsummarizeOptions: ISummarizeOptions;\n\t\t\t\treadonly resultsBuilder: SummarizeResultBuilder;\n\t\t }\n\t\t| undefined;\n\tprivate summarizeCount = 0;\n\tprivate totalSuccessfulAttempts = 0;\n\tprivate initialized = false;\n\n\tprivate readonly runtimeListener;\n\n\t/** The maximum number of summary attempts to do when submit summary fails. */\n\tprivate readonly maxAttemptsForSubmitFailures: number;\n\n\tprivate constructor(\n\t\tbaseLogger: ITelemetryBaseLogger,\n\t\tprivate readonly summaryWatcher: IClientSummaryWatcher,\n\t\tprivate readonly configuration: ISummaryConfiguration,\n\t\tprivate readonly submitSummaryCallback: (\n\t\t\toptions: ISubmitSummaryOptions,\n\t\t) => Promise<SubmitSummaryResult>,\n\t\tprivate readonly refreshLatestSummaryAckCallback: (\n\t\t\toptions: IRefreshSummaryAckOptions,\n\t\t) => Promise<void>,\n\t\tprivate readonly heuristicData: ISummarizeHeuristicData,\n\t\tprivate readonly summaryCollection: SummaryCollection,\n\t\tprivate readonly cancellationToken: ISummaryCancellationToken,\n\t\tprivate readonly stopSummarizerCallback: (reason: SummarizerStopReason) => void,\n\t\tprivate readonly runtime: ISummarizerRuntime,\n\t) {\n\t\tsuper();\n\n\t\tconst telemetryProps: ISummarizeRunnerTelemetry = {\n\t\t\tsummarizeCount: () => this.summarizeCount,\n\t\t\tsummarizerSuccessfulAttempts: () => this.totalSuccessfulAttempts,\n\t\t};\n\n\t\tthis.mc = createChildMonitoringContext({\n\t\t\tlogger: baseLogger,\n\t\t\tnamespace: \"Running\",\n\t\t\tproperties: {\n\t\t\t\tall: telemetryProps,\n\t\t\t},\n\t\t});\n\n\t\tif (configuration.state !== \"disableHeuristics\") {\n\t\t\tassert(\n\t\t\t\tthis.configuration.state === \"enabled\",\n\t\t\t\t0x2ea /* \"Configuration state should be enabled\" */,\n\t\t\t);\n\t\t\tthis.heuristicRunner = new SummarizeHeuristicRunner(\n\t\t\t\theuristicData,\n\t\t\t\tthis.configuration,\n\t\t\t\t(reason) => this.trySummarize(reason),\n\t\t\t\tthis.mc.logger,\n\t\t\t);\n\t\t}\n\n\t\tassert(\n\t\t\tthis.configuration.state !== \"disabled\",\n\t\t\t0x2eb /* \"Summary not supported with configuration disabled\" */,\n\t\t);\n\n\t\t// Cap the maximum amount of time client will wait for a summarize op ack to maxSummarizeAckWaitTime\n\t\t// configuration.maxAckWaitTime is composed from defaults, server values, and runtime overrides\n\n\t\tconst maxAckWaitTime = Math.min(this.configuration.maxAckWaitTime, maxSummarizeAckWaitTime);\n\n\t\tthis.pendingAckTimer = new PromiseTimer(maxAckWaitTime, () => {\n\t\t\t// Note: summarizeCount (from ChildLogger definition) may be 0,\n\t\t\t// since this code path is hit when RunningSummarizer first starts up,\n\t\t\t// before this instance has kicked off a new summarize run.\n\t\t\tthis.mc.logger.sendErrorEvent({\n\t\t\t\teventName: \"SummaryAckWaitTimeout\",\n\t\t\t\tmessage: \"Pending summary ack not received in time\",\n\t\t\t\tmaxAckWaitTime,\n\t\t\t\treferenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,\n\t\t\t\tsummarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,\n\t\t\t\ttimePending: Date.now() - this.heuristicData.lastAttempt.summaryTime,\n\t\t\t});\n\t\t});\n\t\t// Set up pending ack timeout by op timestamp differences for previous summaries.\n\t\tsummaryCollection.setPendingAckTimerTimeoutCallback(maxAckWaitTime, () => {\n\t\t\tif (this.pendingAckTimer.hasTimer) {\n\t\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"MissingSummaryAckFoundByOps\",\n\t\t\t\t\treferenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,\n\t\t\t\t\tsummarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,\n\t\t\t\t});\n\t\t\t\tthis.pendingAckTimer.clear();\n\t\t\t}\n\t\t});\n\n\t\tconst immediatelyRefreshLatestSummaryAck =\n\t\t\tthis.mc.config.getBoolean(\"Fluid.Summarizer.immediatelyRefreshLatestSummaryAck\") ??\n\t\t\ttrue;\n\t\tthis.generator = new SummaryGenerator(\n\t\t\tthis.pendingAckTimer,\n\t\t\tthis.heuristicData,\n\t\t\tthis.submitSummaryCallback,\n\t\t\t() => {\n\t\t\t\tthis.totalSuccessfulAttempts++;\n\t\t\t},\n\t\t\tasync (options: IRefreshSummaryAckOptions) => {\n\t\t\t\tif (immediatelyRefreshLatestSummaryAck) {\n\t\t\t\t\tawait this.refreshLatestSummaryAckAndHandleError(options);\n\t\t\t\t}\n\t\t\t},\n\t\t\tthis.summaryWatcher,\n\t\t\tthis.mc.logger,\n\t\t);\n\n\t\t// Listen to runtime for ops\n\t\tthis.runtimeListener = (op: ISequencedDocumentMessage, runtimeMessage?: boolean) => {\n\t\t\tthis.handleOp(op, runtimeMessage === true);\n\t\t};\n\t\tthis.runtime.on(\"op\", this.runtimeListener);\n\n\t\t// The max attempts for submit failures can be overridden via a feature flag. This allows us to\n\t\t// tweak this as per telemetry data until we arrive at a stable number.\n\t\t// If its set to a number higher than `defaultMaxAttemptsForSubmitFailures`, it will be ignored.\n\t\tconst overrideMaxAttempts = this.mc.config.getNumber(\n\t\t\t\"Fluid.Summarizer.AttemptsForSubmitFailures\",\n\t\t);\n\t\tthis.maxAttemptsForSubmitFailures =\n\t\t\toverrideMaxAttempts && overrideMaxAttempts < defaultMaxAttemptsForSubmitFailures\n\t\t\t\t? overrideMaxAttempts\n\t\t\t\t: defaultMaxAttemptsForSubmitFailures;\n\t}\n\n\tprivate async handleSummaryAck(ack: IAckedSummary) {\n\t\tconst refSequenceNumber = ack.summaryOp.referenceSequenceNumber;\n\t\tconst summaryLogger = this.tryGetCorrelatedLogger(refSequenceNumber) ?? this.mc.logger;\n\t\tconst summaryOpHandle = ack.summaryOp.contents.handle;\n\t\tconst summaryAckHandle = ack.summaryAck.contents.handle;\n\t\twhile (this.summarizingLock !== undefined) {\n\t\t\tsummaryLogger.sendTelemetryEvent({\n\t\t\t\teventName: \"RefreshAttemptWithSummarizerRunning\",\n\t\t\t\treferenceSequenceNumber: refSequenceNumber,\n\t\t\t\tproposalHandle: summaryOpHandle,\n\t\t\t\tackHandle: summaryAckHandle,\n\t\t\t});\n\t\t\tawait this.summarizingLock;\n\t\t}\n\n\t\t// Make sure we block any summarizer from being executed/enqueued while\n\t\t// executing the refreshLatestSummaryAck.\n\t\t// https://dev.azure.com/fluidframework/internal/_workitems/edit/779\n\t\tawait this.lockedSummaryAction(\n\t\t\t() => {},\n\t\t\tasync () => {\n\t\t\t\tconst options: IRefreshSummaryAckOptions = {\n\t\t\t\t\tproposalHandle: summaryOpHandle,\n\t\t\t\t\tackHandle: summaryAckHandle,\n\t\t\t\t\tsummaryRefSeq: refSequenceNumber,\n\t\t\t\t\tsummaryLogger,\n\t\t\t\t};\n\t\t\t\tawait this.refreshLatestSummaryAckAndHandleError(options);\n\t\t\t},\n\t\t\t() => {},\n\t\t);\n\t}\n\n\tprivate readonly refreshLatestSummaryAckAndHandleError = async (\n\t\toptions: IRefreshSummaryAckOptions,\n\t) => {\n\t\treturn this.refreshLatestSummaryAckCallback(options).catch(async (error) => {\n\t\t\t// If the error is 404, so maybe the fetched version no longer exists on server. We just\n\t\t\t// ignore this error in that case, as that means we will have another summaryAck for the\n\t\t\t// latest version with which we will refresh the state. However in case of single commit\n\t\t\t// summary, we might be missing a summary ack, so in that case we are still fine as the\n\t\t\t// code in `submitSummary` function in container runtime, will refresh the latest state\n\t\t\t// by calling `prefetchLatestSummaryThenClose`. We will load the next summarizer from the\n\t\t\t// updated state and be fine.\n\t\t\tconst isIgnoredError =\n\t\t\t\tisFluidError(error) &&\n\t\t\t\terror.errorType === DriverErrorTypes.fileNotFoundOrAccessDeniedError;\n\n\t\t\toptions.summaryLogger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: isIgnoredError\n\t\t\t\t\t\t? \"HandleSummaryAckErrorIgnored\"\n\t\t\t\t\t\t: \"HandleLastSummaryAckError\",\n\t\t\t\t\treferenceSequenceNumber: options.summaryRefSeq,\n\t\t\t\t\tproposalHandle: options.proposalHandle,\n\t\t\t\t\tackHandle: options.ackHandle,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t});\n\t};\n\n\t/**\n\t * Responsible for receiving and processing all the summary acks.\n\t * It starts processing ACKs after the one for the summary this client loaded from (initialSequenceNumber). Any\n\t * ACK before that is not interesting as it will simply be ignored.\n\t *\n\t * @param referenceSequenceNumber - The referenceSequenceNumber of the summary from which to start processing\n\t * acks.\n\t */\n\tprivate async processIncomingSummaryAcks(referenceSequenceNumber: number) {\n\t\t// Start waiting for acks that are for summaries newer that the one this client loaded from.\n\t\tlet nextReferenceSequenceNumber = referenceSequenceNumber;\n\t\twhile (!this.disposed) {\n\t\t\tconst ackedSummary = await this.summaryCollection.waitSummaryAck(\n\t\t\t\tnextReferenceSequenceNumber,\n\t\t\t);\n\t\t\tawait this.handleSummaryAck(ackedSummary);\n\t\t\tnextReferenceSequenceNumber = ackedSummary.summaryOp.referenceSequenceNumber + 1;\n\t\t}\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.runtime.off(\"op\", this.runtimeListener);\n\t\tthis.summaryWatcher.dispose();\n\t\tthis.heuristicRunner?.dispose();\n\t\tthis.heuristicRunner = undefined;\n\t\tthis.generator.dispose();\n\t\tthis.pendingAckTimer.clear();\n\t\tthis.disposeEnqueuedSummary();\n\t\tthis._disposed = true;\n\t\tthis.stopping = true;\n\t}\n\n\t/**\n\t * RunningSummarizer's logger includes the sequenced index of the current summary on each event.\n\t * If some other Summarizer code wants that event on their logs they can get it here,\n\t * but only if they're logging about that same summary.\n\t * @param summaryOpRefSeq - RefSeq number of the summary op, to ensure the log correlation will be correct\n\t */\n\tpublic tryGetCorrelatedLogger = (summaryOpRefSeq) =>\n\t\tthis.heuristicData.lastAttempt.refSequenceNumber === summaryOpRefSeq\n\t\t\t? this.mc.logger\n\t\t\t: undefined;\n\n\t/** We only want a single heuristic runner micro-task (will provide better optimized grouping of ops) */\n\tprivate heuristicRunnerMicroTaskExists = false;\n\n\tpublic handleOp(op: ISequencedDocumentMessage, runtimeMessage: boolean) {\n\t\tthis.heuristicData.lastOpSequenceNumber = op.sequenceNumber;\n\n\t\tif (runtimeMessage) {\n\t\t\tthis.heuristicData.numRuntimeOps++;\n\t\t} else {\n\t\t\tthis.heuristicData.numNonRuntimeOps++;\n\t\t}\n\n\t\tthis.heuristicData.totalOpsSize += opSize(op);\n\n\t\t// Check for enqueued on-demand summaries; Intentionally do nothing otherwise\n\t\tif (\n\t\t\tthis.initialized &&\n\t\t\tthis.opCanTriggerSummary(op, runtimeMessage) &&\n\t\t\t!this.tryRunEnqueuedSummary() &&\n\t\t\t!this.heuristicRunnerMicroTaskExists\n\t\t) {\n\t\t\tthis.heuristicRunnerMicroTaskExists = true;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\t\tPromise.resolve()\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.heuristicRunner?.run();\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.heuristicRunnerMicroTaskExists = false;\n\t\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Can the given op trigger a summary?\n\t * # Currently always prevents summaries for Summarize and SummaryAck/Nack ops\n\t * @param op - op to check\n\t * @returns true if this op can trigger a summary\n\t */\n\tprivate opCanTriggerSummary(op: ISequencedDocumentMessage, runtimeMessage: boolean): boolean {\n\t\tswitch (op.type) {\n\t\t\tcase MessageType.Summarize:\n\t\t\tcase MessageType.SummaryAck:\n\t\t\tcase MessageType.SummaryNack:\n\t\t\t\treturn false;\n\t\t\tdefault:\n\t\t\t\treturn runtimeMessage || this.nonRuntimeOpCanTriggerSummary();\n\t\t}\n\t}\n\n\tprivate nonRuntimeOpCanTriggerSummary(): boolean {\n\t\tconst opsSinceLastAck =\n\t\t\tthis.heuristicData.lastOpSequenceNumber -\n\t\t\tthis.heuristicData.lastSuccessfulSummary.refSequenceNumber;\n\t\treturn (\n\t\t\tthis.configuration.state === \"enabled\" &&\n\t\t\t(this.configuration.nonRuntimeHeuristicThreshold === undefined ||\n\t\t\t\tthis.configuration.nonRuntimeHeuristicThreshold <= opsSinceLastAck)\n\t\t);\n\t}\n\n\tpublic async waitStop(allowLastSummary: boolean): Promise<void> {\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.stopping = true;\n\n\t\tthis.disposeEnqueuedSummary();\n\n\t\t// This will try to run lastSummary if needed.\n\t\tif (allowLastSummary && this.heuristicRunner?.shouldRunLastSummary()) {\n\t\t\tif (this.summarizingLock === undefined) {\n\t\t\t\tthis.trySummarizeOnce(\n\t\t\t\t\t// summarizeProps\n\t\t\t\t\t{ summarizeReason: \"lastSummary\" },\n\t\t\t\t\t// ISummarizeOptions, using defaults: { refreshLatestAck: false, fullTree: false }\n\t\t\t\t\t{},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Note that trySummarizeOnce() call above returns right away, without waiting.\n\t\t// So we need to wait for its completion, otherwise it would be destroyed right away.\n\t\t// That said, if summary lock was taken upfront, this wait might wait on multiple retries to\n\t\t// submit summary. We should reconsider this flow and make summarizer move to exit faster.\n\t\t// This resolves when the current pending summary gets an ack or fails.\n\t\tawait this.summarizingLock;\n\t}\n\n\tprivate async waitStart() {\n\t\t// Wait no longer than ack timeout for all pending\n\t\tconst waitStartResult = await raceTimer(\n\t\t\tthis.summaryWatcher.waitFlushed(),\n\t\t\tthis.pendingAckTimer.start(),\n\t\t);\n\t\tthis.pendingAckTimer.clear();\n\n\t\t// Remove pending ack wait timeout by op timestamp comparison, because\n\t\t// it has race conditions with summaries submitted by this same client.\n\t\tthis.summaryCollection.unsetPendingAckTimerTimeoutCallback();\n\n\t\tif (waitStartResult.result === \"done\" && waitStartResult.value !== undefined) {\n\t\t\tthis.heuristicData.updateWithLastSummaryAckInfo({\n\t\t\t\trefSequenceNumber: waitStartResult.value.summaryOp.referenceSequenceNumber,\n\t\t\t\t// This will be the Summarizer starting point so only use timestamps from client's machine.\n\t\t\t\tsummaryTime: Date.now(),\n\t\t\t\tsummarySequenceNumber: waitStartResult.value.summaryOp.sequenceNumber,\n\t\t\t});\n\t\t}\n\t\tthis.initialized = true;\n\t}\n\n\tprivate beforeSummaryAction() {\n\t\tthis.summarizeCount++;\n\t}\n\n\tprivate afterSummaryAction() {\n\t\tconst retry = this.tryWhileSummarizing;\n\t\tthis.tryWhileSummarizing = false;\n\n\t\t// After summarizing, we should check to see if we need to summarize again.\n\t\t// Rerun the heuristics and check for enqueued summaries.\n\t\tif (!this.stopping && !this.tryRunEnqueuedSummary() && retry) {\n\t\t\tthis.heuristicRunner?.run();\n\t\t}\n\t}\n\n\t/**\n\t * Runs single summary action that prevents any other concurrent actions.\n\t * Assumes that caller checked upfront for lack of concurrent action (this.summarizingLock)\n\t * before calling this API. I.e. caller is responsible for either erroring out or waiting on this promise.\n\t * @param before - set of instructions to run before running the action.\n\t * @param action - action to perform.\n\t * @param after - set of instructions to run after running the action.\n\t * @returns The result of the action.\n\t */\n\tprivate async lockedSummaryAction<T>(\n\t\tbefore: () => void,\n\t\taction: () => Promise<T>,\n\t\tafter: () => void,\n\t) {\n\t\tassert(\n\t\t\tthis.summarizingLock === undefined,\n\t\t\t0x25b /* \"Caller is responsible for checking lock\" */,\n\t\t);\n\n\t\tconst summarizingLock = new Deferred<void>();\n\t\tthis.summarizingLock = summarizingLock.promise;\n\n\t\tbefore();\n\n\t\treturn action().finally(() => {\n\t\t\tsummarizingLock.resolve();\n\t\t\tthis.summarizingLock = undefined;\n\t\t\tafter();\n\t\t});\n\t}\n\n\t/**\n\t * Runs single summarize attempt\n\t * @param summarizeProps - props to log with each telemetry event associated with this attempt\n\t * @param options - summary options\n\t * @param cancellationToken - cancellation token to use to be able to cancel this summary, if needed\n\t * @param resultsBuilder - optional, result builder to use.\n\t * @returns ISummarizeResult - result of running a summary.\n\t */\n\tprivate trySummarizeOnce(\n\t\tsummarizeProps: ISummarizeTelemetryProperties,\n\t\toptions: ISummarizeOptions,\n\t\tresultsBuilder = new SummarizeResultBuilder(),\n\t): ISummarizeResults {\n\t\tthis.lockedSummaryAction(\n\t\t\t() => {\n\t\t\t\tthis.beforeSummaryAction();\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tconst summaryLogger = createChildLogger({\n\t\t\t\t\tlogger: this.mc.logger,\n\t\t\t\t\tproperties: { all: summarizeProps },\n\t\t\t\t});\n\t\t\t\tconst summaryOptions: ISubmitSummaryOptions = {\n\t\t\t\t\t...options,\n\t\t\t\t\tsummaryLogger,\n\t\t\t\t\tcancellationToken: this.cancellationToken,\n\t\t\t\t\tlatestSummaryRefSeqNum:\n\t\t\t\t\t\tthis.heuristicData.lastSuccessfulSummary.refSequenceNumber,\n\t\t\t\t};\n\t\t\t\tconst summarizeResult = this.generator.summarize(summaryOptions, resultsBuilder);\n\t\t\t\t// ensure we wait till the end of the process\n\t\t\t\tconst result = await summarizeResult.receivedSummaryAckOrNack;\n\t\t\t\tif (!result.success) {\n\t\t\t\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"SummarizeFailed\",\n\t\t\t\t\t\t\tmaxAttempts: 1,\n\t\t\t\t\t\t\tsummaryAttempts: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresult.error,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tthis.afterSummaryAction();\n\t\t\t},\n\t\t).catch((error) => {\n\t\t\t// SummaryGenerator.summarize() does not throw exceptions - it converts them to failed result\n\t\t\t// on resultsBuilder\n\t\t\t// We do not care about exceptions on receivedSummaryAckOrNack - caller should check results\n\t\t\t// and take a appropriate action.\n\t\t});\n\n\t\treturn resultsBuilder.build();\n\t}\n\n\t/** Heuristics summarize attempt. */\n\tprivate trySummarize(reason: SummarizeReason): void {\n\t\tif (this.summarizingLock !== undefined) {\n\t\t\t// lockedSummaryAction() will retry heuristic-based summary at the end of current attempt\n\t\t\t// if it's still needed\n\t\t\tthis.tryWhileSummarizing = true;\n\t\t\treturn;\n\t\t}\n\n\t\tthis.lockedSummaryAction(\n\t\t\t() => {\n\t\t\t\tthis.beforeSummaryAction();\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\treturn this.mc.config.getBoolean(\"Fluid.Summarizer.UseDynamicRetries\")\n\t\t\t\t\t? this.trySummarizeWithRetries(reason)\n\t\t\t\t\t: this.trySummarizeWithStaticAttempts(reason);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tthis.afterSummaryAction();\n\t\t\t},\n\t\t).catch((error) => {\n\t\t\tthis.mc.logger.sendErrorEvent({ eventName: \"UnexpectedSummarizeError\" }, error);\n\t\t});\n\t}\n\n\t/**\n\t * Tries to summarize 2 times with pre-defined summary options. If an attempt fails with \"retryAfterSeconds\"\n\t * param, that attempt is tried once more.\n\t */\n\tprivate async trySummarizeWithStaticAttempts(reason: SummarizeReason) {\n\t\tconst attemptOptions: ISummarizeOptions[] = [\n\t\t\t{ refreshLatestAck: false, fullTree: false },\n\t\t\t{ refreshLatestAck: true, fullTree: false },\n\t\t];\n\t\tlet summaryAttempts = 0;\n\t\tlet summaryAttemptsPerPhase = 0;\n\t\tlet summaryAttemptPhase = 0;\n\t\tlet error: any;\n\t\twhile (summaryAttemptPhase < attemptOptions.length) {\n\t\t\tif (this.cancellationToken.cancelled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// We only want to attempt 1 summary when reason is \"lastSummary\"\n\t\t\tif (++summaryAttempts > 1 && reason === \"lastSummary\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsummaryAttemptsPerPhase++;\n\n\t\t\tconst summarizeOptions = attemptOptions[summaryAttemptPhase];\n\t\t\tconst summarizeProps: ISummarizeTelemetryProperties = {\n\t\t\t\tsummarizeReason: reason,\n\t\t\t\tsummaryAttempts,\n\t\t\t\tsummaryAttemptsPerPhase,\n\t\t\t\tsummaryAttemptPhase: summaryAttemptPhase + 1, // make everything 1-based\n\t\t\t\t...summarizeOptions,\n\t\t\t};\n\t\t\tconst summaryLogger = createChildLogger({\n\t\t\t\tlogger: this.mc.logger,\n\t\t\t\tproperties: { all: summarizeProps },\n\t\t\t});\n\t\t\tconst summaryOptions: ISubmitSummaryOptions = {\n\t\t\t\t...summarizeOptions,\n\t\t\t\tsummaryLogger,\n\t\t\t\tcancellationToken: this.cancellationToken,\n\t\t\t\tlatestSummaryRefSeqNum: this.heuristicData.lastSuccessfulSummary.refSequenceNumber,\n\t\t\t};\n\n\t\t\t// Note: no need to account for cancellationToken.waitCancelled here, as\n\t\t\t// this is accounted SummaryGenerator.summarizeCore that controls receivedSummaryAckOrNack.\n\t\t\tconst resultSummarize = this.generator.summarize(summaryOptions);\n\t\t\tconst ackNackResult = await resultSummarize.receivedSummaryAckOrNack;\n\t\t\tif (ackNackResult.success) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\terror = ackNackResult.error;\n\n\t\t\t// Check for retryDelay that can come from summaryNack, upload summary or submit summary flows.\n\t\t\t// Retry the same step only once per retryAfter response.\n\t\t\tconst submitResult = await resultSummarize.summarySubmitted;\n\t\t\tconst delaySeconds = !submitResult.success\n\t\t\t\t? submitResult.data?.retryAfterSeconds\n\t\t\t\t: ackNackResult.data?.retryAfterSeconds;\n\t\t\tif (delaySeconds === undefined || summaryAttemptsPerPhase > 1) {\n\t\t\t\tsummaryAttemptPhase++;\n\t\t\t\tsummaryAttemptsPerPhase = 0;\n\t\t\t}\n\n\t\t\tif (delaySeconds !== undefined) {\n\t\t\t\tthis.mc.logger.sendPerformanceEvent({\n\t\t\t\t\teventName: \"SummarizeAttemptDelay\",\n\t\t\t\t\tduration: delaySeconds,\n\t\t\t\t\tsummaryNackDelay: ackNackResult.data?.retryAfterSeconds !== undefined,\n\t\t\t\t\t...summarizeProps,\n\t\t\t\t});\n\t\t\t\tawait delay(delaySeconds * 1000);\n\t\t\t}\n\t\t}\n\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t{\n\t\t\t\teventName: \"SummarizeFailed\",\n\t\t\t\tmaxAttempts: attemptOptions.length,\n\t\t\t\tsummaryAttempts: summaryAttemptPhase,\n\t\t\t},\n\t\t\terror,\n\t\t);\n\t\tthis.stopSummarizerCallback(\"failToSummarize\");\n\t}\n\n\t/**\n\t * Tries to summarize with retries where retry is based on the failure params.\n\t * For example, summarization may be retried for failures with \"retryAfterSeconds\" param.\n\t */\n\tprivate async trySummarizeWithRetries(\n\t\treason: SummarizeReason,\n\t): Promise<ISummarizeResults | undefined> {\n\t\t// Helper to set summarize options, telemetry properties and call summarize.\n\t\tconst attemptSummarize = (attemptNumber: number, finalAttempt: boolean) => {\n\t\t\tconst summarizeOptions: ISummarizeOptions = {\n\t\t\t\tfullTree: false,\n\t\t\t};\n\t\t\tconst summarizeProps: ISummarizeTelemetryProperties = {\n\t\t\t\tsummarizeReason: reason,\n\t\t\t\tsummaryAttempts: attemptNumber,\n\t\t\t\t...summarizeOptions,\n\t\t\t\tfinalAttempt,\n\t\t\t};\n\t\t\tconst summaryLogger = createChildLogger({\n\t\t\t\tlogger: this.mc.logger,\n\t\t\t\tproperties: { all: summarizeProps },\n\t\t\t});\n\t\t\tconst summaryOptions: ISubmitSummaryOptions = {\n\t\t\t\t...summarizeOptions,\n\t\t\t\tsummaryLogger,\n\t\t\t\tcancellationToken: this.cancellationToken,\n\t\t\t\tfinalAttempt,\n\t\t\t\tlatestSummaryRefSeqNum: this.heuristicData.lastSuccessfulSummary.refSequenceNumber,\n\t\t\t};\n\t\t\tconst summarizeResult = this.generator.summarize(summaryOptions);\n\t\t\treturn { summarizeProps, summarizeResult };\n\t\t};\n\n\t\t// The max number of attempts are based on the stage at which summarization failed. If it fails before it is\n\t\t// submitted, a different value is used compared to if it fails after submission. Usually, in the former case,\n\t\t// we would retry more often as its cheaper and retries are likely to succeed.\n\t\t// This makes it harder to predict how many attempts would actually happen as that depends on how far an attempt\n\t\t// made. To keep things simple, the max attempts is reset after every attempt based on where it failed. This may\n\t\t// result in some failures not being retried depending on what happened before this attempt. That's fine because\n\t\t// such scenarios are very unlikely and even if it happens, it would resolve when a new summarizer starts over.\n\t\t// For example - When failure switches from one the submit failures to nack failure, only one more retry will\n\t\t// happen irrespective of the value of `defaultMaxAttempts`.\n\t\tlet maxAttempts = defaultMaxAttempts;\n\t\tlet currentAttempt = 0;\n\t\tlet retryAfterSeconds: number | undefined;\n\t\tlet done = false;\n\t\tlet status: \"success\" | \"failure\" | \"canceled\" = \"success\";\n\t\tlet results: ISummarizeResults | undefined;\n\t\tlet error: any;\n\t\tdo {\n\t\t\tcurrentAttempt++;\n\t\t\tif (this.cancellationToken.cancelled) {\n\t\t\t\tstatus = \"canceled\";\n\t\t\t\tdone = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst attemptResult = attemptSummarize(currentAttempt, false /* finalAttempt */);\n\t\t\tresults = attemptResult.summarizeResult;\n\n\t\t\t// Ack / nack is the final step, so if it succeeds we're done.\n\t\t\tconst ackNackResult = await results.receivedSummaryAckOrNack;\n\t\t\tif (ackNackResult.success) {\n\t\t\t\tstatus = \"success\";\n\t\t\t\tdone = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Update max attempts and retry params from the failure result.\n\t\t\t// If submit summary failed, use the params from \"summarySubmitted\" result. Else, use the params\n\t\t\t// from \"receivedSummaryAckOrNack\" result.\n\t\t\t// Note: Check \"summarySubmitted\" result first because if it fails, ack nack would fail as well.\n\t\t\tconst submitSummaryResult = await results.summarySubmitted;\n\t\t\tif (!submitSummaryResult.success) {\n\t\t\t\tmaxAttempts = this.maxAttemptsForSubmitFailures;\n\t\t\t\tretryAfterSeconds = submitSummaryResult.data?.retryAfterSeconds;\n\t\t\t} else {\n\t\t\t\tmaxAttempts = defaultMaxAttempts;\n\t\t\t\tretryAfterSeconds = ackNackResult.data?.retryAfterSeconds;\n\t\t\t}\n\n\t\t\t// Emit \"summarize\" event for this failed attempt.\n\t\t\tstatus = \"failure\";\n\t\t\terror = ackNackResult.error;\n\t\t\tconst eventProps: ISummarizeEventProps = {\n\t\t\t\tresult: status,\n\t\t\t\tcurrentAttempt,\n\t\t\t\tmaxAttempts,\n\t\t\t\terror,\n\t\t\t};\n\t\t\tthis.emit(\"summarize\", eventProps);\n\n\t\t\t// If the failure doesn't have \"retryAfterSeconds\" or the max number of attempts have been done, we're done.\n\t\t\tif (retryAfterSeconds === undefined || currentAttempt >= maxAttempts - 1) {\n\t\t\t\tdone = true;\n\t\t\t}\n\n\t\t\t// If the failure has \"retryAfterSeconds\", add a delay of that time. In this case, a final attempt will\n\t\t\t// take place and we need to wait for \"retryAfterSeconds\" before that.\n\t\t\tif (retryAfterSeconds !== undefined) {\n\t\t\t\tthis.mc.logger.sendPerformanceEvent({\n\t\t\t\t\teventName: \"SummarizeAttemptDelay\",\n\t\t\t\t\tduration: retryAfterSeconds,\n\t\t\t\t\tsummaryNackDelay: ackNackResult.data?.retryAfterSeconds !== undefined,\n\t\t\t\t\tstage: submitSummaryResult.data?.stage,\n\t\t\t\t\tdynamicRetries: true, // To differentiate this telemetry from regular retry logic\n\t\t\t\t\t...attemptResult.summarizeProps,\n\t\t\t\t});\n\t\t\t\tawait delay(retryAfterSeconds * 1000);\n\t\t\t}\n\t\t} while (!done);\n\n\t\t// If summarize attempt did not fail, emit \"summarize\" event and return. A failed attempt may be retried below.\n\t\tif (status !== \"failure\") {\n\t\t\tthis.emit(\"summarize\", { result: status, currentAttempt, maxAttempts });\n\t\t\treturn results;\n\t\t}\n\n\t\t// If summarization wasn't successful above and the failure contains \"retryAfterSeconds\", perform one last\n\t\t// attempt. This gives a chance to the runtime to perform additional steps in the last attempt.\n\t\tif (retryAfterSeconds !== undefined) {\n\t\t\tconst { summarizeResult } = attemptSummarize(++currentAttempt, true /* finalAttempt */);\n\t\t\t// Ack / nack is the final step, so if it succeeds we're done.\n\t\t\tconst ackNackResult = await summarizeResult.receivedSummaryAckOrNack;\n\t\t\tstatus = ackNackResult.success ? \"success\" : \"failure\";\n\t\t\tif (!ackNackResult.success) {\n\t\t\t\terror = ackNackResult.error;\n\t\t\t}\n\t\t\tconst eventProps: ISummarizeEventProps = {\n\t\t\t\tresult: status,\n\t\t\t\tcurrentAttempt,\n\t\t\t\tmaxAttempts,\n\t\t\t\terror: ackNackResult.success ? undefined : ackNackResult.error,\n\t\t\t};\n\t\t\tthis.emit(\"summarize\", eventProps);\n\t\t\tresults = summarizeResult;\n\t\t}\n\n\t\t// If summarization is still unsuccessful, stop the summarizer.\n\t\tif (status === \"failure\") {\n\t\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"SummarizeFailed\",\n\t\t\t\t\tmaxAttempts,\n\t\t\t\t\tsummaryAttempts: currentAttempt,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t\tthis.stopSummarizerCallback(\"failToSummarize\");\n\t\t}\n\t\treturn results;\n\t}\n\n\t/**\n\t * Attempts to generate a summary on demand with retries in case of failures. The retry logic is the same\n\t * as heuristics based summaries.\n\t */\n\tprivate async summarizeOnDemandWithRetries(\n\t\treason: SummarizeReason,\n\t\tresultsBuilder: SummarizeResultBuilder,\n\t) {\n\t\tconst results = await this.trySummarizeWithRetries(reason);\n\t\tif (results === undefined) {\n\t\t\tresultsBuilder.fail(\"Summarization was canceled\", undefined);\n\t\t\treturn resultsBuilder.build();\n\t\t}\n\t\tconst submitResult = await results.summarySubmitted;\n\t\tconst summaryOpBroadcastedResult = await results.summaryOpBroadcasted;\n\t\tconst ackNackResult = await results.receivedSummaryAckOrNack;\n\t\tresultsBuilder.summarySubmitted.resolve(submitResult);\n\t\tresultsBuilder.summaryOpBroadcasted.resolve(summaryOpBroadcastedResult);\n\t\tresultsBuilder.receivedSummaryAckOrNack.resolve(ackNackResult);\n\t\treturn resultsBuilder.build();\n\t}\n\n\t/** {@inheritdoc (ISummarizer:interface).summarizeOnDemand} */\n\tpublic summarizeOnDemand(\n\t\toptions: IOnDemandSummarizeOptions,\n\t\tresultsBuilder: SummarizeResultBuilder = new SummarizeResultBuilder(),\n\t): ISummarizeResults {\n\t\tif (this.stopping) {\n\t\t\tresultsBuilder.fail(\"RunningSummarizer stopped or disposed\", undefined);\n\t\t\treturn resultsBuilder.build();\n\t\t}\n\t\t// Check for concurrent summary attempts. If one is found,\n\t\t// return a promise that caller can await before trying again.\n\t\tif (this.summarizingLock !== undefined) {\n\t\t\t// The heuristics are blocking concurrent summarize attempts.\n\t\t\tthrow new UsageError(\"Attempted to run an already-running summarizer on demand\");\n\t\t}\n\n\t\tconst { reason, ...summarizeOptions } = options;\n\t\tif (options.retryOnFailure === true) {\n\t\t\tthis.summarizeOnDemandWithRetries(`onDemand;${reason}`, resultsBuilder).catch(\n\t\t\t\t(error) => {\n\t\t\t\t\tresultsBuilder.fail(\"summarize failed\", error);\n\t\t\t\t},\n\t\t\t);\n\t\t} else {\n\t\t\tthis.trySummarizeOnce(\n\t\t\t\t{ summarizeReason: `onDemand/${reason}` },\n\t\t\t\tsummarizeOptions,\n\t\t\t\tresultsBuilder,\n\t\t\t);\n\t\t}\n\t\treturn resultsBuilder.build();\n\t}\n\n\t/** {@inheritdoc (ISummarizer:interface).enqueueSummarize} */\n\tpublic enqueueSummarize(options: IEnqueueSummarizeOptions): EnqueueSummarizeResult {\n\t\tconst { reason, afterSequenceNumber = 0, override = false, ...summarizeOptions } = options;\n\t\tlet overridden = false;\n\t\tif (this.enqueuedSummary !== undefined) {\n\t\t\tif (!override) {\n\t\t\t\treturn { alreadyEnqueued: true };\n\t\t\t}\n\t\t\t// Override existing enqueued summarize attempt.\n\t\t\tthis.enqueuedSummary.resultsBuilder.fail(\n\t\t\t\t\"Aborted; overridden by another enqueue summarize attempt\",\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tthis.enqueuedSummary = undefined;\n\t\t\toverridden = true;\n\t\t}\n\n\t\tthis.enqueuedSummary = {\n\t\t\treason: `enqueue;${reason}`,\n\t\t\tafterSequenceNumber,\n\t\t\tsummarizeOptions,\n\t\t\tresultsBuilder: new SummarizeResultBuilder(),\n\t\t};\n\t\tconst results = this.enqueuedSummary.resultsBuilder.build();\n\t\tthis.tryRunEnqueuedSummary();\n\t\treturn overridden\n\t\t\t? {\n\t\t\t\t\t...results,\n\t\t\t\t\talreadyEnqueued: true,\n\t\t\t\t\toverridden: true,\n\t\t\t }\n\t\t\t: results;\n\t}\n\n\tprivate tryRunEnqueuedSummary() {\n\t\tif (this.stopping) {\n\t\t\tthis.disposeEnqueuedSummary();\n\t\t\treturn false;\n\t\t}\n\t\tif (\n\t\t\tthis.enqueuedSummary === undefined ||\n\t\t\tthis.heuristicData.lastOpSequenceNumber < this.enqueuedSummary.afterSequenceNumber ||\n\t\t\tthis.summarizingLock !== undefined\n\t\t) {\n\t\t\t// If no enqueued summary is ready or a summary is already in progress, take no action.\n\t\t\treturn false;\n\t\t}\n\t\tconst { reason, resultsBuilder, summarizeOptions } = this.enqueuedSummary;\n\t\t// Set to undefined first, so that subsequent enqueue attempt while summarize will occur later.\n\t\tthis.enqueuedSummary = undefined;\n\t\tthis.trySummarizeOnce(\n\t\t\t{ summarizeReason: `enqueuedSummary/${reason}` },\n\t\t\tsummarizeOptions,\n\t\t\tresultsBuilder,\n\t\t);\n\t\treturn true;\n\t}\n\n\tprivate disposeEnqueuedSummary() {\n\t\tif (this.enqueuedSummary !== undefined) {\n\t\t\tthis.enqueuedSummary.resultsBuilder.fail(\n\t\t\t\t\"RunningSummarizer stopped or disposed\",\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tthis.enqueuedSummary = undefined;\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"runningSummarizer.js","sourceRoot":"","sources":["../../src/summary/runningSummarizer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAiE;AAEjE,kEAA4F;AAC5F,0EAA+E;AAC/E,+EAA8F;AAC9F,uEAMkD;AAGlD,wDAA4C;AAE5C,uEAAqE;AAsBrE,+DAM+B;AAE/B,MAAM,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAE7D;;;GAGG;AACU,QAAA,kBAAkB,GAAG,CAAC,CAAC;AACpC;;;GAGG;AACU,QAAA,mCAAmC,GAAG,CAAC,CAAC;AAErD;;;;;;GAMG;AACH,MAAa,iBAAkB,SAAQ,gCAAoC;IACnE,MAAM,CAAC,KAAK,CAAC,KAAK,CACxB,MAA4B,EAC5B,cAAqC,EACrC,aAAoC,EACpC,qBAAuF,EACvF,+BAAsF,EACtF,aAAsC,EACtC,iBAAoC,EACpC,iBAA4C,EAC5C,sBAA8D,EAC9D,OAA2B;QAE3B,MAAM,UAAU,GAAG,IAAI,iBAAiB,CACvC,MAAM,EACN,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,+BAA+B,EAC/B,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,OAAO,CACP,CAAC;QAEF,wGAAwG;QACxG,yEAAyE;QACzE,yGAAyG;QACzG,0GAA0G;QAC1G,qDAAqD;QACrD,IAAI,2BAA2B,GAAG,OAAO,CAAC,YAAY,CAAC,qBAAqB,GAAG,CAAC,CAAC;QACjF,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC;QAC9C,IACC,SAAS,KAAK,SAAS;YACvB,SAAS,CAAC,SAAS,CAAC,uBAAuB,IAAI,2BAA2B,EACzE,CAAC;YACF,MAAM,UAAU,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAC7C,2BAA2B,GAAG,SAAS,CAAC,SAAS,CAAC,uBAAuB,GAAG,CAAC,CAAC;QAC/E,CAAC;QAED,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC;QAE7B,sCAAsC;QACtC,sGAAsG;QACtG,UAAU,CAAC,0BAA0B,CAAC,2BAA2B,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAClF,IAAA,4BAAiB,EAAC,EAAE,MAAM,EAAE,CAAC,CAAC,cAAc,CAC3C,EAAE,SAAS,EAAE,4BAA4B,EAAE,EAC3C,KAAK,CACL,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,0BAA0B;QAC1B,+FAA+F;QAC/F,uCAAuC;QACvC,yGAAyG;QACzG,wFAAwF;QACxF,6GAA6G;QAC7G,MAAM,IAAI,GACT,OAAO,CAAC,YAAY,CAAC,kBAAkB;YACvC,CAAC,aAAa,CAAC,qBAAqB,CAAC,iBAAiB;gBACrD,aAAa,CAAC,gBAAgB;gBAC9B,aAAa,CAAC,aAAa,CAAC,CAAC;QAC/B,aAAa,CAAC,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC;QAE1C,IAAI,aAAa,CAAC,gBAAgB,EAAE,CAAC;YACpC,8DAA8D;YAC9D,aAAa,CAAC,gBAAgB,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;YACtD,aAAa,CAAC,aAAa,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACrD,CAAC;QAED,+EAA+E;QAC/E,aAAa,CAAC,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,kBAAkB,CAAC;QAE7E,mBAAmB;QACnB,UAAU,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC;QACpC,UAAU,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC;QAElC,OAAO,UAAU,CAAC;IACnB,CAAC;IAED,IAAW,QAAQ;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IA2BD,YACC,UAAgC,EACf,cAAqC,EACrC,aAAoC,EACpC,qBAEgB,EAChB,+BAEC,EACD,aAAsC,EACtC,iBAAoC,EACpC,iBAA4C,EAC5C,sBAA8D,EAC9D,OAA2B;QAE5C,KAAK,EAAE,CAAC;QAdS,mBAAc,GAAd,cAAc,CAAuB;QACrC,kBAAa,GAAb,aAAa,CAAuB;QACpC,0BAAqB,GAArB,qBAAqB,CAEL;QAChB,oCAA+B,GAA/B,+BAA+B,CAE9B;QACD,kBAAa,GAAb,aAAa,CAAyB;QACtC,sBAAiB,GAAjB,iBAAiB,CAAmB;QACpC,sBAAiB,GAAjB,iBAAiB,CAA2B;QAC5C,2BAAsB,GAAtB,sBAAsB,CAAwC;QAC9D,YAAO,GAAP,OAAO,CAAoB;QAxCrC,aAAQ,GAAG,KAAK,CAAC;QACjB,cAAS,GAAG,KAAK,CAAC;QAElB,wBAAmB,GAAG,KAAK,CAAC;QAc5B,mBAAc,GAAG,CAAC,CAAC;QACnB,4BAAuB,GAAG,CAAC,CAAC;QAC5B,gBAAW,GAAG,KAAK,CAAC;QA4JX,0CAAqC,GAAG,KAAK,EAC7D,OAAkC,EACjC,EAAE;YACH,OAAO,IAAI,CAAC,+BAA+B,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBAC1E,wFAAwF;gBACxF,wFAAwF;gBACxF,wFAAwF;gBACxF,uFAAuF;gBACvF,uFAAuF;gBACvF,yFAAyF;gBACzF,6BAA6B;gBAC7B,MAAM,cAAc,GACnB,IAAA,uBAAY,EAAC,KAAK,CAAC;oBACnB,KAAK,CAAC,SAAS,KAAK,2BAAgB,CAAC,+BAA+B,CAAC;gBAEtE,OAAO,CAAC,aAAa,CAAC,kBAAkB,CACvC;oBACC,SAAS,EAAE,cAAc;wBACxB,CAAC,CAAC,8BAA8B;wBAChC,CAAC,CAAC,2BAA2B;oBAC9B,uBAAuB,EAAE,OAAO,CAAC,aAAa;oBAC9C,cAAc,EAAE,OAAO,CAAC,cAAc;oBACtC,SAAS,EAAE,OAAO,CAAC,SAAS;iBAC5B,EACD,KAAK,CACL,CAAC;YACH,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC;QAkCF;;;;;WAKG;QACI,2BAAsB,GAAG,CAAC,eAAe,EAAE,EAAE,CACnD,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,iBAAiB,KAAK,eAAe;YACnE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM;YAChB,CAAC,CAAC,SAAS,CAAC;QAEd,wGAAwG;QAChG,mCAA8B,GAAG,KAAK,CAAC;QA5M9C,MAAM,cAAc,GAA8B;YACjD,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc;YACzC,4BAA4B,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,uBAAuB;SAChE,CAAC;QAEF,IAAI,CAAC,EAAE,GAAG,IAAA,uCAA4B,EAAC;YACtC,MAAM,EAAE,UAAU;YAClB,SAAS,EAAE,SAAS;YACpB,UAAU,EAAE;gBACX,GAAG,EAAE,cAAc;aACnB;SACD,CAAC,CAAC;QAEH,IAAI,aAAa,CAAC,KAAK,KAAK,mBAAmB,EAAE,CAAC;YACjD,IAAA,iBAAM,EACL,IAAI,CAAC,aAAa,CAAC,KAAK,KAAK,SAAS,EACtC,KAAK,CAAC,6CAA6C,CACnD,CAAC;YACF,IAAI,CAAC,eAAe,GAAG,IAAI,kDAAwB,CAClD,aAAa,EACb,IAAI,CAAC,aAAa,EAClB,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EACrC,IAAI,CAAC,EAAE,CAAC,MAAM,CACd,CAAC;QACH,CAAC;QAED,IAAA,iBAAM,EACL,IAAI,CAAC,aAAa,CAAC,KAAK,KAAK,UAAU,EACvC,KAAK,CAAC,yDAAyD,CAC/D,CAAC;QAEF,oGAAoG;QACpG,+FAA+F;QAE/F,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE,uBAAuB,CAAC,CAAC;QAE5F,IAAI,CAAC,eAAe,GAAG,IAAI,uBAAY,CAAC,cAAc,EAAE,GAAG,EAAE;YAC5D,+DAA+D;YAC/D,sEAAsE;YACtE,2DAA2D;YAC3D,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC;gBAC7B,SAAS,EAAE,uBAAuB;gBAClC,OAAO,EAAE,0CAA0C;gBACnD,cAAc;gBACd,uBAAuB,EAAE,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,iBAAiB;gBACzE,qBAAqB,EAAE,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,qBAAqB;gBAC3E,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,WAAW;aACpE,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,iFAAiF;QACjF,iBAAiB,CAAC,iCAAiC,CAAC,cAAc,EAAE,GAAG,EAAE;YACxE,IAAI,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC;gBACnC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC;oBACjC,SAAS,EAAE,6BAA6B;oBACxC,uBAAuB,EAAE,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,iBAAiB;oBACzE,qBAAqB,EAAE,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,qBAAqB;iBAC3E,CAAC,CAAC;gBACH,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAC9B,CAAC;QACF,CAAC,CAAC,CAAC;QAEH,MAAM,kCAAkC,GACvC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,qDAAqD,CAAC;YAChF,IAAI,CAAC;QACN,IAAI,CAAC,SAAS,GAAG,IAAI,sCAAgB,CACpC,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,qBAAqB,EAC1B,GAAG,EAAE;YACJ,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAChC,CAAC,EACD,KAAK,EAAE,OAAkC,EAAE,EAAE;YAC5C,IAAI,kCAAkC,EAAE,CAAC;gBACxC,MAAM,IAAI,CAAC,qCAAqC,CAAC,OAAO,CAAC,CAAC;YAC3D,CAAC;QACF,CAAC,EACD,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,EAAE,CAAC,MAAM,CACd,CAAC;QAEF,4BAA4B;QAC5B,IAAI,CAAC,eAAe,GAAG,CAAC,EAA6B,EAAE,cAAwB,EAAE,EAAE;YAClF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,cAAc,KAAK,IAAI,CAAC,CAAC;QAC5C,CAAC,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAE5C,+FAA+F;QAC/F,uEAAuE;QACvE,gGAAgG;QAChG,MAAM,mBAAmB,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CACnD,4CAA4C,CAC5C,CAAC;QACF,IAAI,CAAC,4BAA4B;YAChC,mBAAmB,IAAI,mBAAmB,GAAG,2CAAmC;gBAC/E,CAAC,CAAC,mBAAmB;gBACrB,CAAC,CAAC,2CAAmC,CAAC;IACzC,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,GAAkB;QAChD,MAAM,iBAAiB,GAAG,GAAG,CAAC,SAAS,CAAC,uBAAuB,CAAC;QAChE,MAAM,aAAa,GAAG,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;QACvF,MAAM,eAAe,GAAG,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;QACtD,MAAM,gBAAgB,GAAG,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC;QACxD,OAAO,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YAC3C,aAAa,CAAC,kBAAkB,CAAC;gBAChC,SAAS,EAAE,qCAAqC;gBAChD,uBAAuB,EAAE,iBAAiB;gBAC1C,cAAc,EAAE,eAAe;gBAC/B,SAAS,EAAE,gBAAgB;aAC3B,CAAC,CAAC;YACH,MAAM,IAAI,CAAC,eAAe,CAAC;QAC5B,CAAC;QAED,uEAAuE;QACvE,yCAAyC;QACzC,oEAAoE;QACpE,MAAM,IAAI,CAAC,mBAAmB,CAC7B,GAAG,EAAE,GAAE,CAAC,EACR,KAAK,IAAI,EAAE;YACV,MAAM,OAAO,GAA8B;gBAC1C,cAAc,EAAE,eAAe;gBAC/B,SAAS,EAAE,gBAAgB;gBAC3B,aAAa,EAAE,iBAAiB;gBAChC,aAAa;aACb,CAAC;YACF,MAAM,IAAI,CAAC,qCAAqC,CAAC,OAAO,CAAC,CAAC;QAC3D,CAAC,EACD,GAAG,EAAE,GAAE,CAAC,CACR,CAAC;IACH,CAAC;IA+BD;;;;;;;OAOG;IACK,KAAK,CAAC,0BAA0B,CAAC,uBAA+B;QACvE,4FAA4F;QAC5F,IAAI,2BAA2B,GAAG,uBAAuB,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAC/D,2BAA2B,CAC3B,CAAC;YACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;YAC1C,2BAA2B,GAAG,YAAY,CAAC,SAAS,CAAC,uBAAuB,GAAG,CAAC,CAAC;QAClF,CAAC;IACF,CAAC;IAEM,OAAO;QACb,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC7C,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC,eAAe,EAAE,OAAO,EAAE,CAAC;QAChC,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACtB,CAAC;IAgBM,QAAQ,CAAC,EAA6B,EAAE,cAAuB;QACrE,IAAI,CAAC,aAAa,CAAC,oBAAoB,GAAG,EAAE,CAAC,cAAc,CAAC;QAE5D,IAAI,cAAc,EAAE,CAAC;YACpB,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;QACpC,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE,CAAC;QACvC,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,YAAY,IAAI,IAAA,wBAAM,EAAC,EAAE,CAAC,CAAC;QAE9C,6EAA6E;QAC7E,IACC,IAAI,CAAC,WAAW;YAChB,IAAI,CAAC,mBAAmB,CAAC,EAAE,EAAE,cAAc,CAAC;YAC5C,CAAC,IAAI,CAAC,qBAAqB,EAAE;YAC7B,CAAC,IAAI,CAAC,8BAA8B,EACnC,CAAC;YACF,IAAI,CAAC,8BAA8B,GAAG,IAAI,CAAC;YAC3C,mEAAmE;YACnE,OAAO,CAAC,OAAO,EAAE;iBACf,IAAI,CAAC,GAAG,EAAE;gBACV,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC;YAC7B,CAAC,CAAC;iBACD,OAAO,CAAC,GAAG,EAAE;gBACb,IAAI,CAAC,8BAA8B,GAAG,KAAK,CAAC;YAC7C,CAAC,CAAC,CAAC;QACL,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACK,mBAAmB,CAAC,EAA6B,EAAE,cAAuB;QACjF,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,kCAAW,CAAC,SAAS,CAAC;YAC3B,KAAK,kCAAW,CAAC,UAAU,CAAC;YAC5B,KAAK,kCAAW,CAAC,WAAW;gBAC3B,OAAO,KAAK,CAAC;YACd;gBACC,OAAO,cAAc,IAAI,IAAI,CAAC,6BAA6B,EAAE,CAAC;QAChE,CAAC;IACF,CAAC;IAEO,6BAA6B;QACpC,MAAM,eAAe,GACpB,IAAI,CAAC,aAAa,CAAC,oBAAoB;YACvC,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,iBAAiB,CAAC;QAC5D,OAAO,CACN,IAAI,CAAC,aAAa,CAAC,KAAK,KAAK,SAAS;YACtC,CAAC,IAAI,CAAC,aAAa,CAAC,4BAA4B,KAAK,SAAS;gBAC7D,IAAI,CAAC,aAAa,CAAC,4BAA4B,IAAI,eAAe,CAAC,CACpE,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,gBAAyB;QAC9C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO;QACR,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAE9B,8CAA8C;QAC9C,IAAI,gBAAgB,IAAI,IAAI,CAAC,eAAe,EAAE,oBAAoB,EAAE,EAAE,CAAC;YACtE,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;gBACxC,IAAI,CAAC,gBAAgB;gBACpB,iBAAiB;gBACjB,EAAE,eAAe,EAAE,aAAa,EAAE,EAClC,EAAE,CACF,CAAC;YACH,CAAC;QACF,CAAC;QAED,+EAA+E;QAC/E,qFAAqF;QACrF,6FAA6F;QAC7F,0FAA0F;QAC1F,uEAAuE;QACvE,MAAM,IAAI,CAAC,eAAe,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,SAAS;QACtB,kDAAkD;QAClD,MAAM,eAAe,GAAG,MAAM,IAAA,+BAAS,EACtC,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,EACjC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAC5B,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAE7B,sEAAsE;QACtE,uEAAuE;QACvE,IAAI,CAAC,iBAAiB,CAAC,mCAAmC,EAAE,CAAC;QAE7D,IAAI,eAAe,CAAC,MAAM,KAAK,MAAM,IAAI,eAAe,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9E,IAAI,CAAC,aAAa,CAAC,4BAA4B,CAAC;gBAC/C,iBAAiB,EAAE,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC,uBAAuB;gBAC1E,2FAA2F;gBAC3F,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;gBACvB,qBAAqB,EAAE,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC,cAAc;aACrE,CAAC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IACzB,CAAC;IAEO,mBAAmB;QAC1B,IAAI,CAAC,cAAc,EAAE,CAAC;IACvB,CAAC;IAEO,kBAAkB;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC;QACvC,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC;QAEjC,2EAA2E;QAC3E,yDAAyD;QACzD,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,IAAI,KAAK,EAAE,CAAC;YAC9D,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC;QAC7B,CAAC;IACF,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK,CAAC,mBAAmB,CAChC,MAAkB,EAClB,MAAwB,EACxB,KAAiB;QAEjB,IAAA,iBAAM,EACL,IAAI,CAAC,eAAe,KAAK,SAAS,EAClC,KAAK,CAAC,+CAA+C,CACrD,CAAC;QAEF,MAAM,eAAe,GAAG,IAAI,mBAAQ,EAAQ,CAAC;QAC7C,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC,OAAO,CAAC;QAE/C,MAAM,EAAE,CAAC;QAET,OAAO,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YAC5B,eAAe,CAAC,OAAO,EAAE,CAAC;YAC1B,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;YACjC,KAAK,EAAE,CAAC;QACT,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACK,gBAAgB,CACvB,cAA6C,EAC7C,OAA0B,EAC1B,cAAc,GAAG,IAAI,4CAAsB,EAAE;QAE7C,IAAI,CAAC,mBAAmB,CACvB,GAAG,EAAE;YACJ,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC5B,CAAC,EACD,KAAK,IAAI,EAAE;YACV,MAAM,aAAa,GAAG,IAAA,4BAAiB,EAAC;gBACvC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM;gBACtB,UAAU,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE;aACnC,CAAC,CAAC;YACH,MAAM,cAAc,GAA0B;gBAC7C,GAAG,OAAO;gBACV,aAAa;gBACb,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;gBACzC,sBAAsB,EACrB,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,iBAAiB;aAC3D,CAAC;YACF,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;YACjF,6CAA6C;YAC7C,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,wBAAwB,CAAC;YAC9D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrB,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,cAAc,CAC5B;oBACC,SAAS,EAAE,iBAAiB;oBAC5B,WAAW,EAAE,CAAC;oBACd,eAAe,EAAE,CAAC;iBAClB,EACD,MAAM,CAAC,KAAK,CACZ,CAAC;YACH,CAAC;QACF,CAAC,EACD,GAAG,EAAE;YACJ,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC3B,CAAC,CACD,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACjB,6FAA6F;YAC7F,oBAAoB;YACpB,4FAA4F;YAC5F,iCAAiC;QAClC,CAAC,CAAC,CAAC;QAEH,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED,oCAAoC;IAC5B,YAAY,CAAC,MAAuB;QAC3C,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACxC,yFAAyF;YACzF,uBAAuB;YACvB,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;YAChC,OAAO;QACR,CAAC;QAED,IAAI,CAAC,mBAAmB,CACvB,GAAG,EAAE;YACJ,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC5B,CAAC,EACD,KAAK,IAAI,EAAE;YACV,OAAO,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;QAC7C,CAAC,EACD,GAAG,EAAE;YACJ,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC3B,CAAC,CACD,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACjB,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,0BAA0B,EAAE,EAAE,KAAK,CAAC,CAAC;QACjF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,uBAAuB,CACpC,MAAuB;QAEvB,4EAA4E;QAC5E,MAAM,gBAAgB,GAAG,CAAC,aAAqB,EAAE,YAAqB,EAAE,EAAE;YACzE,MAAM,gBAAgB,GAAsB;gBAC3C,QAAQ,EAAE,KAAK;aACf,CAAC;YACF,MAAM,cAAc,GAAkC;gBACrD,eAAe,EAAE,MAAM;gBACvB,eAAe,EAAE,aAAa;gBAC9B,GAAG,gBAAgB;gBACnB,YAAY;aACZ,CAAC;YACF,MAAM,aAAa,GAAG,IAAA,4BAAiB,EAAC;gBACvC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM;gBACtB,UAAU,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE;aACnC,CAAC,CAAC;YACH,MAAM,cAAc,GAA0B;gBAC7C,GAAG,gBAAgB;gBACnB,aAAa;gBACb,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;gBACzC,YAAY;gBACZ,sBAAsB,EAAE,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,iBAAiB;aAClF,CAAC;YACF,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;YACjE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC;QAC5C,CAAC,CAAC;QAEF,4GAA4G;QAC5G,8GAA8G;QAC9G,8EAA8E;QAC9E,gHAAgH;QAChH,gHAAgH;QAChH,gHAAgH;QAChH,+GAA+G;QAC/G,6GAA6G;QAC7G,4DAA4D;QAC5D,IAAI,WAAW,GAAG,0BAAkB,CAAC;QACrC,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,IAAI,iBAAqC,CAAC;QAC1C,IAAI,IAAI,GAAG,KAAK,CAAC;QACjB,IAAI,MAAM,GAAuC,SAAS,CAAC;QAC3D,IAAI,OAAsC,CAAC;QAC3C,IAAI,KAAyC,CAAC;QAC9C,GAAG,CAAC;YACH,cAAc,EAAE,CAAC;YACjB,IAAI,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,CAAC;gBACtC,MAAM,GAAG,UAAU,CAAC;gBACpB,IAAI,GAAG,IAAI,CAAC;gBACZ,MAAM;YACP,CAAC;YAED,MAAM,aAAa,GAAG,gBAAgB,CAAC,cAAc,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;YACjF,OAAO,GAAG,aAAa,CAAC,eAAe,CAAC;YAExC,8DAA8D;YAC9D,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,wBAAwB,CAAC;YAC7D,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;gBAC3B,MAAM,GAAG,SAAS,CAAC;gBACnB,IAAI,GAAG,IAAI,CAAC;gBACZ,MAAM;YACP,CAAC;YAED,+CAA+C;YAC/C,+FAA+F;YAC/F,gGAAgG;YAChG,MAAM,mBAAmB,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC;YAC3D,WAAW,GAAG,CAAC,mBAAmB,CAAC,OAAO;gBACzC,CAAC,CAAC,IAAI,CAAC,4BAA4B;gBACnC,CAAC,CAAC,0BAAkB,CAAC;YAEtB,kDAAkD;YAClD,MAAM,GAAG,SAAS,CAAC;YACnB,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC;YAC5B,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,CAAC;YAC5C,MAAM,UAAU,GAAyB;gBACxC,MAAM,EAAE,MAAM;gBACd,cAAc;gBACd,WAAW;gBACX,KAAK;aACL,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;YAEnC,wGAAwG;YACxG,uGAAuG;YACvG,IAAI,iBAAiB,KAAK,SAAS,IAAI,cAAc,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBAC1E,IAAI,GAAG,IAAI,CAAC;YACb,CAAC;YAED,qGAAqG;YACrG,IAAI,iBAAiB,KAAK,SAAS,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;gBAC9D,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC;oBACnC,SAAS,EAAE,uBAAuB;oBAClC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;oBAClC,gBAAgB,EAAE,aAAa,CAAC,IAAI,KAAK,SAAS,EAAE,oDAAoD;oBACxG,KAAK,EAAE,mBAAmB,CAAC,IAAI,EAAE,KAAK;oBACtC,GAAG,aAAa,CAAC,cAAc;iBAC/B,CAAC,CAAC;gBACH,MAAM,IAAA,gBAAK,EAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;YACvC,CAAC;QACF,CAAC,QAAQ,CAAC,IAAI,EAAE;QAEhB,2GAA2G;QAC3G,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YACxE,OAAO,OAAO,CAAC;QAChB,CAAC;QAED,0GAA0G;QAC1G,+FAA+F;QAC/F,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,EAAE,eAAe,EAAE,GAAG,gBAAgB,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;YACxF,8DAA8D;YAC9D,MAAM,aAAa,GAAG,MAAM,eAAe,CAAC,wBAAwB,CAAC;YACrE,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;YACvD,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;gBAC5B,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC;YAC7B,CAAC;YACD,MAAM,UAAU,GAAyB;gBACxC,MAAM,EAAE,MAAM;gBACd,cAAc;gBACd,WAAW;gBACX,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK;aAC9D,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;YACnC,OAAO,GAAG,eAAe,CAAC;QAC3B,CAAC;QAED,+DAA+D;QAC/D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,cAAc,CAC5B;gBACC,SAAS,EAAE,iBAAiB;gBAC5B,WAAW;gBACX,eAAe,EAAE,cAAc;aAC/B,EACD,KAAK,CACL,CAAC;YACF,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,4BAA4B,CACzC,MAAuB,EACvB,cAAsC;QAEtC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,cAAc,CAAC,IAAI,CAClB,4BAA4B,EAC5B,IAAI,2CAAqB,CAAC,4BAA4B,CAAC,CACvD,CAAC;YACF,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC;QAC/B,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC;QACpD,MAAM,0BAA0B,GAAG,MAAM,OAAO,CAAC,oBAAoB,CAAC;QACtE,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,wBAAwB,CAAC;QAC7D,cAAc,CAAC,gBAAgB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACtD,cAAc,CAAC,oBAAoB,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;QACxE,cAAc,CAAC,wBAAwB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC/D,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED,8DAA8D;IACvD,iBAAiB,CACvB,OAAkC,EAClC,iBAAyC,IAAI,4CAAsB,EAAE;QAErE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,cAAc,CAAC,IAAI,CAClB,uCAAuC,EACvC,IAAI,2CAAqB,CAAC,uCAAuC,CAAC,CAClE,CAAC;YACF,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC;QAC/B,CAAC;QACD,0DAA0D;QAC1D,8DAA8D;QAC9D,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACxC,6DAA6D;YAC7D,MAAM,IAAI,qBAAU,CAAC,0DAA0D,CAAC,CAAC;QAClF,CAAC;QAED,MAAM,EAAE,MAAM,EAAE,GAAG,gBAAgB,EAAE,GAAG,OAAO,CAAC;QAChD,IAAI,OAAO,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACrC,IAAI,CAAC,4BAA4B,CAAC,YAAY,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,KAAK,CAC5E,CAAC,KAAK,EAAE,EAAE;gBACT,cAAc,CAAC,IAAI,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;YAChD,CAAC,CACD,CAAC;QACH,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,gBAAgB,CACpB,EAAE,eAAe,EAAE,YAAY,MAAM,EAAE,EAAE,EACzC,gBAAgB,EAChB,cAAc,CACd,CAAC;QACH,CAAC;QACD,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED,6DAA6D;IACtD,gBAAgB,CAAC,OAAiC;QACxD,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,gBAAgB,EAAE,GAAG,OAAO,CAAC;QAC3F,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;YAClC,CAAC;YACD,gDAAgD;YAChD,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CACvC,0DAA0D,EAC1D,IAAI,2CAAqB,CACxB,6DAA6D,CAC7D,CACD,CAAC;YACF,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;YACjC,UAAU,GAAG,IAAI,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,eAAe,GAAG;YACtB,MAAM,EAAE,WAAW,MAAM,EAAE;YAC3B,mBAAmB;YACnB,gBAAgB;YAChB,cAAc,EAAE,IAAI,4CAAsB,EAAE;SAC5C,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5D,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7B,OAAO,UAAU;YAChB,CAAC,CAAC;gBACA,GAAG,OAAO;gBACV,eAAe,EAAE,IAAI;gBACrB,UAAU,EAAE,IAAI;aACf;YACH,CAAC,CAAC,OAAO,CAAC;IACZ,CAAC;IAEO,qBAAqB;QAC5B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACd,CAAC;QACD,IACC,IAAI,CAAC,eAAe,KAAK,SAAS;YAClC,IAAI,CAAC,aAAa,CAAC,oBAAoB,GAAG,IAAI,CAAC,eAAe,CAAC,mBAAmB;YAClF,IAAI,CAAC,eAAe,KAAK,SAAS,EACjC,CAAC;YACF,uFAAuF;YACvF,OAAO,KAAK,CAAC;QACd,CAAC;QACD,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC;QAC1E,+FAA+F;QAC/F,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC,gBAAgB,CACpB,EAAE,eAAe,EAAE,mBAAmB,MAAM,EAAE,EAAE,EAChD,gBAAgB,EAChB,cAAc,CACd,CAAC;QACF,OAAO,IAAI,CAAC;IACb,CAAC;IAEO,sBAAsB;QAC7B,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACxC,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CACvC,uCAAuC,EACvC,IAAI,2CAAqB,CAAC,uCAAuC,CAAC,CAClE,CAAC;YACF,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QAClC,CAAC;IACF,CAAC;CACD;AA/0BD,8CA+0BC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport { IDisposable, ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert, Deferred, PromiseTimer, delay } from \"@fluidframework/core-utils/internal\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions/internal\";\nimport { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport {\n\tMonitoringContext,\n\tUsageError,\n\tcreateChildLogger,\n\tcreateChildMonitoringContext,\n\tisFluidError,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { ISummaryConfiguration } from \"../containerRuntime.js\";\nimport { opSize } from \"../opProperties.js\";\n\nimport { SummarizeHeuristicRunner } from \"./summarizerHeuristics.js\";\nimport {\n\tEnqueueSummarizeResult,\n\tIEnqueueSummarizeOptions,\n\tIOnDemandSummarizeOptions,\n\tIRefreshSummaryAckOptions,\n\tISubmitSummaryOptions,\n\tISummarizeEventProps,\n\tISummarizeHeuristicData,\n\tISummarizeHeuristicRunner,\n\tISummarizeOptions,\n\tISummarizeResults,\n\tISummarizeRunnerTelemetry,\n\tISummarizeTelemetryProperties,\n\tISummarizerEvents,\n\tISummarizerRuntime,\n\tISummaryCancellationToken,\n\tSubmitSummaryResult,\n\tSummarizerStopReason,\n\ttype IRetriableFailureError,\n} from \"./summarizerTypes.js\";\nimport { IAckedSummary, IClientSummaryWatcher, SummaryCollection } from \"./summaryCollection.js\";\nimport {\n\tRetriableSummaryError,\n\tSummarizeReason,\n\tSummarizeResultBuilder,\n\tSummaryGenerator,\n\traceTimer,\n} from \"./summaryGenerator.js\";\n\nconst maxSummarizeAckWaitTime = 10 * 60 * 1000; // 10 minutes\n\n/**\n * The maximum number of summarization attempts that will be done by default in case of failures\n * that can be retried.\n */\nexport const defaultMaxAttempts = 2;\n/**\n * The default value for maximum number of summarization attempts that will be done for summarization failures where\n * submit fails and the failure can be retried.\n */\nexport const defaultMaxAttemptsForSubmitFailures = 5;\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 extends TypedEventEmitter<ISummarizerEvents> implements IDisposable {\n\tpublic static async start(\n\t\tlogger: ITelemetryBaseLogger,\n\t\tsummaryWatcher: IClientSummaryWatcher,\n\t\tconfiguration: ISummaryConfiguration,\n\t\tsubmitSummaryCallback: (options: ISubmitSummaryOptions) => Promise<SubmitSummaryResult>,\n\t\trefreshLatestSummaryAckCallback: (options: IRefreshSummaryAckOptions) => Promise<void>,\n\t\theuristicData: ISummarizeHeuristicData,\n\t\tsummaryCollection: SummaryCollection,\n\t\tcancellationToken: ISummaryCancellationToken,\n\t\tstopSummarizerCallback: (reason: SummarizerStopReason) => void,\n\t\truntime: ISummarizerRuntime,\n\t): Promise<RunningSummarizer> {\n\t\tconst summarizer = new RunningSummarizer(\n\t\t\tlogger,\n\t\t\tsummaryWatcher,\n\t\t\tconfiguration,\n\t\t\tsubmitSummaryCallback,\n\t\t\trefreshLatestSummaryAckCallback,\n\t\t\theuristicData,\n\t\t\tsummaryCollection,\n\t\t\tcancellationToken,\n\t\t\tstopSummarizerCallback,\n\t\t\truntime,\n\t\t);\n\n\t\t// If there have been any acks newer that the one this client loaded from until now, process them before\n\t\t// starting the running summarizer which will trigger summary heuristics.\n\t\t// This is done primarily to handle scenarios where the summarizer loads from a cached snapshot and there\n\t\t// is newer one available. The ack for the newer summary is processed before summarizing because otherwise\n\t\t// that summary would fail as it has an older parent.\n\t\tlet nextReferenceSequenceNumber = runtime.deltaManager.initialSequenceNumber + 1;\n\t\tconst latestAck = summaryCollection.latestAck;\n\t\tif (\n\t\t\tlatestAck !== undefined &&\n\t\t\tlatestAck.summaryOp.referenceSequenceNumber >= nextReferenceSequenceNumber\n\t\t) {\n\t\t\tawait summarizer.handleSummaryAck(latestAck);\n\t\t\tnextReferenceSequenceNumber = latestAck.summaryOp.referenceSequenceNumber + 1;\n\t\t}\n\n\t\tawait summarizer.waitStart();\n\n\t\t// Process summary acks asynchronously\n\t\t// Note: no exceptions are thrown from processIncomingSummaryAcks handler as it handles all exceptions\n\t\tsummarizer.processIncomingSummaryAcks(nextReferenceSequenceNumber).catch((error) => {\n\t\t\tcreateChildLogger({ logger }).sendErrorEvent(\n\t\t\t\t{ eventName: \"HandleSummaryAckFatalError\" },\n\t\t\t\terror,\n\t\t\t);\n\t\t});\n\n\t\t// Update heuristic counts\n\t\t// By the time we get here, there are potentially ops missing from the heuristic summary counts\n\t\t// Examples of where this could happen:\n\t\t// 1. Op is processed during the time that we are initiating the RunningSummarizer instance but before we\n\t\t// listen for the op events (will get missed by the handlers in the current workflow)\n\t\t// 2. Op was sequenced after the last time we summarized (op sequence number > summarize ref sequence number)\n\t\tconst diff =\n\t\t\truntime.deltaManager.lastSequenceNumber -\n\t\t\t(heuristicData.lastSuccessfulSummary.refSequenceNumber +\n\t\t\t\theuristicData.numNonRuntimeOps +\n\t\t\t\theuristicData.numRuntimeOps);\n\t\theuristicData.hasMissingOpData = diff > 0;\n\n\t\tif (heuristicData.hasMissingOpData) {\n\t\t\t// Split the diff 50-50 and increment the counts appropriately\n\t\t\theuristicData.numNonRuntimeOps += Math.ceil(diff / 2);\n\t\t\theuristicData.numRuntimeOps += Math.floor(diff / 2);\n\t\t}\n\n\t\t// Update last seq number (in case the handlers haven't processed anything yet)\n\t\theuristicData.lastOpSequenceNumber = runtime.deltaManager.lastSequenceNumber;\n\n\t\t// Start heuristics\n\t\tsummarizer.heuristicRunner?.start();\n\t\tsummarizer.heuristicRunner?.run();\n\n\t\treturn summarizer;\n\t}\n\n\tpublic get disposed() {\n\t\treturn this._disposed;\n\t}\n\tprivate stopping = false;\n\tprivate _disposed = false;\n\tprivate summarizingLock: Promise<void> | undefined;\n\tprivate tryWhileSummarizing = false;\n\tprivate readonly pendingAckTimer: PromiseTimer;\n\tprivate heuristicRunner?: ISummarizeHeuristicRunner;\n\tprivate readonly generator: SummaryGenerator;\n\tprivate readonly mc: MonitoringContext;\n\n\tprivate enqueuedSummary:\n\t\t| {\n\t\t\t\treason: SummarizeReason;\n\t\t\t\tafterSequenceNumber: number;\n\t\t\t\tsummarizeOptions: ISummarizeOptions;\n\t\t\t\treadonly resultsBuilder: SummarizeResultBuilder;\n\t\t }\n\t\t| undefined;\n\tprivate summarizeCount = 0;\n\tprivate totalSuccessfulAttempts = 0;\n\tprivate initialized = false;\n\n\tprivate readonly runtimeListener;\n\n\t/** The maximum number of summary attempts to do when submit summary fails. */\n\tprivate readonly maxAttemptsForSubmitFailures: number;\n\n\tprivate constructor(\n\t\tbaseLogger: ITelemetryBaseLogger,\n\t\tprivate readonly summaryWatcher: IClientSummaryWatcher,\n\t\tprivate readonly configuration: ISummaryConfiguration,\n\t\tprivate readonly submitSummaryCallback: (\n\t\t\toptions: ISubmitSummaryOptions,\n\t\t) => Promise<SubmitSummaryResult>,\n\t\tprivate readonly refreshLatestSummaryAckCallback: (\n\t\t\toptions: IRefreshSummaryAckOptions,\n\t\t) => Promise<void>,\n\t\tprivate readonly heuristicData: ISummarizeHeuristicData,\n\t\tprivate readonly summaryCollection: SummaryCollection,\n\t\tprivate readonly cancellationToken: ISummaryCancellationToken,\n\t\tprivate readonly stopSummarizerCallback: (reason: SummarizerStopReason) => void,\n\t\tprivate readonly runtime: ISummarizerRuntime,\n\t) {\n\t\tsuper();\n\n\t\tconst telemetryProps: ISummarizeRunnerTelemetry = {\n\t\t\tsummarizeCount: () => this.summarizeCount,\n\t\t\tsummarizerSuccessfulAttempts: () => this.totalSuccessfulAttempts,\n\t\t};\n\n\t\tthis.mc = createChildMonitoringContext({\n\t\t\tlogger: baseLogger,\n\t\t\tnamespace: \"Running\",\n\t\t\tproperties: {\n\t\t\t\tall: telemetryProps,\n\t\t\t},\n\t\t});\n\n\t\tif (configuration.state !== \"disableHeuristics\") {\n\t\t\tassert(\n\t\t\t\tthis.configuration.state === \"enabled\",\n\t\t\t\t0x2ea /* \"Configuration state should be enabled\" */,\n\t\t\t);\n\t\t\tthis.heuristicRunner = new SummarizeHeuristicRunner(\n\t\t\t\theuristicData,\n\t\t\t\tthis.configuration,\n\t\t\t\t(reason) => this.trySummarize(reason),\n\t\t\t\tthis.mc.logger,\n\t\t\t);\n\t\t}\n\n\t\tassert(\n\t\t\tthis.configuration.state !== \"disabled\",\n\t\t\t0x2eb /* \"Summary not supported with configuration disabled\" */,\n\t\t);\n\n\t\t// Cap the maximum amount of time client will wait for a summarize op ack to maxSummarizeAckWaitTime\n\t\t// configuration.maxAckWaitTime is composed from defaults, server values, and runtime overrides\n\n\t\tconst maxAckWaitTime = Math.min(this.configuration.maxAckWaitTime, maxSummarizeAckWaitTime);\n\n\t\tthis.pendingAckTimer = new PromiseTimer(maxAckWaitTime, () => {\n\t\t\t// Note: summarizeCount (from ChildLogger definition) may be 0,\n\t\t\t// since this code path is hit when RunningSummarizer first starts up,\n\t\t\t// before this instance has kicked off a new summarize run.\n\t\t\tthis.mc.logger.sendErrorEvent({\n\t\t\t\teventName: \"SummaryAckWaitTimeout\",\n\t\t\t\tmessage: \"Pending summary ack not received in time\",\n\t\t\t\tmaxAckWaitTime,\n\t\t\t\treferenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,\n\t\t\t\tsummarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,\n\t\t\t\ttimePending: Date.now() - this.heuristicData.lastAttempt.summaryTime,\n\t\t\t});\n\t\t});\n\t\t// Set up pending ack timeout by op timestamp differences for previous summaries.\n\t\tsummaryCollection.setPendingAckTimerTimeoutCallback(maxAckWaitTime, () => {\n\t\t\tif (this.pendingAckTimer.hasTimer) {\n\t\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"MissingSummaryAckFoundByOps\",\n\t\t\t\t\treferenceSequenceNumber: this.heuristicData.lastAttempt.refSequenceNumber,\n\t\t\t\t\tsummarySequenceNumber: this.heuristicData.lastAttempt.summarySequenceNumber,\n\t\t\t\t});\n\t\t\t\tthis.pendingAckTimer.clear();\n\t\t\t}\n\t\t});\n\n\t\tconst immediatelyRefreshLatestSummaryAck =\n\t\t\tthis.mc.config.getBoolean(\"Fluid.Summarizer.immediatelyRefreshLatestSummaryAck\") ??\n\t\t\ttrue;\n\t\tthis.generator = new SummaryGenerator(\n\t\t\tthis.pendingAckTimer,\n\t\t\tthis.heuristicData,\n\t\t\tthis.submitSummaryCallback,\n\t\t\t() => {\n\t\t\t\tthis.totalSuccessfulAttempts++;\n\t\t\t},\n\t\t\tasync (options: IRefreshSummaryAckOptions) => {\n\t\t\t\tif (immediatelyRefreshLatestSummaryAck) {\n\t\t\t\t\tawait this.refreshLatestSummaryAckAndHandleError(options);\n\t\t\t\t}\n\t\t\t},\n\t\t\tthis.summaryWatcher,\n\t\t\tthis.mc.logger,\n\t\t);\n\n\t\t// Listen to runtime for ops\n\t\tthis.runtimeListener = (op: ISequencedDocumentMessage, runtimeMessage?: boolean) => {\n\t\t\tthis.handleOp(op, runtimeMessage === true);\n\t\t};\n\t\tthis.runtime.on(\"op\", this.runtimeListener);\n\n\t\t// The max attempts for submit failures can be overridden via a feature flag. This allows us to\n\t\t// tweak this as per telemetry data until we arrive at a stable number.\n\t\t// If its set to a number higher than `defaultMaxAttemptsForSubmitFailures`, it will be ignored.\n\t\tconst overrideMaxAttempts = this.mc.config.getNumber(\n\t\t\t\"Fluid.Summarizer.AttemptsForSubmitFailures\",\n\t\t);\n\t\tthis.maxAttemptsForSubmitFailures =\n\t\t\toverrideMaxAttempts && overrideMaxAttempts < defaultMaxAttemptsForSubmitFailures\n\t\t\t\t? overrideMaxAttempts\n\t\t\t\t: defaultMaxAttemptsForSubmitFailures;\n\t}\n\n\tprivate async handleSummaryAck(ack: IAckedSummary) {\n\t\tconst refSequenceNumber = ack.summaryOp.referenceSequenceNumber;\n\t\tconst summaryLogger = this.tryGetCorrelatedLogger(refSequenceNumber) ?? this.mc.logger;\n\t\tconst summaryOpHandle = ack.summaryOp.contents.handle;\n\t\tconst summaryAckHandle = ack.summaryAck.contents.handle;\n\t\twhile (this.summarizingLock !== undefined) {\n\t\t\tsummaryLogger.sendTelemetryEvent({\n\t\t\t\teventName: \"RefreshAttemptWithSummarizerRunning\",\n\t\t\t\treferenceSequenceNumber: refSequenceNumber,\n\t\t\t\tproposalHandle: summaryOpHandle,\n\t\t\t\tackHandle: summaryAckHandle,\n\t\t\t});\n\t\t\tawait this.summarizingLock;\n\t\t}\n\n\t\t// Make sure we block any summarizer from being executed/enqueued while\n\t\t// executing the refreshLatestSummaryAck.\n\t\t// https://dev.azure.com/fluidframework/internal/_workitems/edit/779\n\t\tawait this.lockedSummaryAction(\n\t\t\t() => {},\n\t\t\tasync () => {\n\t\t\t\tconst options: IRefreshSummaryAckOptions = {\n\t\t\t\t\tproposalHandle: summaryOpHandle,\n\t\t\t\t\tackHandle: summaryAckHandle,\n\t\t\t\t\tsummaryRefSeq: refSequenceNumber,\n\t\t\t\t\tsummaryLogger,\n\t\t\t\t};\n\t\t\t\tawait this.refreshLatestSummaryAckAndHandleError(options);\n\t\t\t},\n\t\t\t() => {},\n\t\t);\n\t}\n\n\tprivate readonly refreshLatestSummaryAckAndHandleError = async (\n\t\toptions: IRefreshSummaryAckOptions,\n\t) => {\n\t\treturn this.refreshLatestSummaryAckCallback(options).catch(async (error) => {\n\t\t\t// If the error is 404, so maybe the fetched version no longer exists on server. We just\n\t\t\t// ignore this error in that case, as that means we will have another summaryAck for the\n\t\t\t// latest version with which we will refresh the state. However in case of single commit\n\t\t\t// summary, we might be missing a summary ack, so in that case we are still fine as the\n\t\t\t// code in `submitSummary` function in container runtime, will refresh the latest state\n\t\t\t// by calling `prefetchLatestSummaryThenClose`. We will load the next summarizer from the\n\t\t\t// updated state and be fine.\n\t\t\tconst isIgnoredError =\n\t\t\t\tisFluidError(error) &&\n\t\t\t\terror.errorType === DriverErrorTypes.fileNotFoundOrAccessDeniedError;\n\n\t\t\toptions.summaryLogger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: isIgnoredError\n\t\t\t\t\t\t? \"HandleSummaryAckErrorIgnored\"\n\t\t\t\t\t\t: \"HandleLastSummaryAckError\",\n\t\t\t\t\treferenceSequenceNumber: options.summaryRefSeq,\n\t\t\t\t\tproposalHandle: options.proposalHandle,\n\t\t\t\t\tackHandle: options.ackHandle,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t});\n\t};\n\n\t/**\n\t * Responsible for receiving and processing all the summary acks.\n\t * It starts processing ACKs after the one for the summary this client loaded from (initialSequenceNumber). Any\n\t * ACK before that is not interesting as it will simply be ignored.\n\t *\n\t * @param referenceSequenceNumber - The referenceSequenceNumber of the summary from which to start processing\n\t * acks.\n\t */\n\tprivate async processIncomingSummaryAcks(referenceSequenceNumber: number) {\n\t\t// Start waiting for acks that are for summaries newer that the one this client loaded from.\n\t\tlet nextReferenceSequenceNumber = referenceSequenceNumber;\n\t\twhile (!this.disposed) {\n\t\t\tconst ackedSummary = await this.summaryCollection.waitSummaryAck(\n\t\t\t\tnextReferenceSequenceNumber,\n\t\t\t);\n\t\t\tawait this.handleSummaryAck(ackedSummary);\n\t\t\tnextReferenceSequenceNumber = ackedSummary.summaryOp.referenceSequenceNumber + 1;\n\t\t}\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.runtime.off(\"op\", this.runtimeListener);\n\t\tthis.summaryWatcher.dispose();\n\t\tthis.heuristicRunner?.dispose();\n\t\tthis.heuristicRunner = undefined;\n\t\tthis.generator.dispose();\n\t\tthis.pendingAckTimer.clear();\n\t\tthis.disposeEnqueuedSummary();\n\t\tthis._disposed = true;\n\t\tthis.stopping = true;\n\t}\n\n\t/**\n\t * RunningSummarizer's logger includes the sequenced index of the current summary on each event.\n\t * If some other Summarizer code wants that event on their logs they can get it here,\n\t * but only if they're logging about that same summary.\n\t * @param summaryOpRefSeq - RefSeq number of the summary op, to ensure the log correlation will be correct\n\t */\n\tpublic tryGetCorrelatedLogger = (summaryOpRefSeq) =>\n\t\tthis.heuristicData.lastAttempt.refSequenceNumber === summaryOpRefSeq\n\t\t\t? this.mc.logger\n\t\t\t: undefined;\n\n\t/** We only want a single heuristic runner micro-task (will provide better optimized grouping of ops) */\n\tprivate heuristicRunnerMicroTaskExists = false;\n\n\tpublic handleOp(op: ISequencedDocumentMessage, runtimeMessage: boolean) {\n\t\tthis.heuristicData.lastOpSequenceNumber = op.sequenceNumber;\n\n\t\tif (runtimeMessage) {\n\t\t\tthis.heuristicData.numRuntimeOps++;\n\t\t} else {\n\t\t\tthis.heuristicData.numNonRuntimeOps++;\n\t\t}\n\n\t\tthis.heuristicData.totalOpsSize += opSize(op);\n\n\t\t// Check for enqueued on-demand summaries; Intentionally do nothing otherwise\n\t\tif (\n\t\t\tthis.initialized &&\n\t\t\tthis.opCanTriggerSummary(op, runtimeMessage) &&\n\t\t\t!this.tryRunEnqueuedSummary() &&\n\t\t\t!this.heuristicRunnerMicroTaskExists\n\t\t) {\n\t\t\tthis.heuristicRunnerMicroTaskExists = true;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\t\tPromise.resolve()\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.heuristicRunner?.run();\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.heuristicRunnerMicroTaskExists = false;\n\t\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Can the given op trigger a summary?\n\t * # Currently always prevents summaries for Summarize and SummaryAck/Nack ops\n\t * @param op - op to check\n\t * @returns true if this op can trigger a summary\n\t */\n\tprivate opCanTriggerSummary(op: ISequencedDocumentMessage, runtimeMessage: boolean): boolean {\n\t\tswitch (op.type) {\n\t\t\tcase MessageType.Summarize:\n\t\t\tcase MessageType.SummaryAck:\n\t\t\tcase MessageType.SummaryNack:\n\t\t\t\treturn false;\n\t\t\tdefault:\n\t\t\t\treturn runtimeMessage || this.nonRuntimeOpCanTriggerSummary();\n\t\t}\n\t}\n\n\tprivate nonRuntimeOpCanTriggerSummary(): boolean {\n\t\tconst opsSinceLastAck =\n\t\t\tthis.heuristicData.lastOpSequenceNumber -\n\t\t\tthis.heuristicData.lastSuccessfulSummary.refSequenceNumber;\n\t\treturn (\n\t\t\tthis.configuration.state === \"enabled\" &&\n\t\t\t(this.configuration.nonRuntimeHeuristicThreshold === undefined ||\n\t\t\t\tthis.configuration.nonRuntimeHeuristicThreshold <= opsSinceLastAck)\n\t\t);\n\t}\n\n\tpublic async waitStop(allowLastSummary: boolean): Promise<void> {\n\t\tif (this.stopping) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.stopping = true;\n\n\t\tthis.disposeEnqueuedSummary();\n\n\t\t// This will try to run lastSummary if needed.\n\t\tif (allowLastSummary && this.heuristicRunner?.shouldRunLastSummary()) {\n\t\t\tif (this.summarizingLock === undefined) {\n\t\t\t\tthis.trySummarizeOnce(\n\t\t\t\t\t// summarizeProps\n\t\t\t\t\t{ summarizeReason: \"lastSummary\" },\n\t\t\t\t\t{},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Note that trySummarizeOnce() call above returns right away, without waiting.\n\t\t// So we need to wait for its completion, otherwise it would be destroyed right away.\n\t\t// That said, if summary lock was taken upfront, this wait might wait on multiple retries to\n\t\t// submit summary. We should reconsider this flow and make summarizer move to exit faster.\n\t\t// This resolves when the current pending summary gets an ack or fails.\n\t\tawait this.summarizingLock;\n\t}\n\n\tprivate async waitStart() {\n\t\t// Wait no longer than ack timeout for all pending\n\t\tconst waitStartResult = await raceTimer(\n\t\t\tthis.summaryWatcher.waitFlushed(),\n\t\t\tthis.pendingAckTimer.start(),\n\t\t);\n\t\tthis.pendingAckTimer.clear();\n\n\t\t// Remove pending ack wait timeout by op timestamp comparison, because\n\t\t// it has race conditions with summaries submitted by this same client.\n\t\tthis.summaryCollection.unsetPendingAckTimerTimeoutCallback();\n\n\t\tif (waitStartResult.result === \"done\" && waitStartResult.value !== undefined) {\n\t\t\tthis.heuristicData.updateWithLastSummaryAckInfo({\n\t\t\t\trefSequenceNumber: waitStartResult.value.summaryOp.referenceSequenceNumber,\n\t\t\t\t// This will be the Summarizer starting point so only use timestamps from client's machine.\n\t\t\t\tsummaryTime: Date.now(),\n\t\t\t\tsummarySequenceNumber: waitStartResult.value.summaryOp.sequenceNumber,\n\t\t\t});\n\t\t}\n\t\tthis.initialized = true;\n\t}\n\n\tprivate beforeSummaryAction() {\n\t\tthis.summarizeCount++;\n\t}\n\n\tprivate afterSummaryAction() {\n\t\tconst retry = this.tryWhileSummarizing;\n\t\tthis.tryWhileSummarizing = false;\n\n\t\t// After summarizing, we should check to see if we need to summarize again.\n\t\t// Rerun the heuristics and check for enqueued summaries.\n\t\tif (!this.stopping && !this.tryRunEnqueuedSummary() && retry) {\n\t\t\tthis.heuristicRunner?.run();\n\t\t}\n\t}\n\n\t/**\n\t * Runs single summary action that prevents any other concurrent actions.\n\t * Assumes that caller checked upfront for lack of concurrent action (this.summarizingLock)\n\t * before calling this API. I.e. caller is responsible for either erroring out or waiting on this promise.\n\t * @param before - set of instructions to run before running the action.\n\t * @param action - action to perform.\n\t * @param after - set of instructions to run after running the action.\n\t * @returns The result of the action.\n\t */\n\tprivate async lockedSummaryAction<T>(\n\t\tbefore: () => void,\n\t\taction: () => Promise<T>,\n\t\tafter: () => void,\n\t) {\n\t\tassert(\n\t\t\tthis.summarizingLock === undefined,\n\t\t\t0x25b /* \"Caller is responsible for checking lock\" */,\n\t\t);\n\n\t\tconst summarizingLock = new Deferred<void>();\n\t\tthis.summarizingLock = summarizingLock.promise;\n\n\t\tbefore();\n\n\t\treturn action().finally(() => {\n\t\t\tsummarizingLock.resolve();\n\t\t\tthis.summarizingLock = undefined;\n\t\t\tafter();\n\t\t});\n\t}\n\n\t/**\n\t * Runs single summarize attempt\n\t * @param summarizeProps - props to log with each telemetry event associated with this attempt\n\t * @param options - summary options\n\t * @param cancellationToken - cancellation token to use to be able to cancel this summary, if needed\n\t * @param resultsBuilder - optional, result builder to use.\n\t * @returns ISummarizeResult - result of running a summary.\n\t */\n\tprivate trySummarizeOnce(\n\t\tsummarizeProps: ISummarizeTelemetryProperties,\n\t\toptions: ISummarizeOptions,\n\t\tresultsBuilder = new SummarizeResultBuilder(),\n\t): ISummarizeResults {\n\t\tthis.lockedSummaryAction(\n\t\t\t() => {\n\t\t\t\tthis.beforeSummaryAction();\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tconst summaryLogger = createChildLogger({\n\t\t\t\t\tlogger: this.mc.logger,\n\t\t\t\t\tproperties: { all: summarizeProps },\n\t\t\t\t});\n\t\t\t\tconst summaryOptions: ISubmitSummaryOptions = {\n\t\t\t\t\t...options,\n\t\t\t\t\tsummaryLogger,\n\t\t\t\t\tcancellationToken: this.cancellationToken,\n\t\t\t\t\tlatestSummaryRefSeqNum:\n\t\t\t\t\t\tthis.heuristicData.lastSuccessfulSummary.refSequenceNumber,\n\t\t\t\t};\n\t\t\t\tconst summarizeResult = this.generator.summarize(summaryOptions, resultsBuilder);\n\t\t\t\t// ensure we wait till the end of the process\n\t\t\t\tconst result = await summarizeResult.receivedSummaryAckOrNack;\n\t\t\t\tif (!result.success) {\n\t\t\t\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"SummarizeFailed\",\n\t\t\t\t\t\t\tmaxAttempts: 1,\n\t\t\t\t\t\t\tsummaryAttempts: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tresult.error,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tthis.afterSummaryAction();\n\t\t\t},\n\t\t).catch((error) => {\n\t\t\t// SummaryGenerator.summarize() does not throw exceptions - it converts them to failed result\n\t\t\t// on resultsBuilder\n\t\t\t// We do not care about exceptions on receivedSummaryAckOrNack - caller should check results\n\t\t\t// and take a appropriate action.\n\t\t});\n\n\t\treturn resultsBuilder.build();\n\t}\n\n\t/** Heuristics summarize attempt. */\n\tprivate trySummarize(reason: SummarizeReason): void {\n\t\tif (this.summarizingLock !== undefined) {\n\t\t\t// lockedSummaryAction() will retry heuristic-based summary at the end of current attempt\n\t\t\t// if it's still needed\n\t\t\tthis.tryWhileSummarizing = true;\n\t\t\treturn;\n\t\t}\n\n\t\tthis.lockedSummaryAction(\n\t\t\t() => {\n\t\t\t\tthis.beforeSummaryAction();\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\treturn this.trySummarizeWithRetries(reason);\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tthis.afterSummaryAction();\n\t\t\t},\n\t\t).catch((error) => {\n\t\t\tthis.mc.logger.sendErrorEvent({ eventName: \"UnexpectedSummarizeError\" }, error);\n\t\t});\n\t}\n\n\t/**\n\t * Tries to summarize with retries where retry is based on the failure params.\n\t * For example, summarization may be retried for failures with \"retryAfterSeconds\" param.\n\t */\n\tprivate async trySummarizeWithRetries(\n\t\treason: SummarizeReason,\n\t): Promise<ISummarizeResults | undefined> {\n\t\t// Helper to set summarize options, telemetry properties and call summarize.\n\t\tconst attemptSummarize = (attemptNumber: number, finalAttempt: boolean) => {\n\t\t\tconst summarizeOptions: ISummarizeOptions = {\n\t\t\t\tfullTree: false,\n\t\t\t};\n\t\t\tconst summarizeProps: ISummarizeTelemetryProperties = {\n\t\t\t\tsummarizeReason: reason,\n\t\t\t\tsummaryAttempts: attemptNumber,\n\t\t\t\t...summarizeOptions,\n\t\t\t\tfinalAttempt,\n\t\t\t};\n\t\t\tconst summaryLogger = createChildLogger({\n\t\t\t\tlogger: this.mc.logger,\n\t\t\t\tproperties: { all: summarizeProps },\n\t\t\t});\n\t\t\tconst summaryOptions: ISubmitSummaryOptions = {\n\t\t\t\t...summarizeOptions,\n\t\t\t\tsummaryLogger,\n\t\t\t\tcancellationToken: this.cancellationToken,\n\t\t\t\tfinalAttempt,\n\t\t\t\tlatestSummaryRefSeqNum: this.heuristicData.lastSuccessfulSummary.refSequenceNumber,\n\t\t\t};\n\t\t\tconst summarizeResult = this.generator.summarize(summaryOptions);\n\t\t\treturn { summarizeProps, summarizeResult };\n\t\t};\n\n\t\t// The max number of attempts are based on the stage at which summarization failed. If it fails before it is\n\t\t// submitted, a different value is used compared to if it fails after submission. Usually, in the former case,\n\t\t// we would retry more often as its cheaper and retries are likely to succeed.\n\t\t// This makes it harder to predict how many attempts would actually happen as that depends on how far an attempt\n\t\t// made. To keep things simple, the max attempts is reset after every attempt based on where it failed. This may\n\t\t// result in some failures not being retried depending on what happened before this attempt. That's fine because\n\t\t// such scenarios are very unlikely and even if it happens, it would resolve when a new summarizer starts over.\n\t\t// For example - When failure switches from one the submit failures to nack failure, only one more retry will\n\t\t// happen irrespective of the value of `defaultMaxAttempts`.\n\t\tlet maxAttempts = defaultMaxAttempts;\n\t\tlet currentAttempt = 0;\n\t\tlet retryAfterSeconds: number | undefined;\n\t\tlet done = false;\n\t\tlet status: \"success\" | \"failure\" | \"canceled\" = \"success\";\n\t\tlet results: ISummarizeResults | undefined;\n\t\tlet error: IRetriableFailureError | undefined;\n\t\tdo {\n\t\t\tcurrentAttempt++;\n\t\t\tif (this.cancellationToken.cancelled) {\n\t\t\t\tstatus = \"canceled\";\n\t\t\t\tdone = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst attemptResult = attemptSummarize(currentAttempt, false /* finalAttempt */);\n\t\t\tresults = attemptResult.summarizeResult;\n\n\t\t\t// Ack / nack is the final step, so if it succeeds we're done.\n\t\t\tconst ackNackResult = await results.receivedSummaryAckOrNack;\n\t\t\tif (ackNackResult.success) {\n\t\t\t\tstatus = \"success\";\n\t\t\t\tdone = true;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Update max attempts from the failure result.\n\t\t\t// If submit summary failed, use maxAttemptsForSubmitFailures. Else use the defaultMaxAttempts.\n\t\t\t// Note: Check \"summarySubmitted\" result first because if it fails, ack nack would fail as well.\n\t\t\tconst submitSummaryResult = await results.summarySubmitted;\n\t\t\tmaxAttempts = !submitSummaryResult.success\n\t\t\t\t? this.maxAttemptsForSubmitFailures\n\t\t\t\t: defaultMaxAttempts;\n\n\t\t\t// Emit \"summarize\" event for this failed attempt.\n\t\t\tstatus = \"failure\";\n\t\t\terror = ackNackResult.error;\n\t\t\tretryAfterSeconds = error.retryAfterSeconds;\n\t\t\tconst eventProps: ISummarizeEventProps = {\n\t\t\t\tresult: status,\n\t\t\t\tcurrentAttempt,\n\t\t\t\tmaxAttempts,\n\t\t\t\terror,\n\t\t\t};\n\t\t\tthis.emit(\"summarize\", eventProps);\n\n\t\t\t// Break if the failure doesn't have \"retryAfterSeconds\" or we are one less from max number of attempts.\n\t\t\t// Note that the final attempt if \"retryAfterSeconds\" does exist happens outside of the do..while loop.\n\t\t\tif (retryAfterSeconds === undefined || currentAttempt >= maxAttempts - 1) {\n\t\t\t\tdone = true;\n\t\t\t}\n\n\t\t\t// If the failure has \"retryAfterSeconds\", add a delay of that time before starting the next attempt.\n\t\t\tif (retryAfterSeconds !== undefined && retryAfterSeconds > 0) {\n\t\t\t\tthis.mc.logger.sendPerformanceEvent({\n\t\t\t\t\teventName: \"SummarizeAttemptDelay\",\n\t\t\t\t\tduration: retryAfterSeconds * 1000,\n\t\t\t\t\tsummaryNackDelay: ackNackResult.data !== undefined, // This will only be defined only for nack failures.\n\t\t\t\t\tstage: submitSummaryResult.data?.stage,\n\t\t\t\t\t...attemptResult.summarizeProps,\n\t\t\t\t});\n\t\t\t\tawait delay(retryAfterSeconds * 1000);\n\t\t\t}\n\t\t} while (!done);\n\n\t\t// If the attempt was successful, emit \"summarize\" event and return. A failed attempt may be retried below.\n\t\tif (status !== \"failure\") {\n\t\t\tthis.emit(\"summarize\", { result: status, currentAttempt, maxAttempts });\n\t\t\treturn results;\n\t\t}\n\n\t\t// If summarization wasn't successful above and the failure contains \"retryAfterSeconds\", perform one last\n\t\t// attempt. This gives a chance to the runtime to perform additional steps in the last attempt.\n\t\tif (retryAfterSeconds !== undefined) {\n\t\t\tconst { summarizeResult } = attemptSummarize(++currentAttempt, true /* finalAttempt */);\n\t\t\t// Ack / nack is the final step, so if it succeeds we're done.\n\t\t\tconst ackNackResult = await summarizeResult.receivedSummaryAckOrNack;\n\t\t\tstatus = ackNackResult.success ? \"success\" : \"failure\";\n\t\t\tif (!ackNackResult.success) {\n\t\t\t\terror = ackNackResult.error;\n\t\t\t}\n\t\t\tconst eventProps: ISummarizeEventProps = {\n\t\t\t\tresult: status,\n\t\t\t\tcurrentAttempt,\n\t\t\t\tmaxAttempts,\n\t\t\t\terror: ackNackResult.success ? undefined : ackNackResult.error,\n\t\t\t};\n\t\t\tthis.emit(\"summarize\", eventProps);\n\t\t\tresults = summarizeResult;\n\t\t}\n\n\t\t// If summarization is still unsuccessful, stop the summarizer.\n\t\tif (status === \"failure\") {\n\t\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"SummarizeFailed\",\n\t\t\t\t\tmaxAttempts,\n\t\t\t\t\tsummaryAttempts: currentAttempt,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t);\n\t\t\tthis.stopSummarizerCallback(\"failToSummarize\");\n\t\t}\n\t\treturn results;\n\t}\n\n\t/**\n\t * Attempts to generate a summary on demand with retries in case of failures. The retry logic is the same\n\t * as heuristics based summaries.\n\t */\n\tprivate async summarizeOnDemandWithRetries(\n\t\treason: SummarizeReason,\n\t\tresultsBuilder: SummarizeResultBuilder,\n\t) {\n\t\tconst results = await this.trySummarizeWithRetries(reason);\n\t\tif (results === undefined) {\n\t\t\tresultsBuilder.fail(\n\t\t\t\t\"Summarization was canceled\",\n\t\t\t\tnew RetriableSummaryError(\"Summarization was canceled\"),\n\t\t\t);\n\t\t\treturn resultsBuilder.build();\n\t\t}\n\t\tconst submitResult = await results.summarySubmitted;\n\t\tconst summaryOpBroadcastedResult = await results.summaryOpBroadcasted;\n\t\tconst ackNackResult = await results.receivedSummaryAckOrNack;\n\t\tresultsBuilder.summarySubmitted.resolve(submitResult);\n\t\tresultsBuilder.summaryOpBroadcasted.resolve(summaryOpBroadcastedResult);\n\t\tresultsBuilder.receivedSummaryAckOrNack.resolve(ackNackResult);\n\t\treturn resultsBuilder.build();\n\t}\n\n\t/** {@inheritdoc (ISummarizer:interface).summarizeOnDemand} */\n\tpublic summarizeOnDemand(\n\t\toptions: IOnDemandSummarizeOptions,\n\t\tresultsBuilder: SummarizeResultBuilder = new SummarizeResultBuilder(),\n\t): ISummarizeResults {\n\t\tif (this.stopping) {\n\t\t\tresultsBuilder.fail(\n\t\t\t\t\"RunningSummarizer stopped or disposed\",\n\t\t\t\tnew RetriableSummaryError(\"RunningSummarizer stopped or disposed\"),\n\t\t\t);\n\t\t\treturn resultsBuilder.build();\n\t\t}\n\t\t// Check for concurrent summary attempts. If one is found,\n\t\t// return a promise that caller can await before trying again.\n\t\tif (this.summarizingLock !== undefined) {\n\t\t\t// The heuristics are blocking concurrent summarize attempts.\n\t\t\tthrow new UsageError(\"Attempted to run an already-running summarizer on demand\");\n\t\t}\n\n\t\tconst { reason, ...summarizeOptions } = options;\n\t\tif (options.retryOnFailure === true) {\n\t\t\tthis.summarizeOnDemandWithRetries(`onDemand;${reason}`, resultsBuilder).catch(\n\t\t\t\t(error) => {\n\t\t\t\t\tresultsBuilder.fail(\"summarize failed\", error);\n\t\t\t\t},\n\t\t\t);\n\t\t} else {\n\t\t\tthis.trySummarizeOnce(\n\t\t\t\t{ summarizeReason: `onDemand/${reason}` },\n\t\t\t\tsummarizeOptions,\n\t\t\t\tresultsBuilder,\n\t\t\t);\n\t\t}\n\t\treturn resultsBuilder.build();\n\t}\n\n\t/** {@inheritdoc (ISummarizer:interface).enqueueSummarize} */\n\tpublic enqueueSummarize(options: IEnqueueSummarizeOptions): EnqueueSummarizeResult {\n\t\tconst { reason, afterSequenceNumber = 0, override = false, ...summarizeOptions } = options;\n\t\tlet overridden = false;\n\t\tif (this.enqueuedSummary !== undefined) {\n\t\t\tif (!override) {\n\t\t\t\treturn { alreadyEnqueued: true };\n\t\t\t}\n\t\t\t// Override existing enqueued summarize attempt.\n\t\t\tthis.enqueuedSummary.resultsBuilder.fail(\n\t\t\t\t\"Aborted; overridden by another enqueue summarize attempt\",\n\t\t\t\tnew RetriableSummaryError(\n\t\t\t\t\t\"Summary was overridden by another enqueue summarize attempt\",\n\t\t\t\t),\n\t\t\t);\n\t\t\tthis.enqueuedSummary = undefined;\n\t\t\toverridden = true;\n\t\t}\n\n\t\tthis.enqueuedSummary = {\n\t\t\treason: `enqueue;${reason}`,\n\t\t\tafterSequenceNumber,\n\t\t\tsummarizeOptions,\n\t\t\tresultsBuilder: new SummarizeResultBuilder(),\n\t\t};\n\t\tconst results = this.enqueuedSummary.resultsBuilder.build();\n\t\tthis.tryRunEnqueuedSummary();\n\t\treturn overridden\n\t\t\t? {\n\t\t\t\t\t...results,\n\t\t\t\t\talreadyEnqueued: true,\n\t\t\t\t\toverridden: true,\n\t\t\t }\n\t\t\t: results;\n\t}\n\n\tprivate tryRunEnqueuedSummary() {\n\t\tif (this.stopping) {\n\t\t\tthis.disposeEnqueuedSummary();\n\t\t\treturn false;\n\t\t}\n\t\tif (\n\t\t\tthis.enqueuedSummary === undefined ||\n\t\t\tthis.heuristicData.lastOpSequenceNumber < this.enqueuedSummary.afterSequenceNumber ||\n\t\t\tthis.summarizingLock !== undefined\n\t\t) {\n\t\t\t// If no enqueued summary is ready or a summary is already in progress, take no action.\n\t\t\treturn false;\n\t\t}\n\t\tconst { reason, resultsBuilder, summarizeOptions } = this.enqueuedSummary;\n\t\t// Set to undefined first, so that subsequent enqueue attempt while summarize will occur later.\n\t\tthis.enqueuedSummary = undefined;\n\t\tthis.trySummarizeOnce(\n\t\t\t{ summarizeReason: `enqueuedSummary/${reason}` },\n\t\t\tsummarizeOptions,\n\t\t\tresultsBuilder,\n\t\t);\n\t\treturn true;\n\t}\n\n\tprivate disposeEnqueuedSummary() {\n\t\tif (this.enqueuedSummary !== undefined) {\n\t\t\tthis.enqueuedSummary.resultsBuilder.fail(\n\t\t\t\t\"RunningSummarizer stopped or disposed\",\n\t\t\t\tnew RetriableSummaryError(\"RunningSummarizer stopped or disposed\"),\n\t\t\t);\n\t\t\tthis.enqueuedSummary = undefined;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
6
|
-
import { IFluidHandleContext } from "@fluidframework/core-interfaces";
|
|
6
|
+
import { IFluidHandleContext } from "@fluidframework/core-interfaces/internal";
|
|
7
7
|
import { IFluidErrorBase, ITelemetryLoggerExt, LoggingError } from "@fluidframework/telemetry-utils/internal";
|
|
8
8
|
import { ISummaryConfiguration } from "../containerRuntime.js";
|
|
9
9
|
import { ICancellableSummarizerController } from "./runWhileConnectedCoordinator.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../../src/summary/summarizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../../src/summary/summarizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAE/E,OAAO,EACN,eAAe,EACf,mBAAmB,EACnB,YAAY,EAIZ,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,EAAE,gCAAgC,EAAE,MAAM,mCAAmC,CAAC;AAGrF,OAAO,EACN,sBAAsB,EACtB,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EAGzB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,4BAA4B,EAC5B,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAK3D,qBAAa,kBACZ,SAAQ,YACR,YAAW,mBAAmB,EAAE,eAAe;IAO9C,QAAQ,CAAC,MAAM,EAAE,OAAO;IALzB,QAAQ,CAAC,SAAS,sBAAoB;IACtC,QAAQ,CAAC,QAAQ,QAAQ;gBAGxB,YAAY,EAAE,MAAM,EACX,MAAM,GAAE,OAAe;IAKjC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,qBAAiB,EAAE,MAAM,EAAE,mBAAmB;CAI5E;AAED,eAAO,MAAM,wBAAwB,iBAAkB,MAAM,UAAU,OAAO,uBACjC,CAAC;AAE9C;;;;;GAKG;AACH,qBAAa,UAAW,SAAQ,iBAAiB,CAAC,iBAAiB,CAAE,YAAW,WAAW;IAazF;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB;aAElB,iBAAiB,EAAE,iBAAiB;IACpD,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAvBxC,IAAW,WAAW,SAErB;IAED,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,iBAAiB,CAAC,CAAoB;IAC9C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,QAAQ,CAAkB;IAElC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwC;;IAGpE;;OAEG;IACc,OAAO,EAAE,kBAAkB,EAC3B,mBAAmB,EAAE,MAAM,qBAAqB;IACjE;;OAEG;IACc,iBAAiB,EAAE,4BAA4B,EAChE,aAAa,EAAE,mBAAmB,EAClB,iBAAiB,EAAE,iBAAiB,EACnC,sBAAsB,EAAE,CACxC,OAAO,EAAE,mBAAmB,KACxB,OAAO,CAAC,gCAAgC,CAAC;IASlC,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAWnE;;;;OAIG;IACI,IAAI,CAAC,MAAM,EAAE,oBAAoB;IAIjC,KAAK;YAOE,OAAO;IAmDrB;;;;;OAKG;WACW,2BAA2B,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO;IAIpF,OAAO,CAAC,cAAc,CAAsC;IAE5D;;;;;;;;OAQG;YACW,KAAK;IAuDnB,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAEnC;IAEF;;;;;OAKG;IACI,OAAO;IAYP,iBAAiB,CAAC,OAAO,EAAE,yBAAyB,GAAG,iBAAiB;IA4DxE,gBAAgB,CAAC,OAAO,EAAE,wBAAwB,GAAG,sBAAsB;IAW3E,oBAAoB,CAAC,CAAC,gBAAgB,CAAC,EAAE,MAAM;CAGtD"}
|
|
@@ -58,7 +58,10 @@ class Summarizer extends client_utils_1.TypedEventEmitter {
|
|
|
58
58
|
this.handleSummarizeEvent = (eventProps) => {
|
|
59
59
|
this.emit("summarize", eventProps);
|
|
60
60
|
};
|
|
61
|
-
this.logger = (0, internal_2.createChildLogger)({
|
|
61
|
+
this.logger = (0, internal_2.createChildLogger)({
|
|
62
|
+
logger: this.runtime.baseLogger,
|
|
63
|
+
namespace: "Summarizer",
|
|
64
|
+
});
|
|
62
65
|
}
|
|
63
66
|
async run(onBehalfOf) {
|
|
64
67
|
try {
|