From 234f450c02c37001724bd40137e703e99ee7f6e7 Mon Sep 17 00:00:00 2001 From: NicholasCouri Date: Wed, 1 Jun 2022 12:59:44 -0700 Subject: [PATCH] Summary docs (#10435) Update Summary documentation to better describe parameters and returned types. --- api-report/runtime-definitions.api.md | 10 ++- .../api-report/protocol-definitions.api.md | 24 +++---- .../lib/protocol-definitions/src/summary.ts | 64 +++++++++++++++++-- .../datastore-definitions/src/channel.ts | 24 ++++++- .../runtime-definitions/src/summary.ts | 28 ++++++++ 5 files changed, 120 insertions(+), 30 deletions(-) diff --git a/api-report/runtime-definitions.api.md b/api-report/runtime-definitions.api.md index 42c133ae542d..9cbee2977f01 100644 --- a/api-report/runtime-definitions.api.md +++ b/api-report/runtime-definitions.api.md @@ -286,14 +286,14 @@ export interface ISignalEnvelope { }; } -// @public (undocumented) +// @public export interface ISummarizeInternalResult extends ISummarizeResult { // (undocumented) id: string; pathPartsForChildren?: string[]; } -// @public (undocumented) +// @public export interface ISummarizeResult { // (undocumented) stats: ISummaryStats; @@ -354,7 +354,7 @@ export interface ISummarizerNodeWithGC extends ISummarizerNode { updateUsedRoutes(usedRoutes: string[], gcTimestamp?: number): void; } -// @public (undocumented) +// @public export interface ISummaryStats { // (undocumented) blobNodeCount: number; @@ -368,11 +368,9 @@ export interface ISummaryStats { unreferencedBlobSize: number; } -// @public (undocumented) +// @public export interface ISummaryTreeWithStats { - // (undocumented) stats: ISummaryStats; - // (undocumented) summary: ISummaryTree; } diff --git a/common/lib/protocol-definitions/api-report/protocol-definitions.api.md b/common/lib/protocol-definitions/api-report/protocol-definitions.api.md index a192248bb03a..77d7d3f3aa63 100644 --- a/common/lib/protocol-definitions/api-report/protocol-definitions.api.md +++ b/common/lib/protocol-definitions/api-report/protocol-definitions.api.md @@ -408,7 +408,7 @@ export interface ISummaryAck { summaryProposal: ISummaryProposal; } -// @public (undocumented) +// @public export interface ISummaryAttachment { // (undocumented) id: string; @@ -426,7 +426,7 @@ export interface ISummaryAuthor { name: string; } -// @public (undocumented) +// @public export interface ISummaryBlob { // (undocumented) content: string | Uint8Array; @@ -472,11 +472,9 @@ export interface ISummaryContent { parents: string[]; } -// @public (undocumented) +// @public export interface ISummaryHandle { - // (undocumented) handle: string; - // (undocumented) handleType: SummaryTypeNoHandle; // (undocumented) type: SummaryType.Handle; @@ -505,7 +503,7 @@ export interface ISummaryTokenClaims { sub: string; } -// @public (undocumented) +// @public export interface ISummaryTree { // (undocumented) tree: { @@ -664,7 +662,7 @@ export type SummaryObject = ISummaryTree | ISummaryBlob | ISummaryHandle | ISumm // @public (undocumented) export type SummaryTree = ISummaryTree | ISummaryHandle; -// @public (undocumented) +// @public export namespace SummaryType { // (undocumented) export type Attachment = 4; @@ -674,14 +672,10 @@ export namespace SummaryType { export type Handle = 3; // (undocumented) export type Tree = 1; - const // (undocumented) - Tree: Tree; - const // (undocumented) - Blob: Blob; - const // (undocumented) - Handle: Handle; - const // (undocumented) - Attachment: Attachment; + const Tree: Tree; + const Blob: Blob; + const Handle: Handle; + const Attachment: Attachment; } // @public (undocumented) diff --git a/common/lib/protocol-definitions/src/summary.ts b/common/lib/protocol-definitions/src/summary.ts index ba50e306f321..bae9656b050c 100644 --- a/common/lib/protocol-definitions/src/summary.ts +++ b/common/lib/protocol-definitions/src/summary.ts @@ -21,41 +21,93 @@ export interface ISummaryCommitter { date: string; } +/** + * Type tag used to distinguish different types of nodes in a {@link ISummaryTree}. + */ +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace SummaryType { export type Tree = 1; export type Blob = 2; export type Handle = 3; export type Attachment = 4; - export const Tree: Tree = 1 as const; - export const Blob: Blob = 2 as const; - export const Handle: Handle = 3 as const; - export const Attachment: Attachment = 4 as const; + /** + * Represents a sub-tree in the summary. + */ + export const Tree: Tree = 1 as const; + + /** + * Represents a blob of data that is added to the summary. + * Such as the user data that is added to the DDS or metadata added by runtime + * such as data store / channel attributes. + */ + export const Blob: Blob = 2 as const; + + /** + * Path to a summary tree object from the last successful summary. + */ + export const Handle: Handle = 3 as const; + + /** + * Unique identifier to larger blobs uploaded outside of the summary. + * Ex. DDS has large images or video that will be uploaded by the BlobManager and + * receive an Id that can be used in the summary. + */ + export const Attachment: Attachment = 4 as const; } export type SummaryType = SummaryType.Attachment | SummaryType.Blob | SummaryType.Handle | SummaryType.Tree; export type SummaryTypeNoHandle = SummaryType.Tree | SummaryType.Blob | SummaryType.Attachment; +/** + * Path to a summary tree object from the last successful summary indicating the summary object hasn't + * changed since it was uploaded. + * To illustrate, if a DataStore did not change since last summary, the framework runtime will use a handle for the + * entire DataStore instead of re-sending the entire subtree. The same concept applies for a DDS. + * An example of handle would be: '//'. + */ export interface ISummaryHandle { type: SummaryType.Handle; - // No handles, all other SummaryType are Ok + /** + * Type of Summary Handle (SummaryType.Handle is not supported). + */ handleType: SummaryTypeNoHandle; - // Stored handle reference + /** + * Unique path that identifies the corresponding sub-tree in a previous summary. + */ handle: string; } +/** + * String or Binary data to be uploaded to the server as part of the container's Summary. + * Note: Already uploaded blobs would be referenced by a ISummaryAttachment. + * Additional information can be found here: https://github.com/microsoft/FluidFramework/issues/6568 + * Ex. "content": "\{ \"pkg\":\"[\\\"OfficeRootComponent\\\",\\\"LastEditedComponent\\\"]\", + * \"summaryFormatVersion\":2,\"isRootDataStore\":false \}" + */ export interface ISummaryBlob { type: SummaryType.Blob; content: string | Uint8Array; } +/** + * Unique identifier for blobs uploaded outside of the summary. Attachment Blobs are uploaded and + * downloaded separately and do not take part of the snapshot payload. + * The id gets returned from the backend after the attachment has been uploaded. + * Additional information can be found here: https://github.com/microsoft/FluidFramework/issues/6374 + * Ex. "id": "bQAQKARDdMdTgqICmBa_ZB86YXwGP" + */ export interface ISummaryAttachment { type: SummaryType.Attachment; id: string; } +/** + * Tree Node data structure with children that are nodes of SummaryObject type: + * Blob, Handle, Attachment or another Tree. + */ export interface ISummaryTree { type: SummaryType.Tree; diff --git a/packages/runtime/datastore-definitions/src/channel.ts b/packages/runtime/datastore-definitions/src/channel.ts index b7fef85193a8..e45c04959d54 100644 --- a/packages/runtime/datastore-definitions/src/channel.ts +++ b/packages/runtime/datastore-definitions/src/channel.ts @@ -20,15 +20,33 @@ export interface IChannel extends IFluidLoadable { readonly attributes: IChannelAttributes; /** - * Generates summary of the channel synchronously. - * @returns A tree representing the summary of the channel. + * Generates summary of the channel synchronously. It is called when an `attach message` + * for a local channel is generated. In other words, when the channel is being attached + * to make it visible to other clients. + * Note: Since Attach Summary is generated for local channels when making them visible to + * remote clients, they don't have any previous summaries to compare against. For this reason, + * The attach summary cannot contain summary handles (paths to sub-trees or blobs). + * It can, however, contain ISummaryAttachment (handles to blobs uploaded async via the blob manager). + * @param fullTree - flag indicating whether the attempt should generate a full + * summary tree without any handles for unchanged subtrees. + * @param trackState - optimization for tracking state of objects across summaries. If the state + * of an object did not change since last successful summary, an ISummaryHandle can be used + * instead of re-summarizing it. If this is false, the expectation is that you should never + * send an ISummaryHandle since you are not expected to track state. + * Note: The goal is to remove the trackState and automatically decided whether the + * handles will be used or not: https://github.com/microsoft/FluidFramework/issues/10455 + * @returns A summary capturing the current state of the channel. */ getAttachSummary(fullTree?: boolean, trackState?: boolean): ISummaryTreeWithStats; /** * Generates summary of the channel asynchronously. * This should not be called where the channel can be modified while summarization is in progress. - * @returns A tree representing the summary of the channel. + * @param fullTree - flag indicating whether the attempt should generate a full + * summary tree without any handles for unchanged subtrees. It is only set to true when generating + * a summary from the entire container. + * @param trackState - This tells whether we should track state from this summary. + * @returns A summary capturing the current state of the channel. */ summarize(fullTree?: boolean, trackState?: boolean): Promise; diff --git a/packages/runtime/runtime-definitions/src/summary.ts b/packages/runtime/runtime-definitions/src/summary.ts index f8e1ba70aca7..9aeb04ccd12f 100644 --- a/packages/runtime/runtime-definitions/src/summary.ts +++ b/packages/runtime/runtime-definitions/src/summary.ts @@ -16,6 +16,9 @@ import { IGarbageCollectionSummaryDetails, } from "./garbageCollection"; +/** + * Contains the aggregation data from a Tree/Subtree. + */ export interface ISummaryStats { treeNodeCount: number; blobNodeCount: number; @@ -24,16 +27,41 @@ export interface ISummaryStats { unreferencedBlobSize: number; } +/** + * Represents the summary tree for a node along with the statistics for that tree. + * For example, for a given data store, it contains the data for data store along with a subtree for + * each of its DDS. + * Any component that implements IChannelContext, IFluidDataStoreChannel or extends SharedObject + * will be taking part of the summarization process. + */ export interface ISummaryTreeWithStats { + /** Represents an agreggation of node counts and blob sizes associated to the current summary information */ stats: ISummaryStats; + /** + * A recursive data structure that will be converted to a snapshot tree and uploaded + * to the backend. + */ summary: ISummaryTree; } +/** + * Represents a summary at a current sequence number. + */ export interface ISummarizeResult { stats: ISummaryStats; summary: SummaryTree; } +/** + * Contains the same data as ISummaryResult but in order to avoid naming colisions, + * the data store summaries are wrapped around an array of labels identified by pathPartsForChildren. + * Ex: id:"" + pathPartsForChildren: ["path1"] + stats: ... + summary: + ... + "path1": + */ export interface ISummarizeInternalResult extends ISummarizeResult { id: string; /** Additional path parts between this node's ID and its children's IDs. */