From 48539d978c39926fc411be93141a1679ae156125 Mon Sep 17 00:00:00 2001 From: Navin Agarwal <45832642+agarwal-navin@users.noreply.github.com> Date: Fri, 1 Sep 2023 12:18:32 -0700 Subject: [PATCH] Simplfied SummarizerNode:refreshLatestSummary logic (#17106) ## Description #16657 removed the logic to refresh a summary's state by downloading a snapshot. With it gone, summarizer node (and rest of the system) only updates state from a summary that it was tracking. This PR simplifies the logic in `SummarizerNode::refreshLatestSummary` to account for this. It also renames the properties in the returned object to give the caller more context on what happened and what action it can take. Additionally, it removes logging the `PendingSummaryNotFound` telemetry. It is currently logged every time the summarizer loaded for the summary that is loaded from. The reason is that it processes the ack for the summary is loaded from and since the summary was not generated by this instance of the summarizer, this event is logged. Instead, added a property `pendingSummaryTracked` to the refreshLatestSummary_end event. [AB#4435](https://dev.azure.com/fluidframework/235294da-091d-4c29-84fc-cdfc3d90890b/_workitems/edit/4435) --- .../container-runtime/src/containerRuntime.ts | 6 +- .../src/gc/garbageCollection.ts | 7 +- .../container-runtime/src/gc/gcDefinitions.ts | 4 +- .../src/gc/gcSummaryStateTracker.ts | 39 +++++----- .../container-runtime/src/summary/index.ts | 3 +- .../src/summary/summarizerNode/index.ts | 3 +- .../summary/summarizerNode/summarizerNode.ts | 74 ++++++------------- .../summarizerNode/summarizerNodeUtils.ts | 39 ++-------- .../src/test/gc/garbageCollection.spec.ts | 17 ++--- .../src/test/gc/gcSummaryStateTracker.spec.ts | 40 +++------- .../src/test/summarizerNode.spec.ts | 18 ++--- .../src/test/summarizerNodeWithGc.spec.ts | 16 ++-- 12 files changed, 86 insertions(+), 180 deletions(-) diff --git a/packages/runtime/container-runtime/src/containerRuntime.ts b/packages/runtime/container-runtime/src/containerRuntime.ts index a0a1e04aef92..4a891e1a4dd4 100644 --- a/packages/runtime/container-runtime/src/containerRuntime.ts +++ b/packages/runtime/container-runtime/src/containerRuntime.ts @@ -3651,6 +3651,8 @@ export class ContainerRuntime /** Implementation of ISummarizerInternalsProvider.refreshLatestSummaryAck */ public async refreshLatestSummaryAck(options: IRefreshSummaryAckOptions) { const { proposalHandle, ackHandle, summaryRefSeq, summaryLogger } = options; + // proposalHandle is always passed from RunningSummarizer. + assert(proposalHandle !== undefined, "proposalHandle should be available"); const readAndParseBlob = async (id: string) => readAndParse(this.storage, id); const result = await this.summarizerNode.refreshLatestSummary( proposalHandle, @@ -3658,12 +3660,12 @@ export class ContainerRuntime ); /** - * When refreshing a summary ack, this check indicates a new ack of a summary that was newer than the + * When refreshing a summary ack, this check indicates a new ack of a summary that is newer than the * current summary that is tracked, but this summarizer runtime did not produce/track that summary. Thus * it needs to refresh its state. Today refresh is done by fetching the latest snapshot to update the cache * and then close as the current main client is likely to be re-elected as the parent summarizer again. */ - if (result.latestSummaryUpdated && !result.wasSummaryTracked) { + if (!result.isSummaryTracked && result.isSummaryNewer) { const fetchResult = await this.fetchSnapshotFromStorage( summaryLogger, { diff --git a/packages/runtime/container-runtime/src/gc/garbageCollection.ts b/packages/runtime/container-runtime/src/gc/garbageCollection.ts index 4a8f279f6964..b70b11f02305 100644 --- a/packages/runtime/container-runtime/src/gc/garbageCollection.ts +++ b/packages/runtime/container-runtime/src/gc/garbageCollection.ts @@ -29,7 +29,7 @@ import { RuntimeHeaders, } from "../containerRuntime"; import { ClientSessionExpiredError } from "../error"; -import { RefreshSummaryResult } from "../summary"; +import { IRefreshSummaryResult } from "../summary"; import { generateGCConfigs } from "./gcConfigs"; import { GCNodeType, @@ -843,10 +843,9 @@ export class GarbageCollector implements IGarbageCollector { } /** - * Called to refresh the latest summary state. This happens when either a pending summary is acked or a snapshot - * is downloaded and should be used to update the state. + * Called to refresh the latest summary state. This happens when either a pending summary is acked. */ - public async refreshLatestSummary(result: RefreshSummaryResult): Promise { + public async refreshLatestSummary(result: IRefreshSummaryResult): Promise { return this.summaryStateTracker.refreshLatestSummary(result); } diff --git a/packages/runtime/container-runtime/src/gc/gcDefinitions.ts b/packages/runtime/container-runtime/src/gc/gcDefinitions.ts index 6f66a94af10d..6d9ee0e1a0e0 100644 --- a/packages/runtime/container-runtime/src/gc/gcDefinitions.ts +++ b/packages/runtime/container-runtime/src/gc/gcDefinitions.ts @@ -17,7 +17,7 @@ import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils"; import { IContainerRuntimeMetadata, ICreateContainerMetadata, - RefreshSummaryResult, + IRefreshSummaryResult, } from "../summary"; export type GCVersion = number; @@ -228,7 +228,7 @@ export interface IGarbageCollector { /** Returns the GC details generated from the base snapshot. */ getBaseGCDetails(): Promise; /** Called when the latest summary of the system has been refreshed. */ - refreshLatestSummary(result: RefreshSummaryResult): Promise; + refreshLatestSummary(result: IRefreshSummaryResult): Promise; /** Called when a node is updated. Used to detect and log when an inactive node is changed or loaded. */ nodeUpdated( nodePath: string, diff --git a/packages/runtime/container-runtime/src/gc/gcSummaryStateTracker.ts b/packages/runtime/container-runtime/src/gc/gcSummaryStateTracker.ts index 8efa018a471c..fd1dbde79e66 100644 --- a/packages/runtime/container-runtime/src/gc/gcSummaryStateTracker.ts +++ b/packages/runtime/container-runtime/src/gc/gcSummaryStateTracker.ts @@ -13,11 +13,10 @@ import { ISummaryTreeWithStats, } from "@fluidframework/runtime-definitions"; import { mergeStats, SummaryTreeBuilder } from "@fluidframework/runtime-utils"; -import { RefreshSummaryResult } from "../summary"; -import { GCVersion, IGCStats } from "./gcDefinitions"; +import { IRefreshSummaryResult } from "../summary"; +import { GCVersion, IGarbageCollectorConfigs, IGCStats } from "./gcDefinitions"; import { generateSortedGCState } from "./gcHelpers"; import { IGarbageCollectionSnapshotData, IGarbageCollectionState } from "./gcSummaryDefinitions"; -import { IGarbageCollectorConfigs } from "."; export const gcStateBlobKey = `${gcBlobPrefix}_root`; @@ -264,31 +263,27 @@ export class GCSummaryStateTracker { } /** - * Called to refresh the latest summary state. This happens when either a pending summary is acked or a snapshot - * is downloaded and should be used to update the state. + * Called to refresh the latest summary state. This happens when either a pending summary is acked. */ - public async refreshLatestSummary(result: RefreshSummaryResult): Promise { - // If the latest summary was updated and the summary was tracked, this client is the one that generated this - // summary. So, update wasGCRunInLatestSummary. - // Note that this has to be updated if GC did not run too. Otherwise, `gcStateNeedsReset` will always return - // true in scenarios where GC is disabled but enabled in the snapshot we loaded from. - if (result.latestSummaryUpdated && result.wasSummaryTracked) { - this.wasGCRunInLatestSummary = this.configs.shouldRunGC; - } - - if (!result.latestSummaryUpdated || !this.configs.shouldRunGC) { + public async refreshLatestSummary(result: IRefreshSummaryResult): Promise { + if (!result.isSummaryTracked) { return; } - // If the summary was tracked by this client, it was the one that generated the summary in the first place. - // Update latest state from pending. - if (result.wasSummaryTracked) { - this.latestSummaryGCVersion = this.configs.gcVersionInEffect; - this.latestSummaryData = this.pendingSummaryData; - this.pendingSummaryData = undefined; - this.updatedDSCountSinceLastSummary = 0; + // If the summary is tracked, this client is the one that generated it. So, update wasGCRunInLatestSummary. + // Note that this has to be updated if GC did not run too. Otherwise, `gcStateNeedsReset` will always return + // true in scenarios where GC is currently disabled but enabled in the snapshot we loaded from. + this.wasGCRunInLatestSummary = this.configs.shouldRunGC; + + if (!this.configs.shouldRunGC) { return; } + + this.latestSummaryGCVersion = this.configs.gcVersionInEffect; + this.latestSummaryData = this.pendingSummaryData; + this.pendingSummaryData = undefined; + this.updatedDSCountSinceLastSummary = 0; + return; } /** diff --git a/packages/runtime/container-runtime/src/summary/index.ts b/packages/runtime/container-runtime/src/summary/index.ts index 872080c2111b..07029478127b 100644 --- a/packages/runtime/container-runtime/src/summary/index.ts +++ b/packages/runtime/container-runtime/src/summary/index.ts @@ -28,10 +28,9 @@ export { SummarizeHeuristicData, SummarizeHeuristicRunner } from "./summarizerHe export { createRootSummarizerNode, createRootSummarizerNodeWithGC, - IFetchSnapshotResult, + IRefreshSummaryResult, IRootSummarizerNode, IRootSummarizerNodeWithGC, - RefreshSummaryResult, } from "./summarizerNode"; export { IConnectableRuntime, diff --git a/packages/runtime/container-runtime/src/summary/summarizerNode/index.ts b/packages/runtime/container-runtime/src/summary/summarizerNode/index.ts index d1179b9ea808..c5edd913cb21 100644 --- a/packages/runtime/container-runtime/src/summary/summarizerNode/index.ts +++ b/packages/runtime/container-runtime/src/summary/summarizerNode/index.ts @@ -4,9 +4,8 @@ */ export { - IFetchSnapshotResult, + IRefreshSummaryResult, ISummarizerNodeRootContract, - RefreshSummaryResult, ValidateSummaryResult, } from "./summarizerNodeUtils"; export { IRootSummarizerNode, createRootSummarizerNode } from "./summarizerNode"; diff --git a/packages/runtime/container-runtime/src/summary/summarizerNode/summarizerNode.ts b/packages/runtime/container-runtime/src/summary/summarizerNode/summarizerNode.ts index a9877f61346a..38b2264c73b1 100644 --- a/packages/runtime/container-runtime/src/summary/summarizerNode/summarizerNode.ts +++ b/packages/runtime/container-runtime/src/summary/summarizerNode/summarizerNode.ts @@ -35,10 +35,10 @@ import { EscapedPath, ICreateChildDetails, IInitialSummary, + IRefreshSummaryResult, ISummarizerNodeRootContract, parseSummaryForSubtrees, parseSummaryTreeForSubtrees, - RefreshSummaryResult, SummaryNode, ValidateSummaryResult, } from "./summarizerNodeUtils"; @@ -365,27 +365,21 @@ export class SummarizerNode implements IRootSummarizerNode { /** * 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 (e.g., loaded from a service summary), - * we skip the update. If the current summary is behind, then we do not refresh. + * 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. * - * @returns A RefreshSummaryResult type which returns information based on the following three scenarios: - * - * 1. The latest summary was not updated. - * - * 2. The latest summary was updated and the summary corresponding to the params was being tracked. - * - * 3. The latest summary was updated but the summary corresponding to the params was not tracked. + * @returns true if the summary is tracked by this node, false otherwise. */ public async refreshLatestSummary( - proposalHandle: string | undefined, + proposalHandle: string, summaryRefSeq: number, - ): Promise { + ): Promise { const eventProps: { proposalHandle: string | undefined; summaryRefSeq: number; referenceSequenceNumber: number; - latestSummaryUpdated?: boolean; - wasSummaryTracked?: boolean; + isSummaryTracked?: boolean; + pendingSummaryFound?: boolean; } = { proposalHandle, summaryRefSeq, @@ -406,48 +400,22 @@ export class SummarizerNode implements IRootSummarizerNode { }); } - if (proposalHandle !== undefined) { - const maybeSummaryNode = this.pendingSummaries.get(proposalHandle); - - if (maybeSummaryNode !== undefined) { - this.refreshLatestSummaryFromPending( - proposalHandle, - maybeSummaryNode.referenceSequenceNumber, - ); - eventProps.wasSummaryTracked = true; - eventProps.latestSummaryUpdated = true; - event.end(eventProps); - return { - latestSummaryUpdated: true, - wasSummaryTracked: true, - summaryRefSeq, - }; - } + let isSummaryTracked = false; + let isSummaryNewer = false; - const props = { - summaryRefSeq, - pendingSize: this.pendingSummaries.size ?? undefined, - }; - this.logger.sendTelemetryEvent({ - eventName: "PendingSummaryNotFound", - proposalHandle, - referenceSequenceNumber: this.referenceSequenceNumber, - details: JSON.stringify(props), - }); + if (summaryRefSeq > this.referenceSequenceNumber) { + isSummaryNewer = true; } - - // If the summary for which refresh is called is older than the latest tracked summary, ignore it. - if (this.referenceSequenceNumber >= summaryRefSeq) { - eventProps.latestSummaryUpdated = false; - event.end(eventProps); - return { latestSummaryUpdated: false }; + const maybeSummaryNode = this.pendingSummaries.get(proposalHandle); + if (maybeSummaryNode !== undefined) { + this.refreshLatestSummaryFromPending( + proposalHandle, + maybeSummaryNode.referenceSequenceNumber, + ); + isSummaryTracked = true; } - - // Note that we did not track this summary, but that the latest summary was updated. - eventProps.latestSummaryUpdated = true; - eventProps.wasSummaryTracked = false; - event.end(eventProps); - return { latestSummaryUpdated: true, wasSummaryTracked: false }; + event.end({ ...eventProps, isSummaryNewer, pendingSummaryFound: isSummaryTracked }); + return { isSummaryTracked, isSummaryNewer }; }, { start: true, end: true, cancel: "error" }, ); diff --git a/packages/runtime/container-runtime/src/summary/summarizerNode/summarizerNodeUtils.ts b/packages/runtime/container-runtime/src/summary/summarizerNode/summarizerNodeUtils.ts index 99be77de4cad..52cd627f6f76 100644 --- a/packages/runtime/container-runtime/src/summary/summarizerNode/summarizerNodeUtils.ts +++ b/packages/runtime/container-runtime/src/summary/summarizerNode/summarizerNodeUtils.ts @@ -7,36 +7,11 @@ import { ITelemetryLoggerExt, TelemetryDataTag } from "@fluidframework/telemetry import { ISnapshotTree, ISummaryTree, SummaryObject } from "@fluidframework/protocol-definitions"; import { channelsTreeName, ISummaryTreeWithStats } from "@fluidframework/runtime-definitions"; -/** - * Return type of refreshSummaryAck function. There can be three different scenarios based on the passed params: - * - * 1. The latest summary was not updated. - * - * 2. The latest summary was updated and the summary corresponding to the params was tracked by this client. - * - * 3. The latest summary was updated but the summary corresponding to the params was not tracked. The client should - * close - */ -export type RefreshSummaryResult = - | { - latestSummaryUpdated: false; - } - | { - latestSummaryUpdated: true; - wasSummaryTracked: true; - summaryRefSeq: number; - } - | { - latestSummaryUpdated: true; - wasSummaryTracked: false; - }; - -/** - * Result of snapshot fetch during refreshing latest summary state. - */ -export interface IFetchSnapshotResult { - snapshotTree: ISnapshotTree; - snapshotRefSeq: number; +export interface IRefreshSummaryResult { + /** Tells whether this summary is tracked by this client. */ + isSummaryTracked: boolean; + /** Tells whether this summary is newer than the latest one tracked by this client. */ + isSummaryNewer: boolean; } /** @@ -67,9 +42,9 @@ export interface ISummarizerNodeRootContract { completeSummary(proposalHandle: string, validate: boolean): void; clearSummary(): void; refreshLatestSummary( - proposalHandle: string | undefined, + proposalHandle: string, summaryRefSeq: number, - ): Promise; + ): Promise; } /** Path for nodes in a tree with escaped special characters */ diff --git a/packages/runtime/container-runtime/src/test/gc/garbageCollection.spec.ts b/packages/runtime/container-runtime/src/test/gc/garbageCollection.spec.ts index 704c399ab4d8..ae2d20648826 100644 --- a/packages/runtime/container-runtime/src/test/gc/garbageCollection.spec.ts +++ b/packages/runtime/container-runtime/src/test/gc/garbageCollection.spec.ts @@ -53,7 +53,6 @@ import { dataStoreAttributesBlobName, IContainerRuntimeMetadata, metadataBlobName, - RefreshSummaryResult, } from "../../summary"; import { pkgVersion } from "../../packageVersion"; import { configProvider } from "./gcUnitTestHelpers"; @@ -1098,12 +1097,10 @@ describe("Garbage Collection Tests", () => { "Deleted nodes state should be a handle", ); - const refreshSummaryResult: RefreshSummaryResult = { - latestSummaryUpdated: true, - wasSummaryTracked: true, - summaryRefSeq: 0, - }; - await garbageCollector.refreshLatestSummary(refreshSummaryResult); + await garbageCollector.refreshLatestSummary({ + isSummaryTracked: true, + isSummaryNewer: true, + }); // Run GC and summarize again. The whole GC summary should now be a summary handle. await garbageCollector.collectGarbage({}); @@ -1698,11 +1695,9 @@ describe("Garbage Collection Tests", () => { checkGCSummaryType(tree1, SummaryType.Tree, "first"); await garbageCollector.refreshLatestSummary({ - wasSummaryTracked: true, - latestSummaryUpdated: true, - summaryRefSeq: 0, + isSummaryTracked: true, + isSummaryNewer: true, }); - await garbageCollector.collectGarbage({}); const tree2 = garbageCollector.summarize(fullTree, trackState); diff --git a/packages/runtime/container-runtime/src/test/gc/gcSummaryStateTracker.spec.ts b/packages/runtime/container-runtime/src/test/gc/gcSummaryStateTracker.spec.ts index c17dc5b77b04..d9b5461882cc 100644 --- a/packages/runtime/container-runtime/src/test/gc/gcSummaryStateTracker.spec.ts +++ b/packages/runtime/container-runtime/src/test/gc/gcSummaryStateTracker.spec.ts @@ -14,7 +14,6 @@ import { IGarbageCollectionState, IGCStats, } from "../../gc"; -import { RefreshSummaryResult } from "../../summary"; type GCSummaryStateTrackerWithPrivates = Omit & { latestSummaryGCVersion: GCVersion; @@ -41,12 +40,7 @@ describe("GCSummaryStateTracker tests", () => { ); // After the first summary succeeds (refreshLatestSummary called), the state should not need reset. - const refreshSummaryResult: RefreshSummaryResult = { - latestSummaryUpdated: true, - wasSummaryTracked: true, - summaryRefSeq: 0, - }; - await tracker.refreshLatestSummary(refreshSummaryResult); + await tracker.refreshLatestSummary({ isSummaryTracked: true, isSummaryNewer: true }); assert.equal( tracker.doesSummaryStateNeedReset, @@ -94,12 +88,7 @@ describe("GCSummaryStateTracker tests", () => { ); // After the first summary succeeds (refreshLatestSummary called), the state should not need reset. - const refreshSummaryResult: RefreshSummaryResult = { - latestSummaryUpdated: true, - wasSummaryTracked: true, - summaryRefSeq: 0, - }; - await tracker.refreshLatestSummary(refreshSummaryResult); + await tracker.refreshLatestSummary({ isSummaryTracked: true, isSummaryNewer: true }); assert.equal( tracker.doesSummaryStateNeedReset, false, @@ -135,12 +124,7 @@ describe("GCSummaryStateTracker tests", () => { assert.equal(tracker.doesGCStateNeedReset, true, "Should need reset"); // After the first summary succeeds (refreshLatestSummary called), the state should not need reset. - const refreshSummaryResult: RefreshSummaryResult = { - latestSummaryUpdated: true, - wasSummaryTracked: true, - summaryRefSeq: 0, - }; - await tracker.refreshLatestSummary(refreshSummaryResult); + await tracker.refreshLatestSummary({ isSummaryTracked: true, isSummaryNewer: true }); assert.equal( tracker.doesGCStateNeedReset, false, @@ -161,12 +145,7 @@ describe("GCSummaryStateTracker tests", () => { assert.equal(tracker.doesGCStateNeedReset, true, "Should need reset"); // After the first summary succeeds (refreshLatestSummary called), the state should not need reset. - const refreshSummaryResult: RefreshSummaryResult = { - latestSummaryUpdated: true, - wasSummaryTracked: true, - summaryRefSeq: 0, - }; - await tracker.refreshLatestSummary(refreshSummaryResult); + await tracker.refreshLatestSummary({ isSummaryTracked: true, isSummaryNewer: true }); assert.equal( tracker.doesGCStateNeedReset, @@ -384,12 +363,11 @@ describe("GCSummaryStateTracker tests", () => { new Set(), [], ); - const refreshSummaryResult: RefreshSummaryResult = { - latestSummaryUpdated: true, - wasSummaryTracked: true, - summaryRefSeq: 0, - }; - await summaryStateTracker.refreshLatestSummary(refreshSummaryResult); + + await summaryStateTracker.refreshLatestSummary({ + isSummaryTracked: true, + isSummaryNewer: true, + }); assert.strictEqual( summaryStateTracker.updatedDSCountSinceLastSummary, 0, diff --git a/packages/runtime/container-runtime/src/test/summarizerNode.spec.ts b/packages/runtime/container-runtime/src/test/summarizerNode.spec.ts index 0dfc28e0f328..e8604ab0c6dc 100644 --- a/packages/runtime/container-runtime/src/test/summarizerNode.spec.ts +++ b/packages/runtime/container-runtime/src/test/summarizerNode.spec.ts @@ -416,17 +416,13 @@ describe("Runtime", () => { }); describe("Refresh Latest Summary", () => { - it("Should refresh from tree when no proposal handle provided", async () => { - createRoot(); - const result = await rootNode.refreshLatestSummary(undefined, summaryRefSeq); - assert(result.latestSummaryUpdated === true, "should update"); - assert(result.wasSummaryTracked === false, "should not be tracked"); - }); - it("Should not refresh latest if already passed ref seq number", async () => { createRoot({ refSeq: summaryRefSeq }); - const result = await rootNode.refreshLatestSummary(undefined, summaryRefSeq); - assert(result.latestSummaryUpdated === false, "we already got this summary"); + const result = await rootNode.refreshLatestSummary( + "test-handle", + summaryRefSeq, + ); + assert(!result.isSummaryTracked, "we already got this summary"); }); it("Should refresh from pending", async () => { @@ -441,8 +437,8 @@ describe("Runtime", () => { proposalHandle, summaryRefSeq, ); - assert(result.latestSummaryUpdated === true, "should update"); - assert(result.wasSummaryTracked === true, "should be tracked"); + assert(result.isSummaryTracked, "should be tracked"); + assert(result.isSummaryNewer === true, "should be newer"); }); it("should fail refresh when summary is in progress", async () => { diff --git a/packages/runtime/container-runtime/src/test/summarizerNodeWithGc.spec.ts b/packages/runtime/container-runtime/src/test/summarizerNodeWithGc.spec.ts index e76492e0353b..dcaa7910f046 100644 --- a/packages/runtime/container-runtime/src/test/summarizerNodeWithGc.spec.ts +++ b/packages/runtime/container-runtime/src/test/summarizerNodeWithGc.spec.ts @@ -415,8 +415,8 @@ describe("SummarizerNodeWithGC Tests", () => { rootNode.completeSummary("test-handle1", true /* validateSummary */); let result = await rootNode.refreshLatestSummary("test-handle1", summaryRefSeq); - assert(result.latestSummaryUpdated === true, "should update"); - assert(result.wasSummaryTracked === true, "should be tracked"); + assert(result.isSummaryTracked, "should be tracked"); + assert(result.isSummaryNewer === true, "should be newer"); rootNode.startSummary(summaryRefSeq++, logger); rootNode.updateUsedRoutes([`/`, `/${ids[1]}`, `/${ids[1]}/${ids[2]}`]); @@ -430,8 +430,8 @@ describe("SummarizerNodeWithGC Tests", () => { createLeaf({ type: CreateSummarizerNodeSource.Local }); result = await rootNode.refreshLatestSummary("test-handle2", summaryRefSeq); - assert(result.latestSummaryUpdated === true, "should update"); - assert(result.wasSummaryTracked === true, "should be tracked"); + assert(result.isSummaryTracked, "should be tracked"); + assert(result.isSummaryNewer === true, "should be newer"); const leafNodePath = `${ids[0]}/${ids[1]}/${ids[2]}`; const leafNodeLatestSummary = (leafNode as SummarizerNodeWithGC).latestSummary; assert.strictEqual( @@ -453,8 +453,8 @@ describe("SummarizerNodeWithGC Tests", () => { rootNode.completeSummary("test-handle1", true /* validateSummary */); let result = await rootNode.refreshLatestSummary("test-handle1", summaryRefSeq); - assert(result.latestSummaryUpdated === true, "should update"); - assert(result.wasSummaryTracked === true, "should be tracked"); + assert(result.isSummaryTracked, "should be tracked"); + assert(result.isSummaryNewer === true, "should be newer"); rootNode.startSummary(summaryRefSeq++, logger); rootNode.updateUsedRoutes([""]); @@ -468,8 +468,8 @@ describe("SummarizerNodeWithGC Tests", () => { createLeaf({ type: CreateSummarizerNodeSource.Local }); result = await rootNode.refreshLatestSummary("test-handle2", summaryRefSeq); - assert(result.latestSummaryUpdated === true, "should update"); - assert(result.wasSummaryTracked === true, "should be tracked"); + assert(result.isSummaryTracked, "should be tracked"); + assert(result.isSummaryNewer === true, "should be newer"); const leafNodePath = `${ids[0]}/${ids[1]}/${ids[2]}`; const leafNodeLatestSummary = (leafNode as SummarizerNodeWithGC).latestSummary; assert.strictEqual(