/*! * Copyright (c) Microsoft Corporation and contributors. All rights reserved. * Licensed under the MIT License. */ import type { ITelemetryBaseLogger } from "@fluidframework/core-interfaces"; import type { ISnapshotTree, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal"; import { type ITelemetryContext, type CreateChildSummarizerNodeParam, type ISummarizeResult, type ISummarizerNode, type ISummarizerNodeConfig, type SummarizeInternalFn } from "@fluidframework/runtime-definitions/internal"; import type { ITelemetryErrorEventExt, ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal"; import type { ICreateChildDetails, IRefreshSummaryResult, IStartSummaryResult, ISummarizerNodeRootContract, ValidateSummaryResult, PendingSummaryInfo } from "./summarizerNodeUtils.js"; export interface IRootSummarizerNode extends ISummarizerNode, ISummarizerNodeRootContract { } /** * Encapsulates the summarizing work and state of an individual tree node in the * summary tree. It tracks changes and allows for optimizations when unchanged, or * can allow for fallback summaries to be generated when an error is encountered. * Usage is for the root node to call startSummary first to begin tracking a WIP * (work in progress) summary. Then all nodes will call summarize to summaries their * individual parts. Once completed and uploaded to storage, the root node will call * completeSummary or clearSummary to clear the WIP summary tracking state if something * went wrong. The SummarizerNodes will track all pending summaries that have been * recorded by the completeSummary call. When one of them is acked, the root node should * call refreshLatestSummary to inform the tree of SummarizerNodes of the new baseline * latest successful summary. */ export declare class SummarizerNode implements IRootSummarizerNode { private readonly summarizeInternalFn; /** * Encoded handle or path to the node */ private readonly _summaryHandleId; private _changeSequenceNumber; /** * Summary reference sequence number, i.e. last sequence number seen when last successful summary was created */ private _lastSummaryReferenceSequenceNumber?; protected wipSummaryLogger?: ITelemetryBaseLogger | undefined; /** * A unique id of this node to be logged when sending telemetry. */ protected telemetryNodeId?: string | undefined; /** * The reference sequence number of the most recent acked summary. * Returns 0 if there is not yet an acked summary. */ get referenceSequenceNumber(): number; /** * returns the handle of the last successful summary of this summarizerNode in string format * (this getter is primarily only used in the test code) */ get summaryHandleId(): string; protected readonly children: Map; /** * Key value pair of summaries submitted by this client which are not yet acked. * Key is the proposalHandle and value is the summary op's referece sequence number. */ protected readonly pendingSummaries: Map; protected wipReferenceSequenceNumber: number | undefined; /** * True if the current node was summarized during the current summary process * This flag is used to identify scenarios where summarize was not called on a node. * For example, this node was created after its parent was already summarized due to out-of-order realization via application code. */ private wipSummarizeCalled; private wipSkipRecursion; protected readonly logger: ITelemetryLoggerExt; /** * Do not call constructor directly. * Use createRootSummarizerNode to create root node, or createChild to create child nodes. */ constructor(baseLogger: ITelemetryBaseLogger, summarizeInternalFn: SummarizeInternalFn, config: ISummarizerNodeConfig, /** * Encoded handle or path to the node */ _summaryHandleId: string, _changeSequenceNumber: number, /** * Summary reference sequence number, i.e. last sequence number seen when last successful summary was created */ _lastSummaryReferenceSequenceNumber?: number | undefined, wipSummaryLogger?: ITelemetryBaseLogger | undefined, /** * A unique id of this node to be logged when sending telemetry. */ telemetryNodeId?: string | undefined); /** * In order to produce a summary with a summarizer node, the summarizer node system must be notified a summary has * started. This is done by calling startSummary. This will track the reference sequence number of the summary and * run some validation checks to ensure the summary is correct. * @param referenceSequenceNumber - the number of ops processed up to this point * @param summaryLogger - the logger to use for the summary * @param latestSummaryRefSeqNum - the reference sequence number of the latest summary. Another way to think about * it is the reference sequence number of the previous summary. * @returns the number of nodes in the tree, the number of nodes that are invalid, and the different types of * sequence number mismatches */ startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryBaseLogger, latestSummaryRefSeqNum: number): IStartSummaryResult; summarize(fullTree: boolean, trackState?: boolean, telemetryContext?: ITelemetryContext): Promise; /** * Validates that the in-progress summary is correct, i.e., summarize should have run for all non-skipped * nodes. This will only be called for the root summarizer node and is called by it recursively on all child nodes. * * @returns ValidateSummaryResult which contains a boolean success indicating whether the validation was successful. * In case of failure, additional information is returned indicating type of failure and where it was. */ validateSummary(): ValidateSummaryResult; /** * Validates that the in-progress summary is correct for all nodes, i.e., summarize should have run for all * non-skipped nodes. * @param parentSkipRecursion - true if the parent of this node skipped recursing the child nodes when summarizing. * In that case, the children will not have work-in-progress state. * * @returns ValidateSummaryResult which contains a boolean success indicating whether the validation was successful. * In case of failure, additional information is returned indicating type of failure and where it was. */ protected validateSummaryCore(parentSkipRecursion: boolean): ValidateSummaryResult; private wasSummarizeMissed; /** * Called after summary has been uploaded to the server. Add the work-in-progress state to the pending summary * queue. We track this until we get an ack from the server for this summary. * @param proposalHandle - The handle of the summary that was uploaded to the server. */ completeSummary(proposalHandle: string): void; /** * Recursive implementation for completeSummary, with additional internal-only parameters. * @param proposalHandle - The handle of the summary that was uploaded to the server. * @param parentPath - The path of the parent node which is used to build the path of this node. * @param parentSkipRecursion - true if the parent of this node skipped recursing the child nodes when summarizing. * In that case, the children will not have work-in-progress state. * @param validate - true to validate that the in-progress summary is correct for all nodes. */ protected completeSummaryCore(proposalHandle: string, parentSkipRecursion: boolean): void; clearSummary(): void; /** * Refreshes the latest summary tracked by this node. If we have a pending summary for the given proposal handle, * it becomes the latest summary. If the current summary is already ahead, we skip the update. * If the current summary is behind, then we do not refresh. * @param proposalHandle - Handle of the generated / uploaded summary. * @param summaryRefSeq - Reference sequence of the acked summary * @returns true if the summary is tracked by this node, false otherwise. */ refreshLatestSummary(proposalHandle: string, summaryRefSeq: number): Promise; /** * Called when we get an ack from the server for a summary we've just sent. Updates the reference state of this node * from the state in the pending summary queue. * @param proposalHandle - Handle for the current proposal. * @param referenceSequenceNumber - Reference sequence number of sent summary. */ protected refreshLatestSummaryFromPending(proposalHandle: string, referenceSequenceNumber: number): void; updateBaseSummaryState(snapshot: ISnapshotTree): void; recordChange(op: ISequencedDocumentMessage): void; invalidate(sequenceNumber: number): void; /** * True if a change has been recorded with sequence number exceeding * the latest successfully acked summary reference sequence number. * False implies that the previous summary can be reused. */ protected hasChanged(): boolean; protected readonly canReuseHandle: boolean; createChild( /** * Summarize function */ summarizeInternalFn: SummarizeInternalFn, /** * Initial id or path part of this node */ id: string, /** * Information needed to create the node. * If it is from a base summary, it will assert that a summary has been seen. * Attach information if it is created from an attach op. */ createParam: CreateChildSummarizerNodeParam, config?: ISummarizerNodeConfig): ISummarizerNode; getChild(id: string): ISummarizerNode | undefined; /** * Returns the details needed to create a child node. * @param id - Initial id or path part of the child node. * @param createParam - Information needed to create the node. * @returns the details needed to create the child node. */ protected getCreateDetailsForChild(id: string, createParam: CreateChildSummarizerNodeParam): ICreateChildDetails; /** * Updates the state of the child if required. For example, if a summary is currently being tracked, the child's * summary tracking state needs to be updated too. * Also, in case a child node gets realized in between Summary Op and Summary Ack, let's initialize the child's * pending summary as well. * @param child - The child node whose state is to be updated. * @param id - Initial id or path part of this node * */ protected maybeUpdateChildState(child: SummarizerNode, id: string): void; protected addPendingSummary(key: string, pendingSummaryInfo: PendingSummaryInfo): void; /** * Tells whether summary tracking is in progress. True if "startSummary" API is called before summarize. */ isSummaryInProgress(): boolean; /** * Creates and throws an error due to unexpected conditions. */ protected throwUnexpectedError(eventProps: ITelemetryErrorEventExt): never; } /** * Creates a root summarizer node. * @param logger - Logger to use within SummarizerNode * @param summarizeInternalFn - Function to generate summary * @param changeSequenceNumber - Sequence number of latest change to new node/subtree * @param referenceSequenceNumber - Reference sequence number of last acked summary, * or undefined if not loaded from summary * @param config - Configure behavior of summarizer node */ export declare const createRootSummarizerNode: (logger: ITelemetryLoggerExt, summarizeInternalFn: SummarizeInternalFn, changeSequenceNumber: number, referenceSequenceNumber: number | undefined, config?: ISummarizerNodeConfig) => IRootSummarizerNode; //# sourceMappingURL=summarizerNode.d.ts.map