@fluidframework/container-runtime 0.49.2 → 0.50.1
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/dist/containerRuntime.d.ts +2 -2
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +73 -71
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +2 -1
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.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/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/summarizer.d.ts +4 -1
- package/dist/summarizer.d.ts.map +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summarizer.js.map +1 -1
- package/dist/summarizerClientElection.d.ts +1 -1
- package/dist/summarizerClientElection.js +1 -1
- package/dist/summarizerClientElection.js.map +1 -1
- package/dist/summaryManager.d.ts +10 -3
- package/dist/summaryManager.d.ts.map +1 -1
- package/dist/summaryManager.js +9 -6
- package/dist/summaryManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +2 -2
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +73 -71
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +2 -1
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.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/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/summarizer.d.ts +4 -1
- package/lib/summarizer.d.ts.map +1 -1
- package/lib/summarizer.js +3 -3
- package/lib/summarizer.js.map +1 -1
- package/lib/summarizerClientElection.d.ts +1 -1
- package/lib/summarizerClientElection.js +1 -1
- package/lib/summarizerClientElection.js.map +1 -1
- package/lib/summaryManager.d.ts +10 -3
- package/lib/summaryManager.d.ts.map +1 -1
- package/lib/summaryManager.js +9 -6
- package/lib/summaryManager.js.map +1 -1
- package/package.json +16 -16
- package/src/containerRuntime.ts +106 -96
- package/src/dataStoreContext.ts +2 -1
- package/src/dataStores.ts +1 -1
- package/src/index.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/summarizer.ts +5 -2
- package/src/summarizerClientElection.ts +1 -1
- package/src/summaryManager.ts +17 -7
package/lib/summarizer.d.ts
CHANGED
|
@@ -8,8 +8,10 @@ import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
|
8
8
|
import { IFluidErrorBase, LoggingError } from "@fluidframework/telemetry-utils";
|
|
9
9
|
import { IRequest, IResponse, IFluidHandleContext, IFluidHandle } from "@fluidframework/core-interfaces";
|
|
10
10
|
import { ISummaryConfiguration } from "@fluidframework/protocol-definitions";
|
|
11
|
+
import { ICancellableSummarizerController } from "./runWhileConnectedCoordinator";
|
|
11
12
|
import { SummaryCollection } from "./summaryCollection";
|
|
12
13
|
import { ISummarizer, ISummarizerInternalsProvider, ISummarizerOptions, ISummarizerRuntime, ISummarizingWarning, SummarizerStopReason } from "./summarizerTypes";
|
|
14
|
+
import { IConnectableRuntime } from ".";
|
|
13
15
|
export declare class SummarizingWarning extends LoggingError implements ISummarizingWarning, IFluidErrorBase {
|
|
14
16
|
readonly fluidErrorCode: string;
|
|
15
17
|
readonly logged: boolean;
|
|
@@ -35,6 +37,7 @@ export declare class Summarizer extends EventEmitter implements ISummarizer {
|
|
|
35
37
|
*/
|
|
36
38
|
private readonly internalsProvider;
|
|
37
39
|
readonly summaryCollection: SummaryCollection;
|
|
40
|
+
private readonly runCoordinatorCreateFn;
|
|
38
41
|
get IFluidLoadable(): this;
|
|
39
42
|
get IFluidRouter(): this;
|
|
40
43
|
get ISummarizer(): this;
|
|
@@ -54,7 +57,7 @@ export declare class Summarizer extends EventEmitter implements ISummarizer {
|
|
|
54
57
|
/** Represents an object that can generate summary.
|
|
55
58
|
* In practical terms, it's same runtime (this.runtime) with clientType === "summarizer".
|
|
56
59
|
*/
|
|
57
|
-
internalsProvider: ISummarizerInternalsProvider, handleContext: IFluidHandleContext, summaryCollection: SummaryCollection);
|
|
60
|
+
internalsProvider: ISummarizerInternalsProvider, handleContext: IFluidHandleContext, summaryCollection: SummaryCollection, runCoordinatorCreateFn: (runtime: IConnectableRuntime) => Promise<ICancellableSummarizerController>);
|
|
58
61
|
run(onBehalfOf: string, options?: Readonly<Partial<ISummarizerOptions>>): Promise<SummarizerStopReason>;
|
|
59
62
|
/**
|
|
60
63
|
* Stops the summarizer from running. This will complete
|
package/lib/summarizer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../src/summarizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAe,eAAe,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC7F,OAAO,EACH,QAAQ,EACR,SAAS,EACT,mBAAmB,EACnB,YAAY,EACf,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAEH,qBAAqB,EACxB,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../src/summarizer.ts"],"names":[],"mappings":"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"}
|
package/lib/summarizer.js
CHANGED
|
@@ -7,7 +7,6 @@ import { Deferred } from "@fluidframework/common-utils";
|
|
|
7
7
|
import { ChildLogger, LoggingError } from "@fluidframework/telemetry-utils";
|
|
8
8
|
import { wrapErrorAndLog } from "@fluidframework/container-utils";
|
|
9
9
|
import { create404Response } from "@fluidframework/runtime-utils";
|
|
10
|
-
import { RunWhileConnectedCoordinator } from "./runWhileConnectedCoordinator";
|
|
11
10
|
import { SummarizerHandle } from "./summarizerHandle";
|
|
12
11
|
import { RunningSummarizer } from "./runningSummarizer";
|
|
13
12
|
import { SummarizeHeuristicData } from "./summarizerHeuristics";
|
|
@@ -40,12 +39,13 @@ export class Summarizer extends EventEmitter {
|
|
|
40
39
|
/** Represents an object that can generate summary.
|
|
41
40
|
* In practical terms, it's same runtime (this.runtime) with clientType === "summarizer".
|
|
42
41
|
*/
|
|
43
|
-
internalsProvider, handleContext, summaryCollection) {
|
|
42
|
+
internalsProvider, handleContext, summaryCollection, runCoordinatorCreateFn) {
|
|
44
43
|
super();
|
|
45
44
|
this.runtime = runtime;
|
|
46
45
|
this.configurationGetter = configurationGetter;
|
|
47
46
|
this.internalsProvider = internalsProvider;
|
|
48
47
|
this.summaryCollection = summaryCollection;
|
|
48
|
+
this.runCoordinatorCreateFn = runCoordinatorCreateFn;
|
|
49
49
|
this._disposed = false;
|
|
50
50
|
this.stopDeferred = new Deferred();
|
|
51
51
|
this.summarizeOnDemand = (...args) => {
|
|
@@ -105,7 +105,7 @@ export class Summarizer extends EventEmitter {
|
|
|
105
105
|
onBehalfOf,
|
|
106
106
|
initSummarySeqNumber: this.runtime.deltaManager.initialSequenceNumber,
|
|
107
107
|
});
|
|
108
|
-
const runCoordinator = await
|
|
108
|
+
const runCoordinator = await this.runCoordinatorCreateFn(this.runtime);
|
|
109
109
|
// Wait for either external signal to cancel, or loss of connectivity.
|
|
110
110
|
const stopP = Promise.race([runCoordinator.waitCancelled, this.stopDeferred.promise]);
|
|
111
111
|
void stopP.then((reason) => {
|
package/lib/summarizer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../src/summarizer.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { EventEmitter } from \"events\";\nimport { Deferred } from \"@fluidframework/common-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ChildLogger, IFluidErrorBase, LoggingError } from \"@fluidframework/telemetry-utils\";\nimport {\n IRequest,\n IResponse,\n IFluidHandleContext,\n IFluidHandle,\n} from \"@fluidframework/core-interfaces\";\nimport { wrapErrorAndLog } from \"@fluidframework/container-utils\";\nimport {\n ISequencedDocumentMessage,\n ISummaryConfiguration,\n} from \"@fluidframework/protocol-definitions\";\nimport { create404Response } from \"@fluidframework/runtime-utils\";\nimport { RunWhileConnectedCoordinator } from \"./runWhileConnectedCoordinator\";\nimport { SummaryCollection } from \"./summaryCollection\";\nimport { SummarizerHandle } from \"./summarizerHandle\";\nimport { RunningSummarizer } from \"./runningSummarizer\";\nimport {\n ISummarizer,\n ISummarizerInternalsProvider,\n ISummarizerOptions,\n ISummarizerRuntime,\n ISummarizingWarning,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nimport { SummarizeHeuristicData } from \"./summarizerHeuristics\";\n\nconst summarizingError = \"summarizingError\";\n\nexport class SummarizingWarning extends LoggingError implements ISummarizingWarning, IFluidErrorBase {\n readonly errorType = summarizingError;\n readonly canRetry = true;\n\n constructor(\n errorMessage: string,\n readonly fluidErrorCode: string,\n readonly logged: boolean = false,\n ) {\n super(errorMessage);\n }\n\n static wrap(error: any, errorCode: string, logged: boolean = false, logger: ITelemetryLogger) {\n const newErrorFn = (errMsg: string) => new SummarizingWarning(errMsg, errorCode, logged);\n return wrapErrorAndLog<SummarizingWarning>(error, newErrorFn, logger);\n }\n}\n\nexport const createSummarizingWarning =\n (errorCode: string, logged: boolean) => new SummarizingWarning(errorCode, errorCode, logged);\n\n/**\n * Summarizer is responsible for coordinating when to generate and send summaries.\n * It is the main entry point for summary work.\n * It is created only by summarizing container (i.e. one with clientType === \"summarizer\")\n */\nexport class Summarizer extends EventEmitter implements ISummarizer {\n public get IFluidLoadable() { return this; }\n public get IFluidRouter() { return this; }\n public get ISummarizer() { return this; }\n\n private readonly logger: ITelemetryLogger;\n private runningSummarizer?: RunningSummarizer;\n private systemOpListener?: (op: ISequencedDocumentMessage) => void;\n private opListener?: (error: any, op: ISequencedDocumentMessage) => void;\n private _disposed: boolean = false;\n\n private readonly innerHandle: IFluidHandle<this>;\n\n public get handle(): IFluidHandle<this> { return this.innerHandle; }\n private readonly stopDeferred = new Deferred<SummarizerStopReason>();\n\n constructor(\n url: string,\n /** Reference to runtime that created this object.\n * i.e. runtime with clientType === \"summarizer\"\n */\n private readonly runtime: ISummarizerRuntime,\n private readonly configurationGetter: () => ISummaryConfiguration,\n /** Represents an object that can generate summary.\n * In practical terms, it's same runtime (this.runtime) with clientType === \"summarizer\".\n */\n private readonly internalsProvider: ISummarizerInternalsProvider,\n handleContext: IFluidHandleContext,\n public readonly summaryCollection: SummaryCollection,\n ) {\n super();\n this.logger = ChildLogger.create(this.runtime.logger, \"Summarizer\");\n this.innerHandle = new SummarizerHandle(this, url, handleContext);\n }\n\n public async run(\n onBehalfOf: string,\n options?: Readonly<Partial<ISummarizerOptions>>): Promise<SummarizerStopReason>\n {\n try {\n return await this.runCore(onBehalfOf, options);\n } catch (error) {\n this.stop(\"summarizerException\");\n throw SummarizingWarning.wrap(error, \"summarizerRun\", false /* logged */, this.logger);\n } finally {\n this.dispose();\n this.runtime.closeFn();\n }\n }\n\n /**\n * Stops the summarizer from running. This will complete\n * the run promise, and also close the container.\n * @param reason - reason code for stopping\n */\n public stop(reason: SummarizerStopReason) {\n this.stopDeferred.resolve(reason);\n }\n\n public async request(request: IRequest): Promise<IResponse> {\n if (request.url === \"/\" || request.url === \"\") {\n return {\n mimeType: \"fluid/object\",\n status: 200,\n value: this,\n };\n }\n return create404Response(request);\n }\n\n private async runCore(\n onBehalfOf: string,\n options?: Readonly<Partial<ISummarizerOptions>>): Promise<SummarizerStopReason>\n {\n // Initialize values and first ack (time is not exact)\n this.logger.sendTelemetryEvent({\n eventName: \"RunningSummarizer\",\n onBehalfOf,\n initSummarySeqNumber: this.runtime.deltaManager.initialSequenceNumber,\n });\n\n const runCoordinator = await RunWhileConnectedCoordinator.create(this.runtime);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopP = Promise.race([runCoordinator.waitCancelled, this.stopDeferred.promise]);\n void stopP.then((reason) => {\n this.logger.sendTelemetryEvent({\n eventName: \"StoppingSummarizer\",\n onBehalfOf,\n reason,\n });\n });\n\n if (runCoordinator.cancelled) {\n return runCoordinator.waitCancelled;\n }\n\n // Summarizing container ID (with clientType === \"summarizer\")\n const clientId = this.runtime.clientId;\n if (clientId === undefined) {\n throw Error(\"clientId should be defined if connected.\");\n }\n\n const runningSummarizer = await RunningSummarizer.start(\n this.logger,\n this.summaryCollection.createWatcher(clientId),\n this.configurationGetter(),\n async (...args) => this.internalsProvider.submitSummary(...args), // submitSummaryCallback\n new SummarizeHeuristicData(\n this.runtime.deltaManager.lastSequenceNumber,\n { /** summary attempt baseline for heuristics */\n refSequenceNumber: this.runtime.deltaManager.initialSequenceNumber,\n summaryTime: Date.now(),\n } as const,\n ),\n (errorCode: string) => {\n if (!this._disposed) {\n this.emit(\"summarizingError\", createSummarizingWarning(errorCode, true));\n }\n },\n this.summaryCollection,\n runCoordinator /* cancellationToken */,\n (reason) => runCoordinator.stop(reason), /* stopSummarizerCallback */\n options,\n );\n this.runningSummarizer = runningSummarizer;\n\n // Handle summary acks\n // Note: no exceptions are thrown from handleSummaryAcks handler as it handles all exceptions\n this.handleSummaryAcks().catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"HandleSummaryAckFatalError\" }, error);\n });\n\n // Listen for ops\n this.systemOpListener = (op: ISequencedDocumentMessage) => runningSummarizer.handleSystemOp(op);\n this.runtime.deltaManager.inbound.on(\"op\", this.systemOpListener);\n\n this.opListener = (error: any, op: ISequencedDocumentMessage) => runningSummarizer.handleOp(error, op);\n this.runtime.on(\"batchEnd\", this.opListener);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopReason = await stopP;\n\n // There are two possible approaches here:\n // 1. Propagate cancellation from this.stopDeferred to runCoordinator. This will ensure that we move to the exit\n // faster, including breaking out of the RunningSummarizer.trySummarize() faster.\n // We could create new coordinator and pass it to waitStop() -> trySummarizeOnce(\"lastSummary\") flow.\n // The con of this approach is that we might cancel active summary, and lastSummary will fail because it\n // did not wait for ack/nack from previous summary. Plus we disregard any 429 kind of info from service\n // that way (i.e. trySummarize() loop might have been waiting for 5 min because storage told us so).\n // In general, it's more wasted resources.\n // 2. We can not do it and make waitStop() do last summary only if there was no active summary. This ensures\n // that client behaves properly (from server POV) and we do not waste resources. But, it may mean we wait\n // substantially longer for trySummarize() retries to play out and thus this summary loop may run into\n // conflict with new summarizer client starting on different client.\n // As of now, #2 is implemented. It's more forward looking, as issue #7279 suggests changing design for new\n // summarizer client to not be created until current summarizer fully moves to exit, and that would reduce\n // cons of #2 substantially.\n\n // Cleanup after running\n await runningSummarizer.waitStop(!runCoordinator.cancelled /* allowLastSummary */);\n\n // Propagate reason and ensure that if someone is waiting for cancellation token, they are moving to exit\n runCoordinator.stop(stopReason);\n\n return stopReason;\n }\n\n /**\n * Disposes of resources after running. This cleanup will\n * clear any outstanding timers and reset some of the state\n * properties.\n * Called by ContainerRuntime when it is disposed, as well as at the end the run().\n */\n public dispose() {\n // Given that the call can come from own ContainerRuntime, ensure that we stop all the processes.\n this.stop(\"summarizerClientDisconnected\");\n\n this._disposed = true;\n if (this.runningSummarizer) {\n this.runningSummarizer.dispose();\n this.runningSummarizer = undefined;\n }\n if (this.systemOpListener) {\n this.runtime.deltaManager.inbound.off(\"op\", this.systemOpListener);\n }\n if (this.opListener) {\n this.runtime.removeListener(\"batchEnd\", this.opListener);\n }\n }\n\n public readonly summarizeOnDemand: ISummarizer[\"summarizeOnDemand\"] = (...args) => {\n if (this._disposed || this.runningSummarizer === undefined || this.runningSummarizer.disposed) {\n throw Error(\"Summarizer is not running or already disposed.\");\n }\n return this.runningSummarizer.summarizeOnDemand(...args);\n };\n\n public readonly enqueueSummarize: ISummarizer[\"enqueueSummarize\"] = (...args) => {\n if (this._disposed || this.runningSummarizer === undefined || this.runningSummarizer.disposed) {\n throw Error(\"Summarizer is not running or already disposed.\");\n }\n return this.runningSummarizer.enqueueSummarize(...args);\n };\n\n private async handleSummaryAcks() {\n let refSequenceNumber = this.runtime.deltaManager.initialSequenceNumber;\n while (this.runningSummarizer) {\n const summaryLogger = this.runningSummarizer.tryGetCorrelatedLogger(refSequenceNumber) ?? this.logger;\n try {\n const ack = await this.summaryCollection.waitSummaryAck(refSequenceNumber);\n refSequenceNumber = ack.summaryOp.referenceSequenceNumber;\n\n await this.internalsProvider.refreshLatestSummaryAck(\n ack.summaryOp.contents.handle,\n ack.summaryAck.contents.handle,\n refSequenceNumber,\n summaryLogger,\n );\n } catch (error) {\n summaryLogger.sendErrorEvent({ eventName: \"HandleSummaryAckError\", refSequenceNumber }, error);\n }\n refSequenceNumber++;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../src/summarizer.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { EventEmitter } from \"events\";\nimport { Deferred } from \"@fluidframework/common-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ChildLogger, IFluidErrorBase, LoggingError } from \"@fluidframework/telemetry-utils\";\nimport {\n IRequest,\n IResponse,\n IFluidHandleContext,\n IFluidHandle,\n} from \"@fluidframework/core-interfaces\";\nimport { wrapErrorAndLog } from \"@fluidframework/container-utils\";\nimport {\n ISequencedDocumentMessage,\n ISummaryConfiguration,\n} from \"@fluidframework/protocol-definitions\";\nimport { create404Response } from \"@fluidframework/runtime-utils\";\nimport { ICancellableSummarizerController } from \"./runWhileConnectedCoordinator\";\nimport { SummaryCollection } from \"./summaryCollection\";\nimport { SummarizerHandle } from \"./summarizerHandle\";\nimport { RunningSummarizer } from \"./runningSummarizer\";\nimport {\n ISummarizer,\n ISummarizerInternalsProvider,\n ISummarizerOptions,\n ISummarizerRuntime,\n ISummarizingWarning,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nimport { SummarizeHeuristicData } from \"./summarizerHeuristics\";\nimport { IConnectableRuntime } from \".\";\n\nconst summarizingError = \"summarizingError\";\n\nexport class SummarizingWarning extends LoggingError implements ISummarizingWarning, IFluidErrorBase {\n readonly errorType = summarizingError;\n readonly canRetry = true;\n\n constructor(\n errorMessage: string,\n readonly fluidErrorCode: string,\n readonly logged: boolean = false,\n ) {\n super(errorMessage);\n }\n\n static wrap(error: any, errorCode: string, logged: boolean = false, logger: ITelemetryLogger) {\n const newErrorFn = (errMsg: string) => new SummarizingWarning(errMsg, errorCode, logged);\n return wrapErrorAndLog<SummarizingWarning>(error, newErrorFn, logger);\n }\n}\n\nexport const createSummarizingWarning =\n (errorCode: string, logged: boolean) => new SummarizingWarning(errorCode, errorCode, logged);\n\n/**\n * Summarizer is responsible for coordinating when to generate and send summaries.\n * It is the main entry point for summary work.\n * It is created only by summarizing container (i.e. one with clientType === \"summarizer\")\n */\nexport class Summarizer extends EventEmitter implements ISummarizer {\n public get IFluidLoadable() { return this; }\n public get IFluidRouter() { return this; }\n public get ISummarizer() { return this; }\n\n private readonly logger: ITelemetryLogger;\n private runningSummarizer?: RunningSummarizer;\n private systemOpListener?: (op: ISequencedDocumentMessage) => void;\n private opListener?: (error: any, op: ISequencedDocumentMessage) => void;\n private _disposed: boolean = false;\n\n private readonly innerHandle: IFluidHandle<this>;\n\n public get handle(): IFluidHandle<this> { return this.innerHandle; }\n private readonly stopDeferred = new Deferred<SummarizerStopReason>();\n\n constructor(\n url: string,\n /** Reference to runtime that created this object.\n * i.e. runtime with clientType === \"summarizer\"\n */\n private readonly runtime: ISummarizerRuntime,\n private readonly configurationGetter: () => ISummaryConfiguration,\n /** Represents an object that can generate summary.\n * In practical terms, it's same runtime (this.runtime) with clientType === \"summarizer\".\n */\n private readonly internalsProvider: ISummarizerInternalsProvider,\n handleContext: IFluidHandleContext,\n public readonly summaryCollection: SummaryCollection,\n private readonly runCoordinatorCreateFn:\n (runtime: IConnectableRuntime) => Promise<ICancellableSummarizerController>,\n ) {\n super();\n this.logger = ChildLogger.create(this.runtime.logger, \"Summarizer\");\n this.innerHandle = new SummarizerHandle(this, url, handleContext);\n }\n\n public async run(\n onBehalfOf: string,\n options?: Readonly<Partial<ISummarizerOptions>>): Promise<SummarizerStopReason>\n {\n try {\n return await this.runCore(onBehalfOf, options);\n } catch (error) {\n this.stop(\"summarizerException\");\n throw SummarizingWarning.wrap(error, \"summarizerRun\", false /* logged */, this.logger);\n } finally {\n this.dispose();\n this.runtime.closeFn();\n }\n }\n\n /**\n * Stops the summarizer from running. This will complete\n * the run promise, and also close the container.\n * @param reason - reason code for stopping\n */\n public stop(reason: SummarizerStopReason) {\n this.stopDeferred.resolve(reason);\n }\n\n public async request(request: IRequest): Promise<IResponse> {\n if (request.url === \"/\" || request.url === \"\") {\n return {\n mimeType: \"fluid/object\",\n status: 200,\n value: this,\n };\n }\n return create404Response(request);\n }\n\n private async runCore(\n onBehalfOf: string,\n options?: Readonly<Partial<ISummarizerOptions>>): Promise<SummarizerStopReason>\n {\n // Initialize values and first ack (time is not exact)\n this.logger.sendTelemetryEvent({\n eventName: \"RunningSummarizer\",\n onBehalfOf,\n initSummarySeqNumber: this.runtime.deltaManager.initialSequenceNumber,\n });\n\n const runCoordinator: ICancellableSummarizerController = await this.runCoordinatorCreateFn(this.runtime);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopP = Promise.race([runCoordinator.waitCancelled, this.stopDeferred.promise]);\n void stopP.then((reason) => {\n this.logger.sendTelemetryEvent({\n eventName: \"StoppingSummarizer\",\n onBehalfOf,\n reason,\n });\n });\n\n if (runCoordinator.cancelled) {\n return runCoordinator.waitCancelled;\n }\n\n // Summarizing container ID (with clientType === \"summarizer\")\n const clientId = this.runtime.clientId;\n if (clientId === undefined) {\n throw Error(\"clientId should be defined if connected.\");\n }\n\n const runningSummarizer = await RunningSummarizer.start(\n this.logger,\n this.summaryCollection.createWatcher(clientId),\n this.configurationGetter(),\n async (...args) => this.internalsProvider.submitSummary(...args), // submitSummaryCallback\n new SummarizeHeuristicData(\n this.runtime.deltaManager.lastSequenceNumber,\n { /** summary attempt baseline for heuristics */\n refSequenceNumber: this.runtime.deltaManager.initialSequenceNumber,\n summaryTime: Date.now(),\n } as const,\n ),\n (errorCode: string) => {\n if (!this._disposed) {\n this.emit(\"summarizingError\", createSummarizingWarning(errorCode, true));\n }\n },\n this.summaryCollection,\n runCoordinator /* cancellationToken */,\n (reason) => runCoordinator.stop(reason), /* stopSummarizerCallback */\n options,\n );\n this.runningSummarizer = runningSummarizer;\n\n // Handle summary acks\n // Note: no exceptions are thrown from handleSummaryAcks handler as it handles all exceptions\n this.handleSummaryAcks().catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"HandleSummaryAckFatalError\" }, error);\n });\n\n // Listen for ops\n this.systemOpListener = (op: ISequencedDocumentMessage) => runningSummarizer.handleSystemOp(op);\n this.runtime.deltaManager.inbound.on(\"op\", this.systemOpListener);\n\n this.opListener = (error: any, op: ISequencedDocumentMessage) => runningSummarizer.handleOp(error, op);\n this.runtime.on(\"batchEnd\", this.opListener);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopReason = await stopP;\n\n // There are two possible approaches here:\n // 1. Propagate cancellation from this.stopDeferred to runCoordinator. This will ensure that we move to the exit\n // faster, including breaking out of the RunningSummarizer.trySummarize() faster.\n // We could create new coordinator and pass it to waitStop() -> trySummarizeOnce(\"lastSummary\") flow.\n // The con of this approach is that we might cancel active summary, and lastSummary will fail because it\n // did not wait for ack/nack from previous summary. Plus we disregard any 429 kind of info from service\n // that way (i.e. trySummarize() loop might have been waiting for 5 min because storage told us so).\n // In general, it's more wasted resources.\n // 2. We can not do it and make waitStop() do last summary only if there was no active summary. This ensures\n // that client behaves properly (from server POV) and we do not waste resources. But, it may mean we wait\n // substantially longer for trySummarize() retries to play out and thus this summary loop may run into\n // conflict with new summarizer client starting on different client.\n // As of now, #2 is implemented. It's more forward looking, as issue #7279 suggests changing design for new\n // summarizer client to not be created until current summarizer fully moves to exit, and that would reduce\n // cons of #2 substantially.\n\n // Cleanup after running\n await runningSummarizer.waitStop(!runCoordinator.cancelled /* allowLastSummary */);\n\n // Propagate reason and ensure that if someone is waiting for cancellation token, they are moving to exit\n runCoordinator.stop(stopReason);\n\n return stopReason;\n }\n\n /**\n * Disposes of resources after running. This cleanup will\n * clear any outstanding timers and reset some of the state\n * properties.\n * Called by ContainerRuntime when it is disposed, as well as at the end the run().\n */\n public dispose() {\n // Given that the call can come from own ContainerRuntime, ensure that we stop all the processes.\n this.stop(\"summarizerClientDisconnected\");\n\n this._disposed = true;\n if (this.runningSummarizer) {\n this.runningSummarizer.dispose();\n this.runningSummarizer = undefined;\n }\n if (this.systemOpListener) {\n this.runtime.deltaManager.inbound.off(\"op\", this.systemOpListener);\n }\n if (this.opListener) {\n this.runtime.removeListener(\"batchEnd\", this.opListener);\n }\n }\n\n public readonly summarizeOnDemand: ISummarizer[\"summarizeOnDemand\"] = (...args) => {\n if (this._disposed || this.runningSummarizer === undefined || this.runningSummarizer.disposed) {\n throw Error(\"Summarizer is not running or already disposed.\");\n }\n return this.runningSummarizer.summarizeOnDemand(...args);\n };\n\n public readonly enqueueSummarize: ISummarizer[\"enqueueSummarize\"] = (...args) => {\n if (this._disposed || this.runningSummarizer === undefined || this.runningSummarizer.disposed) {\n throw Error(\"Summarizer is not running or already disposed.\");\n }\n return this.runningSummarizer.enqueueSummarize(...args);\n };\n\n private async handleSummaryAcks() {\n let refSequenceNumber = this.runtime.deltaManager.initialSequenceNumber;\n while (this.runningSummarizer) {\n const summaryLogger = this.runningSummarizer.tryGetCorrelatedLogger(refSequenceNumber) ?? this.logger;\n try {\n const ack = await this.summaryCollection.waitSummaryAck(refSequenceNumber);\n refSequenceNumber = ack.summaryOp.referenceSequenceNumber;\n\n await this.internalsProvider.refreshLatestSummaryAck(\n ack.summaryOp.contents.handle,\n ack.summaryAck.contents.handle,\n refSequenceNumber,\n summaryLogger,\n );\n } catch (error) {\n summaryLogger.sendErrorEvent({ eventName: \"HandleSummaryAckError\", refSequenceNumber }, error);\n }\n refSequenceNumber++;\n }\n }\n}\n"]}
|
|
@@ -16,7 +16,7 @@ export interface ISummarizerClientElection extends IEventProvider<ISummarizerCli
|
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* This class encapsulates logic around tracking the elected summarizer client.
|
|
19
|
-
* It will handle
|
|
19
|
+
* It will handle updating the elected client when a summary ack hasn't been seen
|
|
20
20
|
* for some configured number of ops.
|
|
21
21
|
*/
|
|
22
22
|
export declare class SummarizerClientElection extends TypedEventEmitter<ISummarizerClientElectionEvents> implements ISummarizerClientElection {
|
|
@@ -7,7 +7,7 @@ import { MessageType } from "@fluidframework/protocol-definitions";
|
|
|
7
7
|
export const summarizerClientType = "summarizer";
|
|
8
8
|
/**
|
|
9
9
|
* This class encapsulates logic around tracking the elected summarizer client.
|
|
10
|
-
* It will handle
|
|
10
|
+
* It will handle updating the elected client when a summary ack hasn't been seen
|
|
11
11
|
* for some configured number of ops.
|
|
12
12
|
*/
|
|
13
13
|
export class SummarizerClientElection extends TypedEventEmitter {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizerClientElection.js","sourceRoot":"","sources":["../src/summarizerClientElection.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 { IEvent, IEventProvider, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport { IClientDetails, MessageType } from \"@fluidframework/protocol-definitions\";\nimport { IOrderedClientElection, ISerializedElection, ITrackedClient } from \"./orderedClientElection\";\nimport { ISummaryCollectionOpEvents } from \"./summaryCollection\";\n\nexport const summarizerClientType = \"summarizer\";\n\nexport interface ISummarizerClientElectionEvents extends IEvent {\n (event: \"electedSummarizerChanged\", handler: () => void): void;\n}\n\nexport interface ISummarizerClientElection extends IEventProvider<ISummarizerClientElectionEvents> {\n readonly electedClientId: string | undefined;\n}\n\n/**\n * This class encapsulates logic around tracking the elected summarizer client.\n * It will handle updated the elected client when a summary ack hasn't been seen\n * for some configured number of ops.\n */\nexport class SummarizerClientElection\n extends TypedEventEmitter<ISummarizerClientElectionEvents>\n implements ISummarizerClientElection {\n /**\n * Used to calculate number of ops since last summary ack for the current elected client.\n * This will be undefined if there is no elected summarizer, or no summary ack has been\n * observed since this client was elected.\n * When a summary ack comes in, this will be set to the sequence number of the summary ack.\n */\n private lastSummaryAckSeqForClient: number | undefined;\n /**\n * Used to prevent excess logging by recording the sequence number that we last reported at,\n * and making sure we don't report another event to telemetry. If things work as intended,\n * this is not needed, otherwise it could report an event on every op in worst case scenario.\n */\n private lastReportedSeq = 0;\n\n public get electedClientId() {\n return this.clientElection.electedClient?.clientId;\n }\n\n constructor(\n private readonly logger: ITelemetryLogger,\n private readonly summaryCollection: IEventProvider<ISummaryCollectionOpEvents>,\n public readonly clientElection: IOrderedClientElection,\n private readonly maxOpsSinceLastSummary: number,\n private readonly electionEnabled: boolean,\n ) {\n super();\n // On every inbound op, if enough ops pass without seeing a summary ack (per elected client),\n // elect a new client and log to telemetry.\n this.summaryCollection.on(\"default\", ({ sequenceNumber }) => {\n const electedClientId = this.electedClientId;\n if (electedClientId === undefined) {\n // Reset election if no elected client, but eligible clients are connected.\n // This should be uncommon, but is possible if the initial state of the\n // ordered client election contains an undefined client id or one not found\n // in the quorum (the latter would already log an error).\n if (this.clientElection.eligibleCount > 0) {\n this.clientElection.resetElectedClient(sequenceNumber);\n }\n return;\n }\n let electionSequenceNumber = this.clientElection.electionSequenceNumber;\n const opsWithoutSummary = sequenceNumber - (this.lastSummaryAckSeqForClient ?? electionSequenceNumber);\n if (opsWithoutSummary > this.maxOpsSinceLastSummary) {\n // Log and elect a new summarizer client.\n const opsSinceLastReport = sequenceNumber - this.lastReportedSeq;\n if (opsSinceLastReport > this.maxOpsSinceLastSummary) {\n this.logger.sendErrorEvent({\n eventName: \"ElectedClientNotSummarizing\",\n electedClientId,\n lastSummaryAckSeqForClient: this.lastSummaryAckSeqForClient,\n electionSequenceNumber,\n nextElectedClientId: this.clientElection.peekNextElectedClient()?.clientId,\n });\n this.lastReportedSeq = sequenceNumber;\n }\n\n if (this.electionEnabled) {\n this.clientElection.incrementElectedClient(sequenceNumber);\n\n // Verify that state incremented as expected. This should be reliable,\n // since all of OrderedClientElection is synchronous.\n electionSequenceNumber = this.clientElection.electionSequenceNumber;\n if (sequenceNumber > (this.lastSummaryAckSeqForClient ?? electionSequenceNumber)) {\n if (opsSinceLastReport > this.maxOpsSinceLastSummary) {\n this.logger.sendErrorEvent({\n eventName: \"UnexpectedElectionSequenceNumber\",\n // Expected to be undefined\n lastSummaryAckSeqForClient: this.lastSummaryAckSeqForClient,\n // Expected to be same as op sequenceNumber\n electionSequenceNumber,\n });\n }\n }\n }\n }\n });\n\n // When a summary ack comes in, reset our op seq counter.\n this.summaryCollection.on(MessageType.SummaryAck, (op) => {\n this.lastSummaryAckSeqForClient = op.sequenceNumber;\n });\n\n // Use oldest client election for unanimously and deterministically deciding\n // which client should summarize.\n this.clientElection.on(\"election\", (client, sequenceNumber) => {\n this.lastSummaryAckSeqForClient = undefined;\n if (client === undefined && this.clientElection.eligibleCount > 0) {\n // If no client is valid for election, reset to the oldest again.\n // Also make extra sure not to get stuck in an infinite loop here:\n // If there are no eligible clients, just wait until a client joins\n // and will be auto-elected.\n this.clientElection.resetElectedClient(sequenceNumber);\n }\n // Election can trigger a change in SummaryManager state.\n this.emit(\"electedSummarizerChanged\");\n });\n }\n\n public serialize(): ISerializedElection {\n const { electedClientId, electionSequenceNumber } = this.clientElection.serialize();\n return {\n electedClientId,\n electionSequenceNumber: this.lastSummaryAckSeqForClient ?? electionSequenceNumber,\n };\n }\n\n public static isClientEligible(client: ITrackedClient): boolean {\n const details = client.client.details;\n if (details === undefined) {\n // Very old clients back-compat\n return true;\n }\n return SummarizerClientElection.clientDetailsPermitElection(details);\n }\n\n public static readonly clientDetailsPermitElection = (details: IClientDetails): boolean =>\n details.capabilities.interactive && details.type !== summarizerClientType;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"summarizerClientElection.js","sourceRoot":"","sources":["../src/summarizerClientElection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAkB,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAInF,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAY,CAAC;AAUjD;;;;GAIG;AACH,MAAM,OAAO,wBACT,SAAQ,iBAAkD;IAoB1D,YACqB,MAAwB,EACxB,iBAA6D,EAC9D,cAAsC,EACrC,sBAA8B,EAC9B,eAAwB;QAEzC,KAAK,EAAE,CAAC;QANS,WAAM,GAAN,MAAM,CAAkB;QACxB,sBAAiB,GAAjB,iBAAiB,CAA4C;QAC9D,mBAAc,GAAd,cAAc,CAAwB;QACrC,2BAAsB,GAAtB,sBAAsB,CAAQ;QAC9B,oBAAe,GAAf,eAAe,CAAS;QAhB7C;;;;WAIG;QACK,oBAAe,GAAG,CAAC,CAAC;QAcxB,6FAA6F;QAC7F,2CAA2C;QAC3C,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE;;YACxD,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;YAC7C,IAAI,eAAe,KAAK,SAAS,EAAE;gBAC/B,2EAA2E;gBAC3E,uEAAuE;gBACvE,2EAA2E;gBAC3E,yDAAyD;gBACzD,IAAI,IAAI,CAAC,cAAc,CAAC,aAAa,GAAG,CAAC,EAAE;oBACvC,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;iBAC1D;gBACD,OAAO;aACV;YACD,IAAI,sBAAsB,GAAG,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAAC;YACxE,MAAM,iBAAiB,GAAG,cAAc,GAAG,OAAC,IAAI,CAAC,0BAA0B,mCAAI,sBAAsB,CAAC,CAAC;YACvG,IAAI,iBAAiB,GAAG,IAAI,CAAC,sBAAsB,EAAE;gBACjD,yCAAyC;gBACzC,MAAM,kBAAkB,GAAG,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC;gBACjE,IAAI,kBAAkB,GAAG,IAAI,CAAC,sBAAsB,EAAE;oBAClD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;wBACvB,SAAS,EAAE,6BAA6B;wBACxC,eAAe;wBACf,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;wBAC3D,sBAAsB;wBACtB,mBAAmB,QAAE,IAAI,CAAC,cAAc,CAAC,qBAAqB,EAAE,0CAAE,QAAQ;qBAC7E,CAAC,CAAC;oBACH,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC;iBACzC;gBAED,IAAI,IAAI,CAAC,eAAe,EAAE;oBACtB,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC;oBAE3D,sEAAsE;oBACtE,qDAAqD;oBACrD,sBAAsB,GAAG,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAAC;oBACpE,IAAI,cAAc,GAAG,OAAC,IAAI,CAAC,0BAA0B,mCAAI,sBAAsB,CAAC,EAAE;wBAC9E,IAAI,kBAAkB,GAAG,IAAI,CAAC,sBAAsB,EAAE;4BAClD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;gCACvB,SAAS,EAAE,kCAAkC;gCAC7C,2BAA2B;gCAC3B,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;gCAC3D,2CAA2C;gCAC3C,sBAAsB;6BACzB,CAAC,CAAC;yBACN;qBACJ;iBACJ;aACJ;QACL,CAAC,CAAC,CAAC;QAEH,yDAAyD;QACzD,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE;YACrD,IAAI,CAAC,0BAA0B,GAAG,EAAE,CAAC,cAAc,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,4EAA4E;QAC5E,iCAAiC;QACjC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE;YAC1D,IAAI,CAAC,0BAA0B,GAAG,SAAS,CAAC;YAC5C,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,cAAc,CAAC,aAAa,GAAG,CAAC,EAAE;gBAC/D,iEAAiE;gBACjE,kEAAkE;gBAClE,mEAAmE;gBACnE,4BAA4B;gBAC5B,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;aAC1D;YACD,yDAAyD;YACzD,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACP,CAAC;IAlFD,IAAW,eAAe;;QACtB,aAAO,IAAI,CAAC,cAAc,CAAC,aAAa,0CAAE,QAAQ,CAAC;IACvD,CAAC;IAkFM,SAAS;;QACZ,MAAM,EAAE,eAAe,EAAE,sBAAsB,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC;QACpF,OAAO;YACH,eAAe;YACf,sBAAsB,QAAE,IAAI,CAAC,0BAA0B,mCAAI,sBAAsB;SACpF,CAAC;IACN,CAAC;IAEM,MAAM,CAAC,gBAAgB,CAAC,MAAsB;QACjD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QACtC,IAAI,OAAO,KAAK,SAAS,EAAE;YACvB,+BAA+B;YAC/B,OAAO,IAAI,CAAC;SACf;QACD,OAAO,wBAAwB,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAC;IACzE,CAAC;;AAEsB,oDAA2B,GAAG,CAAC,OAAuB,EAAW,EAAE,CACtF,OAAO,CAAC,YAAY,CAAC,WAAW,IAAI,OAAO,CAAC,IAAI,KAAK,oBAAoB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IEvent, IEventProvider, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport { IClientDetails, MessageType } from \"@fluidframework/protocol-definitions\";\nimport { IOrderedClientElection, ISerializedElection, ITrackedClient } from \"./orderedClientElection\";\nimport { ISummaryCollectionOpEvents } from \"./summaryCollection\";\n\nexport const summarizerClientType = \"summarizer\";\n\nexport interface ISummarizerClientElectionEvents extends IEvent {\n (event: \"electedSummarizerChanged\", handler: () => void): void;\n}\n\nexport interface ISummarizerClientElection extends IEventProvider<ISummarizerClientElectionEvents> {\n readonly electedClientId: string | undefined;\n}\n\n/**\n * This class encapsulates logic around tracking the elected summarizer client.\n * It will handle updating the elected client when a summary ack hasn't been seen\n * for some configured number of ops.\n */\nexport class SummarizerClientElection\n extends TypedEventEmitter<ISummarizerClientElectionEvents>\n implements ISummarizerClientElection {\n /**\n * Used to calculate number of ops since last summary ack for the current elected client.\n * This will be undefined if there is no elected summarizer, or no summary ack has been\n * observed since this client was elected.\n * When a summary ack comes in, this will be set to the sequence number of the summary ack.\n */\n private lastSummaryAckSeqForClient: number | undefined;\n /**\n * Used to prevent excess logging by recording the sequence number that we last reported at,\n * and making sure we don't report another event to telemetry. If things work as intended,\n * this is not needed, otherwise it could report an event on every op in worst case scenario.\n */\n private lastReportedSeq = 0;\n\n public get electedClientId() {\n return this.clientElection.electedClient?.clientId;\n }\n\n constructor(\n private readonly logger: ITelemetryLogger,\n private readonly summaryCollection: IEventProvider<ISummaryCollectionOpEvents>,\n public readonly clientElection: IOrderedClientElection,\n private readonly maxOpsSinceLastSummary: number,\n private readonly electionEnabled: boolean,\n ) {\n super();\n // On every inbound op, if enough ops pass without seeing a summary ack (per elected client),\n // elect a new client and log to telemetry.\n this.summaryCollection.on(\"default\", ({ sequenceNumber }) => {\n const electedClientId = this.electedClientId;\n if (electedClientId === undefined) {\n // Reset election if no elected client, but eligible clients are connected.\n // This should be uncommon, but is possible if the initial state of the\n // ordered client election contains an undefined client id or one not found\n // in the quorum (the latter would already log an error).\n if (this.clientElection.eligibleCount > 0) {\n this.clientElection.resetElectedClient(sequenceNumber);\n }\n return;\n }\n let electionSequenceNumber = this.clientElection.electionSequenceNumber;\n const opsWithoutSummary = sequenceNumber - (this.lastSummaryAckSeqForClient ?? electionSequenceNumber);\n if (opsWithoutSummary > this.maxOpsSinceLastSummary) {\n // Log and elect a new summarizer client.\n const opsSinceLastReport = sequenceNumber - this.lastReportedSeq;\n if (opsSinceLastReport > this.maxOpsSinceLastSummary) {\n this.logger.sendErrorEvent({\n eventName: \"ElectedClientNotSummarizing\",\n electedClientId,\n lastSummaryAckSeqForClient: this.lastSummaryAckSeqForClient,\n electionSequenceNumber,\n nextElectedClientId: this.clientElection.peekNextElectedClient()?.clientId,\n });\n this.lastReportedSeq = sequenceNumber;\n }\n\n if (this.electionEnabled) {\n this.clientElection.incrementElectedClient(sequenceNumber);\n\n // Verify that state incremented as expected. This should be reliable,\n // since all of OrderedClientElection is synchronous.\n electionSequenceNumber = this.clientElection.electionSequenceNumber;\n if (sequenceNumber > (this.lastSummaryAckSeqForClient ?? electionSequenceNumber)) {\n if (opsSinceLastReport > this.maxOpsSinceLastSummary) {\n this.logger.sendErrorEvent({\n eventName: \"UnexpectedElectionSequenceNumber\",\n // Expected to be undefined\n lastSummaryAckSeqForClient: this.lastSummaryAckSeqForClient,\n // Expected to be same as op sequenceNumber\n electionSequenceNumber,\n });\n }\n }\n }\n }\n });\n\n // When a summary ack comes in, reset our op seq counter.\n this.summaryCollection.on(MessageType.SummaryAck, (op) => {\n this.lastSummaryAckSeqForClient = op.sequenceNumber;\n });\n\n // Use oldest client election for unanimously and deterministically deciding\n // which client should summarize.\n this.clientElection.on(\"election\", (client, sequenceNumber) => {\n this.lastSummaryAckSeqForClient = undefined;\n if (client === undefined && this.clientElection.eligibleCount > 0) {\n // If no client is valid for election, reset to the oldest again.\n // Also make extra sure not to get stuck in an infinite loop here:\n // If there are no eligible clients, just wait until a client joins\n // and will be auto-elected.\n this.clientElection.resetElectedClient(sequenceNumber);\n }\n // Election can trigger a change in SummaryManager state.\n this.emit(\"electedSummarizerChanged\");\n });\n }\n\n public serialize(): ISerializedElection {\n const { electedClientId, electionSequenceNumber } = this.clientElection.serialize();\n return {\n electedClientId,\n electionSequenceNumber: this.lastSummaryAckSeqForClient ?? electionSequenceNumber,\n };\n }\n\n public static isClientEligible(client: ITrackedClient): boolean {\n const details = client.client.details;\n if (details === undefined) {\n // Very old clients back-compat\n return true;\n }\n return SummarizerClientElection.clientDetailsPermitElection(details);\n }\n\n public static readonly clientDetailsPermitElection = (details: IClientDetails): boolean =>\n details.capabilities.interactive && details.type !== summarizerClientType;\n}\n"]}
|
package/lib/summaryManager.d.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import { IDisposable, IEvent, IEventProvider, ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
6
6
|
import { TypedEventEmitter } from "@fluidframework/common-utils";
|
|
7
7
|
import { IFluidRouter } from "@fluidframework/core-interfaces";
|
|
8
|
-
import { IDeltaManager } from "@fluidframework/container-definitions";
|
|
9
8
|
import { ISummarizerClientElection } from "./summarizerClientElection";
|
|
10
9
|
import { IThrottler } from "./throttler";
|
|
11
10
|
import { ISummarizer, ISummarizerOptions, ISummarizingWarning } from "./summarizerTypes";
|
|
@@ -92,10 +91,18 @@ export declare class SummaryManager extends TypedEventEmitter<ISummaryManagerEve
|
|
|
92
91
|
readonly enqueueSummarize: ISummarizer["enqueueSummarize"];
|
|
93
92
|
dispose(): void;
|
|
94
93
|
}
|
|
94
|
+
export interface ISummarizerRequestOptions {
|
|
95
|
+
cache: boolean;
|
|
96
|
+
reconnect: boolean;
|
|
97
|
+
summarizingClient: boolean;
|
|
98
|
+
}
|
|
95
99
|
/**
|
|
96
100
|
* Forms a function that will request a Summarizer.
|
|
97
101
|
* @param loaderRouter - the loader acting as an IFluidRouter
|
|
98
|
-
* @param
|
|
102
|
+
* @param lastSequenceNumber - the last sequence number (e.g., from DeltaManager)
|
|
103
|
+
* @param cache - use cache to retrieve summarizer
|
|
104
|
+
* @param summarizingClient - is summarizer client
|
|
105
|
+
* @param reconnect - can reconnect on connection loss
|
|
99
106
|
*/
|
|
100
|
-
export declare const formRequestSummarizerFn: (loaderRouter: IFluidRouter,
|
|
107
|
+
export declare const formRequestSummarizerFn: (loaderRouter: IFluidRouter, lastSequenceNumber: number, { cache, reconnect, summarizingClient }: ISummarizerRequestOptions) => () => Promise<ISummarizer>;
|
|
101
108
|
//# sourceMappingURL=summaryManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summaryManager.d.ts","sourceRoot":"","sources":["../src/summaryManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3G,OAAO,EAAE,iBAAiB,EAAU,MAAM,8BAA8B,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAY,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"summaryManager.d.ts","sourceRoot":"","sources":["../src/summaryManager.ts"],"names":[],"mappings":"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"}
|
package/lib/summaryManager.js
CHANGED
|
@@ -258,20 +258,23 @@ export class SummaryManager extends TypedEventEmitter {
|
|
|
258
258
|
/**
|
|
259
259
|
* Forms a function that will request a Summarizer.
|
|
260
260
|
* @param loaderRouter - the loader acting as an IFluidRouter
|
|
261
|
-
* @param
|
|
261
|
+
* @param lastSequenceNumber - the last sequence number (e.g., from DeltaManager)
|
|
262
|
+
* @param cache - use cache to retrieve summarizer
|
|
263
|
+
* @param summarizingClient - is summarizer client
|
|
264
|
+
* @param reconnect - can reconnect on connection loss
|
|
262
265
|
*/
|
|
263
|
-
export const formRequestSummarizerFn = (loaderRouter,
|
|
266
|
+
export const formRequestSummarizerFn = (loaderRouter, lastSequenceNumber, { cache, reconnect, summarizingClient }) => async () => {
|
|
264
267
|
// TODO eventually we may wish to spawn an execution context from which to run this
|
|
265
268
|
const request = {
|
|
266
269
|
headers: {
|
|
267
|
-
[LoaderHeader.cache]:
|
|
270
|
+
[LoaderHeader.cache]: cache,
|
|
268
271
|
[LoaderHeader.clientDetails]: {
|
|
269
272
|
capabilities: { interactive: false },
|
|
270
273
|
type: summarizerClientType,
|
|
271
274
|
},
|
|
272
|
-
[DriverHeader.summarizingClient]:
|
|
273
|
-
[LoaderHeader.reconnect]:
|
|
274
|
-
[LoaderHeader.sequenceNumber]:
|
|
275
|
+
[DriverHeader.summarizingClient]: summarizingClient,
|
|
276
|
+
[LoaderHeader.reconnect]: reconnect,
|
|
277
|
+
[LoaderHeader.sequenceNumber]: lastSequenceNumber,
|
|
275
278
|
},
|
|
276
279
|
url: "/_summarizer",
|
|
277
280
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summaryManager.js","sourceRoot":"","sources":["../src/summaryManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDisposable, IEvent, IEventProvider, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { TypedEventEmitter, assert } from \"@fluidframework/common-utils\";\nimport { ChildLogger, PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { IFluidRouter, IRequest } from \"@fluidframework/core-interfaces\";\nimport { IDeltaManager, LoaderHeader } from \"@fluidframework/container-definitions\";\nimport { DriverHeader } from \"@fluidframework/driver-definitions\";\nimport { requestFluidObject } from \"@fluidframework/runtime-utils\";\nimport { createSummarizingWarning } from \"./summarizer\";\nimport { ISummarizerClientElection, summarizerClientType } from \"./summarizerClientElection\";\nimport { IThrottler } from \"./throttler\";\nimport { ISummarizer, ISummarizerOptions, ISummarizingWarning, SummarizerStopReason } from \"./summarizerTypes\";\nimport { SummaryCollection } from \"./summaryCollection\";\n\nconst defaultInitialDelayMs = 5000;\nconst defaultOpsToBypassInitialDelay = 4000;\n\nexport enum SummaryManagerState {\n Off = 0,\n Starting = 1,\n Running = 2,\n Stopping = 3,\n}\n\n// Please note that all reasons in this list are not errors,\n// and thus they are not raised today to parent container as error.\n// If this needs to be changed in future, we should re-evaluate what and how we raise to summarizer\ntype StopReason = Extract<SummarizerStopReason, \"parentNotConnected\" | \"parentShouldNotSummarize\">;\ntype ShouldSummarizeState =\n | { shouldSummarize: true; }\n | { shouldSummarize: false; stopReason: StopReason; };\n\nexport interface IConnectedEvents extends IEvent {\n (event: \"connected\", listener: (clientId: string) => void);\n (event: \"disconnected\", listener: () => void);\n}\n\n/**\n * IConnectedState describes an object that SummaryManager can watch to observe connection/disconnection.\n *\n * Under current implementation, its role will be fulfilled by the ContainerRuntime, but this could be replaced\n * with anything else that fulfills the contract if we want to shift the layer that the SummaryManager lives at.\n */\nexport interface IConnectedState extends IEventProvider<IConnectedEvents> {\n readonly connected: boolean;\n\n /**\n * Under current implementation this is undefined if we've never connected, otherwise it's the clientId from our\n * latest connection (even if we've since disconnected!). Although this happens to be the behavior we want in\n * SummaryManager, I suspect that globally we may eventually want to modify this behavior (e.g. make clientId\n * undefined while disconnected). To protect against this, let's assume this field can't be trusted while\n * disconnected and instead separately track \"latest clientId\" in SummaryManager.\n */\n readonly clientId: string | undefined;\n}\n\nexport interface ISummaryManagerEvents extends IEvent {\n (event: \"summarizerWarning\", listener: (warning: ISummarizingWarning) => void);\n}\n\nexport interface ISummaryManagerConfig {\n initialDelayMs: number;\n opsToBypassInitialDelay: number;\n}\n\n/**\n * SummaryManager is created by parent container (i.e. interactive container with clientType !== \"summarizer\") only.\n * It observes changes in calculated summarizer and reacts to changes by either creating summarizer client or\n * stopping existing summarizer client.\n */\nexport class SummaryManager extends TypedEventEmitter<ISummaryManagerEvents> implements IDisposable {\n private readonly logger: ITelemetryLogger;\n private readonly opsToBypassInitialDelay: number;\n private readonly initialDelayMs: number;\n private latestClientId: string | undefined;\n private state = SummaryManagerState.Off;\n private summarizer?: ISummarizer;\n private _disposed = false;\n\n public get disposed() {\n return this._disposed;\n }\n\n public get currentState() { return this.state; }\n\n constructor(\n private readonly clientElection: ISummarizerClientElection,\n private readonly connectedState: IConnectedState,\n private readonly summaryCollection:\n Pick<SummaryCollection, \"opsSinceLastAck\" | \"addOpListener\" | \"removeOpListener\">,\n parentLogger: ITelemetryLogger,\n /** Creates summarizer by asking interactive container to spawn summarizing container and\n * get back its Summarizer instance. */\n private readonly requestSummarizerFn: () => Promise<ISummarizer>,\n private readonly startThrottler: IThrottler,\n {\n initialDelayMs = defaultInitialDelayMs,\n opsToBypassInitialDelay = defaultOpsToBypassInitialDelay,\n }: Readonly<Partial<ISummaryManagerConfig>> = {},\n private readonly summarizerOptions?: Readonly<Partial<ISummarizerOptions>>,\n ) {\n super();\n\n this.logger = ChildLogger.create(\n parentLogger,\n \"SummaryManager\",\n {all:{ clientId: () => this.latestClientId }});\n\n this.connectedState.on(\"connected\", this.handleConnected);\n this.connectedState.on(\"disconnected\", this.handleDisconnected);\n this.latestClientId = this.connectedState.clientId;\n\n this.opsToBypassInitialDelay = opsToBypassInitialDelay;\n this.initialDelayMs = initialDelayMs;\n }\n\n /**\n * Until start is called, the SummaryManager won't begin attempting to start summarization. This ensures there's\n * a window between construction and starting where the caller can attach listeners.\n */\n public start(): void {\n this.clientElection.on(\"electedSummarizerChanged\", this.refreshSummarizer);\n this.refreshSummarizer();\n }\n\n private readonly handleConnected = (clientId: string) => {\n this.latestClientId = clientId;\n // If we have a summarizer, it should have been either cancelled on disconnected by now.\n // But because of lastSummary process, it can still hang around, so there is not much we can\n // check or assert.\n this.refreshSummarizer();\n };\n\n private readonly handleDisconnected = () => {\n this.refreshSummarizer();\n };\n\n private getShouldSummarizeState(): ShouldSummarizeState {\n if (!this.connectedState.connected) {\n return { shouldSummarize: false, stopReason: \"parentNotConnected\" };\n } else if (this.connectedState.clientId !== this.clientElection.electedClientId) {\n return { shouldSummarize: false, stopReason: \"parentShouldNotSummarize\" };\n } else if (this.disposed) {\n assert(false, 0x260 /* \"Disposed should mean disconnected!\" */);\n } else {\n return { shouldSummarize: true };\n }\n }\n\n private readonly refreshSummarizer = () => {\n // Transition states depending on shouldSummarize, which is a calculated property\n // that is only true if this client is connected and is the elected summarizer.\n const shouldSummarizeState = this.getShouldSummarizeState();\n switch (this.state) {\n case SummaryManagerState.Off: {\n if (shouldSummarizeState.shouldSummarize) {\n this.startSummarization();\n }\n return;\n }\n case SummaryManagerState.Starting: {\n // Cannot take any action until summarizer is created\n // state transition will occur after creation\n return;\n }\n case SummaryManagerState.Running: {\n if (shouldSummarizeState.shouldSummarize === false) {\n this.stop(shouldSummarizeState.stopReason);\n }\n return;\n }\n case SummaryManagerState.Stopping: {\n // Cannot take any action until running summarizer finishes\n // state transition will occur after it stops\n return;\n }\n default: {\n return;\n }\n }\n };\n\n private startSummarization() {\n assert(this.state === SummaryManagerState.Off, 0x261 /* \"Expected: off\" */);\n this.state = SummaryManagerState.Starting;\n\n assert(this.summarizer === undefined, 0x262 /* \"Old summarizer is still working!\" */);\n\n let reason = \"unknown\";\n\n this.delayBeforeCreatingSummarizer().then(async (startWithInitialDelay: boolean) => {\n // Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n // but only if creation was delayed. If it was not, then we want to ensure we always create\n // a summarizer to kick off lastSummary. Without that, we would not be able to summarize and get\n // document out of broken state if it has too many ops and ordering service keeps nacking main\n // container (and thus it goes into cycle of reconnects)\n if (startWithInitialDelay && this.getShouldSummarizeState().shouldSummarize === false) {\n return;\n }\n\n const summarizer = await this.requestSummarizerFn();\n\n // Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n const shouldSummarizeState = this.getShouldSummarizeState();\n if (shouldSummarizeState.shouldSummarize === false) {\n summarizer.stop(shouldSummarizeState.stopReason);\n return;\n }\n\n assert(this.state === SummaryManagerState.Starting, 0x263 /* \"Expected: starting\" */);\n this.state = SummaryManagerState.Running;\n\n summarizer.on(\"summarizingError\",\n (warning: ISummarizingWarning) => this.emit(\"summarizerWarning\", warning));\n this.summarizer = summarizer;\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const clientId = this.latestClientId!;\n\n reason = await PerformanceEvent.timedExecAsync(\n this.logger,\n { eventName: \"RunningSummarizer\", attempt: this.startThrottler.numAttempts },\n async () => summarizer.run(clientId, this.summarizerOptions),\n );\n }).catch((error) => {\n // Most of exceptions happen due to container being closed while loading it, due to\n // summarizer container loosing connection while load.\n // Not worth reporting such errors as errors. That said, we might miss some real errors if\n // we ignore blindly, so try to narrow signature we are looking for - skip logging\n // error only if this client should no longer be a summarizer (which in practice\n // means it also lost connection), and error happened on load (we do not have summarizer).\n // We could add error.fluidErrorCode !== \"containerClosedWithoutErrorDuringLoad\" check to narrow it down,\n // but that does not seem to be necessary.\n if (this.getShouldSummarizeState().shouldSummarize || this.summarizer !== undefined) {\n this.logger.sendErrorEvent({ eventName: \"SummarizerException\" }, error);\n this.emit(\"summarizerWarning\", error);\n\n // Note that summarizer may keep going (like doing last summary).\n // Ideally we await stopping process, but this code path is due to a bug\n // that needs to be fixed either way.\n this.stop(\"summarizerException\");\n }\n }).finally(() => {\n assert(this.state !== SummaryManagerState.Off, 0x264 /* \"Expected: Not Off\" */);\n this.state = SummaryManagerState.Off;\n\n this.summarizer = undefined;\n\n this.logger.sendTelemetryEvent({\n eventName: \"EndingSummarizer\",\n reason,\n });\n\n if (this.getShouldSummarizeState().shouldSummarize) {\n this.startSummarization();\n }\n });\n }\n\n private stop(reason: SummarizerStopReason) {\n assert(this.state === SummaryManagerState.Running || this.state === SummaryManagerState.Starting,\n 0x265 /* \"Expected: Starting or Running\" */);\n this.state = SummaryManagerState.Stopping;\n\n // Stopping the running summarizer client should trigger a change\n // in states when the running summarizer closes\n this.summarizer?.stop(reason);\n }\n\n /**\n * Implements initial delay before creating summarizer\n * @returns true, if creation is delayed due to heuristics (not many ops to summarize).\n * False if summarizer should start immediately due to too many unsummarized ops.\n */\n private async delayBeforeCreatingSummarizer(): Promise<boolean> {\n // throttle creation of new summarizer containers to prevent spamming the server with websocket connections\n let delayMs = this.startThrottler.getDelay();\n if (delayMs > 0 && delayMs > this.startThrottler.maxDelayMs) {\n this.emit(\n \"summarizerWarning\",\n createSummarizingWarning(\"summaryManagerCreateSummarizerMaxThrottleDelay\", false),\n );\n }\n\n // We have been elected the summarizer. Some day we may be able to summarize with a live document but for\n // now we play it safe and launch a second copy.\n this.logger.sendTelemetryEvent({\n eventName: \"CreatingSummarizer\",\n throttlerDelay: delayMs,\n initialDelay: this.initialDelayMs,\n opsSinceLastAck: this.summaryCollection.opsSinceLastAck,\n opsToBypassInitialDelay: this.opsToBypassInitialDelay,\n });\n\n // This delay helps ensure that last summarizer that might be left from previous client\n // has enough time to complete its last summary and thus new summarizer not conflict with previous one.\n // If, however, there are too many unsummarized ops, try to resolve it as quickly as possible, with\n // understanding that we may see nacks because of such quick action.\n // A better design would be for summarizer election logic to always select current summarizer as\n // summarizing client (i.e. clientType === \"summarizer\" can be elected) to ensure that nobody else can\n // summarizer while it finishes its work and moves to exit.\n // It also helps with pure boot scenario (single client) to offset expensive work a bit out from\n // critical boot sequence.\n let startWithInitialDelay = false;\n if (this.summaryCollection.opsSinceLastAck < this.opsToBypassInitialDelay) {\n startWithInitialDelay = true;\n delayMs = Math.max(delayMs, this.initialDelayMs);\n }\n\n if (delayMs > 0) {\n let timer;\n let resolveOpPromiseFn;\n // Create a listener that will break the delay if we've exceeded the initial delay ops count.\n const opsListenerFn = () => {\n if (this.summaryCollection.opsSinceLastAck >= this.opsToBypassInitialDelay) {\n clearTimeout(timer);\n resolveOpPromiseFn();\n }\n };\n // Create a Promise that will resolve when the delay expires.\n const delayPromise = new Promise<void>((resolve) => {\n timer = setTimeout(() => resolve(), delayMs);\n });\n // Create a Promise that will resolve if the ops count passes the threshold.\n const opPromise = new Promise<void>((resolve) => { resolveOpPromiseFn = resolve; });\n this.summaryCollection.addOpListener(opsListenerFn);\n await Promise.race([ delayPromise, opPromise ]);\n this.summaryCollection.removeOpListener(opsListenerFn);\n }\n return startWithInitialDelay;\n }\n\n public readonly summarizeOnDemand: ISummarizer[\"summarizeOnDemand\"] = (...args) => {\n if (this.summarizer === undefined) {\n throw Error(\"No running summarizer client\");\n // TODO: could spawn a summarizer client temporarily.\n }\n return this.summarizer.summarizeOnDemand(...args);\n };\n\n public readonly enqueueSummarize: ISummarizer[\"enqueueSummarize\"] = (...args) => {\n if (this.summarizer === undefined) {\n throw Error(\"No running summarizer client\");\n // TODO: could spawn a summarizer client temporarily.\n }\n return this.summarizer.enqueueSummarize(...args);\n };\n\n public dispose() {\n this.clientElection.off(\"electedSummarizerChanged\", this.refreshSummarizer);\n this.connectedState.off(\"connected\", this.handleConnected);\n this.connectedState.off(\"disconnected\", this.handleDisconnected);\n this._disposed = true;\n }\n}\n\n/**\n * Forms a function that will request a Summarizer.\n * @param loaderRouter - the loader acting as an IFluidRouter\n * @param deltaManager - delta manager to get last sequence number\n */\nexport const formRequestSummarizerFn = (\n loaderRouter: IFluidRouter,\n deltaManager: Pick<IDeltaManager<unknown, unknown>, \"lastSequenceNumber\">,\n) => async () => {\n // TODO eventually we may wish to spawn an execution context from which to run this\n const request: IRequest = {\n headers: {\n [LoaderHeader.cache]: false,\n [LoaderHeader.clientDetails]: {\n capabilities: { interactive: false },\n type: summarizerClientType,\n },\n [DriverHeader.summarizingClient]: true,\n [LoaderHeader.reconnect]: false,\n [LoaderHeader.sequenceNumber]: deltaManager.lastSequenceNumber,\n },\n url: \"/_summarizer\",\n };\n\n const fluidObject = await requestFluidObject(loaderRouter, request);\n const summarizer = fluidObject.ISummarizer;\n\n if (!summarizer) {\n return Promise.reject(new Error(\"Fluid object does not implement ISummarizer\"));\n }\n\n return summarizer;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"summaryManager.js","sourceRoot":"","sources":["../src/summaryManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDisposable, IEvent, IEventProvider, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { TypedEventEmitter, assert } from \"@fluidframework/common-utils\";\nimport { ChildLogger, PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { IFluidRouter, IRequest } from \"@fluidframework/core-interfaces\";\nimport { LoaderHeader } from \"@fluidframework/container-definitions\";\nimport { DriverHeader } from \"@fluidframework/driver-definitions\";\nimport { requestFluidObject } from \"@fluidframework/runtime-utils\";\nimport { createSummarizingWarning } from \"./summarizer\";\nimport { ISummarizerClientElection, summarizerClientType } from \"./summarizerClientElection\";\nimport { IThrottler } from \"./throttler\";\nimport { ISummarizer, ISummarizerOptions, ISummarizingWarning, SummarizerStopReason } from \"./summarizerTypes\";\nimport { SummaryCollection } from \"./summaryCollection\";\n\nconst defaultInitialDelayMs = 5000;\nconst defaultOpsToBypassInitialDelay = 4000;\n\nexport enum SummaryManagerState {\n Off = 0,\n Starting = 1,\n Running = 2,\n Stopping = 3,\n}\n\n// Please note that all reasons in this list are not errors,\n// and thus they are not raised today to parent container as error.\n// If this needs to be changed in future, we should re-evaluate what and how we raise to summarizer\ntype StopReason = Extract<SummarizerStopReason, \"parentNotConnected\" | \"parentShouldNotSummarize\">;\ntype ShouldSummarizeState =\n | { shouldSummarize: true; }\n | { shouldSummarize: false; stopReason: StopReason; };\n\nexport interface IConnectedEvents extends IEvent {\n (event: \"connected\", listener: (clientId: string) => void);\n (event: \"disconnected\", listener: () => void);\n}\n\n/**\n * IConnectedState describes an object that SummaryManager can watch to observe connection/disconnection.\n *\n * Under current implementation, its role will be fulfilled by the ContainerRuntime, but this could be replaced\n * with anything else that fulfills the contract if we want to shift the layer that the SummaryManager lives at.\n */\nexport interface IConnectedState extends IEventProvider<IConnectedEvents> {\n readonly connected: boolean;\n\n /**\n * Under current implementation this is undefined if we've never connected, otherwise it's the clientId from our\n * latest connection (even if we've since disconnected!). Although this happens to be the behavior we want in\n * SummaryManager, I suspect that globally we may eventually want to modify this behavior (e.g. make clientId\n * undefined while disconnected). To protect against this, let's assume this field can't be trusted while\n * disconnected and instead separately track \"latest clientId\" in SummaryManager.\n */\n readonly clientId: string | undefined;\n}\n\nexport interface ISummaryManagerEvents extends IEvent {\n (event: \"summarizerWarning\", listener: (warning: ISummarizingWarning) => void);\n}\n\nexport interface ISummaryManagerConfig {\n initialDelayMs: number;\n opsToBypassInitialDelay: number;\n}\n\n/**\n * SummaryManager is created by parent container (i.e. interactive container with clientType !== \"summarizer\") only.\n * It observes changes in calculated summarizer and reacts to changes by either creating summarizer client or\n * stopping existing summarizer client.\n */\nexport class SummaryManager extends TypedEventEmitter<ISummaryManagerEvents> implements IDisposable {\n private readonly logger: ITelemetryLogger;\n private readonly opsToBypassInitialDelay: number;\n private readonly initialDelayMs: number;\n private latestClientId: string | undefined;\n private state = SummaryManagerState.Off;\n private summarizer?: ISummarizer;\n private _disposed = false;\n\n public get disposed() {\n return this._disposed;\n }\n\n public get currentState() { return this.state; }\n\n constructor(\n private readonly clientElection: ISummarizerClientElection,\n private readonly connectedState: IConnectedState,\n private readonly summaryCollection:\n Pick<SummaryCollection, \"opsSinceLastAck\" | \"addOpListener\" | \"removeOpListener\">,\n parentLogger: ITelemetryLogger,\n /** Creates summarizer by asking interactive container to spawn summarizing container and\n * get back its Summarizer instance. */\n private readonly requestSummarizerFn: () => Promise<ISummarizer>,\n private readonly startThrottler: IThrottler,\n {\n initialDelayMs = defaultInitialDelayMs,\n opsToBypassInitialDelay = defaultOpsToBypassInitialDelay,\n }: Readonly<Partial<ISummaryManagerConfig>> = {},\n private readonly summarizerOptions?: Readonly<Partial<ISummarizerOptions>>,\n ) {\n super();\n\n this.logger = ChildLogger.create(\n parentLogger,\n \"SummaryManager\",\n {all:{ clientId: () => this.latestClientId }});\n\n this.connectedState.on(\"connected\", this.handleConnected);\n this.connectedState.on(\"disconnected\", this.handleDisconnected);\n this.latestClientId = this.connectedState.clientId;\n\n this.opsToBypassInitialDelay = opsToBypassInitialDelay;\n this.initialDelayMs = initialDelayMs;\n }\n\n /**\n * Until start is called, the SummaryManager won't begin attempting to start summarization. This ensures there's\n * a window between construction and starting where the caller can attach listeners.\n */\n public start(): void {\n this.clientElection.on(\"electedSummarizerChanged\", this.refreshSummarizer);\n this.refreshSummarizer();\n }\n\n private readonly handleConnected = (clientId: string) => {\n this.latestClientId = clientId;\n // If we have a summarizer, it should have been either cancelled on disconnected by now.\n // But because of lastSummary process, it can still hang around, so there is not much we can\n // check or assert.\n this.refreshSummarizer();\n };\n\n private readonly handleDisconnected = () => {\n this.refreshSummarizer();\n };\n\n private getShouldSummarizeState(): ShouldSummarizeState {\n if (!this.connectedState.connected) {\n return { shouldSummarize: false, stopReason: \"parentNotConnected\" };\n } else if (this.connectedState.clientId !== this.clientElection.electedClientId) {\n return { shouldSummarize: false, stopReason: \"parentShouldNotSummarize\" };\n } else if (this.disposed) {\n assert(false, 0x260 /* \"Disposed should mean disconnected!\" */);\n } else {\n return { shouldSummarize: true };\n }\n }\n\n private readonly refreshSummarizer = () => {\n // Transition states depending on shouldSummarize, which is a calculated property\n // that is only true if this client is connected and is the elected summarizer.\n const shouldSummarizeState = this.getShouldSummarizeState();\n switch (this.state) {\n case SummaryManagerState.Off: {\n if (shouldSummarizeState.shouldSummarize) {\n this.startSummarization();\n }\n return;\n }\n case SummaryManagerState.Starting: {\n // Cannot take any action until summarizer is created\n // state transition will occur after creation\n return;\n }\n case SummaryManagerState.Running: {\n if (shouldSummarizeState.shouldSummarize === false) {\n this.stop(shouldSummarizeState.stopReason);\n }\n return;\n }\n case SummaryManagerState.Stopping: {\n // Cannot take any action until running summarizer finishes\n // state transition will occur after it stops\n return;\n }\n default: {\n return;\n }\n }\n };\n\n private startSummarization() {\n assert(this.state === SummaryManagerState.Off, 0x261 /* \"Expected: off\" */);\n this.state = SummaryManagerState.Starting;\n\n assert(this.summarizer === undefined, 0x262 /* \"Old summarizer is still working!\" */);\n\n let reason = \"unknown\";\n\n this.delayBeforeCreatingSummarizer().then(async (startWithInitialDelay: boolean) => {\n // Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n // but only if creation was delayed. If it was not, then we want to ensure we always create\n // a summarizer to kick off lastSummary. Without that, we would not be able to summarize and get\n // document out of broken state if it has too many ops and ordering service keeps nacking main\n // container (and thus it goes into cycle of reconnects)\n if (startWithInitialDelay && this.getShouldSummarizeState().shouldSummarize === false) {\n return;\n }\n\n const summarizer = await this.requestSummarizerFn();\n\n // Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n const shouldSummarizeState = this.getShouldSummarizeState();\n if (shouldSummarizeState.shouldSummarize === false) {\n summarizer.stop(shouldSummarizeState.stopReason);\n return;\n }\n\n assert(this.state === SummaryManagerState.Starting, 0x263 /* \"Expected: starting\" */);\n this.state = SummaryManagerState.Running;\n\n summarizer.on(\"summarizingError\",\n (warning: ISummarizingWarning) => this.emit(\"summarizerWarning\", warning));\n this.summarizer = summarizer;\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const clientId = this.latestClientId!;\n\n reason = await PerformanceEvent.timedExecAsync(\n this.logger,\n { eventName: \"RunningSummarizer\", attempt: this.startThrottler.numAttempts },\n async () => summarizer.run(clientId, this.summarizerOptions),\n );\n }).catch((error) => {\n // Most of exceptions happen due to container being closed while loading it, due to\n // summarizer container loosing connection while load.\n // Not worth reporting such errors as errors. That said, we might miss some real errors if\n // we ignore blindly, so try to narrow signature we are looking for - skip logging\n // error only if this client should no longer be a summarizer (which in practice\n // means it also lost connection), and error happened on load (we do not have summarizer).\n // We could add error.fluidErrorCode !== \"containerClosedWithoutErrorDuringLoad\" check to narrow it down,\n // but that does not seem to be necessary.\n if (this.getShouldSummarizeState().shouldSummarize || this.summarizer !== undefined) {\n this.logger.sendErrorEvent({ eventName: \"SummarizerException\" }, error);\n this.emit(\"summarizerWarning\", error);\n\n // Note that summarizer may keep going (like doing last summary).\n // Ideally we await stopping process, but this code path is due to a bug\n // that needs to be fixed either way.\n this.stop(\"summarizerException\");\n }\n }).finally(() => {\n assert(this.state !== SummaryManagerState.Off, 0x264 /* \"Expected: Not Off\" */);\n this.state = SummaryManagerState.Off;\n\n this.summarizer = undefined;\n\n this.logger.sendTelemetryEvent({\n eventName: \"EndingSummarizer\",\n reason,\n });\n\n if (this.getShouldSummarizeState().shouldSummarize) {\n this.startSummarization();\n }\n });\n }\n\n private stop(reason: SummarizerStopReason) {\n assert(this.state === SummaryManagerState.Running || this.state === SummaryManagerState.Starting,\n 0x265 /* \"Expected: Starting or Running\" */);\n this.state = SummaryManagerState.Stopping;\n\n // Stopping the running summarizer client should trigger a change\n // in states when the running summarizer closes\n this.summarizer?.stop(reason);\n }\n\n /**\n * Implements initial delay before creating summarizer\n * @returns true, if creation is delayed due to heuristics (not many ops to summarize).\n * False if summarizer should start immediately due to too many unsummarized ops.\n */\n private async delayBeforeCreatingSummarizer(): Promise<boolean> {\n // throttle creation of new summarizer containers to prevent spamming the server with websocket connections\n let delayMs = this.startThrottler.getDelay();\n if (delayMs > 0 && delayMs > this.startThrottler.maxDelayMs) {\n this.emit(\n \"summarizerWarning\",\n createSummarizingWarning(\"summaryManagerCreateSummarizerMaxThrottleDelay\", false),\n );\n }\n\n // We have been elected the summarizer. Some day we may be able to summarize with a live document but for\n // now we play it safe and launch a second copy.\n this.logger.sendTelemetryEvent({\n eventName: \"CreatingSummarizer\",\n throttlerDelay: delayMs,\n initialDelay: this.initialDelayMs,\n opsSinceLastAck: this.summaryCollection.opsSinceLastAck,\n opsToBypassInitialDelay: this.opsToBypassInitialDelay,\n });\n\n // This delay helps ensure that last summarizer that might be left from previous client\n // has enough time to complete its last summary and thus new summarizer not conflict with previous one.\n // If, however, there are too many unsummarized ops, try to resolve it as quickly as possible, with\n // understanding that we may see nacks because of such quick action.\n // A better design would be for summarizer election logic to always select current summarizer as\n // summarizing client (i.e. clientType === \"summarizer\" can be elected) to ensure that nobody else can\n // summarizer while it finishes its work and moves to exit.\n // It also helps with pure boot scenario (single client) to offset expensive work a bit out from\n // critical boot sequence.\n let startWithInitialDelay = false;\n if (this.summaryCollection.opsSinceLastAck < this.opsToBypassInitialDelay) {\n startWithInitialDelay = true;\n delayMs = Math.max(delayMs, this.initialDelayMs);\n }\n\n if (delayMs > 0) {\n let timer;\n let resolveOpPromiseFn;\n // Create a listener that will break the delay if we've exceeded the initial delay ops count.\n const opsListenerFn = () => {\n if (this.summaryCollection.opsSinceLastAck >= this.opsToBypassInitialDelay) {\n clearTimeout(timer);\n resolveOpPromiseFn();\n }\n };\n // Create a Promise that will resolve when the delay expires.\n const delayPromise = new Promise<void>((resolve) => {\n timer = setTimeout(() => resolve(), delayMs);\n });\n // Create a Promise that will resolve if the ops count passes the threshold.\n const opPromise = new Promise<void>((resolve) => { resolveOpPromiseFn = resolve; });\n this.summaryCollection.addOpListener(opsListenerFn);\n await Promise.race([ delayPromise, opPromise ]);\n this.summaryCollection.removeOpListener(opsListenerFn);\n }\n return startWithInitialDelay;\n }\n\n public readonly summarizeOnDemand: ISummarizer[\"summarizeOnDemand\"] = (...args) => {\n if (this.summarizer === undefined) {\n throw Error(\"No running summarizer client\");\n // TODO: could spawn a summarizer client temporarily.\n }\n return this.summarizer.summarizeOnDemand(...args);\n };\n\n public readonly enqueueSummarize: ISummarizer[\"enqueueSummarize\"] = (...args) => {\n if (this.summarizer === undefined) {\n throw Error(\"No running summarizer client\");\n // TODO: could spawn a summarizer client temporarily.\n }\n return this.summarizer.enqueueSummarize(...args);\n };\n\n public dispose() {\n this.clientElection.off(\"electedSummarizerChanged\", this.refreshSummarizer);\n this.connectedState.off(\"connected\", this.handleConnected);\n this.connectedState.off(\"disconnected\", this.handleDisconnected);\n this._disposed = true;\n }\n}\n\nexport interface ISummarizerRequestOptions {\n cache: boolean,\n reconnect: boolean,\n summarizingClient: boolean,\n}\n\n/**\n * Forms a function that will request a Summarizer.\n * @param loaderRouter - the loader acting as an IFluidRouter\n * @param lastSequenceNumber - the last sequence number (e.g., from DeltaManager)\n * @param cache - use cache to retrieve summarizer\n * @param summarizingClient - is summarizer client\n * @param reconnect - can reconnect on connection loss\n */\nexport const formRequestSummarizerFn = (\n loaderRouter: IFluidRouter,\n lastSequenceNumber: number,\n { cache, reconnect, summarizingClient }: ISummarizerRequestOptions,\n) => async () => {\n // TODO eventually we may wish to spawn an execution context from which to run this\n const request: IRequest = {\n headers: {\n [LoaderHeader.cache]: cache,\n [LoaderHeader.clientDetails]: {\n capabilities: { interactive: false },\n type: summarizerClientType,\n },\n [DriverHeader.summarizingClient]: summarizingClient,\n [LoaderHeader.reconnect]: reconnect,\n [LoaderHeader.sequenceNumber]: lastSequenceNumber,\n },\n url: \"/_summarizer\",\n };\n\n const fluidObject = await requestFluidObject(loaderRouter, request);\n const summarizer = fluidObject.ISummarizer;\n\n if (!summarizer) {\n return Promise.reject(new Error(\"Fluid object does not implement ISummarizer\"));\n }\n\n return summarizer;\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.50.1",
|
|
4
4
|
"description": "Fluid container runtime",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": "https://github.com/microsoft/FluidFramework",
|
|
@@ -58,27 +58,27 @@
|
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
60
60
|
"@fluidframework/common-utils": "^0.32.1",
|
|
61
|
-
"@fluidframework/container-definitions": "^0.
|
|
62
|
-
"@fluidframework/container-runtime-definitions": "^0.
|
|
63
|
-
"@fluidframework/container-utils": "^0.
|
|
64
|
-
"@fluidframework/core-interfaces": "^0.
|
|
65
|
-
"@fluidframework/datastore": "^0.
|
|
66
|
-
"@fluidframework/driver-definitions": "^0.
|
|
67
|
-
"@fluidframework/driver-utils": "^0.
|
|
68
|
-
"@fluidframework/garbage-collector": "^0.
|
|
69
|
-
"@fluidframework/protocol-base": "^0.
|
|
70
|
-
"@fluidframework/protocol-definitions": "^0.1025.
|
|
71
|
-
"@fluidframework/runtime-definitions": "^0.
|
|
72
|
-
"@fluidframework/runtime-utils": "^0.
|
|
73
|
-
"@fluidframework/telemetry-utils": "^0.
|
|
61
|
+
"@fluidframework/container-definitions": "^0.41.0",
|
|
62
|
+
"@fluidframework/container-runtime-definitions": "^0.50.1",
|
|
63
|
+
"@fluidframework/container-utils": "^0.50.1",
|
|
64
|
+
"@fluidframework/core-interfaces": "^0.40.0",
|
|
65
|
+
"@fluidframework/datastore": "^0.50.1",
|
|
66
|
+
"@fluidframework/driver-definitions": "^0.41.0",
|
|
67
|
+
"@fluidframework/driver-utils": "^0.50.1",
|
|
68
|
+
"@fluidframework/garbage-collector": "^0.50.1",
|
|
69
|
+
"@fluidframework/protocol-base": "^0.1033.0",
|
|
70
|
+
"@fluidframework/protocol-definitions": "^0.1025.0",
|
|
71
|
+
"@fluidframework/runtime-definitions": "^0.50.1",
|
|
72
|
+
"@fluidframework/runtime-utils": "^0.50.1",
|
|
73
|
+
"@fluidframework/telemetry-utils": "^0.50.1",
|
|
74
74
|
"double-ended-queue": "^2.1.0-0",
|
|
75
75
|
"uuid": "^8.3.1"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@fluidframework/build-common": "^0.23.0",
|
|
79
79
|
"@fluidframework/eslint-config-fluid": "^0.23.0",
|
|
80
|
-
"@fluidframework/mocha-test-setup": "^0.
|
|
81
|
-
"@fluidframework/test-runtime-utils": "^0.
|
|
80
|
+
"@fluidframework/mocha-test-setup": "^0.50.1",
|
|
81
|
+
"@fluidframework/test-runtime-utils": "^0.50.1",
|
|
82
82
|
"@microsoft/api-extractor": "^7.16.1",
|
|
83
83
|
"@types/double-ended-queue": "^2.1.0",
|
|
84
84
|
"@types/mocha": "^8.2.2",
|