Skip to content

Commit 6aaac7e

Browse files
anthony-murphy-agentanthony-murphyclaude
authored
fix(local-server-stress-tests): defer containerObjectMap registration during staging mode (#26257)
## Summary - Fix containerObjectMap registration during staging mode to prevent rollback issues - When a data store is created during staging mode and then discarded, the containerObjectMap.set() was rolled back, but the data store still existed locally - When the data store was later attached by storing its handle in a DDS, other clients couldn't find it ## Changes - Defer containerObjectMap registration during staging mode by adding to a pending list - Flush pending registrations when staging mode exits (both commit and discard) - This ensures registration ops are never part of the staged batch and can't be rolled back ## Test plan - [x] All 200 local-server-stress-tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: anthony-murphy-agent <[email protected]> Co-authored-by: anthony-murphy <[email protected]> Co-authored-by: Claude Opus 4.5 <[email protected]>
1 parent 6fd7a9c commit 6aaac7e

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

packages/test/local-server-stress-tests/src/stressDataObject.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,13 +289,33 @@ export class DefaultStressDataObject extends StressDataObject {
289289
)) as any as ISharedMap;
290290
}
291291

292-
public registerLocallyCreatedObject(obj: ContainerObjects): void {
292+
/**
293+
* Objects created during staging mode that need to be registered in containerObjectMap
294+
* after staging mode exits. We defer the write to avoid it being rolled back on discard.
295+
*/
296+
private readonly _pendingContainerObjectRegistrations: ContainerObjects[] = [];
297+
298+
/**
299+
* Registers an object to the containerObjectMap if not already present.
300+
*/
301+
private registerToContainerObjectMap(obj: ContainerObjects): void {
293302
if (obj.handle !== undefined) {
294303
const handle = toFluidHandleInternal(obj.handle);
295304
if (this.containerObjectMap.get(handle.absolutePath) === undefined) {
296305
this.containerObjectMap.set(handle.absolutePath, { tag: obj.tag, type: obj.type });
297306
}
298307
}
308+
}
309+
310+
public registerLocallyCreatedObject(obj: ContainerObjects): void {
311+
if (obj.handle !== undefined) {
312+
if (this.inStagingMode()) {
313+
// Defer registration until staging mode exits to avoid rollback on discard
314+
this._pendingContainerObjectRegistrations.push(obj);
315+
} else {
316+
this.registerToContainerObjectMap(obj);
317+
}
318+
}
299319
this._locallyCreatedObjects.push(obj);
300320
}
301321

@@ -325,6 +345,13 @@ export class DefaultStressDataObject extends StressDataObject {
325345
this.stageControls.discardChanges();
326346
}
327347
this.stageControls = undefined;
348+
349+
// Flush any pending containerObjectMap registrations that were deferred during staging mode.
350+
// This happens after staging mode exits so the writes won't be rolled back.
351+
for (const obj of this._pendingContainerObjectRegistrations) {
352+
this.registerToContainerObjectMap(obj);
353+
}
354+
this._pendingContainerObjectRegistrations.length = 0;
328355
}
329356
}
330357

0 commit comments

Comments
 (0)