@fluidframework/container-runtime 2.0.0-internal.3.2.1 → 2.0.0-internal.3.3.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/dist/containerRuntime.d.ts +32 -53
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +55 -21
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +8 -3
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts +19 -0
- package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -0
- package/dist/deltaManagerSummarizerProxy.js +40 -0
- package/dist/deltaManagerSummarizerProxy.js.map +1 -0
- package/dist/gc/garbageCollection.d.ts +2 -33
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +36 -181
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts +22 -0
- package/dist/gc/gcConfigs.d.ts.map +1 -0
- package/dist/gc/gcConfigs.js +138 -0
- package/dist/gc/gcConfigs.js.map +1 -0
- package/dist/gc/gcDefinitions.d.ts +101 -3
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +8 -3
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +12 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +55 -1
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts +1 -2
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +28 -37
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/index.d.ts +3 -2
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +2 -1
- package/dist/gc/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +9 -0
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +19 -2
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +2 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +24 -10
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +4 -0
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +42 -4
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts +14 -2
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +35 -18
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +29 -21
- 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/storageServiceWithAttachBlobs.d.ts +17 -0
- package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -0
- package/dist/storageServiceWithAttachBlobs.js +32 -0
- package/dist/storageServiceWithAttachBlobs.js.map +1 -0
- package/dist/summary/runWhileConnectedCoordinator.d.ts +3 -2
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js +5 -4
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +2 -0
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/lib/containerRuntime.d.ts +32 -53
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +56 -22
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +9 -4
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaManagerSummarizerProxy.d.ts +19 -0
- package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -0
- package/lib/deltaManagerSummarizerProxy.js +36 -0
- package/lib/deltaManagerSummarizerProxy.js.map +1 -0
- package/lib/gc/garbageCollection.d.ts +2 -33
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +39 -184
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts +22 -0
- package/lib/gc/gcConfigs.d.ts.map +1 -0
- package/lib/gc/gcConfigs.js +134 -0
- package/lib/gc/gcConfigs.js.map +1 -0
- package/lib/gc/gcDefinitions.d.ts +101 -3
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +7 -2
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +12 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +53 -0
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts +1 -2
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +28 -37
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/index.d.ts +3 -2
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -1
- package/lib/gc/index.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +9 -0
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +17 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +25 -11
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +4 -0
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +42 -4
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts +14 -2
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +35 -18
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +30 -22
- 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/storageServiceWithAttachBlobs.d.ts +17 -0
- package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -0
- package/lib/storageServiceWithAttachBlobs.js +28 -0
- package/lib/storageServiceWithAttachBlobs.js.map +1 -0
- package/lib/summary/runWhileConnectedCoordinator.d.ts +3 -2
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js +5 -4
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +2 -0
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/package.json +20 -31
- package/src/containerRuntime.ts +92 -76
- package/src/dataStores.ts +9 -4
- package/src/deltaManagerSummarizerProxy.ts +46 -0
- package/src/gc/garbageCollection.ts +50 -290
- package/src/gc/gcConfigs.ts +177 -0
- package/src/gc/gcDefinitions.ts +110 -4
- package/src/gc/gcHelpers.ts +78 -1
- package/src/gc/gcSummaryStateTracker.ts +35 -42
- package/src/gc/index.ts +8 -2
- package/src/index.ts +1 -2
- package/src/opLifecycle/README.md +2 -2
- package/src/opLifecycle/batchManager.ts +19 -1
- package/src/opLifecycle/index.ts +1 -1
- package/src/opLifecycle/opCompressor.ts +31 -12
- package/src/opLifecycle/opDecompressor.ts +49 -5
- package/src/opLifecycle/opSplitter.ts +44 -20
- package/src/opLifecycle/outbox.ts +36 -22
- package/src/packageVersion.ts +1 -1
- package/src/storageServiceWithAttachBlobs.ts +38 -0
- package/src/summary/runWhileConnectedCoordinator.ts +7 -7
- package/src/summary/summarizerTypes.ts +2 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summarizerTypes.js","sourceRoot":"","sources":["../../src/summary/summarizerTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAqBH;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAA6B,aAAa,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIEvent,\n\tIEventProvider,\n\tITelemetryLogger,\n\tITelemetryProperties,\n} from \"@fluidframework/common-definitions\";\nimport { ITelemetryLoggerPropertyBag } from \"@fluidframework/telemetry-utils\";\nimport { IFluidLoadable } from \"@fluidframework/core-interfaces\";\nimport { ContainerWarning, IDeltaManager } from \"@fluidframework/container-definitions\";\nimport {\n\tISequencedDocumentMessage,\n\tISummaryTree,\n\tIDocumentMessage,\n} from \"@fluidframework/protocol-definitions\";\nimport { ISummaryStats } from \"@fluidframework/runtime-definitions\";\nimport { ISummaryConfigurationHeuristics } from \"../containerRuntime\";\nimport { ISummaryAckMessage, ISummaryNackMessage, ISummaryOpMessage } from \"./summaryCollection\";\nimport { SummarizeReason } from \"./summaryGenerator\";\n\n/**\n * @deprecated This will be removed in a later release.\n */\nexport const ISummarizer: keyof IProvideSummarizer = \"ISummarizer\";\n\n/**\n * @deprecated This will be removed in a later release.\n */\nexport interface IProvideSummarizer {\n\t/**\n\t * @deprecated This will be removed in a later release.\n\t */\n\treadonly ISummarizer: ISummarizer;\n}\n\n/**\n * Similar to AbortSignal, but using promise instead of events\n * @param T - cancellation reason type\n */\nexport interface ICancellationToken<T> {\n\t/** Tells if this cancellable token is cancelled */\n\treadonly cancelled: boolean;\n\t/**\n\t * Promise that gets fulfilled when this cancellable token is cancelled\n\t * @returns reason of cancellation\n\t */\n\treadonly waitCancelled: Promise<T>;\n}\n\n/* Similar to AbortSignal, but using promise instead of events */\nexport type ISummaryCancellationToken = ICancellationToken<SummarizerStopReason>;\n\nexport interface ISummarizerInternalsProvider {\n\t/** Encapsulates the work to walk the internals of the running container to generate a summary */\n\tsubmitSummary(options: ISubmitSummaryOptions): Promise<SubmitSummaryResult>;\n\n\t/** Callback whenever a new SummaryAck is received, to update internal tracking state */\n\trefreshLatestSummaryAck(options: IRefreshSummaryAckOptions): Promise<void>;\n}\n\n/**\n * @deprecated Options that control the behavior of a running summarizer.\n * */\nexport interface ISummarizerOptions {\n\t/**\n\t * Set to true to disable the default heuristics from running; false by default.\n\t * This affects only the heuristics around when a summarizer should\n\t * submit summaries. So when it is disabled, summarizer clients should\n\t * not be expected to summarize unless an on-demand summary is requested.\n\t */\n\tdisableHeuristics: boolean;\n}\n\nexport interface ISummarizingWarning extends ContainerWarning {\n\treadonly errorType: \"summarizingError\";\n\treadonly logged: boolean;\n}\n\nexport interface IConnectableRuntime {\n\treadonly disposed: boolean;\n\treadonly connected: boolean;\n\treadonly clientId: string | undefined;\n\treadonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;\n\tonce(event: \"connected\" | \"disconnected\" | \"dispose\", listener: () => void): this;\n}\n\nexport interface ISummarizerRuntime extends IConnectableRuntime {\n\treadonly logger: ITelemetryLogger;\n\t/** clientId of parent (non-summarizing) container that owns summarizer container */\n\treadonly summarizerClientId: string | undefined;\n\tdisposeFn?(): void;\n\tcloseFn(): void;\n}\n\n/** Options affecting summarize behavior. */\nexport interface ISummarizeOptions {\n\t/** True to generate the full tree with no handle reuse optimizations; defaults to false */\n\treadonly fullTree?: boolean;\n\t/** True to ask the server what the latest summary is first; defaults to false */\n\treadonly refreshLatestAck?: boolean;\n}\n\n/**\n * Data required to update internal tracking state after receiving a Summary Ack.\n */\nexport interface IRefreshSummaryAckOptions {\n\t/** Handle from the ack's summary op. */\n\treadonly proposalHandle: string | undefined;\n\t/** Handle from the summary ack just received */\n\treadonly ackHandle: string;\n\t/** Reference sequence number from the ack's summary op */\n\treadonly summaryRefSeq: number;\n\t/** Telemetry logger to which telemetry events will be forwarded. */\n\treadonly summaryLogger: ITelemetryLogger;\n}\n\nexport interface ISubmitSummaryOptions extends ISummarizeOptions {\n\t/** Logger to use for correlated summary events */\n\treadonly summaryLogger: ITelemetryLogger;\n\t/** Tells when summary process should be cancelled */\n\treadonly cancellationToken: ISummaryCancellationToken;\n}\n\nexport interface IOnDemandSummarizeOptions extends ISummarizeOptions {\n\t/** Reason for generating summary. */\n\treadonly reason: string;\n}\n\n/** Options to use when enqueueing a summarize attempt. */\nexport interface IEnqueueSummarizeOptions extends IOnDemandSummarizeOptions {\n\t/** If specified, The summarize attempt will not occur until after this sequence number. */\n\treadonly afterSequenceNumber?: number;\n\n\t/**\n\t * True to override the existing enqueued summarize attempt if there is one.\n\t * This will guarantee that this attempt gets enqueued. If override is false,\n\t * than an existing enqueued summarize attempt will block a new one from being\n\t * enqueued. There can only be one enqueued at a time. Defaults to false.\n\t */\n\treadonly override?: boolean;\n}\n\n/**\n * In addition to the normal summary tree + stats, this contains additional stats\n * only relevant at the root of the tree.\n */\nexport interface IGeneratedSummaryStats extends ISummaryStats {\n\t/** The total number of data stores in the container. */\n\treadonly dataStoreCount: number;\n\t/** The number of data stores that were summarized in this summary. */\n\treadonly summarizedDataStoreCount: number;\n\t/** The number of data stores whose GC reference state was updated in this summary. */\n\treadonly gcStateUpdatedDataStoreCount?: number;\n\t/** The size of the gc blobs in this summary. */\n\treadonly gcTotalBlobsSize?: number;\n\t/** The number of gc blobs in this summary. */\n\treadonly gcBlobNodeCount?: number;\n\t/** The summary number for a container's summary. Incremented on summaries throughout its lifetime. */\n\treadonly summaryNumber: number;\n}\n\n/** Base results for all submitSummary attempts. */\nexport interface IBaseSummarizeResult {\n\treadonly stage: \"base\";\n\t/** Error object related to failed summarize attempt. */\n\treadonly error: any;\n\t/** Reference sequence number as of the generate summary attempt. */\n\treadonly referenceSequenceNumber: number;\n\treadonly minimumSequenceNumber: number;\n}\n\n/** Results of submitSummary after generating the summary tree. */\nexport interface IGenerateSummaryTreeResult extends Omit<IBaseSummarizeResult, \"stage\"> {\n\treadonly stage: \"generate\";\n\t/** Generated summary tree. */\n\treadonly summaryTree: ISummaryTree;\n\t/** Stats for generated summary tree. */\n\treadonly summaryStats: IGeneratedSummaryStats;\n\t/** Time it took to generate the summary tree and stats. */\n\treadonly generateDuration: number;\n\t/** True if the full tree regeneration with no handle reuse optimizations was forced. */\n\treadonly forcedFullTree: boolean;\n}\n\n/** Results of submitSummary after uploading the tree to storage. */\nexport interface IUploadSummaryResult extends Omit<IGenerateSummaryTreeResult, \"stage\"> {\n\treadonly stage: \"upload\";\n\t/** The handle returned by storage pointing to the uploaded summary tree. */\n\treadonly handle: string;\n\t/** Time it took to upload the summary tree to storage. */\n\treadonly uploadDuration: number;\n}\n\n/** Results of submitSummary after submitting the summarize op. */\nexport interface ISubmitSummaryOpResult extends Omit<IUploadSummaryResult, \"stage\" | \"error\"> {\n\treadonly stage: \"submit\";\n\t/** The client sequence number of the summarize op submitted for the summary. */\n\treadonly clientSequenceNumber: number;\n\t/** Time it took to submit the summarize op to the broadcasting service. */\n\treadonly submitOpDuration: number;\n}\n\n/**\n * Strict type representing result of a submitSummary attempt.\n * The result consists of 4 possible stages, each with its own data.\n * The data is cumulative, so each stage will contain the data from the previous stages.\n * If the final \"submitted\" stage is not reached, the result may contain the error object.\n *\n * Stages:\n *\n * 1. \"base\" - stopped before the summary tree was even generated, and the result only contains the base data\n *\n * 2. \"generate\" - the summary tree was generated, and the result will contain that tree + stats\n *\n * 3. \"upload\" - the summary was uploaded to storage, and the result contains the server-provided handle\n *\n * 4. \"submit\" - the summarize op was submitted, and the result contains the op client sequence number.\n */\nexport type SubmitSummaryResult =\n\t| IBaseSummarizeResult\n\t| IGenerateSummaryTreeResult\n\t| IUploadSummaryResult\n\t| ISubmitSummaryOpResult;\n\nexport interface IBroadcastSummaryResult {\n\treadonly summarizeOp: ISummaryOpMessage;\n\treadonly broadcastDuration: number;\n}\n\nexport interface IAckSummaryResult {\n\treadonly summaryAckOp: ISummaryAckMessage;\n\treadonly ackNackDuration: number;\n}\n\nexport interface INackSummaryResult {\n\treadonly summaryNackOp: ISummaryNackMessage;\n\treadonly ackNackDuration: number;\n}\n\nexport type SummarizeResultPart<TSuccess, TFailure = undefined> =\n\t| {\n\t\t\tsuccess: true;\n\t\t\tdata: TSuccess;\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\tdata: TFailure | undefined;\n\t\t\tmessage: string;\n\t\t\terror: any;\n\t\t\tretryAfterSeconds?: number;\n\t };\n\nexport interface ISummarizeResults {\n\t/** Resolves when we generate, upload, and submit the summary. */\n\treadonly summarySubmitted: Promise<SummarizeResultPart<SubmitSummaryResult>>;\n\t/** Resolves when we observe our summarize op broadcast. */\n\treadonly summaryOpBroadcasted: Promise<SummarizeResultPart<IBroadcastSummaryResult>>;\n\t/** Resolves when we receive a summaryAck or summaryNack. */\n\treadonly receivedSummaryAckOrNack: Promise<\n\t\tSummarizeResultPart<IAckSummaryResult, INackSummaryResult>\n\t>;\n}\n\nexport type EnqueueSummarizeResult =\n\t| (ISummarizeResults & {\n\t\t\t/**\n\t\t\t * Indicates that another summarize attempt is not already enqueued,\n\t\t\t * and this attempt has been enqueued.\n\t\t\t */\n\t\t\treadonly alreadyEnqueued?: undefined;\n\t })\n\t| (ISummarizeResults & {\n\t\t\t/** Indicates that another summarize attempt was already enqueued. */\n\t\t\treadonly alreadyEnqueued: true;\n\t\t\t/**\n\t\t\t * Indicates that the other enqueued summarize attempt was abandoned,\n\t\t\t * and this attempt has been enqueued enqueued.\n\t\t\t */\n\t\t\treadonly overridden: true;\n\t })\n\t| {\n\t\t\t/** Indicates that another summarize attempt was already enqueued. */\n\t\t\treadonly alreadyEnqueued: true;\n\t\t\t/**\n\t\t\t * Indicates that the other enqueued summarize attempt remains enqueued,\n\t\t\t * and this attempt has not been enqueued.\n\t\t\t */\n\t\t\treadonly overridden?: undefined;\n\t };\n\nexport type SummarizerStopReason =\n\t/** Summarizer client failed to summarize in all 3 consecutive attempts. */\n\t| \"failToSummarize\"\n\t/** Parent client reported that it is no longer connected. */\n\t| \"parentNotConnected\"\n\t/**\n\t * Parent client reported that it is no longer elected the summarizer.\n\t * This is the normal flow; a disconnect will always trigger the parent\n\t * client to no longer be elected as responsible for summaries. Then it\n\t * tries to stop its spawned summarizer client.\n\t */\n\t| \"notElectedParent\"\n\t/**\n\t * We are not already running the summarizer and we are not the current elected client id.\n\t */\n\t| \"notElectedClient\"\n\t/** Summarizer client was disconnected */\n\t| \"summarizerClientDisconnected\"\n\t/* running summarizer threw an exception */\n\t| \"summarizerException\";\n\nexport interface ISummarizerEvents extends IEvent {\n\t/**\n\t * An event indicating that the Summarizer is having problems summarizing\n\t */\n\t(event: \"summarizingError\", listener: (error: ISummarizingWarning) => void);\n}\n\nexport interface ISummarizer\n\textends IEventProvider<ISummarizerEvents>,\n\t\tIFluidLoadable,\n\t\tPartial<IProvideSummarizer> {\n\t/*\n\t * Asks summarizer to move to exit.\n\t * Summarizer will finish current processes, which may take a while.\n\t * For example, summarizer may complete last summary before exiting.\n\t */\n\tstop(reason: SummarizerStopReason): void;\n\n\t/* Closes summarizer. Any pending processes (summary in flight) are abandoned. */\n\tclose(): void;\n\n\trun(onBehalfOf: string, disableHeuristics?: boolean): Promise<SummarizerStopReason>;\n\n\t/**\n\t * Attempts to generate a summary on demand. If already running, takes no action.\n\t * @param options - options controlling the summarize attempt\n\t * @returns an alreadyRunning promise if a summarize attempt is already in progress,\n\t * which will resolve when the current attempt completes. At that point caller can\n\t * decide to try again or not. Otherwise, it will return an object containing promises\n\t * that resolve as the summarize attempt progresses. They will resolve with success\n\t * false if a failure is encountered.\n\t */\n\tsummarizeOnDemand(options: IOnDemandSummarizeOptions): ISummarizeResults;\n\t/**\n\t * Enqueue an attempt to summarize after the specified sequence number.\n\t * If afterSequenceNumber is provided, the summarize attempt is \"enqueued\"\n\t * to run once an eligible op comes in with sequenceNumber \\>= afterSequenceNumber.\n\t * @param options - options controlling the summarize attempt\n\t * @returns an object containing an alreadyEnqueued flag to indicate if another\n\t * summarize attempt has already been enqueued. It also may contain an overridden flag\n\t * when alreadyEnqueued is true, that indicates whether this attempt forced the\n\t * previous attempt to abort. If this attempt becomes enqueued, it returns an object\n\t * containing promises that resolve as the summarize attempt progresses. They will\n\t * resolve with success false if a failure is encountered.\n\t */\n\tenqueueSummarize(options: IEnqueueSummarizeOptions): EnqueueSummarizeResult;\n}\n\n/** Data about an attempt to summarize used for heuristics. */\nexport interface ISummarizeAttempt {\n\t/** Reference sequence number when summary was generated or attempted */\n\treadonly refSequenceNumber: number;\n\n\t/** Time of summary attempt after it was sent or attempted */\n\treadonly summaryTime: number;\n\n\t/** Sequence number of summary op */\n\tsummarySequenceNumber?: number;\n}\n\n/** Data relevant for summary heuristics. */\nexport interface ISummarizeHeuristicData {\n\t/** Latest received op sequence number */\n\tlastOpSequenceNumber: number;\n\n\t/** Most recent summary attempt from this client */\n\treadonly lastAttempt: ISummarizeAttempt;\n\n\t/** Most recent summary that received an ack */\n\treadonly lastSuccessfulSummary: Readonly<ISummarizeAttempt>;\n\n\t/** Number of runtime ops since last summary */\n\tnumRuntimeOps: number;\n\n\t/** Number of non-runtime ops since last summary */\n\tnumNonRuntimeOps: number;\n\n\t/** Cumulative size in bytes of all the ops since the last summary */\n\ttotalOpsSize: number;\n\n\t/** Wether or not this instance contains adjusted metrics due to missing op data */\n\thasMissingOpData: boolean;\n\n\t/**\n\t * Updates lastAttempt and lastSuccessfulAttempt based on the last summary.\n\t * @param lastSummary - last ack summary\n\t */\n\tupdateWithLastSummaryAckInfo(lastSummary: ISummarizeAttempt): void;\n\n\t/**\n\t * Records a summary attempt. If the attempt was successfully sent,\n\t * provide the reference sequence number, otherwise it will be set\n\t * to the last seen op sequence number.\n\t * @param referenceSequenceNumber - reference sequence number of sent summary\n\t */\n\trecordAttempt(referenceSequenceNumber?: number): void;\n\n\t/** Mark that the last sent summary attempt has received an ack */\n\tmarkLastAttemptAsSuccessful(): void;\n}\n\n/** Responsible for running heuristics determining when to summarize. */\nexport interface ISummarizeHeuristicRunner {\n\t/** Start specific heuristic trackers (ex: idle timer) */\n\tstart(): void;\n\n\t/** Runs the heuristics to determine if it should try to summarize */\n\trun(): void;\n\n\t/** Runs a different heuristic to check if it should summarize before closing */\n\tshouldRunLastSummary(): boolean;\n\n\t/** Disposes of resources */\n\tdispose(): void;\n}\n\ntype ISummarizeTelemetryRequiredProperties =\n\t/** Reason code for attempting to summarize */\n\t\"reason\";\n\ntype ISummarizeTelemetryOptionalProperties =\n\t/** Number of attempts within the last time window, used for calculating the throttle delay. */\n\t| \"summaryAttempts\"\n\t/** Number of attempts within the current phase (currently capped at 2 ) */\n\t| \"summaryAttemptsPerPhase\"\n\t/** One-based count of phases we've attempted (used to index into an array of ISummarizeOptions */\n\t| \"summaryAttemptPhase\"\n\t| keyof ISummarizeOptions;\n\nexport type ISummarizeTelemetryProperties = Pick<\n\tITelemetryProperties,\n\tISummarizeTelemetryRequiredProperties\n> &\n\tPartial<Pick<ITelemetryProperties, ISummarizeTelemetryOptionalProperties>>;\n\n/** Strategy used to heuristically determine when we should run a summary */\nexport interface ISummaryHeuristicStrategy {\n\t/** Summarize reason for this summarize heuristic strategy (ex: \"maxTime\") */\n\tsummarizeReason: Readonly<SummarizeReason>;\n\n\t/**\n\t * Determines if this strategy's summarize criteria been met\n\t * @param configuration - summary configuration we are to check against\n\t * @param heuristicData - heuristic data used to confirm conditions are met\n\t */\n\tshouldRunSummary(\n\t\tconfiguration: ISummaryConfigurationHeuristics,\n\t\theuristicData: ISummarizeHeuristicData,\n\t): boolean;\n}\n\ntype SummaryGeneratorRequiredTelemetryProperties =\n\t/** True to generate the full tree with no handle reuse optimizations */\n\t| \"fullTree\"\n\t/** Time since we last attempted to generate a summary */\n\t| \"timeSinceLastAttempt\"\n\t/** Time since we last successfully generated a summary */\n\t| \"timeSinceLastSummary\";\n\ntype SummaryGeneratorOptionalTelemetryProperties =\n\t/** Reference sequence number as of the generate summary attempt. */\n\t| \"referenceSequenceNumber\"\n\t/** minimum sequence number (at the reference sequence number) */\n\t| \"minimumSequenceNumber\"\n\t/** Delta between the current reference sequence number and the reference sequence number of the last attempt */\n\t| \"opsSinceLastAttempt\"\n\t/** Delta between the current reference sequence number and the reference sequence number of the last summary */\n\t| \"opsSinceLastSummary\"\n\t/**\n\t * Delta in sum of op sizes between the current reference sequence number and the reference\n\t * sequence number of the last summary\n\t */\n\t| \"opsSizesSinceLastSummary\"\n\t/** Delta between the number of non-runtime ops since the last summary */\n\t| \"nonRuntimeOpsSinceLastSummary\"\n\t/** Wether or not this instance contains adjusted metrics due to missing op data */\n\t| \"hasMissingOpData\"\n\t/** Time it took to generate the summary tree and stats. */\n\t| \"generateDuration\"\n\t/** The handle returned by storage pointing to the uploaded summary tree. */\n\t| \"handle\"\n\t/** Time it took to upload the summary tree to storage. */\n\t| \"uploadDuration\"\n\t/** The client sequence number of the summarize op submitted for the summary. */\n\t| \"clientSequenceNumber\"\n\t/** Time it took for this summary to be acked after it was generated */\n\t| \"ackWaitDuration\"\n\t/** Reference sequence number of the ack/nack message */\n\t| \"ackNackSequenceNumber\"\n\t/** Actual sequence number of the summary op proposal. */\n\t| \"summarySequenceNumber\"\n\t/** Optional Retry-After time in seconds. If specified, the client should wait this many seconds before retrying. */\n\t| \"nackRetryAfter\";\n\nexport type SummaryGeneratorTelemetry = Pick<\n\tITelemetryProperties,\n\tSummaryGeneratorRequiredTelemetryProperties\n> &\n\tPartial<Pick<ITelemetryProperties, SummaryGeneratorOptionalTelemetryProperties>>;\n\nexport interface ISummarizeRunnerTelemetry extends ITelemetryLoggerPropertyBag {\n\t/** Number of times the summarizer run. */\n\tsummarizeCount: () => number;\n\t/** Number of successful attempts to summarize. */\n\tsummarizerSuccessfulAttempts: () => number;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"summarizerTypes.js","sourceRoot":"","sources":["../../src/summary/summarizerTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAqBH;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAA6B,aAAa,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIEvent,\n\tIEventProvider,\n\tITelemetryLogger,\n\tITelemetryProperties,\n} from \"@fluidframework/common-definitions\";\nimport { ITelemetryLoggerPropertyBag } from \"@fluidframework/telemetry-utils\";\nimport { IFluidLoadable } from \"@fluidframework/core-interfaces\";\nimport { ContainerWarning, IDeltaManager } from \"@fluidframework/container-definitions\";\nimport {\n\tISequencedDocumentMessage,\n\tISummaryTree,\n\tIDocumentMessage,\n} from \"@fluidframework/protocol-definitions\";\nimport { ISummaryStats } from \"@fluidframework/runtime-definitions\";\nimport { ISummaryConfigurationHeuristics } from \"../containerRuntime\";\nimport { ISummaryAckMessage, ISummaryNackMessage, ISummaryOpMessage } from \"./summaryCollection\";\nimport { SummarizeReason } from \"./summaryGenerator\";\n\n/**\n * @deprecated This will be removed in a later release.\n */\nexport const ISummarizer: keyof IProvideSummarizer = \"ISummarizer\";\n\n/**\n * @deprecated This will be removed in a later release.\n */\nexport interface IProvideSummarizer {\n\t/**\n\t * @deprecated This will be removed in a later release.\n\t */\n\treadonly ISummarizer: ISummarizer;\n}\n\n/**\n * Similar to AbortSignal, but using promise instead of events\n * @param T - cancellation reason type\n */\nexport interface ICancellationToken<T> {\n\t/** Tells if this cancellable token is cancelled */\n\treadonly cancelled: boolean;\n\t/**\n\t * Promise that gets fulfilled when this cancellable token is cancelled\n\t * @returns reason of cancellation\n\t */\n\treadonly waitCancelled: Promise<T>;\n}\n\n/* Similar to AbortSignal, but using promise instead of events */\nexport type ISummaryCancellationToken = ICancellationToken<SummarizerStopReason>;\n\nexport interface ISummarizerInternalsProvider {\n\t/** Encapsulates the work to walk the internals of the running container to generate a summary */\n\tsubmitSummary(options: ISubmitSummaryOptions): Promise<SubmitSummaryResult>;\n\n\t/** Callback whenever a new SummaryAck is received, to update internal tracking state */\n\trefreshLatestSummaryAck(options: IRefreshSummaryAckOptions): Promise<void>;\n}\n\n/**\n * @deprecated Options that control the behavior of a running summarizer.\n * */\nexport interface ISummarizerOptions {\n\t/**\n\t * Set to true to disable the default heuristics from running; false by default.\n\t * This affects only the heuristics around when a summarizer should\n\t * submit summaries. So when it is disabled, summarizer clients should\n\t * not be expected to summarize unless an on-demand summary is requested.\n\t */\n\tdisableHeuristics: boolean;\n}\n\nexport interface ISummarizingWarning extends ContainerWarning {\n\treadonly errorType: \"summarizingError\";\n\treadonly logged: boolean;\n}\n\nexport interface IConnectableRuntime {\n\treadonly disposed: boolean;\n\treadonly connected: boolean;\n\treadonly clientId: string | undefined;\n\t/** @deprecated - Moved to `ISummarizerRuntime` as it's no longer needed here */\n\treadonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;\n\tonce(event: \"connected\" | \"disconnected\" | \"dispose\", listener: () => void): this;\n}\n\nexport interface ISummarizerRuntime extends IConnectableRuntime {\n\treadonly logger: ITelemetryLogger;\n\t/** clientId of parent (non-summarizing) container that owns summarizer container */\n\treadonly summarizerClientId: string | undefined;\n\treadonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;\n\tdisposeFn?(): void;\n\tcloseFn(): void;\n}\n\n/** Options affecting summarize behavior. */\nexport interface ISummarizeOptions {\n\t/** True to generate the full tree with no handle reuse optimizations; defaults to false */\n\treadonly fullTree?: boolean;\n\t/** True to ask the server what the latest summary is first; defaults to false */\n\treadonly refreshLatestAck?: boolean;\n}\n\n/**\n * Data required to update internal tracking state after receiving a Summary Ack.\n */\nexport interface IRefreshSummaryAckOptions {\n\t/** Handle from the ack's summary op. */\n\treadonly proposalHandle: string | undefined;\n\t/** Handle from the summary ack just received */\n\treadonly ackHandle: string;\n\t/** Reference sequence number from the ack's summary op */\n\treadonly summaryRefSeq: number;\n\t/** Telemetry logger to which telemetry events will be forwarded. */\n\treadonly summaryLogger: ITelemetryLogger;\n}\n\nexport interface ISubmitSummaryOptions extends ISummarizeOptions {\n\t/** Logger to use for correlated summary events */\n\treadonly summaryLogger: ITelemetryLogger;\n\t/** Tells when summary process should be cancelled */\n\treadonly cancellationToken: ISummaryCancellationToken;\n}\n\nexport interface IOnDemandSummarizeOptions extends ISummarizeOptions {\n\t/** Reason for generating summary. */\n\treadonly reason: string;\n}\n\n/** Options to use when enqueueing a summarize attempt. */\nexport interface IEnqueueSummarizeOptions extends IOnDemandSummarizeOptions {\n\t/** If specified, The summarize attempt will not occur until after this sequence number. */\n\treadonly afterSequenceNumber?: number;\n\n\t/**\n\t * True to override the existing enqueued summarize attempt if there is one.\n\t * This will guarantee that this attempt gets enqueued. If override is false,\n\t * than an existing enqueued summarize attempt will block a new one from being\n\t * enqueued. There can only be one enqueued at a time. Defaults to false.\n\t */\n\treadonly override?: boolean;\n}\n\n/**\n * In addition to the normal summary tree + stats, this contains additional stats\n * only relevant at the root of the tree.\n */\nexport interface IGeneratedSummaryStats extends ISummaryStats {\n\t/** The total number of data stores in the container. */\n\treadonly dataStoreCount: number;\n\t/** The number of data stores that were summarized in this summary. */\n\treadonly summarizedDataStoreCount: number;\n\t/** The number of data stores whose GC reference state was updated in this summary. */\n\treadonly gcStateUpdatedDataStoreCount?: number;\n\t/** The size of the gc blobs in this summary. */\n\treadonly gcTotalBlobsSize?: number;\n\t/** The number of gc blobs in this summary. */\n\treadonly gcBlobNodeCount?: number;\n\t/** The summary number for a container's summary. Incremented on summaries throughout its lifetime. */\n\treadonly summaryNumber: number;\n}\n\n/** Base results for all submitSummary attempts. */\nexport interface IBaseSummarizeResult {\n\treadonly stage: \"base\";\n\t/** Error object related to failed summarize attempt. */\n\treadonly error: any;\n\t/** Reference sequence number as of the generate summary attempt. */\n\treadonly referenceSequenceNumber: number;\n\treadonly minimumSequenceNumber: number;\n}\n\n/** Results of submitSummary after generating the summary tree. */\nexport interface IGenerateSummaryTreeResult extends Omit<IBaseSummarizeResult, \"stage\"> {\n\treadonly stage: \"generate\";\n\t/** Generated summary tree. */\n\treadonly summaryTree: ISummaryTree;\n\t/** Stats for generated summary tree. */\n\treadonly summaryStats: IGeneratedSummaryStats;\n\t/** Time it took to generate the summary tree and stats. */\n\treadonly generateDuration: number;\n\t/** True if the full tree regeneration with no handle reuse optimizations was forced. */\n\treadonly forcedFullTree: boolean;\n}\n\n/** Results of submitSummary after uploading the tree to storage. */\nexport interface IUploadSummaryResult extends Omit<IGenerateSummaryTreeResult, \"stage\"> {\n\treadonly stage: \"upload\";\n\t/** The handle returned by storage pointing to the uploaded summary tree. */\n\treadonly handle: string;\n\t/** Time it took to upload the summary tree to storage. */\n\treadonly uploadDuration: number;\n}\n\n/** Results of submitSummary after submitting the summarize op. */\nexport interface ISubmitSummaryOpResult extends Omit<IUploadSummaryResult, \"stage\" | \"error\"> {\n\treadonly stage: \"submit\";\n\t/** The client sequence number of the summarize op submitted for the summary. */\n\treadonly clientSequenceNumber: number;\n\t/** Time it took to submit the summarize op to the broadcasting service. */\n\treadonly submitOpDuration: number;\n}\n\n/**\n * Strict type representing result of a submitSummary attempt.\n * The result consists of 4 possible stages, each with its own data.\n * The data is cumulative, so each stage will contain the data from the previous stages.\n * If the final \"submitted\" stage is not reached, the result may contain the error object.\n *\n * Stages:\n *\n * 1. \"base\" - stopped before the summary tree was even generated, and the result only contains the base data\n *\n * 2. \"generate\" - the summary tree was generated, and the result will contain that tree + stats\n *\n * 3. \"upload\" - the summary was uploaded to storage, and the result contains the server-provided handle\n *\n * 4. \"submit\" - the summarize op was submitted, and the result contains the op client sequence number.\n */\nexport type SubmitSummaryResult =\n\t| IBaseSummarizeResult\n\t| IGenerateSummaryTreeResult\n\t| IUploadSummaryResult\n\t| ISubmitSummaryOpResult;\n\nexport interface IBroadcastSummaryResult {\n\treadonly summarizeOp: ISummaryOpMessage;\n\treadonly broadcastDuration: number;\n}\n\nexport interface IAckSummaryResult {\n\treadonly summaryAckOp: ISummaryAckMessage;\n\treadonly ackNackDuration: number;\n}\n\nexport interface INackSummaryResult {\n\treadonly summaryNackOp: ISummaryNackMessage;\n\treadonly ackNackDuration: number;\n}\n\nexport type SummarizeResultPart<TSuccess, TFailure = undefined> =\n\t| {\n\t\t\tsuccess: true;\n\t\t\tdata: TSuccess;\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\tdata: TFailure | undefined;\n\t\t\tmessage: string;\n\t\t\terror: any;\n\t\t\tretryAfterSeconds?: number;\n\t };\n\nexport interface ISummarizeResults {\n\t/** Resolves when we generate, upload, and submit the summary. */\n\treadonly summarySubmitted: Promise<SummarizeResultPart<SubmitSummaryResult>>;\n\t/** Resolves when we observe our summarize op broadcast. */\n\treadonly summaryOpBroadcasted: Promise<SummarizeResultPart<IBroadcastSummaryResult>>;\n\t/** Resolves when we receive a summaryAck or summaryNack. */\n\treadonly receivedSummaryAckOrNack: Promise<\n\t\tSummarizeResultPart<IAckSummaryResult, INackSummaryResult>\n\t>;\n}\n\nexport type EnqueueSummarizeResult =\n\t| (ISummarizeResults & {\n\t\t\t/**\n\t\t\t * Indicates that another summarize attempt is not already enqueued,\n\t\t\t * and this attempt has been enqueued.\n\t\t\t */\n\t\t\treadonly alreadyEnqueued?: undefined;\n\t })\n\t| (ISummarizeResults & {\n\t\t\t/** Indicates that another summarize attempt was already enqueued. */\n\t\t\treadonly alreadyEnqueued: true;\n\t\t\t/**\n\t\t\t * Indicates that the other enqueued summarize attempt was abandoned,\n\t\t\t * and this attempt has been enqueued enqueued.\n\t\t\t */\n\t\t\treadonly overridden: true;\n\t })\n\t| {\n\t\t\t/** Indicates that another summarize attempt was already enqueued. */\n\t\t\treadonly alreadyEnqueued: true;\n\t\t\t/**\n\t\t\t * Indicates that the other enqueued summarize attempt remains enqueued,\n\t\t\t * and this attempt has not been enqueued.\n\t\t\t */\n\t\t\treadonly overridden?: undefined;\n\t };\n\nexport type SummarizerStopReason =\n\t/** Summarizer client failed to summarize in all 3 consecutive attempts. */\n\t| \"failToSummarize\"\n\t/** Parent client reported that it is no longer connected. */\n\t| \"parentNotConnected\"\n\t/**\n\t * Parent client reported that it is no longer elected the summarizer.\n\t * This is the normal flow; a disconnect will always trigger the parent\n\t * client to no longer be elected as responsible for summaries. Then it\n\t * tries to stop its spawned summarizer client.\n\t */\n\t| \"notElectedParent\"\n\t/**\n\t * We are not already running the summarizer and we are not the current elected client id.\n\t */\n\t| \"notElectedClient\"\n\t/** Summarizer client was disconnected */\n\t| \"summarizerClientDisconnected\"\n\t/* running summarizer threw an exception */\n\t| \"summarizerException\";\n\nexport interface ISummarizerEvents extends IEvent {\n\t/**\n\t * An event indicating that the Summarizer is having problems summarizing\n\t */\n\t(event: \"summarizingError\", listener: (error: ISummarizingWarning) => void);\n}\n\nexport interface ISummarizer\n\textends IEventProvider<ISummarizerEvents>,\n\t\tIFluidLoadable,\n\t\tPartial<IProvideSummarizer> {\n\t/*\n\t * Asks summarizer to move to exit.\n\t * Summarizer will finish current processes, which may take a while.\n\t * For example, summarizer may complete last summary before exiting.\n\t */\n\tstop(reason: SummarizerStopReason): void;\n\n\t/* Closes summarizer. Any pending processes (summary in flight) are abandoned. */\n\tclose(): void;\n\n\trun(onBehalfOf: string, disableHeuristics?: boolean): Promise<SummarizerStopReason>;\n\n\t/**\n\t * Attempts to generate a summary on demand. If already running, takes no action.\n\t * @param options - options controlling the summarize attempt\n\t * @returns an alreadyRunning promise if a summarize attempt is already in progress,\n\t * which will resolve when the current attempt completes. At that point caller can\n\t * decide to try again or not. Otherwise, it will return an object containing promises\n\t * that resolve as the summarize attempt progresses. They will resolve with success\n\t * false if a failure is encountered.\n\t */\n\tsummarizeOnDemand(options: IOnDemandSummarizeOptions): ISummarizeResults;\n\t/**\n\t * Enqueue an attempt to summarize after the specified sequence number.\n\t * If afterSequenceNumber is provided, the summarize attempt is \"enqueued\"\n\t * to run once an eligible op comes in with sequenceNumber \\>= afterSequenceNumber.\n\t * @param options - options controlling the summarize attempt\n\t * @returns an object containing an alreadyEnqueued flag to indicate if another\n\t * summarize attempt has already been enqueued. It also may contain an overridden flag\n\t * when alreadyEnqueued is true, that indicates whether this attempt forced the\n\t * previous attempt to abort. If this attempt becomes enqueued, it returns an object\n\t * containing promises that resolve as the summarize attempt progresses. They will\n\t * resolve with success false if a failure is encountered.\n\t */\n\tenqueueSummarize(options: IEnqueueSummarizeOptions): EnqueueSummarizeResult;\n}\n\n/** Data about an attempt to summarize used for heuristics. */\nexport interface ISummarizeAttempt {\n\t/** Reference sequence number when summary was generated or attempted */\n\treadonly refSequenceNumber: number;\n\n\t/** Time of summary attempt after it was sent or attempted */\n\treadonly summaryTime: number;\n\n\t/** Sequence number of summary op */\n\tsummarySequenceNumber?: number;\n}\n\n/** Data relevant for summary heuristics. */\nexport interface ISummarizeHeuristicData {\n\t/** Latest received op sequence number */\n\tlastOpSequenceNumber: number;\n\n\t/** Most recent summary attempt from this client */\n\treadonly lastAttempt: ISummarizeAttempt;\n\n\t/** Most recent summary that received an ack */\n\treadonly lastSuccessfulSummary: Readonly<ISummarizeAttempt>;\n\n\t/** Number of runtime ops since last summary */\n\tnumRuntimeOps: number;\n\n\t/** Number of non-runtime ops since last summary */\n\tnumNonRuntimeOps: number;\n\n\t/** Cumulative size in bytes of all the ops since the last summary */\n\ttotalOpsSize: number;\n\n\t/** Wether or not this instance contains adjusted metrics due to missing op data */\n\thasMissingOpData: boolean;\n\n\t/**\n\t * Updates lastAttempt and lastSuccessfulAttempt based on the last summary.\n\t * @param lastSummary - last ack summary\n\t */\n\tupdateWithLastSummaryAckInfo(lastSummary: ISummarizeAttempt): void;\n\n\t/**\n\t * Records a summary attempt. If the attempt was successfully sent,\n\t * provide the reference sequence number, otherwise it will be set\n\t * to the last seen op sequence number.\n\t * @param referenceSequenceNumber - reference sequence number of sent summary\n\t */\n\trecordAttempt(referenceSequenceNumber?: number): void;\n\n\t/** Mark that the last sent summary attempt has received an ack */\n\tmarkLastAttemptAsSuccessful(): void;\n}\n\n/** Responsible for running heuristics determining when to summarize. */\nexport interface ISummarizeHeuristicRunner {\n\t/** Start specific heuristic trackers (ex: idle timer) */\n\tstart(): void;\n\n\t/** Runs the heuristics to determine if it should try to summarize */\n\trun(): void;\n\n\t/** Runs a different heuristic to check if it should summarize before closing */\n\tshouldRunLastSummary(): boolean;\n\n\t/** Disposes of resources */\n\tdispose(): void;\n}\n\ntype ISummarizeTelemetryRequiredProperties =\n\t/** Reason code for attempting to summarize */\n\t\"reason\";\n\ntype ISummarizeTelemetryOptionalProperties =\n\t/** Number of attempts within the last time window, used for calculating the throttle delay. */\n\t| \"summaryAttempts\"\n\t/** Number of attempts within the current phase (currently capped at 2 ) */\n\t| \"summaryAttemptsPerPhase\"\n\t/** One-based count of phases we've attempted (used to index into an array of ISummarizeOptions */\n\t| \"summaryAttemptPhase\"\n\t| keyof ISummarizeOptions;\n\nexport type ISummarizeTelemetryProperties = Pick<\n\tITelemetryProperties,\n\tISummarizeTelemetryRequiredProperties\n> &\n\tPartial<Pick<ITelemetryProperties, ISummarizeTelemetryOptionalProperties>>;\n\n/** Strategy used to heuristically determine when we should run a summary */\nexport interface ISummaryHeuristicStrategy {\n\t/** Summarize reason for this summarize heuristic strategy (ex: \"maxTime\") */\n\tsummarizeReason: Readonly<SummarizeReason>;\n\n\t/**\n\t * Determines if this strategy's summarize criteria been met\n\t * @param configuration - summary configuration we are to check against\n\t * @param heuristicData - heuristic data used to confirm conditions are met\n\t */\n\tshouldRunSummary(\n\t\tconfiguration: ISummaryConfigurationHeuristics,\n\t\theuristicData: ISummarizeHeuristicData,\n\t): boolean;\n}\n\ntype SummaryGeneratorRequiredTelemetryProperties =\n\t/** True to generate the full tree with no handle reuse optimizations */\n\t| \"fullTree\"\n\t/** Time since we last attempted to generate a summary */\n\t| \"timeSinceLastAttempt\"\n\t/** Time since we last successfully generated a summary */\n\t| \"timeSinceLastSummary\";\n\ntype SummaryGeneratorOptionalTelemetryProperties =\n\t/** Reference sequence number as of the generate summary attempt. */\n\t| \"referenceSequenceNumber\"\n\t/** minimum sequence number (at the reference sequence number) */\n\t| \"minimumSequenceNumber\"\n\t/** Delta between the current reference sequence number and the reference sequence number of the last attempt */\n\t| \"opsSinceLastAttempt\"\n\t/** Delta between the current reference sequence number and the reference sequence number of the last summary */\n\t| \"opsSinceLastSummary\"\n\t/**\n\t * Delta in sum of op sizes between the current reference sequence number and the reference\n\t * sequence number of the last summary\n\t */\n\t| \"opsSizesSinceLastSummary\"\n\t/** Delta between the number of non-runtime ops since the last summary */\n\t| \"nonRuntimeOpsSinceLastSummary\"\n\t/** Wether or not this instance contains adjusted metrics due to missing op data */\n\t| \"hasMissingOpData\"\n\t/** Time it took to generate the summary tree and stats. */\n\t| \"generateDuration\"\n\t/** The handle returned by storage pointing to the uploaded summary tree. */\n\t| \"handle\"\n\t/** Time it took to upload the summary tree to storage. */\n\t| \"uploadDuration\"\n\t/** The client sequence number of the summarize op submitted for the summary. */\n\t| \"clientSequenceNumber\"\n\t/** Time it took for this summary to be acked after it was generated */\n\t| \"ackWaitDuration\"\n\t/** Reference sequence number of the ack/nack message */\n\t| \"ackNackSequenceNumber\"\n\t/** Actual sequence number of the summary op proposal. */\n\t| \"summarySequenceNumber\"\n\t/** Optional Retry-After time in seconds. If specified, the client should wait this many seconds before retrying. */\n\t| \"nackRetryAfter\";\n\nexport type SummaryGeneratorTelemetry = Pick<\n\tITelemetryProperties,\n\tSummaryGeneratorRequiredTelemetryProperties\n> &\n\tPartial<Pick<ITelemetryProperties, SummaryGeneratorOptionalTelemetryProperties>>;\n\nexport interface ISummarizeRunnerTelemetry extends ITelemetryLoggerPropertyBag {\n\t/** Number of times the summarizer run. */\n\tsummarizeCount: () => number;\n\t/** Number of successful attempts to summarize. */\n\tsummarizerSuccessfulAttempts: () => number;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-runtime",
|
|
3
|
-
"version": "2.0.0-internal.3.
|
|
3
|
+
"version": "2.0.0-internal.3.3.0",
|
|
4
4
|
"description": "Fluid container runtime",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -37,32 +37,32 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
39
39
|
"@fluidframework/common-utils": "^1.1.1",
|
|
40
|
-
"@fluidframework/container-definitions": ">=2.0.0-internal.3.
|
|
41
|
-
"@fluidframework/container-runtime-definitions": ">=2.0.0-internal.3.
|
|
42
|
-
"@fluidframework/container-utils": ">=2.0.0-internal.3.
|
|
43
|
-
"@fluidframework/core-interfaces": ">=2.0.0-internal.3.
|
|
44
|
-
"@fluidframework/datastore": ">=2.0.0-internal.3.
|
|
45
|
-
"@fluidframework/driver-definitions": ">=2.0.0-internal.3.
|
|
46
|
-
"@fluidframework/driver-utils": ">=2.0.0-internal.3.
|
|
47
|
-
"@fluidframework/garbage-collector": ">=2.0.0-internal.3.
|
|
48
|
-
"@fluidframework/protocol-base": "^0.1038.
|
|
40
|
+
"@fluidframework/container-definitions": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
41
|
+
"@fluidframework/container-runtime-definitions": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
42
|
+
"@fluidframework/container-utils": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
43
|
+
"@fluidframework/core-interfaces": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
44
|
+
"@fluidframework/datastore": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
45
|
+
"@fluidframework/driver-definitions": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
46
|
+
"@fluidframework/driver-utils": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
47
|
+
"@fluidframework/garbage-collector": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
48
|
+
"@fluidframework/protocol-base": "^0.1038.3000",
|
|
49
49
|
"@fluidframework/protocol-definitions": "^1.1.0",
|
|
50
|
-
"@fluidframework/runtime-definitions": ">=2.0.0-internal.3.
|
|
51
|
-
"@fluidframework/runtime-utils": ">=2.0.0-internal.3.
|
|
52
|
-
"@fluidframework/telemetry-utils": ">=2.0.0-internal.3.
|
|
50
|
+
"@fluidframework/runtime-definitions": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
51
|
+
"@fluidframework/runtime-utils": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
52
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
53
53
|
"double-ended-queue": "^2.1.0-0",
|
|
54
54
|
"events": "^3.1.0",
|
|
55
55
|
"lz4js": "^0.2.0",
|
|
56
56
|
"uuid": "^8.3.1"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@fluid-tools/build-cli": "^0.
|
|
59
|
+
"@fluid-tools/build-cli": "^0.12.0",
|
|
60
60
|
"@fluidframework/build-common": "^1.1.0",
|
|
61
|
-
"@fluidframework/build-tools": "^0.
|
|
62
|
-
"@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-internal.3.
|
|
61
|
+
"@fluidframework/build-tools": "^0.12.0",
|
|
62
|
+
"@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-internal.3.2.0",
|
|
63
63
|
"@fluidframework/eslint-config-fluid": "^2.0.0",
|
|
64
|
-
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.3.
|
|
65
|
-
"@fluidframework/test-runtime-utils": ">=2.0.0-internal.3.
|
|
64
|
+
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
65
|
+
"@fluidframework/test-runtime-utils": ">=2.0.0-internal.3.3.0 <2.0.0-internal.4.0.0",
|
|
66
66
|
"@microsoft/api-extractor": "^7.22.2",
|
|
67
67
|
"@rushstack/eslint-config": "^2.5.1",
|
|
68
68
|
"@types/double-ended-queue": "^2.1.0",
|
|
@@ -82,18 +82,7 @@
|
|
|
82
82
|
"typescript": "~4.5.5"
|
|
83
83
|
},
|
|
84
84
|
"typeValidation": {
|
|
85
|
-
"
|
|
86
|
-
"previousVersionStyle": "~previousMinor",
|
|
87
|
-
"baselineRange": ">=2.0.0-internal.3.1.0 <2.0.0-internal.3.2.0",
|
|
88
|
-
"baselineVersion": "2.0.0-internal.3.1.0",
|
|
89
|
-
"broken": {
|
|
90
|
-
"EnumDeclaration_RuntimeHeaders": {
|
|
91
|
-
"forwardCompat": false
|
|
92
|
-
},
|
|
93
|
-
"ClassDeclaration_ContainerRuntime": {
|
|
94
|
-
"forwardCompat": false
|
|
95
|
-
}
|
|
96
|
-
}
|
|
85
|
+
"broken": {}
|
|
97
86
|
},
|
|
98
87
|
"scripts": {
|
|
99
88
|
"build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
|
|
@@ -120,7 +109,7 @@
|
|
|
120
109
|
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
|
|
121
110
|
"tsc": "tsc",
|
|
122
111
|
"tsc:watch": "tsc --watch",
|
|
123
|
-
"typetests:gen": "
|
|
112
|
+
"typetests:gen": "fluid-type-test-generator",
|
|
124
113
|
"typetests:prepare": "flub generate typetests --prepare --dir . --pin"
|
|
125
114
|
}
|
|
126
115
|
}
|
package/src/containerRuntime.ts
CHANGED
|
@@ -31,7 +31,13 @@ import {
|
|
|
31
31
|
IContainerRuntime,
|
|
32
32
|
IContainerRuntimeEvents,
|
|
33
33
|
} from "@fluidframework/container-runtime-definitions";
|
|
34
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
assert,
|
|
36
|
+
LazyPromise,
|
|
37
|
+
Trace,
|
|
38
|
+
TypedEventEmitter,
|
|
39
|
+
unreachableCase,
|
|
40
|
+
} from "@fluidframework/common-utils";
|
|
35
41
|
import {
|
|
36
42
|
ChildLogger,
|
|
37
43
|
raiseConnectedEvent,
|
|
@@ -147,8 +153,8 @@ import {
|
|
|
147
153
|
GarbageCollector,
|
|
148
154
|
GCNodeType,
|
|
149
155
|
gcTombstoneGenerationOptionName,
|
|
150
|
-
IGarbageCollectionRuntime,
|
|
151
156
|
IGarbageCollector,
|
|
157
|
+
IGCRuntimeOptions,
|
|
152
158
|
IGCStats,
|
|
153
159
|
shouldAllowGcTombstoneEnforcement,
|
|
154
160
|
} from "./gc";
|
|
@@ -168,6 +174,7 @@ import {
|
|
|
168
174
|
OpSplitter,
|
|
169
175
|
RemoteMessageProcessor,
|
|
170
176
|
} from "./opLifecycle";
|
|
177
|
+
import { DeltaManagerSummarizerProxy } from "./deltaManagerSummarizerProxy";
|
|
171
178
|
|
|
172
179
|
export enum ContainerMessageType {
|
|
173
180
|
// An op to be delivered to store
|
|
@@ -312,54 +319,6 @@ export const DefaultSummaryConfiguration: ISummaryConfiguration = {
|
|
|
312
319
|
nonRuntimeHeuristicThreshold: 20,
|
|
313
320
|
};
|
|
314
321
|
|
|
315
|
-
export interface IGCRuntimeOptions {
|
|
316
|
-
/**
|
|
317
|
-
* Flag that if true, will enable running garbage collection (GC) for a new container.
|
|
318
|
-
*
|
|
319
|
-
* GC has mark phase and sweep phase. In mark phase, unreferenced objects are identified
|
|
320
|
-
* and marked as such in the summary. This option enables the mark phase.
|
|
321
|
-
* In sweep phase, unreferenced objects are eventually deleted from the container if they meet certain conditions.
|
|
322
|
-
* Sweep phase can be enabled via the "sweepAllowed" option.
|
|
323
|
-
*
|
|
324
|
-
* Note: This setting is persisted in the container's summary and cannot be changed.
|
|
325
|
-
*/
|
|
326
|
-
gcAllowed?: boolean;
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Flag that if true, enables GC's sweep phase for a new container.
|
|
330
|
-
*
|
|
331
|
-
* This will allow GC to eventually delete unreferenced objects from the container.
|
|
332
|
-
* This flag should only be set to true if "gcAllowed" is true.
|
|
333
|
-
*
|
|
334
|
-
* Note: This setting is persisted in the container's summary and cannot be changed.
|
|
335
|
-
*/
|
|
336
|
-
sweepAllowed?: boolean;
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Flag that if true, will disable garbage collection for the session.
|
|
340
|
-
* Can be used to disable running GC on containers where it is allowed via the gcAllowed option.
|
|
341
|
-
*/
|
|
342
|
-
disableGC?: boolean;
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Flag that will bypass optimizations and generate GC data for all nodes irrespective of whether a node
|
|
346
|
-
* changed or not.
|
|
347
|
-
*/
|
|
348
|
-
runFullGC?: boolean;
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* Maximum session duration for a new container. If not present, a default value will be used.
|
|
352
|
-
*
|
|
353
|
-
* Note: This setting is persisted in the container's summary and cannot be changed.
|
|
354
|
-
*/
|
|
355
|
-
sessionExpiryTimeoutMs?: number;
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Allows additional GC options to be passed.
|
|
359
|
-
*/
|
|
360
|
-
[key: string]: any;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
322
|
export interface ISummaryRuntimeOptions {
|
|
364
323
|
/** Override summary configurations set by the server. */
|
|
365
324
|
summaryConfigOverrides?: ISummaryConfiguration;
|
|
@@ -433,7 +392,8 @@ export interface IContainerRuntimeOptions {
|
|
|
433
392
|
readonly maxBatchSizeInBytes?: number;
|
|
434
393
|
/**
|
|
435
394
|
* If the op payload needs to be chunked in order to work around the maximum size of the batch, this value represents
|
|
436
|
-
* how large the individual chunks will be. This is only supported when compression is enabled.
|
|
395
|
+
* how large the individual chunks will be. This is only supported when compression is enabled. If after compression, the
|
|
396
|
+
* batch size exceeds this value, it will be chunked into smaller ops of this size.
|
|
437
397
|
*
|
|
438
398
|
* If unspecified, if a batch exceeds `maxBatchSizeInBytes` after compression, the container will close with an instance
|
|
439
399
|
* of `GenericError` with the `BatchTooLarge` message.
|
|
@@ -598,12 +558,7 @@ export function getDeviceSpec() {
|
|
|
598
558
|
*/
|
|
599
559
|
export class ContainerRuntime
|
|
600
560
|
extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
601
|
-
implements
|
|
602
|
-
IContainerRuntime,
|
|
603
|
-
IGarbageCollectionRuntime,
|
|
604
|
-
IRuntime,
|
|
605
|
-
ISummarizerRuntime,
|
|
606
|
-
ISummarizerInternalsProvider
|
|
561
|
+
implements IContainerRuntime, IRuntime, ISummarizerRuntime, ISummarizerInternalsProvider
|
|
607
562
|
{
|
|
608
563
|
public get IContainerRuntime() {
|
|
609
564
|
return this;
|
|
@@ -651,13 +606,16 @@ export class ContainerRuntime
|
|
|
651
606
|
* Load the stores from a snapshot and returns the runtime.
|
|
652
607
|
* @param params - An object housing the runtime properties:
|
|
653
608
|
* - context - Context of the container.
|
|
654
|
-
* - registryEntries - Mapping to
|
|
655
|
-
* - existing -
|
|
656
|
-
* - requestHandler - Request
|
|
609
|
+
* - registryEntries - Mapping from data store types to their corresponding factories.
|
|
610
|
+
* - existing - Pass 'true' if loading from an existing snapshot.
|
|
611
|
+
* - requestHandler - (optional) Request handler for the request() method of the container runtime.
|
|
612
|
+
* Only relevant for back-compat while we remove the request() method and move fully to entryPoint as the main pattern.
|
|
657
613
|
* - runtimeOptions - Additional options to be passed to the runtime
|
|
658
614
|
* - containerScope - runtime services provided with context
|
|
659
615
|
* - containerRuntimeCtor - Constructor to use to create the ContainerRuntime instance.
|
|
660
616
|
* This allows mixin classes to leverage this method to define their own async initializer.
|
|
617
|
+
* - initializeEntryPoint - Promise that resolves to an object which will act as entryPoint for the Container.
|
|
618
|
+
* This object should provide all the functionality that the Container is expected to provide to the loader layer.
|
|
661
619
|
*/
|
|
662
620
|
public static async loadRuntime(params: {
|
|
663
621
|
context: IContainerContext;
|
|
@@ -667,6 +625,7 @@ export class ContainerRuntime
|
|
|
667
625
|
runtimeOptions?: IContainerRuntimeOptions;
|
|
668
626
|
containerScope?: FluidObject;
|
|
669
627
|
containerRuntimeCtor?: typeof ContainerRuntime;
|
|
628
|
+
initializeEntryPoint?: (containerRuntime: IContainerRuntime) => Promise<FluidObject>;
|
|
670
629
|
}): Promise<ContainerRuntime> {
|
|
671
630
|
const {
|
|
672
631
|
context,
|
|
@@ -676,6 +635,7 @@ export class ContainerRuntime
|
|
|
676
635
|
runtimeOptions = {},
|
|
677
636
|
containerScope = {},
|
|
678
637
|
containerRuntimeCtor = ContainerRuntime,
|
|
638
|
+
initializeEntryPoint,
|
|
679
639
|
} = params;
|
|
680
640
|
|
|
681
641
|
// If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
|
|
@@ -800,6 +760,8 @@ export class ContainerRuntime
|
|
|
800
760
|
blobManagerSnapshot,
|
|
801
761
|
storage,
|
|
802
762
|
requestHandler,
|
|
763
|
+
undefined, // summaryConfiguration
|
|
764
|
+
initializeEntryPoint,
|
|
803
765
|
);
|
|
804
766
|
|
|
805
767
|
if (pendingRuntimeState) {
|
|
@@ -826,10 +788,6 @@ export class ContainerRuntime
|
|
|
826
788
|
return this.context.clientDetails;
|
|
827
789
|
}
|
|
828
790
|
|
|
829
|
-
public get deltaManager(): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {
|
|
830
|
-
return this.context.deltaManager;
|
|
831
|
-
}
|
|
832
|
-
|
|
833
791
|
public get storage(): IDocumentStorageService {
|
|
834
792
|
return this._storage;
|
|
835
793
|
}
|
|
@@ -878,6 +836,19 @@ export class ContainerRuntime
|
|
|
878
836
|
}
|
|
879
837
|
private readonly handleContext: ContainerFluidHandleContext;
|
|
880
838
|
|
|
839
|
+
/**
|
|
840
|
+
* This is a proxy to the delta manager provided by the container context (innerDeltaManager). It restricts certain
|
|
841
|
+
* accesses such as sets "read-only" mode for the summarizer client. This is the default delta manager that should
|
|
842
|
+
* be used unless the innerDeltaManager is required.
|
|
843
|
+
*/
|
|
844
|
+
public readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
|
|
845
|
+
/**
|
|
846
|
+
* The delta manager provided by the container context. By default, using the default delta manager (proxy)
|
|
847
|
+
* should be sufficient. This should be used only if necessary. For example, for validating and propagating connected
|
|
848
|
+
* events which requires access to the actual real only info, this is needed.
|
|
849
|
+
*/
|
|
850
|
+
private readonly innerDeltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
|
|
851
|
+
|
|
881
852
|
// internal logger for ContainerRuntime. Use this.logger for stores, summaries, etc.
|
|
882
853
|
private readonly mc: MonitoringContext;
|
|
883
854
|
|
|
@@ -976,7 +947,6 @@ export class ContainerRuntime
|
|
|
976
947
|
private readonly blobManager: BlobManager;
|
|
977
948
|
private readonly pendingStateManager: PendingStateManager;
|
|
978
949
|
private readonly outbox: Outbox;
|
|
979
|
-
|
|
980
950
|
private readonly garbageCollector: IGarbageCollector;
|
|
981
951
|
|
|
982
952
|
private readonly dataStores: DataStores;
|
|
@@ -1057,9 +1027,13 @@ export class ContainerRuntime
|
|
|
1057
1027
|
// the runtime configuration overrides
|
|
1058
1028
|
...runtimeOptions.summaryOptions?.summaryConfigOverrides,
|
|
1059
1029
|
},
|
|
1030
|
+
initializeEntryPoint?: (containerRuntime: IContainerRuntime) => Promise<FluidObject>,
|
|
1060
1031
|
) {
|
|
1061
1032
|
super();
|
|
1062
1033
|
|
|
1034
|
+
this.innerDeltaManager = context.deltaManager;
|
|
1035
|
+
this.deltaManager = new DeltaManagerSummarizerProxy(context.deltaManager);
|
|
1036
|
+
|
|
1063
1037
|
let loadSummaryNumber: number;
|
|
1064
1038
|
// Get the container creation metadata. For new container, we initialize these. For existing containers,
|
|
1065
1039
|
// get the values from the metadata blob.
|
|
@@ -1113,7 +1087,10 @@ export class ContainerRuntime
|
|
|
1113
1087
|
runtimeOptions.maxBatchSizeInBytes,
|
|
1114
1088
|
this.mc.logger,
|
|
1115
1089
|
);
|
|
1116
|
-
this.remoteMessageProcessor = new RemoteMessageProcessor(
|
|
1090
|
+
this.remoteMessageProcessor = new RemoteMessageProcessor(
|
|
1091
|
+
opSplitter,
|
|
1092
|
+
new OpDecompressor(this.mc.logger),
|
|
1093
|
+
);
|
|
1117
1094
|
|
|
1118
1095
|
this.handleContext = new ContainerFluidHandleContext("", this);
|
|
1119
1096
|
|
|
@@ -1177,7 +1154,9 @@ export class ContainerRuntime
|
|
|
1177
1154
|
getLastSummaryTimestampMs: () => this.messageAtLastSummary?.timestamp,
|
|
1178
1155
|
readAndParseBlob: async <T>(id: string) => readAndParse<T>(this.storage, id),
|
|
1179
1156
|
getContainerDiagnosticId: () => this.context.id,
|
|
1180
|
-
|
|
1157
|
+
// GC runs in summarizer client and needs access to the real (non-proxy) active information. The proxy
|
|
1158
|
+
// delta manager would always return false for summarizer client.
|
|
1159
|
+
activeConnection: () => this.innerDeltaManager.active,
|
|
1181
1160
|
});
|
|
1182
1161
|
|
|
1183
1162
|
const loadedFromSequenceNumber = this.deltaManager.initialSequenceNumber;
|
|
@@ -1346,7 +1325,12 @@ export class ContainerRuntime
|
|
|
1346
1325
|
this.handleContext,
|
|
1347
1326
|
this.summaryCollection,
|
|
1348
1327
|
async (runtime: IConnectableRuntime) =>
|
|
1349
|
-
RunWhileConnectedCoordinator.create(
|
|
1328
|
+
RunWhileConnectedCoordinator.create(
|
|
1329
|
+
runtime,
|
|
1330
|
+
// Summarization runs in summarizer client and needs access to the real (non-proxy) active
|
|
1331
|
+
// information. The proxy delta manager would always return false for summarizer client.
|
|
1332
|
+
() => this.innerDeltaManager.active,
|
|
1333
|
+
),
|
|
1350
1334
|
);
|
|
1351
1335
|
} else if (
|
|
1352
1336
|
SummarizerClientElection.clientDetailsPermitElection(this.context.clientDetails)
|
|
@@ -1396,8 +1380,9 @@ export class ContainerRuntime
|
|
|
1396
1380
|
this.deltaManager.on("readonly", (readonly: boolean) => {
|
|
1397
1381
|
// we accumulate ops while being in read-only state.
|
|
1398
1382
|
// once user gets write permissions and we have active connection, flush all pending ops.
|
|
1383
|
+
// Note that the inner (non-proxy) delta manager is needed here to get the readonly information.
|
|
1399
1384
|
assert(
|
|
1400
|
-
readonly === this.
|
|
1385
|
+
readonly === this.innerDeltaManager.readOnlyInfo.readonly,
|
|
1401
1386
|
0x124 /* "inconsistent readonly property/event state" */,
|
|
1402
1387
|
);
|
|
1403
1388
|
|
|
@@ -1447,6 +1432,8 @@ export class ContainerRuntime
|
|
|
1447
1432
|
|
|
1448
1433
|
ReportOpPerfTelemetry(this.context.clientId, this.deltaManager, this.logger);
|
|
1449
1434
|
BindBatchTracker(this, this.logger);
|
|
1435
|
+
|
|
1436
|
+
this.entryPoint = new LazyPromise(async () => initializeEntryPoint?.(this));
|
|
1450
1437
|
}
|
|
1451
1438
|
|
|
1452
1439
|
/**
|
|
@@ -1566,6 +1553,14 @@ export class ContainerRuntime
|
|
|
1566
1553
|
}
|
|
1567
1554
|
}
|
|
1568
1555
|
|
|
1556
|
+
/**
|
|
1557
|
+
* {@inheritDoc @fluidframework/container-definitions#IRuntime.getEntryPoint}
|
|
1558
|
+
*/
|
|
1559
|
+
public async getEntryPoint?(): Promise<FluidObject | undefined> {
|
|
1560
|
+
return this.entryPoint;
|
|
1561
|
+
}
|
|
1562
|
+
private readonly entryPoint: LazyPromise<FluidObject | undefined>;
|
|
1563
|
+
|
|
1569
1564
|
private internalId(maybeAlias: string): string {
|
|
1570
1565
|
return this.dataStores.aliases.get(maybeAlias) ?? maybeAlias;
|
|
1571
1566
|
}
|
|
@@ -1757,8 +1752,9 @@ export class ContainerRuntime
|
|
|
1757
1752
|
// If attachment blobs were added while disconnected, we need to delay
|
|
1758
1753
|
// propagation of the "connected" event until we have uploaded them to
|
|
1759
1754
|
// ensure we don't submit ops referencing a blob that has not been uploaded
|
|
1755
|
+
// Note that the inner (non-proxy) delta manager is needed here to get the readonly information.
|
|
1760
1756
|
const connecting =
|
|
1761
|
-
connected && !this._connected && !this.
|
|
1757
|
+
connected && !this._connected && !this.innerDeltaManager.readOnlyInfo.readonly;
|
|
1762
1758
|
if (connecting && this.blobManager.hasPendingOfflineUploads) {
|
|
1763
1759
|
assert(
|
|
1764
1760
|
!this.delayConnectClientId,
|
|
@@ -1890,7 +1886,23 @@ export class ContainerRuntime
|
|
|
1890
1886
|
case ContainerMessageType.Rejoin:
|
|
1891
1887
|
break;
|
|
1892
1888
|
default:
|
|
1893
|
-
|
|
1889
|
+
if (runtimeMessage) {
|
|
1890
|
+
const error = DataProcessingError.create(
|
|
1891
|
+
// Former assert 0x3ce
|
|
1892
|
+
"Runtime message of unknown type",
|
|
1893
|
+
"OpProcessing",
|
|
1894
|
+
message,
|
|
1895
|
+
{
|
|
1896
|
+
local,
|
|
1897
|
+
type: message.type,
|
|
1898
|
+
contentType: typeof message.contents,
|
|
1899
|
+
batch: message.metadata?.batch,
|
|
1900
|
+
compression: message.compression,
|
|
1901
|
+
},
|
|
1902
|
+
);
|
|
1903
|
+
this.closeFn(error);
|
|
1904
|
+
throw error;
|
|
1905
|
+
}
|
|
1894
1906
|
}
|
|
1895
1907
|
|
|
1896
1908
|
// For back-compat, notify only about runtime messages for now.
|
|
@@ -2107,7 +2119,9 @@ export class ContainerRuntime
|
|
|
2107
2119
|
}
|
|
2108
2120
|
|
|
2109
2121
|
private canSendOps() {
|
|
2110
|
-
|
|
2122
|
+
// Note that the real (non-proxy) delta manager is needed here to get the readonly info. This is because
|
|
2123
|
+
// container runtime's ability to send ops depend on the actual readonly state of the delta manager.
|
|
2124
|
+
return this.connected && !this.innerDeltaManager.readOnlyInfo.readonly;
|
|
2111
2125
|
}
|
|
2112
2126
|
|
|
2113
2127
|
/**
|
|
@@ -2339,10 +2353,10 @@ export class ContainerRuntime
|
|
|
2339
2353
|
}
|
|
2340
2354
|
|
|
2341
2355
|
/**
|
|
2342
|
-
* Implementation of IGarbageCollectionRuntime::updateStateBeforeGC.
|
|
2343
2356
|
* Before GC runs, called by the garbage collector to update any pending GC state. This is mainly used to notify
|
|
2344
2357
|
* the garbage collector of references detected since the last GC run. Most references are notified immediately
|
|
2345
2358
|
* but there can be some for which async operation is required (such as detecting new root data stores).
|
|
2359
|
+
* @see IGarbageCollectionRuntime.updateStateBeforeGC
|
|
2346
2360
|
*/
|
|
2347
2361
|
public async updateStateBeforeGC() {
|
|
2348
2362
|
return this.dataStores.updateStateBeforeGC();
|
|
@@ -2353,9 +2367,9 @@ export class ContainerRuntime
|
|
|
2353
2367
|
}
|
|
2354
2368
|
|
|
2355
2369
|
/**
|
|
2356
|
-
* Implementation of IGarbageCollectionRuntime::getGCData.
|
|
2357
2370
|
* Generates and returns the GC data for this container.
|
|
2358
2371
|
* @param fullGC - true to bypass optimizations and force full generation of GC data.
|
|
2372
|
+
* @see IGarbageCollectionRuntime.getGCData
|
|
2359
2373
|
*/
|
|
2360
2374
|
public async getGCData(fullGC?: boolean): Promise<IGarbageCollectionData> {
|
|
2361
2375
|
const builder = new GCDataBuilder();
|
|
@@ -2368,9 +2382,9 @@ export class ContainerRuntime
|
|
|
2368
2382
|
}
|
|
2369
2383
|
|
|
2370
2384
|
/**
|
|
2371
|
-
* Implementation of IGarbageCollectionRuntime::updateUsedRoutes.
|
|
2372
2385
|
* After GC has run, called to notify this container's nodes of routes that are used in it.
|
|
2373
2386
|
* @param usedRoutes - The routes that are used in all nodes in this Container.
|
|
2387
|
+
* @see IGarbageCollectionRuntime.updateUsedRoutes
|
|
2374
2388
|
*/
|
|
2375
2389
|
public updateUsedRoutes(usedRoutes: string[]) {
|
|
2376
2390
|
// Update our summarizer node's used routes. Updating used routes in summarizer node before
|
|
@@ -2834,7 +2848,9 @@ export class ContainerRuntime
|
|
|
2834
2848
|
|
|
2835
2849
|
const serializedContent = JSON.stringify({ type, contents });
|
|
2836
2850
|
|
|
2837
|
-
|
|
2851
|
+
// Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
|
|
2852
|
+
// container runtime's ability to submit ops depend on the actual readonly state of the delta manager.
|
|
2853
|
+
if (this.innerDeltaManager.readOnlyInfo.readonly) {
|
|
2838
2854
|
this.logger.sendTelemetryEvent({
|
|
2839
2855
|
eventName: "SubmitOpInReadonly",
|
|
2840
2856
|
connected: this.connected,
|
package/src/dataStores.ts
CHANGED
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
TelemetryDataTag,
|
|
44
44
|
} from "@fluidframework/telemetry-utils";
|
|
45
45
|
import { AttachState } from "@fluidframework/container-definitions";
|
|
46
|
-
import {
|
|
46
|
+
import { buildSnapshotTree } from "@fluidframework/driver-utils";
|
|
47
47
|
import { assert, Lazy } from "@fluidframework/common-utils";
|
|
48
48
|
import { v4 as uuid } from "uuid";
|
|
49
49
|
import { GCDataBuilder, unpackChildNodesUsedRoutes } from "@fluidframework/garbage-collector";
|
|
@@ -61,6 +61,7 @@ import {
|
|
|
61
61
|
createAttributesBlob,
|
|
62
62
|
LocalDetachedFluidDataStoreContext,
|
|
63
63
|
} from "./dataStoreContext";
|
|
64
|
+
import { StorageServiceWithAttachBlobs } from "./storageServiceWithAttachBlobs";
|
|
64
65
|
import { IDataStoreAliasMessage, isDataStoreAliasMessage } from "./dataStore";
|
|
65
66
|
import {
|
|
66
67
|
GCNodeType,
|
|
@@ -245,10 +246,10 @@ export class DataStores implements IDisposable {
|
|
|
245
246
|
throw error;
|
|
246
247
|
}
|
|
247
248
|
|
|
248
|
-
const
|
|
249
|
+
const flatAttachBlobs = new Map<string, ArrayBufferLike>();
|
|
249
250
|
let snapshotTree: ISnapshotTree | undefined;
|
|
250
251
|
if (attachMessage.snapshot) {
|
|
251
|
-
snapshotTree = buildSnapshotTree(attachMessage.snapshot.entries,
|
|
252
|
+
snapshotTree = buildSnapshotTree(attachMessage.snapshot.entries, flatAttachBlobs);
|
|
252
253
|
}
|
|
253
254
|
|
|
254
255
|
// Include the type of attach message which is the pkg of the store to be
|
|
@@ -258,7 +259,7 @@ export class DataStores implements IDisposable {
|
|
|
258
259
|
id: attachMessage.id,
|
|
259
260
|
snapshotTree,
|
|
260
261
|
runtime: this.runtime,
|
|
261
|
-
storage: new
|
|
262
|
+
storage: new StorageServiceWithAttachBlobs(this.runtime.storage, flatAttachBlobs),
|
|
262
263
|
scope: this.runtime.scope,
|
|
263
264
|
createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(attachMessage.id, {
|
|
264
265
|
type: CreateSummarizerNodeSource.FromAttach,
|
|
@@ -576,6 +577,10 @@ export class DataStores implements IDisposable {
|
|
|
576
577
|
eventName: "SetConnectionStateError",
|
|
577
578
|
clientId,
|
|
578
579
|
fluidDataStore,
|
|
580
|
+
details: JSON.stringify({
|
|
581
|
+
runtimeConnected: this.runtime.connected,
|
|
582
|
+
connected,
|
|
583
|
+
}),
|
|
579
584
|
},
|
|
580
585
|
error,
|
|
581
586
|
);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IDeltaManager, ReadOnlyInfo } from "@fluidframework/container-definitions";
|
|
7
|
+
import { DeltaManagerProxyBase } from "@fluidframework/container-utils";
|
|
8
|
+
import { IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
9
|
+
import { summarizerClientType } from "./summary";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Proxy to the real IDeltaManager for restricting certain access to layers below container runtime in summarizer clients:
|
|
13
|
+
* - Summarizer client should be read-only to layers below the container runtime to restrict local changes.
|
|
14
|
+
* - Summarizer client should not be active to layers below the container runtime to restrict local changes.
|
|
15
|
+
*/
|
|
16
|
+
export class DeltaManagerSummarizerProxy
|
|
17
|
+
extends DeltaManagerProxyBase
|
|
18
|
+
implements IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>
|
|
19
|
+
{
|
|
20
|
+
public get active(): boolean {
|
|
21
|
+
// Summarize clients should not be active. There shouldn't be any local changes (writes) in the summarizer
|
|
22
|
+
// except for the SummarizeOp which is generated by the runtime.
|
|
23
|
+
return !this.isSummarizerClient && this.deltaManager.active;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public get readOnlyInfo(): ReadOnlyInfo {
|
|
27
|
+
// Summarizer clients should be read-only as far as the runtime and layers below are concerned. There shouldn't
|
|
28
|
+
// be any local changes (writes) in the summarizer except for the summarize op which is generated by the runtime.
|
|
29
|
+
if (this.isSummarizerClient) {
|
|
30
|
+
return {
|
|
31
|
+
readonly: true,
|
|
32
|
+
forced: false,
|
|
33
|
+
permissions: undefined,
|
|
34
|
+
storageOnly: false,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return this.deltaManager.readOnlyInfo;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private readonly isSummarizerClient: boolean;
|
|
41
|
+
|
|
42
|
+
constructor(deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>) {
|
|
43
|
+
super(deltaManager);
|
|
44
|
+
this.isSummarizerClient = this.deltaManager.clientDetails.type === summarizerClientType;
|
|
45
|
+
}
|
|
46
|
+
}
|