@fluidframework/container-runtime 2.102.0 → 2.110.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/container-runtime.test-files.tar +0 -0
- package/dist/batchTracker.d.ts +1 -1
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.d.ts +2 -2
- package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +16 -5
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +112 -9
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts +2 -2
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/deltaScheduler.d.ts +2 -2
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +2 -2
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +3 -3
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +3 -3
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/inboundBatchAggregator.d.ts +2 -2
- package/dist/inboundBatchAggregator.d.ts.map +1 -1
- package/dist/inboundBatchAggregator.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.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 +48 -1
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +54 -1
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/runtimeLayerCompatState.d.ts +1 -1
- package/dist/signalTelemetryProcessing.d.ts +2 -2
- package/dist/signalTelemetryProcessing.d.ts.map +1 -1
- package/dist/signalTelemetryProcessing.js.map +1 -1
- package/dist/summary/documentSchema.d.ts +2 -2
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +2 -2
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +2 -2
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +3 -3
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -2
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +3 -3
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts +2 -2
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts +2 -2
- package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts +2 -2
- package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +2 -2
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/batchTracker.d.ts +1 -1
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.d.ts +2 -2
- package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +16 -5
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +112 -9
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts +2 -2
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/deltaScheduler.d.ts +2 -2
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +1 -1
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +2 -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/gcDefinitions.d.ts +3 -3
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +3 -3
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/inboundBatchAggregator.d.ts +2 -2
- package/lib/inboundBatchAggregator.d.ts.map +1 -1
- package/lib/inboundBatchAggregator.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +1 -1
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +1 -1
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +1 -1
- package/lib/opLifecycle/outbox.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 +48 -1
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +55 -2
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/runtimeLayerCompatState.d.ts +1 -1
- package/lib/signalTelemetryProcessing.d.ts +2 -2
- package/lib/signalTelemetryProcessing.d.ts.map +1 -1
- package/lib/signalTelemetryProcessing.js.map +1 -1
- package/lib/summary/documentSchema.d.ts +2 -2
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +2 -2
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +2 -2
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +3 -3
- package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +2 -2
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +3 -3
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts +2 -2
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js +1 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts +2 -2
- package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.js +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts +2 -2
- package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +2 -2
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +1 -1
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +19 -19
- package/src/batchTracker.ts +3 -3
- package/src/blobManager/blobManagerSnapSum.ts +2 -2
- package/src/connectionTelemetry.ts +5 -5
- package/src/containerRuntime.ts +134 -15
- package/src/dataStore.ts +3 -3
- package/src/dataStoreContexts.ts +2 -2
- package/src/deltaScheduler.ts +2 -5
- package/src/gc/garbageCollection.ts +6 -6
- package/src/gc/gcDefinitions.ts +3 -3
- package/src/gc/gcTelemetry.ts +5 -5
- package/src/inboundBatchAggregator.ts +2 -2
- package/src/opLifecycle/opCompressor.ts +3 -3
- package/src/opLifecycle/opDecompressor.ts +2 -2
- package/src/opLifecycle/opGroupingManager.ts +2 -2
- package/src/opLifecycle/opSplitter.ts +3 -3
- package/src/opLifecycle/outbox.ts +4 -4
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +82 -4
- package/src/signalTelemetryProcessing.ts +2 -2
- package/src/summary/documentSchema.ts +2 -2
- package/src/summary/orderedClientElection.ts +4 -4
- package/src/summary/summarizerClientElection.ts +2 -2
- package/src/summary/summarizerNode/summarizerNode.ts +3 -3
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +2 -2
- package/src/summary/summarizerTypes.ts +3 -3
- package/src/summary/summaryCollection.ts +2 -2
- package/src/summary/summaryDelayLoadedModule/runningSummarizer.ts +4 -6
- package/src/summary/summaryDelayLoadedModule/summarizer.ts +4 -4
- package/src/summary/summaryDelayLoadedModule/summarizerHeuristics.ts +2 -2
- package/src/summary/summaryDelayLoadedModule/summaryGenerator.ts +2 -2
- package/src/summary/summaryManager.ts +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summaryManager.js","sourceRoot":"","sources":["../../src/summary/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 { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type {\n\tISummarizerEvents,\n\tSummarizerStopReason,\n} from \"@fluidframework/container-runtime-definitions/internal\";\nimport type {\n\tIDisposable,\n\tIEvent,\n\tIEventProvider,\n\tITelemetryBaseLogger,\n} from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype ITelemetryLoggerExt,\n\tPerformanceEvent,\n\tcreateChildLogger,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { IThrottler } from \"../throttler.js\";\n\nimport type { ISummarizerClientElection } from \"./summarizerClientElection.js\";\nimport type {\n\tIEnqueueSummarizeOptions,\n\tIOnDemandSummarizeOptions,\n\tISummarizer,\n} from \"./summarizerTypes.js\";\nimport { stopReasonCanRunLastSummary } from \"./summarizerUtils.js\";\nimport type { SummaryCollection } from \"./summaryCollection.js\";\nimport type {\n\tEnqueueSummarizeResult,\n\tISummarizeResults,\n} from \"./summaryDelayLoadedModule/index.js\";\n\nconst defaultInitialDelayMs = 5000;\nconst defaultOpsToBypassInitialDelay = 4000;\n\nexport enum SummaryManagerState {\n\tOff = 0,\n\tStarting = 1,\n\tRunning = 2,\n\tStopping = 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<\n\tSummarizerStopReason,\n\t\"parentNotConnected\" | \"notElectedParent\" | \"notElectedClient\"\n>;\ntype ShouldSummarizeState =\n\t| { shouldSummarize: true }\n\t| { shouldSummarize: false; stopReason: StopReason };\n\nexport interface IConnectedEvents extends IEvent {\n\t(event: \"connected\", listener: (clientId: string) => void);\n\t(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\treadonly connected: boolean;\n\n\t/**\n\t * Under current implementation this is undefined if we've never connected, otherwise it's the clientId from our\n\t * latest connection (even if we've since disconnected!). Although this happens to be the behavior we want in\n\t * SummaryManager, I suspect that globally we may eventually want to modify this behavior (e.g. make clientId\n\t * undefined while disconnected). To protect against this, let's assume this field can't be trusted while\n\t * disconnected and instead separately track \"latest clientId\" in SummaryManager.\n\t */\n\treadonly clientId: string | undefined;\n}\n\nexport interface ISummaryManagerConfig {\n\tinitialDelayMs: number;\n\topsToBypassInitialDelay: 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\n\textends TypedEventEmitter<ISummarizerEvents>\n\timplements IDisposable\n{\n\tprivate readonly logger: ITelemetryLoggerExt;\n\tprivate readonly opsToBypassInitialDelay: number;\n\tprivate readonly initialDelayMs: number;\n\tprivate latestClientId: string | undefined;\n\tprivate state = SummaryManagerState.Off;\n\tprivate summarizer?: ISummarizer;\n\tprivate pendingStopReason?: SummarizerStopReason;\n\tprivate _disposed = false;\n\tprivate summarizerStopTimeout?: ReturnType<typeof setTimeout>;\n\t/**\n\t * Monotonically increasing counter that tracks summarizer lifecycle generations.\n\t * Incremented each time {@link cleanupAfterSummarizerStop} runs. Used by the\n\t * promise chain in {@link startSummarization} to detect that cleanup has already\n\t * been performed by another path (e.g. the stop timeout), so it can skip\n\t * redundant cleanup that would corrupt the state machine.\n\t */\n\tprivate summarizerGeneration = 0;\n\n\tpublic get disposed(): boolean {\n\t\treturn this._disposed;\n\t}\n\n\tpublic get currentState(): SummaryManagerState {\n\t\treturn this.state;\n\t}\n\n\tconstructor(\n\t\tprivate readonly clientElection: ISummarizerClientElection,\n\t\tprivate readonly connectedState: IConnectedState,\n\t\tprivate readonly summaryCollection: Pick<\n\t\t\tSummaryCollection,\n\t\t\t\"opsSinceLastAck\" | \"addOpListener\" | \"removeOpListener\"\n\t\t>,\n\t\tparentLogger: ITelemetryBaseLogger,\n\t\t/**\n\t\t * Creates summarizer by asking interactive container to spawn summarizing container and\n\t\t * get back its Summarizer instance.\n\t\t */\n\t\tprivate readonly createSummarizerFn: () => Promise<ISummarizer>,\n\t\tprivate readonly startThrottler: IThrottler,\n\t\t{\n\t\t\tinitialDelayMs = defaultInitialDelayMs,\n\t\t\topsToBypassInitialDelay = defaultOpsToBypassInitialDelay,\n\t\t}: Readonly<Partial<ISummaryManagerConfig>> = {},\n\t) {\n\t\tsuper();\n\n\t\tthis.logger = createChildLogger({\n\t\t\tlogger: parentLogger,\n\t\t\tnamespace: \"SummaryManager\",\n\t\t\tproperties: {\n\t\t\t\tall: { clientId: () => this.latestClientId },\n\t\t\t},\n\t\t});\n\n\t\tthis.connectedState.on(\"connected\", this.handleConnected);\n\t\tthis.connectedState.on(\"disconnected\", this.handleDisconnected);\n\t\tthis.latestClientId = this.connectedState.clientId;\n\n\t\tthis.opsToBypassInitialDelay = opsToBypassInitialDelay;\n\t\tthis.initialDelayMs = initialDelayMs;\n\t}\n\n\t/**\n\t * Until start is called, the SummaryManager won't begin attempting to start summarization. This ensures there's\n\t * a window between construction and starting where the caller can attach listeners.\n\t */\n\tpublic start(): void {\n\t\tthis.clientElection.on(\"electedSummarizerChanged\", this.refreshSummarizer);\n\t\tthis.refreshSummarizer();\n\t}\n\n\tprivate readonly handleConnected = (clientId: string): void => {\n\t\tthis.latestClientId = clientId;\n\t\t// If we have a summarizer, it should have been either cancelled on disconnected by now.\n\t\t// But because of lastSummary process, it can still hang around, so there is not much we can\n\t\t// check or assert.\n\t\tthis.refreshSummarizer();\n\t};\n\n\tprivate readonly handleDisconnected = (): void => {\n\t\tthis.refreshSummarizer();\n\t};\n\n\tprivate static readonly isStartingOrRunning = (\n\t\tstate: SummaryManagerState,\n\t): state is SummaryManagerState.Starting | SummaryManagerState.Running =>\n\t\tstate === SummaryManagerState.Starting || state === SummaryManagerState.Running;\n\n\tprivate getShouldSummarizeState(): ShouldSummarizeState {\n\t\tif (this.disposed) {\n\t\t\treturn { shouldSummarize: false, stopReason: \"parentNotConnected\" };\n\t\t}\n\n\t\t// Note that if we're in the Running state, the electedClient may be a summarizer client, so we can't\n\t\t// enforce connectedState.clientId === clientElection.electedClientId. But once we're Running, we should\n\t\t// only transition to Stopping when the electedParentId changes. Stopping the summarizer without\n\t\t// changing the electedParent will just cause us to transition to Starting again.\n\n\t\t// New Parent has been elected and it is not the current client, or\n\t\tif (this.connectedState.clientId !== this.clientElection.electedParentId) {\n\t\t\treturn { shouldSummarize: false, stopReason: \"notElectedParent\" };\n\t\t}\n\n\t\t// We are not already running the summarizer and we are not the current elected client id.\n\t\tif (\n\t\t\tthis.state !== SummaryManagerState.Running &&\n\t\t\tthis.connectedState.clientId !== this.clientElection.electedClientId\n\t\t) {\n\t\t\treturn { shouldSummarize: false, stopReason: \"notElectedClient\" };\n\t\t}\n\n\t\tif (!this.connectedState.connected) {\n\t\t\treturn { shouldSummarize: false, stopReason: \"parentNotConnected\" };\n\t\t}\n\n\t\treturn { shouldSummarize: true };\n\t}\n\n\tprivate readonly refreshSummarizer = (): void => {\n\t\t// Transition states depending on shouldSummarize, which is a calculated property\n\t\t// that is only true if this client is connected and is the elected summarizer.\n\t\tconst shouldSummarizeState = this.getShouldSummarizeState();\n\t\tswitch (this.state) {\n\t\t\tcase SummaryManagerState.Off: {\n\t\t\t\tif (shouldSummarizeState.shouldSummarize) {\n\t\t\t\t\tthis.startSummarization();\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase SummaryManagerState.Starting: {\n\t\t\t\t// Cannot take any action until summarizer is created\n\t\t\t\t// state transition will occur after creation\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase SummaryManagerState.Running: {\n\t\t\t\tif (shouldSummarizeState.shouldSummarize === false) {\n\t\t\t\t\tthis.stop(shouldSummarizeState.stopReason);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase SummaryManagerState.Stopping: {\n\t\t\t\t// Cannot take any action until running summarizer finishes\n\t\t\t\t// state transition will occur after it stops\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate startSummarization(): void {\n\t\tassert(this.state === SummaryManagerState.Off, 0x261 /* \"Expected: off\" */);\n\t\tthis.state = SummaryManagerState.Starting;\n\n\t\tassert(this.summarizer === undefined, 0x262 /* \"Old summarizer is still working!\" */);\n\n\t\tconst generation = this.summarizerGeneration;\n\n\t\tthis.delayBeforeCreatingSummarizer()\n\t\t\t.then(async (startWithInitialDelay: boolean) => {\n\t\t\t\tif (this.disposed) {\n\t\t\t\t\treturn \"early exit (disposed)\";\n\t\t\t\t}\n\n\t\t\t\t// Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n\t\t\t\t// but only if creation was delayed. If it was not, then we want to ensure we always create\n\t\t\t\t// a summarizer to kick off lastSummary. Without that, we would not be able to summarize and get\n\t\t\t\t// document out of broken state if it has too many ops and ordering service keeps nacking main\n\t\t\t\t// container (and thus it goes into cycle of reconnects)\n\t\t\t\t// If we can't run the LastSummary, simply return as to avoid paying the cost of launching\n\t\t\t\t// the summarizer at all.\n\t\t\t\tconst shouldSummarizeStateEarlyStage = this.getShouldSummarizeState();\n\t\t\t\tif (\n\t\t\t\t\tstartWithInitialDelay &&\n\t\t\t\t\tshouldSummarizeStateEarlyStage.shouldSummarize === false\n\t\t\t\t) {\n\t\t\t\t\treturn `early exit ${shouldSummarizeStateEarlyStage.stopReason}`;\n\t\t\t\t}\n\n\t\t\t\t// We transition to Running before requesting the summarizer, because after requesting we can't predict\n\t\t\t\t// when the electedClient will be replaced with the new summarizer client.\n\t\t\t\t// The alternative would be to let connectedState.clientId !== clientElection.electedClientId when\n\t\t\t\t// state === Starting || state === Running.\n\t\t\t\tassert(this.state === SummaryManagerState.Starting, 0x263 /* \"Expected: starting\" */);\n\t\t\t\tthis.state = SummaryManagerState.Running;\n\n\t\t\t\tconst summarizer = await this.createSummarizerFn();\n\t\t\t\tthis.summarizer = summarizer;\n\t\t\t\tthis.setupForwardedEvents(summarizer);\n\n\t\t\t\t// A stop may have been requested while we were awaiting summarizer creation.\n\t\t\t\t// Replay it now so the summarizer can observe the stop intent and move to exit.\n\t\t\t\tif (this.pendingStopReason !== undefined) {\n\t\t\t\t\tsummarizer.stop(this.pendingStopReason);\n\t\t\t\t\tthis.pendingStopReason = undefined;\n\t\t\t\t}\n\n\t\t\t\t// Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n\t\t\t\t// If we can't run the LastSummary, simply return as to avoid paying the cost of launching\n\t\t\t\t// the summarizer at all.\n\t\t\t\tconst shouldSummarizeState = this.getShouldSummarizeState();\n\t\t\t\tif (shouldSummarizeState.shouldSummarize === false) {\n\t\t\t\t\t// In order to allow the last summary to run, we not only need a stop reason that would\n\t\t\t\t\t// allow it but also, startWithInitialDelay to be false (start the summarization immediately),\n\t\t\t\t\t// which would happen when we have a high enough number of unsummarized ops.\n\t\t\t\t\tif (\n\t\t\t\t\t\tstartWithInitialDelay ||\n\t\t\t\t\t\t!stopReasonCanRunLastSummary(shouldSummarizeState.stopReason)\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.state = SummaryManagerState.Starting;\n\t\t\t\t\t\tsummarizer.stop(shouldSummarizeState.stopReason);\n\t\t\t\t\t\treturn `early exit after starting summarizer ${shouldSummarizeState.stopReason}`;\n\t\t\t\t\t}\n\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"LastAttemptToSummarize\",\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst clientId = this.latestClientId!;\n\n\t\t\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\t\t\tthis.logger,\n\t\t\t\t\t{ eventName: \"RunningSummarizer\", attempt: this.startThrottler.numAttempts },\n\t\t\t\t\tasync () => summarizer.run(clientId),\n\t\t\t\t);\n\t\t\t})\n\t\t\t.then((reason: string) => {\n\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"EndingSummarizer\",\n\t\t\t\t\treason,\n\t\t\t\t});\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"EndingSummarizer\",\n\t\t\t\t\t\treason: \"exception\",\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\n\t\t\t\t// Most of exceptions happen due to container being closed while loading it, due to\n\t\t\t\t// summarizer container loosing connection while load.\n\t\t\t\t// Not worth reporting such errors as errors. That said, we might miss some real errors if\n\t\t\t\t// we ignore blindly, so try to narrow signature we are looking for - skip logging\n\t\t\t\t// error only if this client should no longer be a summarizer (which in practice\n\t\t\t\t// means it also lost connection), and error happened on load (we do not have summarizer).\n\t\t\t\t// We could annotate the error raised in Container.load where the container closed during load with no error\n\t\t\t\t// and check for that case here, but that does not seem to be necessary.\n\t\t\t\tif (this.getShouldSummarizeState().shouldSummarize || this.summarizer !== undefined) {\n\t\t\t\t\t// Report any failure as an error unless it was due to cancellation (like \"disconnected\" error)\n\t\t\t\t\t// If failure happened on container load, we may not yet realized that socket disconnected, so check\n\t\t\t\t\t// offlineError.\n\t\t\t\t\tconst category =\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\t\terror?.errorType === DriverErrorTypes.offlineError ? \"generic\" : \"error\";\n\t\t\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"SummarizerException\",\n\t\t\t\t\t\t\tcategory,\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (generation !== this.summarizerGeneration) {\n\t\t\t\t\t// Cleanup was already performed by another path (e.g. the stop timeout),\n\t\t\t\t\t// and a new summarizer cycle may have started. Running cleanup again\n\t\t\t\t\t// would corrupt the current state machine cycle.\n\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"SummarizerCleanupAlreadyDone\",\n\t\t\t\t\t\tcurrentState: this.state,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tassert(this.state !== SummaryManagerState.Off, 0x264 /* \"Expected: Not Off\" */);\n\t\t\t\tthis.cleanupAfterSummarizerStop();\n\t\t\t});\n\t}\n\n\tprivate cleanupAfterSummarizerStop(): void {\n\t\tthis.summarizerGeneration++;\n\t\tthis.state = SummaryManagerState.Off;\n\t\tthis.pendingStopReason = undefined;\n\n\t\t// Clear any pending stop timeout to avoid it firing for a different summarizer\n\t\tif (this.summarizerStopTimeout !== undefined) {\n\t\t\tclearTimeout(this.summarizerStopTimeout);\n\t\t\tthis.summarizerStopTimeout = undefined;\n\t\t}\n\n\t\tthis.cleanupForwardedEvents();\n\t\tthis.summarizer?.close();\n\t\tthis.summarizer = undefined;\n\n\t\tif (this.getShouldSummarizeState().shouldSummarize) {\n\t\t\tthis.startSummarization();\n\t\t}\n\t}\n\n\tprivate stop(reason: SummarizerStopReason): void {\n\t\tif (!SummaryManager.isStartingOrRunning(this.state)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.state = SummaryManagerState.Stopping;\n\t\tthis.pendingStopReason = reason;\n\n\t\t// Stopping the running summarizer client should trigger a change\n\t\t// in states when the running summarizer closes\n\t\tthis.summarizer?.stop(reason);\n\n\t\tconst summarizerCloseTimeoutMs = 2 * 60 * 1000; // 2 minutes\n\t\t// Clear any existing timeout before setting a new one\n\t\tif (this.summarizerStopTimeout !== undefined) {\n\t\t\tclearTimeout(this.summarizerStopTimeout);\n\t\t}\n\t\t// Set a timeout to force cleanup if the summarizer doesn't close in time\n\t\tthis.summarizerStopTimeout = setTimeout(() => {\n\t\t\tif (this.state === SummaryManagerState.Stopping && this.summarizer !== undefined) {\n\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"SummarizerStopTimeout\",\n\t\t\t\t\ttimeoutMs: summarizerCloseTimeoutMs,\n\t\t\t\t\tstopReason: reason,\n\t\t\t\t});\n\t\t\t\tthis.cleanupAfterSummarizerStop();\n\t\t\t}\n\t\t}, summarizerCloseTimeoutMs);\n\t}\n\n\t/**\n\t * Implements initial delay before creating summarizer\n\t * @returns `true`, if creation is delayed due to heuristics (not many ops to summarize).\n\t * `false` if summarizer should start immediately due to too many unsummarized ops.\n\t */\n\tprivate async delayBeforeCreatingSummarizer(): Promise<boolean> {\n\t\t// throttle creation of new summarizer containers to prevent spamming the server with websocket connections\n\t\tlet delayMs = this.startThrottler.getDelay();\n\n\t\t// We have been elected the summarizer. Some day we may be able to summarize with a live document but for\n\t\t// now we play it safe and launch a second copy.\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"CreatingSummarizer\",\n\t\t\tthrottlerDelay: delayMs,\n\t\t\tinitialDelay: this.initialDelayMs,\n\t\t\tstartThrottlerMaxDelayMs: this.startThrottler.maxDelayMs,\n\t\t\topsSinceLastAck: this.summaryCollection.opsSinceLastAck,\n\t\t\topsToBypassInitialDelay: this.opsToBypassInitialDelay,\n\t\t\telectedParentId: this.clientElection.electedParentId,\n\t\t\telectedClientId: this.clientElection.electedClientId,\n\t\t});\n\n\t\t// This delay helps ensure that last summarizer that might be left from previous client\n\t\t// has enough time to complete its last summary and thus new summarizer not conflict with previous one.\n\t\t// If, however, there are too many unsummarized ops, try to resolve it as quickly as possible, with\n\t\t// understanding that we may see nacks because of such quick action.\n\t\t// A better design would be for summarizer election logic to always select current summarizer as\n\t\t// summarizing client (i.e. clientType === \"summarizer\" can be elected) to ensure that nobody else can\n\t\t// summarizer while it finishes its work and moves to exit.\n\t\t// It also helps with pure boot scenario (single client) to offset expensive work a bit out from\n\t\t// critical boot sequence.\n\t\tlet startWithInitialDelay = false;\n\t\tif (this.summaryCollection.opsSinceLastAck < this.opsToBypassInitialDelay) {\n\t\t\tstartWithInitialDelay = true;\n\t\t\tdelayMs = Math.max(delayMs, this.initialDelayMs);\n\t\t}\n\n\t\tif (delayMs > 0) {\n\t\t\tlet timer: number | undefined;\n\t\t\tlet resolveOpPromiseFn: (value: void | PromiseLike<void>) => void;\n\t\t\t// Create a listener that will break the delay if we've exceeded the initial delay ops count.\n\t\t\tconst opsListenerFn = (): void => {\n\t\t\t\tif (this.summaryCollection.opsSinceLastAck >= this.opsToBypassInitialDelay) {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tresolveOpPromiseFn();\n\t\t\t\t}\n\t\t\t};\n\t\t\t// Create a Promise that will resolve when the delay expires.\n\t\t\tconst delayPromise = new Promise<void>((resolve) => {\n\t\t\t\ttimer = setTimeout(() => resolve(), delayMs);\n\t\t\t});\n\t\t\t// Create a Promise that will resolve if the ops count passes the threshold.\n\t\t\tconst opPromise = new Promise<void>((resolve) => {\n\t\t\t\tresolveOpPromiseFn = resolve;\n\t\t\t});\n\t\t\tthis.summaryCollection.addOpListener(opsListenerFn);\n\t\t\tawait Promise.race([delayPromise, opPromise]);\n\t\t\tthis.summaryCollection.removeOpListener(opsListenerFn);\n\t\t}\n\t\treturn startWithInitialDelay;\n\t}\n\n\tpublic summarizeOnDemand(options: IOnDemandSummarizeOptions): ISummarizeResults {\n\t\tif (this.summarizer === undefined) {\n\t\t\tthrow new Error(\"No running summarizer client\");\n\t\t\t// TODO: could spawn a summarizer client temporarily.\n\t\t}\n\t\treturn this.summarizer.summarizeOnDemand(options);\n\t}\n\n\tpublic enqueueSummarize(options: IEnqueueSummarizeOptions): EnqueueSummarizeResult {\n\t\tif (this.summarizer === undefined) {\n\t\t\tthrow new Error(\"No running summarizer client\");\n\t\t\t// TODO: could spawn a summarizer client temporarily.\n\t\t}\n\t\treturn this.summarizer.enqueueSummarize(options);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.clientElection.off(\"electedSummarizerChanged\", this.refreshSummarizer);\n\t\tthis.connectedState.off(\"connected\", this.handleConnected);\n\t\tthis.connectedState.off(\"disconnected\", this.handleDisconnected);\n\t\tthis.cleanupForwardedEvents();\n\t\tthis.pendingStopReason = undefined;\n\t\tif (this.summarizerStopTimeout !== undefined) {\n\t\t\tclearTimeout(this.summarizerStopTimeout);\n\t\t}\n\t\tthis._disposed = true;\n\t}\n\n\tprivate readonly forwardedEventsCleanup: (() => void)[] = [];\n\n\tprivate setupForwardedEvents(summarizer: ISummarizer): void {\n\t\tfor (const event of [\n\t\t\t\"summarize\",\n\t\t\t\"summarizeAllAttemptsFailed\",\n\t\t\t\"summarizerStop\",\n\t\t\t\"summarizerStart\",\n\t\t\t\"summarizerStartupFailed\",\n\t\t\t\"summarizeTimeout\",\n\t\t] as const) {\n\t\t\tconst listener = (...args: unknown[]): void => {\n\t\t\t\tthis.emit(event, ...args);\n\t\t\t};\n\t\t\t// TODO: better typing here\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument\n\t\t\tsummarizer.on(event as any, listener);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument\n\t\t\tthis.forwardedEventsCleanup.push(() => summarizer.off(event as any, listener));\n\t\t}\n\t}\n\n\tprivate cleanupForwardedEvents(): void {\n\t\tfor (const cleanup of this.forwardedEventsCleanup) {\n\t\t\tcleanup();\n\t\t}\n\t\tthis.forwardedEventsCleanup.length = 0;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"summaryManager.js","sourceRoot":"","sources":["../../src/summary/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 { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type {\n\tISummarizerEvents,\n\tSummarizerStopReason,\n} from \"@fluidframework/container-runtime-definitions/internal\";\nimport type {\n\tIDisposable,\n\tIEvent,\n\tIEventProvider,\n\tITelemetryBaseLogger,\n} from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { DriverErrorTypes } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tcreateChildLogger,\n\tPerformanceEvent,\n\ttype TelemetryLoggerExt,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport type { IThrottler } from \"../throttler.js\";\n\nimport type { ISummarizerClientElection } from \"./summarizerClientElection.js\";\nimport type {\n\tIEnqueueSummarizeOptions,\n\tIOnDemandSummarizeOptions,\n\tISummarizer,\n} from \"./summarizerTypes.js\";\nimport { stopReasonCanRunLastSummary } from \"./summarizerUtils.js\";\nimport type { SummaryCollection } from \"./summaryCollection.js\";\nimport type {\n\tEnqueueSummarizeResult,\n\tISummarizeResults,\n} from \"./summaryDelayLoadedModule/index.js\";\n\nconst defaultInitialDelayMs = 5000;\nconst defaultOpsToBypassInitialDelay = 4000;\n\nexport enum SummaryManagerState {\n\tOff = 0,\n\tStarting = 1,\n\tRunning = 2,\n\tStopping = 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<\n\tSummarizerStopReason,\n\t\"parentNotConnected\" | \"notElectedParent\" | \"notElectedClient\"\n>;\ntype ShouldSummarizeState =\n\t| { shouldSummarize: true }\n\t| { shouldSummarize: false; stopReason: StopReason };\n\nexport interface IConnectedEvents extends IEvent {\n\t(event: \"connected\", listener: (clientId: string) => void);\n\t(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\treadonly connected: boolean;\n\n\t/**\n\t * Under current implementation this is undefined if we've never connected, otherwise it's the clientId from our\n\t * latest connection (even if we've since disconnected!). Although this happens to be the behavior we want in\n\t * SummaryManager, I suspect that globally we may eventually want to modify this behavior (e.g. make clientId\n\t * undefined while disconnected). To protect against this, let's assume this field can't be trusted while\n\t * disconnected and instead separately track \"latest clientId\" in SummaryManager.\n\t */\n\treadonly clientId: string | undefined;\n}\n\nexport interface ISummaryManagerConfig {\n\tinitialDelayMs: number;\n\topsToBypassInitialDelay: 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\n\textends TypedEventEmitter<ISummarizerEvents>\n\timplements IDisposable\n{\n\tprivate readonly logger: TelemetryLoggerExt;\n\tprivate readonly opsToBypassInitialDelay: number;\n\tprivate readonly initialDelayMs: number;\n\tprivate latestClientId: string | undefined;\n\tprivate state = SummaryManagerState.Off;\n\tprivate summarizer?: ISummarizer;\n\tprivate pendingStopReason?: SummarizerStopReason;\n\tprivate _disposed = false;\n\tprivate summarizerStopTimeout?: ReturnType<typeof setTimeout>;\n\t/**\n\t * Monotonically increasing counter that tracks summarizer lifecycle generations.\n\t * Incremented each time {@link cleanupAfterSummarizerStop} runs. Used by the\n\t * promise chain in {@link startSummarization} to detect that cleanup has already\n\t * been performed by another path (e.g. the stop timeout), so it can skip\n\t * redundant cleanup that would corrupt the state machine.\n\t */\n\tprivate summarizerGeneration = 0;\n\n\tpublic get disposed(): boolean {\n\t\treturn this._disposed;\n\t}\n\n\tpublic get currentState(): SummaryManagerState {\n\t\treturn this.state;\n\t}\n\n\tconstructor(\n\t\tprivate readonly clientElection: ISummarizerClientElection,\n\t\tprivate readonly connectedState: IConnectedState,\n\t\tprivate readonly summaryCollection: Pick<\n\t\t\tSummaryCollection,\n\t\t\t\"opsSinceLastAck\" | \"addOpListener\" | \"removeOpListener\"\n\t\t>,\n\t\tparentLogger: ITelemetryBaseLogger,\n\t\t/**\n\t\t * Creates summarizer by asking interactive container to spawn summarizing container and\n\t\t * get back its Summarizer instance.\n\t\t */\n\t\tprivate readonly createSummarizerFn: () => Promise<ISummarizer>,\n\t\tprivate readonly startThrottler: IThrottler,\n\t\t{\n\t\t\tinitialDelayMs = defaultInitialDelayMs,\n\t\t\topsToBypassInitialDelay = defaultOpsToBypassInitialDelay,\n\t\t}: Readonly<Partial<ISummaryManagerConfig>> = {},\n\t) {\n\t\tsuper();\n\n\t\tthis.logger = createChildLogger({\n\t\t\tlogger: parentLogger,\n\t\t\tnamespace: \"SummaryManager\",\n\t\t\tproperties: {\n\t\t\t\tall: { clientId: () => this.latestClientId },\n\t\t\t},\n\t\t});\n\n\t\tthis.connectedState.on(\"connected\", this.handleConnected);\n\t\tthis.connectedState.on(\"disconnected\", this.handleDisconnected);\n\t\tthis.latestClientId = this.connectedState.clientId;\n\n\t\tthis.opsToBypassInitialDelay = opsToBypassInitialDelay;\n\t\tthis.initialDelayMs = initialDelayMs;\n\t}\n\n\t/**\n\t * Until start is called, the SummaryManager won't begin attempting to start summarization. This ensures there's\n\t * a window between construction and starting where the caller can attach listeners.\n\t */\n\tpublic start(): void {\n\t\tthis.clientElection.on(\"electedSummarizerChanged\", this.refreshSummarizer);\n\t\tthis.refreshSummarizer();\n\t}\n\n\tprivate readonly handleConnected = (clientId: string): void => {\n\t\tthis.latestClientId = clientId;\n\t\t// If we have a summarizer, it should have been either cancelled on disconnected by now.\n\t\t// But because of lastSummary process, it can still hang around, so there is not much we can\n\t\t// check or assert.\n\t\tthis.refreshSummarizer();\n\t};\n\n\tprivate readonly handleDisconnected = (): void => {\n\t\tthis.refreshSummarizer();\n\t};\n\n\tprivate static readonly isStartingOrRunning = (\n\t\tstate: SummaryManagerState,\n\t): state is SummaryManagerState.Starting | SummaryManagerState.Running =>\n\t\tstate === SummaryManagerState.Starting || state === SummaryManagerState.Running;\n\n\tprivate getShouldSummarizeState(): ShouldSummarizeState {\n\t\tif (this.disposed) {\n\t\t\treturn { shouldSummarize: false, stopReason: \"parentNotConnected\" };\n\t\t}\n\n\t\t// Note that if we're in the Running state, the electedClient may be a summarizer client, so we can't\n\t\t// enforce connectedState.clientId === clientElection.electedClientId. But once we're Running, we should\n\t\t// only transition to Stopping when the electedParentId changes. Stopping the summarizer without\n\t\t// changing the electedParent will just cause us to transition to Starting again.\n\n\t\t// New Parent has been elected and it is not the current client, or\n\t\tif (this.connectedState.clientId !== this.clientElection.electedParentId) {\n\t\t\treturn { shouldSummarize: false, stopReason: \"notElectedParent\" };\n\t\t}\n\n\t\t// We are not already running the summarizer and we are not the current elected client id.\n\t\tif (\n\t\t\tthis.state !== SummaryManagerState.Running &&\n\t\t\tthis.connectedState.clientId !== this.clientElection.electedClientId\n\t\t) {\n\t\t\treturn { shouldSummarize: false, stopReason: \"notElectedClient\" };\n\t\t}\n\n\t\tif (!this.connectedState.connected) {\n\t\t\treturn { shouldSummarize: false, stopReason: \"parentNotConnected\" };\n\t\t}\n\n\t\treturn { shouldSummarize: true };\n\t}\n\n\tprivate readonly refreshSummarizer = (): void => {\n\t\t// Transition states depending on shouldSummarize, which is a calculated property\n\t\t// that is only true if this client is connected and is the elected summarizer.\n\t\tconst shouldSummarizeState = this.getShouldSummarizeState();\n\t\tswitch (this.state) {\n\t\t\tcase SummaryManagerState.Off: {\n\t\t\t\tif (shouldSummarizeState.shouldSummarize) {\n\t\t\t\t\tthis.startSummarization();\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase SummaryManagerState.Starting: {\n\t\t\t\t// Cannot take any action until summarizer is created\n\t\t\t\t// state transition will occur after creation\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase SummaryManagerState.Running: {\n\t\t\t\tif (shouldSummarizeState.shouldSummarize === false) {\n\t\t\t\t\tthis.stop(shouldSummarizeState.stopReason);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase SummaryManagerState.Stopping: {\n\t\t\t\t// Cannot take any action until running summarizer finishes\n\t\t\t\t// state transition will occur after it stops\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t};\n\n\tprivate startSummarization(): void {\n\t\tassert(this.state === SummaryManagerState.Off, 0x261 /* \"Expected: off\" */);\n\t\tthis.state = SummaryManagerState.Starting;\n\n\t\tassert(this.summarizer === undefined, 0x262 /* \"Old summarizer is still working!\" */);\n\n\t\tconst generation = this.summarizerGeneration;\n\n\t\tthis.delayBeforeCreatingSummarizer()\n\t\t\t.then(async (startWithInitialDelay: boolean) => {\n\t\t\t\tif (this.disposed) {\n\t\t\t\t\treturn \"early exit (disposed)\";\n\t\t\t\t}\n\n\t\t\t\t// Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n\t\t\t\t// but only if creation was delayed. If it was not, then we want to ensure we always create\n\t\t\t\t// a summarizer to kick off lastSummary. Without that, we would not be able to summarize and get\n\t\t\t\t// document out of broken state if it has too many ops and ordering service keeps nacking main\n\t\t\t\t// container (and thus it goes into cycle of reconnects)\n\t\t\t\t// If we can't run the LastSummary, simply return as to avoid paying the cost of launching\n\t\t\t\t// the summarizer at all.\n\t\t\t\tconst shouldSummarizeStateEarlyStage = this.getShouldSummarizeState();\n\t\t\t\tif (\n\t\t\t\t\tstartWithInitialDelay &&\n\t\t\t\t\tshouldSummarizeStateEarlyStage.shouldSummarize === false\n\t\t\t\t) {\n\t\t\t\t\treturn `early exit ${shouldSummarizeStateEarlyStage.stopReason}`;\n\t\t\t\t}\n\n\t\t\t\t// We transition to Running before requesting the summarizer, because after requesting we can't predict\n\t\t\t\t// when the electedClient will be replaced with the new summarizer client.\n\t\t\t\t// The alternative would be to let connectedState.clientId !== clientElection.electedClientId when\n\t\t\t\t// state === Starting || state === Running.\n\t\t\t\tassert(this.state === SummaryManagerState.Starting, 0x263 /* \"Expected: starting\" */);\n\t\t\t\tthis.state = SummaryManagerState.Running;\n\n\t\t\t\tconst summarizer = await this.createSummarizerFn();\n\t\t\t\tthis.summarizer = summarizer;\n\t\t\t\tthis.setupForwardedEvents(summarizer);\n\n\t\t\t\t// A stop may have been requested while we were awaiting summarizer creation.\n\t\t\t\t// Replay it now so the summarizer can observe the stop intent and move to exit.\n\t\t\t\tif (this.pendingStopReason !== undefined) {\n\t\t\t\t\tsummarizer.stop(this.pendingStopReason);\n\t\t\t\t\tthis.pendingStopReason = undefined;\n\t\t\t\t}\n\n\t\t\t\t// Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n\t\t\t\t// If we can't run the LastSummary, simply return as to avoid paying the cost of launching\n\t\t\t\t// the summarizer at all.\n\t\t\t\tconst shouldSummarizeState = this.getShouldSummarizeState();\n\t\t\t\tif (shouldSummarizeState.shouldSummarize === false) {\n\t\t\t\t\t// In order to allow the last summary to run, we not only need a stop reason that would\n\t\t\t\t\t// allow it but also, startWithInitialDelay to be false (start the summarization immediately),\n\t\t\t\t\t// which would happen when we have a high enough number of unsummarized ops.\n\t\t\t\t\tif (\n\t\t\t\t\t\tstartWithInitialDelay ||\n\t\t\t\t\t\t!stopReasonCanRunLastSummary(shouldSummarizeState.stopReason)\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.state = SummaryManagerState.Starting;\n\t\t\t\t\t\tsummarizer.stop(shouldSummarizeState.stopReason);\n\t\t\t\t\t\treturn `early exit after starting summarizer ${shouldSummarizeState.stopReason}`;\n\t\t\t\t\t}\n\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"LastAttemptToSummarize\",\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst clientId = this.latestClientId!;\n\n\t\t\t\treturn PerformanceEvent.timedExecAsync(\n\t\t\t\t\tthis.logger,\n\t\t\t\t\t{ eventName: \"RunningSummarizer\", attempt: this.startThrottler.numAttempts },\n\t\t\t\t\tasync () => summarizer.run(clientId),\n\t\t\t\t);\n\t\t\t})\n\t\t\t.then((reason: string) => {\n\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"EndingSummarizer\",\n\t\t\t\t\treason,\n\t\t\t\t});\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"EndingSummarizer\",\n\t\t\t\t\t\treason: \"exception\",\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\n\t\t\t\t// Most of exceptions happen due to container being closed while loading it, due to\n\t\t\t\t// summarizer container loosing connection while load.\n\t\t\t\t// Not worth reporting such errors as errors. That said, we might miss some real errors if\n\t\t\t\t// we ignore blindly, so try to narrow signature we are looking for - skip logging\n\t\t\t\t// error only if this client should no longer be a summarizer (which in practice\n\t\t\t\t// means it also lost connection), and error happened on load (we do not have summarizer).\n\t\t\t\t// We could annotate the error raised in Container.load where the container closed during load with no error\n\t\t\t\t// and check for that case here, but that does not seem to be necessary.\n\t\t\t\tif (this.getShouldSummarizeState().shouldSummarize || this.summarizer !== undefined) {\n\t\t\t\t\t// Report any failure as an error unless it was due to cancellation (like \"disconnected\" error)\n\t\t\t\t\t// If failure happened on container load, we may not yet realized that socket disconnected, so check\n\t\t\t\t\t// offlineError.\n\t\t\t\t\tconst category =\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\t\t\t\terror?.errorType === DriverErrorTypes.offlineError ? \"generic\" : \"error\";\n\t\t\t\t\tthis.logger.sendTelemetryEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: \"SummarizerException\",\n\t\t\t\t\t\t\tcategory,\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (generation !== this.summarizerGeneration) {\n\t\t\t\t\t// Cleanup was already performed by another path (e.g. the stop timeout),\n\t\t\t\t\t// and a new summarizer cycle may have started. Running cleanup again\n\t\t\t\t\t// would corrupt the current state machine cycle.\n\t\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\t\teventName: \"SummarizerCleanupAlreadyDone\",\n\t\t\t\t\t\tcurrentState: this.state,\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tassert(this.state !== SummaryManagerState.Off, 0x264 /* \"Expected: Not Off\" */);\n\t\t\t\tthis.cleanupAfterSummarizerStop();\n\t\t\t});\n\t}\n\n\tprivate cleanupAfterSummarizerStop(): void {\n\t\tthis.summarizerGeneration++;\n\t\tthis.state = SummaryManagerState.Off;\n\t\tthis.pendingStopReason = undefined;\n\n\t\t// Clear any pending stop timeout to avoid it firing for a different summarizer\n\t\tif (this.summarizerStopTimeout !== undefined) {\n\t\t\tclearTimeout(this.summarizerStopTimeout);\n\t\t\tthis.summarizerStopTimeout = undefined;\n\t\t}\n\n\t\tthis.cleanupForwardedEvents();\n\t\tthis.summarizer?.close();\n\t\tthis.summarizer = undefined;\n\n\t\tif (this.getShouldSummarizeState().shouldSummarize) {\n\t\t\tthis.startSummarization();\n\t\t}\n\t}\n\n\tprivate stop(reason: SummarizerStopReason): void {\n\t\tif (!SummaryManager.isStartingOrRunning(this.state)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.state = SummaryManagerState.Stopping;\n\t\tthis.pendingStopReason = reason;\n\n\t\t// Stopping the running summarizer client should trigger a change\n\t\t// in states when the running summarizer closes\n\t\tthis.summarizer?.stop(reason);\n\n\t\tconst summarizerCloseTimeoutMs = 2 * 60 * 1000; // 2 minutes\n\t\t// Clear any existing timeout before setting a new one\n\t\tif (this.summarizerStopTimeout !== undefined) {\n\t\t\tclearTimeout(this.summarizerStopTimeout);\n\t\t}\n\t\t// Set a timeout to force cleanup if the summarizer doesn't close in time\n\t\tthis.summarizerStopTimeout = setTimeout(() => {\n\t\t\tif (this.state === SummaryManagerState.Stopping && this.summarizer !== undefined) {\n\t\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"SummarizerStopTimeout\",\n\t\t\t\t\ttimeoutMs: summarizerCloseTimeoutMs,\n\t\t\t\t\tstopReason: reason,\n\t\t\t\t});\n\t\t\t\tthis.cleanupAfterSummarizerStop();\n\t\t\t}\n\t\t}, summarizerCloseTimeoutMs);\n\t}\n\n\t/**\n\t * Implements initial delay before creating summarizer\n\t * @returns `true`, if creation is delayed due to heuristics (not many ops to summarize).\n\t * `false` if summarizer should start immediately due to too many unsummarized ops.\n\t */\n\tprivate async delayBeforeCreatingSummarizer(): Promise<boolean> {\n\t\t// throttle creation of new summarizer containers to prevent spamming the server with websocket connections\n\t\tlet delayMs = this.startThrottler.getDelay();\n\n\t\t// We have been elected the summarizer. Some day we may be able to summarize with a live document but for\n\t\t// now we play it safe and launch a second copy.\n\t\tthis.logger.sendTelemetryEvent({\n\t\t\teventName: \"CreatingSummarizer\",\n\t\t\tthrottlerDelay: delayMs,\n\t\t\tinitialDelay: this.initialDelayMs,\n\t\t\tstartThrottlerMaxDelayMs: this.startThrottler.maxDelayMs,\n\t\t\topsSinceLastAck: this.summaryCollection.opsSinceLastAck,\n\t\t\topsToBypassInitialDelay: this.opsToBypassInitialDelay,\n\t\t\telectedParentId: this.clientElection.electedParentId,\n\t\t\telectedClientId: this.clientElection.electedClientId,\n\t\t});\n\n\t\t// This delay helps ensure that last summarizer that might be left from previous client\n\t\t// has enough time to complete its last summary and thus new summarizer not conflict with previous one.\n\t\t// If, however, there are too many unsummarized ops, try to resolve it as quickly as possible, with\n\t\t// understanding that we may see nacks because of such quick action.\n\t\t// A better design would be for summarizer election logic to always select current summarizer as\n\t\t// summarizing client (i.e. clientType === \"summarizer\" can be elected) to ensure that nobody else can\n\t\t// summarizer while it finishes its work and moves to exit.\n\t\t// It also helps with pure boot scenario (single client) to offset expensive work a bit out from\n\t\t// critical boot sequence.\n\t\tlet startWithInitialDelay = false;\n\t\tif (this.summaryCollection.opsSinceLastAck < this.opsToBypassInitialDelay) {\n\t\t\tstartWithInitialDelay = true;\n\t\t\tdelayMs = Math.max(delayMs, this.initialDelayMs);\n\t\t}\n\n\t\tif (delayMs > 0) {\n\t\t\tlet timer: number | undefined;\n\t\t\tlet resolveOpPromiseFn: (value: void | PromiseLike<void>) => void;\n\t\t\t// Create a listener that will break the delay if we've exceeded the initial delay ops count.\n\t\t\tconst opsListenerFn = (): void => {\n\t\t\t\tif (this.summaryCollection.opsSinceLastAck >= this.opsToBypassInitialDelay) {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tresolveOpPromiseFn();\n\t\t\t\t}\n\t\t\t};\n\t\t\t// Create a Promise that will resolve when the delay expires.\n\t\t\tconst delayPromise = new Promise<void>((resolve) => {\n\t\t\t\ttimer = setTimeout(() => resolve(), delayMs);\n\t\t\t});\n\t\t\t// Create a Promise that will resolve if the ops count passes the threshold.\n\t\t\tconst opPromise = new Promise<void>((resolve) => {\n\t\t\t\tresolveOpPromiseFn = resolve;\n\t\t\t});\n\t\t\tthis.summaryCollection.addOpListener(opsListenerFn);\n\t\t\tawait Promise.race([delayPromise, opPromise]);\n\t\t\tthis.summaryCollection.removeOpListener(opsListenerFn);\n\t\t}\n\t\treturn startWithInitialDelay;\n\t}\n\n\tpublic summarizeOnDemand(options: IOnDemandSummarizeOptions): ISummarizeResults {\n\t\tif (this.summarizer === undefined) {\n\t\t\tthrow new Error(\"No running summarizer client\");\n\t\t\t// TODO: could spawn a summarizer client temporarily.\n\t\t}\n\t\treturn this.summarizer.summarizeOnDemand(options);\n\t}\n\n\tpublic enqueueSummarize(options: IEnqueueSummarizeOptions): EnqueueSummarizeResult {\n\t\tif (this.summarizer === undefined) {\n\t\t\tthrow new Error(\"No running summarizer client\");\n\t\t\t// TODO: could spawn a summarizer client temporarily.\n\t\t}\n\t\treturn this.summarizer.enqueueSummarize(options);\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.clientElection.off(\"electedSummarizerChanged\", this.refreshSummarizer);\n\t\tthis.connectedState.off(\"connected\", this.handleConnected);\n\t\tthis.connectedState.off(\"disconnected\", this.handleDisconnected);\n\t\tthis.cleanupForwardedEvents();\n\t\tthis.pendingStopReason = undefined;\n\t\tif (this.summarizerStopTimeout !== undefined) {\n\t\t\tclearTimeout(this.summarizerStopTimeout);\n\t\t}\n\t\tthis._disposed = true;\n\t}\n\n\tprivate readonly forwardedEventsCleanup: (() => void)[] = [];\n\n\tprivate setupForwardedEvents(summarizer: ISummarizer): void {\n\t\tfor (const event of [\n\t\t\t\"summarize\",\n\t\t\t\"summarizeAllAttemptsFailed\",\n\t\t\t\"summarizerStop\",\n\t\t\t\"summarizerStart\",\n\t\t\t\"summarizerStartupFailed\",\n\t\t\t\"summarizeTimeout\",\n\t\t] as const) {\n\t\t\tconst listener = (...args: unknown[]): void => {\n\t\t\t\tthis.emit(event, ...args);\n\t\t\t};\n\t\t\t// TODO: better typing here\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument\n\t\t\tsummarizer.on(event as any, listener);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument\n\t\t\tthis.forwardedEventsCleanup.push(() => summarizer.off(event as any, listener));\n\t\t}\n\t}\n\n\tprivate cleanupForwardedEvents(): void {\n\t\tfor (const cleanup of this.forwardedEventsCleanup) {\n\t\t\tcleanup();\n\t\t}\n\t\tthis.forwardedEventsCleanup.length = 0;\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-runtime",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.110.0",
|
|
4
4
|
"description": "Fluid container runtime",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -119,18 +119,18 @@
|
|
|
119
119
|
"temp-directory": "nyc/.nyc_output"
|
|
120
120
|
},
|
|
121
121
|
"dependencies": {
|
|
122
|
-
"@fluid-internal/client-utils": "~2.
|
|
123
|
-
"@fluidframework/container-definitions": "~2.
|
|
124
|
-
"@fluidframework/container-runtime-definitions": "~2.
|
|
125
|
-
"@fluidframework/core-interfaces": "~2.
|
|
126
|
-
"@fluidframework/core-utils": "~2.
|
|
127
|
-
"@fluidframework/datastore": "~2.
|
|
128
|
-
"@fluidframework/driver-definitions": "~2.
|
|
129
|
-
"@fluidframework/driver-utils": "~2.
|
|
130
|
-
"@fluidframework/id-compressor": "~2.
|
|
131
|
-
"@fluidframework/runtime-definitions": "~2.
|
|
132
|
-
"@fluidframework/runtime-utils": "~2.
|
|
133
|
-
"@fluidframework/telemetry-utils": "~2.
|
|
122
|
+
"@fluid-internal/client-utils": "~2.110.0",
|
|
123
|
+
"@fluidframework/container-definitions": "~2.110.0",
|
|
124
|
+
"@fluidframework/container-runtime-definitions": "~2.110.0",
|
|
125
|
+
"@fluidframework/core-interfaces": "~2.110.0",
|
|
126
|
+
"@fluidframework/core-utils": "~2.110.0",
|
|
127
|
+
"@fluidframework/datastore": "~2.110.0",
|
|
128
|
+
"@fluidframework/driver-definitions": "~2.110.0",
|
|
129
|
+
"@fluidframework/driver-utils": "~2.110.0",
|
|
130
|
+
"@fluidframework/id-compressor": "~2.110.0",
|
|
131
|
+
"@fluidframework/runtime-definitions": "~2.110.0",
|
|
132
|
+
"@fluidframework/runtime-utils": "~2.110.0",
|
|
133
|
+
"@fluidframework/telemetry-utils": "~2.110.0",
|
|
134
134
|
"@tylerbu/sorted-btree-es6": "^2.1.1",
|
|
135
135
|
"double-ended-queue": "^2.1.0-0",
|
|
136
136
|
"lz4js": "^0.2.0",
|
|
@@ -140,16 +140,16 @@
|
|
|
140
140
|
"devDependencies": {
|
|
141
141
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
142
142
|
"@biomejs/biome": "~2.4.5",
|
|
143
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
144
|
-
"@fluid-private/stochastic-test-utils": "~2.
|
|
145
|
-
"@fluid-private/test-pairwise-generator": "~2.
|
|
143
|
+
"@fluid-internal/mocha-test-setup": "~2.110.0",
|
|
144
|
+
"@fluid-private/stochastic-test-utils": "~2.110.0",
|
|
145
|
+
"@fluid-private/test-pairwise-generator": "~2.110.0",
|
|
146
146
|
"@fluid-tools/benchmark": "^0.59.0",
|
|
147
147
|
"@fluid-tools/build-cli": "^0.65.0",
|
|
148
148
|
"@fluidframework/build-common": "^2.0.3",
|
|
149
149
|
"@fluidframework/build-tools": "^0.65.0",
|
|
150
|
-
"@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.
|
|
151
|
-
"@fluidframework/eslint-config-fluid": "^
|
|
152
|
-
"@fluidframework/test-runtime-utils": "~2.
|
|
150
|
+
"@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.103.0",
|
|
151
|
+
"@fluidframework/eslint-config-fluid": "^13.0.0",
|
|
152
|
+
"@fluidframework/test-runtime-utils": "~2.110.0",
|
|
153
153
|
"@microsoft/api-extractor": "7.58.1",
|
|
154
154
|
"@types/double-ended-queue": "^2.1.0",
|
|
155
155
|
"@types/lz4js": "^0.2.0",
|
package/src/batchTracker.ts
CHANGED
|
@@ -9,14 +9,14 @@ import type { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
|
9
9
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
10
10
|
import type { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
11
11
|
import {
|
|
12
|
-
type ITelemetryLoggerExt,
|
|
13
12
|
createChildLogger,
|
|
13
|
+
type TelemetryLoggerExt,
|
|
14
14
|
} from "@fluidframework/telemetry-utils/internal";
|
|
15
15
|
|
|
16
16
|
type BatchTrackerMessage = Pick<ISequencedDocumentMessage, "sequenceNumber">;
|
|
17
17
|
|
|
18
18
|
export class BatchTracker {
|
|
19
|
-
private readonly logger:
|
|
19
|
+
private readonly logger: TelemetryLoggerExt;
|
|
20
20
|
private startBatchSequenceNumber: number | undefined;
|
|
21
21
|
private trackedBatchCount: number = 0;
|
|
22
22
|
private batchProcessingStartTimeStamp: number | undefined;
|
|
@@ -75,7 +75,7 @@ export class BatchTracker {
|
|
|
75
75
|
* Track batch sizes in terms of op counts and processing times
|
|
76
76
|
*
|
|
77
77
|
* @param batchEventEmitter - event emitter which tracks the lifecycle of batch operations
|
|
78
|
-
* @param logger - See {@link @fluidframework/core-interfaces#
|
|
78
|
+
* @param logger - See {@link @fluidframework/core-interfaces#TelemetryLoggerExt}
|
|
79
79
|
* @param batchLengthThreshold - threshold for the length of a batch when to send an error event
|
|
80
80
|
* @param batchCountSamplingRate - rate for batches for which to send an event with its characteristics
|
|
81
81
|
*/
|
|
@@ -7,7 +7,7 @@ import type { IContainerContext } from "@fluidframework/container-definitions/in
|
|
|
7
7
|
import { readAndParse } from "@fluidframework/driver-utils/internal";
|
|
8
8
|
import type { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions/internal";
|
|
9
9
|
import { SummaryTreeBuilder } from "@fluidframework/runtime-utils/internal";
|
|
10
|
-
import type {
|
|
10
|
+
import type { TelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Information from a snapshot needed to load BlobManager
|
|
@@ -58,7 +58,7 @@ const loadV1 = async (
|
|
|
58
58
|
|
|
59
59
|
export const toRedirectTable = (
|
|
60
60
|
blobManagerLoadInfo: IBlobManagerLoadInfo,
|
|
61
|
-
logger:
|
|
61
|
+
logger: TelemetryLoggerExt,
|
|
62
62
|
): Map<string, string> => {
|
|
63
63
|
const count = blobManagerLoadInfo.ids?.length ?? 0;
|
|
64
64
|
const redirectTableLength = blobManagerLoadInfo.redirectTable?.length ?? 0;
|
|
@@ -16,12 +16,12 @@ import {
|
|
|
16
16
|
} from "@fluidframework/driver-definitions/internal";
|
|
17
17
|
import { isRuntimeMessage } from "@fluidframework/driver-utils/internal";
|
|
18
18
|
import {
|
|
19
|
-
type IEventSampler,
|
|
20
|
-
type ITelemetryLoggerExt,
|
|
21
|
-
type ISampledTelemetryLogger,
|
|
22
19
|
createChildLogger,
|
|
23
20
|
createSampledLogger,
|
|
24
21
|
formatTick,
|
|
22
|
+
type IEventSampler,
|
|
23
|
+
type ISampledTelemetryLogger,
|
|
24
|
+
type TelemetryLoggerExt,
|
|
25
25
|
} from "@fluidframework/telemetry-utils/internal";
|
|
26
26
|
|
|
27
27
|
/**
|
|
@@ -105,7 +105,7 @@ class OpPerfTelemetry {
|
|
|
105
105
|
*/
|
|
106
106
|
private processedOpSizeForTelemetry = 0;
|
|
107
107
|
|
|
108
|
-
private readonly logger:
|
|
108
|
+
private readonly logger: TelemetryLoggerExt;
|
|
109
109
|
|
|
110
110
|
private static readonly OP_LATENCY_SAMPLE_RATE = 500;
|
|
111
111
|
private readonly opLatencyLogger: ISampledTelemetryLogger;
|
|
@@ -151,7 +151,7 @@ class OpPerfTelemetry {
|
|
|
151
151
|
/**
|
|
152
152
|
* Telemetry logger to write events to.
|
|
153
153
|
*/
|
|
154
|
-
logger:
|
|
154
|
+
logger: TelemetryLoggerExt,
|
|
155
155
|
) {
|
|
156
156
|
this.logger = createChildLogger({ logger, namespace: "OpPerf" });
|
|
157
157
|
|
package/src/containerRuntime.ts
CHANGED
|
@@ -152,8 +152,8 @@ import type {
|
|
|
152
152
|
IEventSampler,
|
|
153
153
|
IFluidErrorBase,
|
|
154
154
|
ITelemetryGenericEventExt,
|
|
155
|
-
ITelemetryLoggerExt,
|
|
156
155
|
MonitoringContext,
|
|
156
|
+
TelemetryLoggerExt,
|
|
157
157
|
} from "@fluidframework/telemetry-utils/internal";
|
|
158
158
|
import {
|
|
159
159
|
DataCorruptionError,
|
|
@@ -735,7 +735,7 @@ function lastMessageFromMetadata(
|
|
|
735
735
|
* to understand if/when it is hit.
|
|
736
736
|
* We only want to log this once, to avoid spamming telemetry if we are wrong and these cases are hit commonly.
|
|
737
737
|
*/
|
|
738
|
-
export let getSingleUseLegacyLogCallback = (logger:
|
|
738
|
+
export let getSingleUseLegacyLogCallback = (logger: TelemetryLoggerExt, type: string) => {
|
|
739
739
|
return (codePath: string): void => {
|
|
740
740
|
logger.sendTelemetryEvent({
|
|
741
741
|
eventName: "LegacyMessageFormat",
|
|
@@ -1360,7 +1360,25 @@ export class ContainerRuntime
|
|
|
1360
1360
|
return this._getAttachState();
|
|
1361
1361
|
}
|
|
1362
1362
|
|
|
1363
|
-
|
|
1363
|
+
/**
|
|
1364
|
+
* Whether local op submission is currently disallowed.
|
|
1365
|
+
*
|
|
1366
|
+
* This is `true` in two distinct situations.
|
|
1367
|
+
*
|
|
1368
|
+
* First: the delta manager reports a read-only connection (host/service-imposed permission or connection state — the historical meaning of `readOnly`).
|
|
1369
|
+
*
|
|
1370
|
+
* Second: the `PendingStateManager` is replaying stashed ops (`isApplyingStashedOps`). During this window DDSes must not submit new local ops, as doing so would interleave fresh content ahead of the stashed pending stream and corrupt pending local state. Surfacing it through `isReadOnly()` lets DDSes that consult `readOnly` at realize time self-suppress; see the apply-lifecycle docs on `PendingStateManager` for the full rationale.
|
|
1371
|
+
*
|
|
1372
|
+
* Note this layers a third meaning ("transiently quiescing for stashed-op replay") onto the `readOnly` predicate, which is broader than its host/connection-permission origin.
|
|
1373
|
+
*/
|
|
1374
|
+
public readonly isReadOnly = (): boolean =>
|
|
1375
|
+
// `_deltaManager` and `pendingStateManager` are both assigned partway
|
|
1376
|
+
// through the constructor; `baseLogger` is built earlier and stamps
|
|
1377
|
+
// `isReadOnly` on every error event (e.g. layer-compat failures
|
|
1378
|
+
// during construction), so this can be called before either is
|
|
1379
|
+
// assigned. Optional chains keep that window safe.
|
|
1380
|
+
this._deltaManager?.readOnlyInfo.readonly === true ||
|
|
1381
|
+
this.pendingStateManager?.isApplyingStashedOps === true;
|
|
1364
1382
|
|
|
1365
1383
|
/**
|
|
1366
1384
|
* Current session schema - defines what options are on & off.
|
|
@@ -1597,6 +1615,8 @@ export class ContainerRuntime
|
|
|
1597
1615
|
|
|
1598
1616
|
private readonly extensions = new Map<ContainerExtensionId, ExtensionEntry>();
|
|
1599
1617
|
|
|
1618
|
+
public readonly baseLogger: ITelemetryBaseLogger;
|
|
1619
|
+
|
|
1600
1620
|
/***/
|
|
1601
1621
|
protected constructor(
|
|
1602
1622
|
context: IContainerContext,
|
|
@@ -1610,7 +1630,7 @@ export class ContainerRuntime
|
|
|
1610
1630
|
private readonly runtimeOptions: Readonly<ContainerRuntimeOptionsInternal>,
|
|
1611
1631
|
private readonly containerScope: FluidObject,
|
|
1612
1632
|
// Create a custom ITelemetryBaseLogger to output telemetry events.
|
|
1613
|
-
|
|
1633
|
+
baseLogger: ITelemetryBaseLogger,
|
|
1614
1634
|
existing: boolean,
|
|
1615
1635
|
|
|
1616
1636
|
blobManagerLoadInfo: IBlobManagerLoadInfo,
|
|
@@ -1663,15 +1683,20 @@ export class ContainerRuntime
|
|
|
1663
1683
|
|
|
1664
1684
|
this.isSnapshotInstanceOfISnapshot = snapshotWithContents !== undefined;
|
|
1665
1685
|
|
|
1666
|
-
this.
|
|
1667
|
-
logger:
|
|
1668
|
-
namespace: "ContainerRuntime",
|
|
1686
|
+
this.baseLogger = createChildLogger({
|
|
1687
|
+
logger: baseLogger,
|
|
1669
1688
|
properties: {
|
|
1670
|
-
|
|
1671
|
-
inStagingMode: this.inStagingMode,
|
|
1689
|
+
error: {
|
|
1690
|
+
inStagingMode: () => this.inStagingMode,
|
|
1691
|
+
isApplyingStashedOps: () => this.pendingStateManager?.isApplyingStashedOps,
|
|
1692
|
+
isReadOnly: () => this.isReadOnly(),
|
|
1672
1693
|
},
|
|
1673
1694
|
},
|
|
1674
1695
|
});
|
|
1696
|
+
this.mc = createChildMonitoringContext({
|
|
1697
|
+
logger: this.baseLogger,
|
|
1698
|
+
namespace: "ContainerRuntime",
|
|
1699
|
+
});
|
|
1675
1700
|
|
|
1676
1701
|
// Validate that the Loader is compatible with this Runtime.
|
|
1677
1702
|
const maybeLoaderCompatDetailsForRuntime = context as FluidObject<ILayerCompatDetails>;
|
|
@@ -1840,6 +1865,18 @@ export class ContainerRuntime
|
|
|
1840
1865
|
},
|
|
1841
1866
|
pendingRuntimeState?.pending,
|
|
1842
1867
|
this.baseLogger,
|
|
1868
|
+
{
|
|
1869
|
+
// PSM has cleared `isApplyingStashedOps`; `isReadOnly()` now
|
|
1870
|
+
// reflects the network-readonly state again. Fan out so DDSes
|
|
1871
|
+
// know they can submit once more. No open hook is needed —
|
|
1872
|
+
// the apply window opens before `channelCollection` exists,
|
|
1873
|
+
// so a fanout there would be a no-op; data stores instead
|
|
1874
|
+
// pick up the initial readonly state from `isReadOnly()`
|
|
1875
|
+
// when they're first asked.
|
|
1876
|
+
onAfterStashedOpsApplied: () => {
|
|
1877
|
+
this.notifyReadOnlyState();
|
|
1878
|
+
},
|
|
1879
|
+
},
|
|
1843
1880
|
);
|
|
1844
1881
|
|
|
1845
1882
|
let outerDeltaManager: IDeltaManagerFull = this.innerDeltaManager;
|
|
@@ -2187,6 +2224,14 @@ export class ContainerRuntime
|
|
|
2187
2224
|
telemetryDocumentId: this.telemetryDocumentId,
|
|
2188
2225
|
groupedBatchingEnabled: this.groupedBatchingEnabled,
|
|
2189
2226
|
initialSequenceNumber: this.deltaManager.initialSequenceNumber,
|
|
2227
|
+
// Number of ops since the last summary that this client is aware of (including ops still
|
|
2228
|
+
// queued for processing). Computed as the gap between the latest known op sequence number
|
|
2229
|
+
// and the sequence number of the message at which the last summary was taken (per snapshot
|
|
2230
|
+
// metadata). Falls back to lastKnownSeqNumber when no prior summary message is recorded
|
|
2231
|
+
// (e.g. new container or older snapshot without metadata).
|
|
2232
|
+
numUnsummarizedOps:
|
|
2233
|
+
this.deltaManager.lastKnownSeqNumber -
|
|
2234
|
+
(this.messageAtLastSummary?.sequenceNumber ?? 0),
|
|
2190
2235
|
minVersionForCollab: this.minVersionForCollab,
|
|
2191
2236
|
// logging hardware telemetry
|
|
2192
2237
|
deviceSpec: { ...getDeviceSpec() },
|
|
@@ -2805,6 +2850,28 @@ export class ContainerRuntime
|
|
|
2805
2850
|
return;
|
|
2806
2851
|
}
|
|
2807
2852
|
|
|
2853
|
+
// Invariant: the canSendOps edge in `setConnectionStateCore` — the
|
|
2854
|
+
// only caller of this method — cannot fire while
|
|
2855
|
+
// `applyStashedOpsAt` is in flight, because the loader awaits the
|
|
2856
|
+
// apply before transitioning the runtime to a write-capable
|
|
2857
|
+
// connection. If this assert ever fires, that contract has changed
|
|
2858
|
+
// and the submit guard at `submit()` would catch a runtime-internal
|
|
2859
|
+
// resubmit (`Rejoin`, `GC`, `FluidDataStoreOp`) for an op type
|
|
2860
|
+
// outside the apply-window allowlist.
|
|
2861
|
+
//
|
|
2862
|
+
// The precondition is held by the load sequence: `loadRuntime2`
|
|
2863
|
+
// awaits `pendingStateManager.applyStashedOpsAt(...)` before
|
|
2864
|
+
// returning the runtime, and the loader gates `setLoaded` on that
|
|
2865
|
+
// completion before any write-capable connection edge fires. A
|
|
2866
|
+
// maintainer reordering either sequence (or adding a new
|
|
2867
|
+
// `canSendOps` edge that fires before the apply resolves) is what
|
|
2868
|
+
// would trip this assert.
|
|
2869
|
+
// @see {@link ContainerRuntime.loadRuntime2} (awaits `applyStashedOpsAt`)
|
|
2870
|
+
assert(
|
|
2871
|
+
!this.pendingStateManager.isApplyingStashedOps,
|
|
2872
|
+
0xd01 /* replayPendingStates must not be called during stashed-op apply window */,
|
|
2873
|
+
);
|
|
2874
|
+
|
|
2808
2875
|
// Replaying is an internal operation and we don't want to generate noise while doing it.
|
|
2809
2876
|
// So temporarily disable dirty state change events, and save the old state.
|
|
2810
2877
|
// When we're done, we'll emit the event if the state changed.
|
|
@@ -2920,8 +2987,14 @@ export class ContainerRuntime
|
|
|
2920
2987
|
}
|
|
2921
2988
|
}
|
|
2922
2989
|
|
|
2923
|
-
|
|
2924
|
-
|
|
2990
|
+
// Boolean payload from the `"readonly"` delta-manager event is intentionally
|
|
2991
|
+
// ignored — `isReadOnly()` aggregates delta-manager readonly with the PSM
|
|
2992
|
+
// apply window, and that aggregation is the source of truth for fanout.
|
|
2993
|
+
// `channelCollection?.` guards against future wiring changes; both callers
|
|
2994
|
+
// today (the `"readonly"` listener and `onAfterStashedOpsApplied`) fire
|
|
2995
|
+
// after `channelCollection` is assigned.
|
|
2996
|
+
private readonly notifyReadOnlyState = (_readonly?: boolean): void =>
|
|
2997
|
+
this.channelCollection?.notifyReadOnlyState(this.isReadOnly());
|
|
2925
2998
|
|
|
2926
2999
|
public setConnectionState(canSendOps: boolean, clientId?: string): void {
|
|
2927
3000
|
this.setConnectionStateToConnectedOrDisconnected(canSendOps, clientId);
|
|
@@ -4078,7 +4151,7 @@ export class ContainerRuntime
|
|
|
4078
4151
|
/**
|
|
4079
4152
|
* Logger to use for correlated summary events
|
|
4080
4153
|
*/
|
|
4081
|
-
summaryLogger?:
|
|
4154
|
+
summaryLogger?: TelemetryLoggerExt;
|
|
4082
4155
|
/**
|
|
4083
4156
|
* True to run garbage collection before summarizing; defaults to true
|
|
4084
4157
|
*/
|
|
@@ -4287,7 +4360,7 @@ export class ContainerRuntime
|
|
|
4287
4360
|
/**
|
|
4288
4361
|
* Logger to use for logging GC events
|
|
4289
4362
|
*/
|
|
4290
|
-
logger?:
|
|
4363
|
+
logger?: TelemetryLoggerExt;
|
|
4291
4364
|
/**
|
|
4292
4365
|
* True to run GC sweep phase after the mark phase
|
|
4293
4366
|
*/
|
|
@@ -4718,7 +4791,7 @@ export class ContainerRuntime
|
|
|
4718
4791
|
* @returns failed summarize result (IBaseSummarizeResult) if summary should be failed, undefined otherwise.
|
|
4719
4792
|
*/
|
|
4720
4793
|
private async shouldFailSummaryOnPendingOps(
|
|
4721
|
-
logger:
|
|
4794
|
+
logger: TelemetryLoggerExt,
|
|
4722
4795
|
referenceSequenceNumber: number,
|
|
4723
4796
|
minimumSequenceNumber: number,
|
|
4724
4797
|
finalAttempt: boolean,
|
|
@@ -4840,6 +4913,52 @@ export class ContainerRuntime
|
|
|
4840
4913
|
): void {
|
|
4841
4914
|
this.verifyNotClosed();
|
|
4842
4915
|
|
|
4916
|
+
// Nothing should be submitting while we're replaying stashed ops.
|
|
4917
|
+
// The runtime is readonly during the apply window (see
|
|
4918
|
+
// `PendingStateManager._applyLifecycle`), so a compliant DDS skips
|
|
4919
|
+
// submits. If we land here anyway, a DDS bypassed the readonly gate
|
|
4920
|
+
// (e.g. a realize-time write that doesn't consult `readOnly`) and
|
|
4921
|
+
// produced a local op that has no counterpart in the saved-op
|
|
4922
|
+
// replay — we cannot reconcile the mismatch, so fail fatally. We
|
|
4923
|
+
// check here (rather than at flush) because outbox flushes are
|
|
4924
|
+
// deferred and the apply window could close before the offending op
|
|
4925
|
+
// reaches the pending queue.
|
|
4926
|
+
//
|
|
4927
|
+
// Allowlist: `BlobAttach` is a runtime-internal op type that may
|
|
4928
|
+
// legitimately fire during apply — produced by `sharePendingBlobs`,
|
|
4929
|
+
// which is invoked from `loadRuntime2` before `applyStashedOpsAt`
|
|
4930
|
+
// resolves. `IdAllocation` is not in this allowlist because the
|
|
4931
|
+
// assert at 0x9a5 below enforces that it never reaches `submit()`
|
|
4932
|
+
// at all; treating that assert as the single source of truth.
|
|
4933
|
+
//
|
|
4934
|
+
// Always surface the error event to telemetry on a bypass so we can
|
|
4935
|
+
// attribute incidents regardless of the on-switch state. The
|
|
4936
|
+
// `EnableSubmitDuringStashedApplyThrow` config opts in to the
|
|
4937
|
+
// throw + container close; by default we log only, so a first- or
|
|
4938
|
+
// third-party DDS that quietly bypasses the readonly gate in
|
|
4939
|
+
// production is observable without escalating to a fatal close.
|
|
4940
|
+
if (
|
|
4941
|
+
this.pendingStateManager.isApplyingStashedOps &&
|
|
4942
|
+
containerRuntimeMessage.type !== ContainerMessageType.BlobAttach
|
|
4943
|
+
) {
|
|
4944
|
+
const error = new UsageError("Local op submitted during stashed-op apply window", {
|
|
4945
|
+
messageType: containerRuntimeMessage.type,
|
|
4946
|
+
});
|
|
4947
|
+
this.mc.logger.sendErrorEvent({ eventName: "SubmitDuringStashedOpApply" }, error);
|
|
4948
|
+
if (
|
|
4949
|
+
this.mc.config.getBoolean(
|
|
4950
|
+
"Fluid.ContainerRuntime.EnableSubmitDuringStashedApplyThrow",
|
|
4951
|
+
) === true
|
|
4952
|
+
) {
|
|
4953
|
+
// Close the container before throwing so the "throw + close"
|
|
4954
|
+
// contract is enforced by this code path rather than by
|
|
4955
|
+
// whichever caller happens to wrap the throw in `.catch(closeFn)`.
|
|
4956
|
+
// `closeFn` is idempotent; a caller that also closes won't double-close.
|
|
4957
|
+
this.closeFn(error);
|
|
4958
|
+
throw error;
|
|
4959
|
+
}
|
|
4960
|
+
}
|
|
4961
|
+
|
|
4843
4962
|
// There should be no ops in detached container state!
|
|
4844
4963
|
assert(
|
|
4845
4964
|
this.attachState !== AttachState.Detached,
|
|
@@ -5228,7 +5347,7 @@ export class ContainerRuntime
|
|
|
5228
5347
|
private async fetchLatestSnapshotAndMaybeClose(
|
|
5229
5348
|
targetRefSeq: number,
|
|
5230
5349
|
targetAckHandle: string,
|
|
5231
|
-
logger:
|
|
5350
|
+
logger: TelemetryLoggerExt,
|
|
5232
5351
|
): Promise<void> {
|
|
5233
5352
|
const fetchedSnapshotRefSeq = await PerformanceEvent.timedExecAsync(
|
|
5234
5353
|
logger,
|
package/src/dataStore.ts
CHANGED
|
@@ -13,8 +13,8 @@ import type {
|
|
|
13
13
|
IFluidDataStoreChannel,
|
|
14
14
|
} from "@fluidframework/runtime-definitions/internal";
|
|
15
15
|
import {
|
|
16
|
-
type ITelemetryLoggerExt,
|
|
17
16
|
TelemetryDataTag,
|
|
17
|
+
type TelemetryLoggerExt,
|
|
18
18
|
UsageError,
|
|
19
19
|
} from "@fluidframework/telemetry-utils/internal";
|
|
20
20
|
|
|
@@ -58,7 +58,7 @@ export const channelToDataStore = (
|
|
|
58
58
|
fluidDataStoreChannel: IFluidDataStoreChannel,
|
|
59
59
|
internalId: string,
|
|
60
60
|
channelCollection: ChannelCollection,
|
|
61
|
-
logger:
|
|
61
|
+
logger: TelemetryLoggerExt,
|
|
62
62
|
): IDataStore => new DataStore(fluidDataStoreChannel, internalId, channelCollection, logger);
|
|
63
63
|
|
|
64
64
|
enum AliasState {
|
|
@@ -194,7 +194,7 @@ class DataStore implements IDataStore {
|
|
|
194
194
|
private readonly fluidDataStoreChannel: IFluidDataStoreChannel,
|
|
195
195
|
private readonly internalId: string,
|
|
196
196
|
private readonly channelCollection: ChannelCollection,
|
|
197
|
-
private readonly logger:
|
|
197
|
+
private readonly logger: TelemetryLoggerExt,
|
|
198
198
|
private readonly parentContext = channelCollection.parentContext,
|
|
199
199
|
) {
|
|
200
200
|
this.pendingAliases = channelCollection.pendingAliases;
|
package/src/dataStoreContexts.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
import type { IDisposable, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
7
7
|
import { assert, Deferred, Lazy } from "@fluidframework/core-utils/internal";
|
|
8
8
|
import {
|
|
9
|
-
type ITelemetryLoggerExt,
|
|
10
9
|
createChildLogger,
|
|
10
|
+
type TelemetryLoggerExt,
|
|
11
11
|
} from "@fluidframework/telemetry-utils/internal";
|
|
12
12
|
|
|
13
13
|
import type { FluidDataStoreContext, LocalFluidDataStoreContext } from "./dataStoreContext.js";
|
|
@@ -68,7 +68,7 @@ export class DataStoreContexts
|
|
|
68
68
|
}
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
private readonly _logger:
|
|
71
|
+
private readonly _logger: TelemetryLoggerExt;
|
|
72
72
|
|
|
73
73
|
constructor(baseLogger: ITelemetryBaseLogger) {
|
|
74
74
|
this._logger = createChildLogger({ logger: baseLogger });
|
package/src/deltaScheduler.ts
CHANGED
|
@@ -7,10 +7,7 @@ import { performanceNow, type TypedEventEmitter } from "@fluid-internal/client-u
|
|
|
7
7
|
import type { IDeltaManagerFull } from "@fluidframework/container-definitions/internal";
|
|
8
8
|
import type { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
9
9
|
import type { IContainerRuntimeBaseEvents } from "@fluidframework/runtime-definitions/internal";
|
|
10
|
-
import {
|
|
11
|
-
type ITelemetryLoggerExt,
|
|
12
|
-
formatTick,
|
|
13
|
-
} from "@fluidframework/telemetry-utils/internal";
|
|
10
|
+
import { formatTick, type TelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
|
|
14
11
|
|
|
15
12
|
/**
|
|
16
13
|
* DeltaScheduler is responsible for the scheduling of inbound delta queue in cases where there
|
|
@@ -55,7 +52,7 @@ export class DeltaScheduler {
|
|
|
55
52
|
constructor(
|
|
56
53
|
private readonly deltaManager: IDeltaManagerFull,
|
|
57
54
|
private readonly runtimeEventsEmitter: TypedEventEmitter<IContainerRuntimeBaseEvents>,
|
|
58
|
-
private readonly logger:
|
|
55
|
+
private readonly logger: TelemetryLoggerExt,
|
|
59
56
|
) {
|
|
60
57
|
this.deltaManager.inbound.on("idle", this.inboundQueueIdle);
|
|
61
58
|
runtimeEventsEmitter.on("batchBegin", this.batchBegin);
|