From 8542be311fae7d03060422149dcc97fd7d45eaa5 Mon Sep 17 00:00:00 2001 From: Daniel Madrid <105010181+dannimad@users.noreply.github.com> Date: Wed, 1 Oct 2025 11:33:28 -0700 Subject: [PATCH 1/6] Do not refresh the snapshot on frozen containers. --- .../loader/container-loader/src/container.ts | 5 ++ .../src/serializedStateManager.ts | 20 ++++--- .../src/test/serializedStateManager.spec.ts | 55 +++++++++++++++++++ 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/packages/loader/container-loader/src/container.ts b/packages/loader/container-loader/src/container.ts index 1f9c4465e1fc..397afc521582 100644 --- a/packages/loader/container-loader/src/container.ts +++ b/packages/loader/container-loader/src/container.ts @@ -1021,12 +1021,17 @@ export class Container (this.isInteractiveClient && this.mc.config.getBoolean("Fluid.Container.enableOfflineLoad")) ?? options.enableOfflineLoad === true; + let storageOnly = false; + if (this.readOnlyInfo.readonly === true) { + storageOnly = this.readOnlyInfo.storageOnly; + } this.serializedStateManager = new SerializedStateManager( pendingLocalState, this.subLogger, this.storageAdapter, offlineLoadEnabled, this, + storageOnly, () => this._deltaManager.connectionManager.shouldJoinWrite(), () => this.supportGetSnapshotApi(), this.mc.config.getNumber("Fluid.Container.snapshotRefreshTimeoutMs"), diff --git a/packages/loader/container-loader/src/serializedStateManager.ts b/packages/loader/container-loader/src/serializedStateManager.ts index 7af0bee31042..8ee795fa49f4 100644 --- a/packages/loader/container-loader/src/serializedStateManager.ts +++ b/packages/loader/container-loader/src/serializedStateManager.ts @@ -149,7 +149,7 @@ export class SerializedStateManager { private latestSnapshot: ISnapshotInfo | undefined; private _refreshSnapshotP: Promise | undefined; private readonly lastSavedOpSequenceNumber: number = 0; - private readonly refreshTimer: Timer; + private readonly refreshTimer: Timer | undefined; private readonly snapshotRefreshTimeoutMs: number = 60 * 60 * 24 * 1000; /** @@ -166,6 +166,7 @@ export class SerializedStateManager { private readonly storageAdapter: ISerializedStateManagerDocumentStorageService, private readonly _offlineLoadEnabled: boolean, containerEvent: IEventProvider, + private readonly storageOnly: boolean, private readonly containerDirty: () => boolean, private readonly supportGetSnapshotApi: () => boolean, snapshotRefreshTimeoutMs?: number, @@ -176,9 +177,9 @@ export class SerializedStateManager { }); this.snapshotRefreshTimeoutMs = snapshotRefreshTimeoutMs ?? this.snapshotRefreshTimeoutMs; - this.refreshTimer = new Timer(this.snapshotRefreshTimeoutMs, () => - this.tryRefreshSnapshot(), - ); + this.refreshTimer = this.storageOnly + ? undefined + : new Timer(this.snapshotRefreshTimeoutMs, () => this.tryRefreshSnapshot()); // special case handle. Obtaining the last saved op seq num to avoid // refreshing the snapshot before we have processed it. It could cause // a subsequent stashing to have a newer snapshot than allowed. @@ -244,7 +245,7 @@ export class SerializedStateManager { snapshotBlobs, snapshotSequenceNumber: attributes.sequenceNumber, }; - this.refreshTimer.start(); + this.refreshTimer?.start(); } return { baseSnapshot, version }; } else { @@ -276,7 +277,8 @@ export class SerializedStateManager { if ( this.mc.config.getBoolean("Fluid.Container.enableOfflineSnapshotRefresh") === true && this._refreshSnapshotP === undefined && - this.latestSnapshot === undefined + this.latestSnapshot === undefined && + !this.storageOnly ) { // Don't block on the refresh snapshot call - it is for the next time we serialize, not booting this incarnation this._refreshSnapshotP = this.refreshLatestSnapshot(this.supportGetSnapshotApi()); @@ -361,14 +363,14 @@ export class SerializedStateManager { stashedSnapshotSequenceNumber: this.snapshot?.snapshotSequenceNumber, }); this.latestSnapshot = undefined; - this.refreshTimer.restart(); + this.refreshTimer?.restart(); } else if (snapshotSequenceNumber <= lastProcessedOpSequenceNumber) { // Snapshot seq num is between the first and last processed op. // Remove the ops that are already part of the snapshot this.processedOps.splice(0, snapshotSequenceNumber - firstProcessedOpSequenceNumber + 1); this.snapshot = this.latestSnapshot; this.latestSnapshot = undefined; - this.refreshTimer.restart(); + this.refreshTimer?.restart(); this.mc.logger.sendTelemetryEvent({ eventName: "SnapshotRefreshed", snapshotSequenceNumber, @@ -410,7 +412,7 @@ export class SerializedStateManager { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access snapshotSequenceNumber: attributes.sequenceNumber as number, }; - this.refreshTimer.start(); + this.refreshTimer?.start(); } } diff --git a/packages/loader/container-loader/src/test/serializedStateManager.spec.ts b/packages/loader/container-loader/src/test/serializedStateManager.spec.ts index aef818dc276c..dead3f21f670 100644 --- a/packages/loader/container-loader/src/test/serializedStateManager.spec.ts +++ b/packages/loader/container-loader/src/test/serializedStateManager.spec.ts @@ -191,6 +191,7 @@ describe("serializedStateManager", () => { storageAdapter, false, eventEmitter, + false, () => false, () => false, ); @@ -217,6 +218,7 @@ describe("serializedStateManager", () => { }), true, eventEmitter, + false, () => false, () => false, ); @@ -246,6 +248,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, () => false, () => false, ); @@ -269,6 +272,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, () => false, () => false, ); @@ -304,6 +308,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, () => false, () => false, ); @@ -355,6 +360,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, () => false, () => false, ); @@ -418,6 +424,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, () => false, () => false, ); @@ -459,6 +466,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, ); @@ -519,6 +527,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, ); @@ -571,6 +580,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, ); @@ -634,6 +644,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, () => isDirty, () => false, ); @@ -666,6 +677,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, ); @@ -737,6 +749,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, ); @@ -787,6 +800,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, () => isDirty, () => false, ); @@ -822,6 +836,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, () => isDirty, () => false, ); @@ -873,6 +888,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, ); @@ -974,6 +990,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1043,6 +1060,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1112,6 +1130,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1176,6 +1195,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1246,6 +1266,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1313,6 +1334,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1363,6 +1385,39 @@ describe("serializedStateManager", () => { lastProcessedOpSequenceNumber, ); }); + + it(`no snapshot refresh on storage only mode. isDirty: ${isDirty}`, async () => { + const storageAdapter = new MockStorageAdapter(); + const saved = false; + const isDirtyF = (): boolean => (saved ? false : isDirty); + const serializedStateManager = new SerializedStateManager( + undefined, + enableOfflineSnapshotRefresh(logger), + storageAdapter, + true, + eventEmitter, + true, + isDirtyF, + () => false, + snapshotRefreshTimeoutMs, + ); + + await serializedStateManager.fetchSnapshot(undefined); + const lastProcessedOpSequenceNumber = 20; + let seq = 1; + while (seq <= lastProcessedOpSequenceNumber) { + serializedStateManager.addProcessedOp(generateSavedOp(seq++)); + } + const snapshotSequenceNumber = 11; // latest snapshot will be among processed ops + storageAdapter.uploadSummary(snapshotSequenceNumber); + // snapshot refresh promise is undefined before timeout + const snapshotRefreshP = serializedStateManager.refreshSnapshotP; + assert.strictEqual(snapshotRefreshP, undefined); + clock.tick(snapshotRefreshTimeoutMs); + // now it's a promise + const initialRefreshP = serializedStateManager.refreshSnapshotP; + assert.strictEqual(initialRefreshP, undefined, "no refresh expected"); + }); } }); }); From 058a938fdebbcd071048215c4787e1b7f5f7de4d Mon Sep 17 00:00:00 2001 From: Daniel Madrid <105010181+dannimad@users.noreply.github.com> Date: Wed, 1 Oct 2025 11:48:16 -0700 Subject: [PATCH 2/6] isStorageOnly getter --- .../loader/container-loader/src/container.ts | 10 +++- .../src/serializedStateManager.ts | 6 +-- .../src/test/serializedStateManager.spec.ts | 46 +++++++++---------- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/packages/loader/container-loader/src/container.ts b/packages/loader/container-loader/src/container.ts index 397afc521582..68a5234e16f0 100644 --- a/packages/loader/container-loader/src/container.ts +++ b/packages/loader/container-loader/src/container.ts @@ -744,6 +744,14 @@ export class Container return this._dirtyContainer; } + private get isStorageOnly(): boolean { + let storageOnly = false; + if (this.readOnlyInfo.readonly === true) { + storageOnly = this.readOnlyInfo.storageOnly; + } + return storageOnly; + } + /** * {@inheritDoc @fluidframework/container-definitions#IContainer.entryPoint} */ @@ -1031,7 +1039,7 @@ export class Container this.storageAdapter, offlineLoadEnabled, this, - storageOnly, + () => this.isStorageOnly, () => this._deltaManager.connectionManager.shouldJoinWrite(), () => this.supportGetSnapshotApi(), this.mc.config.getNumber("Fluid.Container.snapshotRefreshTimeoutMs"), diff --git a/packages/loader/container-loader/src/serializedStateManager.ts b/packages/loader/container-loader/src/serializedStateManager.ts index 8ee795fa49f4..4e44470c0efe 100644 --- a/packages/loader/container-loader/src/serializedStateManager.ts +++ b/packages/loader/container-loader/src/serializedStateManager.ts @@ -166,7 +166,7 @@ export class SerializedStateManager { private readonly storageAdapter: ISerializedStateManagerDocumentStorageService, private readonly _offlineLoadEnabled: boolean, containerEvent: IEventProvider, - private readonly storageOnly: boolean, + private readonly storageOnly: () => boolean, private readonly containerDirty: () => boolean, private readonly supportGetSnapshotApi: () => boolean, snapshotRefreshTimeoutMs?: number, @@ -177,7 +177,7 @@ export class SerializedStateManager { }); this.snapshotRefreshTimeoutMs = snapshotRefreshTimeoutMs ?? this.snapshotRefreshTimeoutMs; - this.refreshTimer = this.storageOnly + this.refreshTimer = this.storageOnly() ? undefined : new Timer(this.snapshotRefreshTimeoutMs, () => this.tryRefreshSnapshot()); // special case handle. Obtaining the last saved op seq num to avoid @@ -278,7 +278,7 @@ export class SerializedStateManager { this.mc.config.getBoolean("Fluid.Container.enableOfflineSnapshotRefresh") === true && this._refreshSnapshotP === undefined && this.latestSnapshot === undefined && - !this.storageOnly + !this.storageOnly() ) { // Don't block on the refresh snapshot call - it is for the next time we serialize, not booting this incarnation this._refreshSnapshotP = this.refreshLatestSnapshot(this.supportGetSnapshotApi()); diff --git a/packages/loader/container-loader/src/test/serializedStateManager.spec.ts b/packages/loader/container-loader/src/test/serializedStateManager.spec.ts index dead3f21f670..70b2ed052c1f 100644 --- a/packages/loader/container-loader/src/test/serializedStateManager.spec.ts +++ b/packages/loader/container-loader/src/test/serializedStateManager.spec.ts @@ -191,7 +191,7 @@ describe("serializedStateManager", () => { storageAdapter, false, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -218,7 +218,7 @@ describe("serializedStateManager", () => { }), true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -248,7 +248,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -272,7 +272,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -308,7 +308,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -360,7 +360,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -424,7 +424,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -466,7 +466,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -527,7 +527,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -580,7 +580,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -644,7 +644,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => isDirty, () => false, ); @@ -677,7 +677,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -749,7 +749,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -800,7 +800,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => isDirty, () => false, ); @@ -836,7 +836,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => isDirty, () => false, ); @@ -888,7 +888,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -990,7 +990,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1060,7 +1060,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1130,7 +1130,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1195,7 +1195,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1266,7 +1266,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1334,7 +1334,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1396,7 +1396,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - true, + () => true, isDirtyF, () => false, snapshotRefreshTimeoutMs, From 49d0b36432560620d48abd274c84a2ce858a0148 Mon Sep 17 00:00:00 2001 From: Daniel Madrid <105010181+dannimad@users.noreply.github.com> Date: Wed, 1 Oct 2025 11:58:40 -0700 Subject: [PATCH 3/6] getter boolean --- .../src/serializedStateManager.ts | 6 +-- .../src/test/serializedStateManager.spec.ts | 46 +++++++++---------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/packages/loader/container-loader/src/serializedStateManager.ts b/packages/loader/container-loader/src/serializedStateManager.ts index 4e44470c0efe..8ee795fa49f4 100644 --- a/packages/loader/container-loader/src/serializedStateManager.ts +++ b/packages/loader/container-loader/src/serializedStateManager.ts @@ -166,7 +166,7 @@ export class SerializedStateManager { private readonly storageAdapter: ISerializedStateManagerDocumentStorageService, private readonly _offlineLoadEnabled: boolean, containerEvent: IEventProvider, - private readonly storageOnly: () => boolean, + private readonly storageOnly: boolean, private readonly containerDirty: () => boolean, private readonly supportGetSnapshotApi: () => boolean, snapshotRefreshTimeoutMs?: number, @@ -177,7 +177,7 @@ export class SerializedStateManager { }); this.snapshotRefreshTimeoutMs = snapshotRefreshTimeoutMs ?? this.snapshotRefreshTimeoutMs; - this.refreshTimer = this.storageOnly() + this.refreshTimer = this.storageOnly ? undefined : new Timer(this.snapshotRefreshTimeoutMs, () => this.tryRefreshSnapshot()); // special case handle. Obtaining the last saved op seq num to avoid @@ -278,7 +278,7 @@ export class SerializedStateManager { this.mc.config.getBoolean("Fluid.Container.enableOfflineSnapshotRefresh") === true && this._refreshSnapshotP === undefined && this.latestSnapshot === undefined && - !this.storageOnly() + !this.storageOnly ) { // Don't block on the refresh snapshot call - it is for the next time we serialize, not booting this incarnation this._refreshSnapshotP = this.refreshLatestSnapshot(this.supportGetSnapshotApi()); diff --git a/packages/loader/container-loader/src/test/serializedStateManager.spec.ts b/packages/loader/container-loader/src/test/serializedStateManager.spec.ts index 70b2ed052c1f..dead3f21f670 100644 --- a/packages/loader/container-loader/src/test/serializedStateManager.spec.ts +++ b/packages/loader/container-loader/src/test/serializedStateManager.spec.ts @@ -191,7 +191,7 @@ describe("serializedStateManager", () => { storageAdapter, false, eventEmitter, - () => false, + false, () => false, () => false, ); @@ -218,7 +218,7 @@ describe("serializedStateManager", () => { }), true, eventEmitter, - () => false, + false, () => false, () => false, ); @@ -248,7 +248,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, () => false, () => false, ); @@ -272,7 +272,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, () => false, () => false, ); @@ -308,7 +308,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, () => false, () => false, ); @@ -360,7 +360,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, () => false, () => false, ); @@ -424,7 +424,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, () => false, () => false, ); @@ -466,7 +466,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, ); @@ -527,7 +527,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, ); @@ -580,7 +580,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, ); @@ -644,7 +644,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, () => isDirty, () => false, ); @@ -677,7 +677,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, ); @@ -749,7 +749,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, ); @@ -800,7 +800,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, () => isDirty, () => false, ); @@ -836,7 +836,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, () => isDirty, () => false, ); @@ -888,7 +888,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, ); @@ -990,7 +990,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1060,7 +1060,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1130,7 +1130,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1195,7 +1195,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1266,7 +1266,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1334,7 +1334,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => false, + false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1396,7 +1396,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - () => true, + true, isDirtyF, () => false, snapshotRefreshTimeoutMs, From e2cf053181af88b42f613c31f03be2705aa889b5 Mon Sep 17 00:00:00 2001 From: Daniel Madrid <105010181+dannimad@users.noreply.github.com> Date: Wed, 1 Oct 2025 12:00:30 -0700 Subject: [PATCH 4/6] nit --- packages/loader/container-loader/src/container.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/loader/container-loader/src/container.ts b/packages/loader/container-loader/src/container.ts index 68a5234e16f0..460b0ab240de 100644 --- a/packages/loader/container-loader/src/container.ts +++ b/packages/loader/container-loader/src/container.ts @@ -1039,7 +1039,7 @@ export class Container this.storageAdapter, offlineLoadEnabled, this, - () => this.isStorageOnly, + this.isStorageOnly, () => this._deltaManager.connectionManager.shouldJoinWrite(), () => this.supportGetSnapshotApi(), this.mc.config.getNumber("Fluid.Container.snapshotRefreshTimeoutMs"), From 5b8c050eaecae1cd8eb53802474ea278263782c2 Mon Sep 17 00:00:00 2001 From: Daniel Madrid <105010181+dannimad@users.noreply.github.com> Date: Wed, 1 Oct 2025 12:02:15 -0700 Subject: [PATCH 5/6] nit --- packages/loader/container-loader/src/container.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/loader/container-loader/src/container.ts b/packages/loader/container-loader/src/container.ts index 460b0ab240de..ed095d43db3d 100644 --- a/packages/loader/container-loader/src/container.ts +++ b/packages/loader/container-loader/src/container.ts @@ -1029,10 +1029,6 @@ export class Container (this.isInteractiveClient && this.mc.config.getBoolean("Fluid.Container.enableOfflineLoad")) ?? options.enableOfflineLoad === true; - let storageOnly = false; - if (this.readOnlyInfo.readonly === true) { - storageOnly = this.readOnlyInfo.storageOnly; - } this.serializedStateManager = new SerializedStateManager( pendingLocalState, this.subLogger, From 779c7036d78571ee8ad207b7e4c8f6c9cc72e916 Mon Sep 17 00:00:00 2001 From: Daniel Madrid <105010181+dannimad@users.noreply.github.com> Date: Wed, 1 Oct 2025 12:16:43 -0700 Subject: [PATCH 6/6] back to function --- .../loader/container-loader/src/container.ts | 2 +- .../src/serializedStateManager.ts | 6 +-- .../src/test/serializedStateManager.spec.ts | 46 +++++++++---------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/packages/loader/container-loader/src/container.ts b/packages/loader/container-loader/src/container.ts index ed095d43db3d..865f14d57a2d 100644 --- a/packages/loader/container-loader/src/container.ts +++ b/packages/loader/container-loader/src/container.ts @@ -1035,7 +1035,7 @@ export class Container this.storageAdapter, offlineLoadEnabled, this, - this.isStorageOnly, + () => this.isStorageOnly, () => this._deltaManager.connectionManager.shouldJoinWrite(), () => this.supportGetSnapshotApi(), this.mc.config.getNumber("Fluid.Container.snapshotRefreshTimeoutMs"), diff --git a/packages/loader/container-loader/src/serializedStateManager.ts b/packages/loader/container-loader/src/serializedStateManager.ts index 8ee795fa49f4..4e44470c0efe 100644 --- a/packages/loader/container-loader/src/serializedStateManager.ts +++ b/packages/loader/container-loader/src/serializedStateManager.ts @@ -166,7 +166,7 @@ export class SerializedStateManager { private readonly storageAdapter: ISerializedStateManagerDocumentStorageService, private readonly _offlineLoadEnabled: boolean, containerEvent: IEventProvider, - private readonly storageOnly: boolean, + private readonly storageOnly: () => boolean, private readonly containerDirty: () => boolean, private readonly supportGetSnapshotApi: () => boolean, snapshotRefreshTimeoutMs?: number, @@ -177,7 +177,7 @@ export class SerializedStateManager { }); this.snapshotRefreshTimeoutMs = snapshotRefreshTimeoutMs ?? this.snapshotRefreshTimeoutMs; - this.refreshTimer = this.storageOnly + this.refreshTimer = this.storageOnly() ? undefined : new Timer(this.snapshotRefreshTimeoutMs, () => this.tryRefreshSnapshot()); // special case handle. Obtaining the last saved op seq num to avoid @@ -278,7 +278,7 @@ export class SerializedStateManager { this.mc.config.getBoolean("Fluid.Container.enableOfflineSnapshotRefresh") === true && this._refreshSnapshotP === undefined && this.latestSnapshot === undefined && - !this.storageOnly + !this.storageOnly() ) { // Don't block on the refresh snapshot call - it is for the next time we serialize, not booting this incarnation this._refreshSnapshotP = this.refreshLatestSnapshot(this.supportGetSnapshotApi()); diff --git a/packages/loader/container-loader/src/test/serializedStateManager.spec.ts b/packages/loader/container-loader/src/test/serializedStateManager.spec.ts index dead3f21f670..70b2ed052c1f 100644 --- a/packages/loader/container-loader/src/test/serializedStateManager.spec.ts +++ b/packages/loader/container-loader/src/test/serializedStateManager.spec.ts @@ -191,7 +191,7 @@ describe("serializedStateManager", () => { storageAdapter, false, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -218,7 +218,7 @@ describe("serializedStateManager", () => { }), true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -248,7 +248,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -272,7 +272,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -308,7 +308,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -360,7 +360,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -424,7 +424,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => false, () => false, ); @@ -466,7 +466,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -527,7 +527,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -580,7 +580,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -644,7 +644,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => isDirty, () => false, ); @@ -677,7 +677,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -749,7 +749,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -800,7 +800,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => isDirty, () => false, ); @@ -836,7 +836,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, () => isDirty, () => false, ); @@ -888,7 +888,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, ); @@ -990,7 +990,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1060,7 +1060,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1130,7 +1130,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1195,7 +1195,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1266,7 +1266,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1334,7 +1334,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - false, + () => false, isDirtyF, () => false, snapshotRefreshTimeoutMs, @@ -1396,7 +1396,7 @@ describe("serializedStateManager", () => { storageAdapter, true, eventEmitter, - true, + () => true, isDirtyF, () => false, snapshotRefreshTimeoutMs,