Skip to content

Fix flaky TestPerCursorReads via atomic meta updates#11

Merged
schovi merged 1 commit intomainfrom
fix/flaky-cursor-test
Feb 25, 2026
Merged

Fix flaky TestPerCursorReads via atomic meta updates#11
schovi merged 1 commit intomainfrom
fix/flaky-cursor-test

Conversation

@schovi
Copy link
Owner

@schovi schovi commented Feb 25, 2026

Bug

TestPerCursorReads fails intermittently on CI (Linux) because concurrent meta update paths can overwrite each other's changes. When captureOutput cleanup saves session state, it replaces the entire meta object, clobbering cursor positions that handleRead just wrote. The next read then starts from position 0 and returns duplicate content.

Solution

An UpdateMeta method on the OutputStorage interface performs atomic read-modify-write under a single lock. Each call site only mutates the fields it owns (cursors, state, dimensions), so concurrent updates no longer overwrite unrelated fields.

Changes

Storage interface (storage.go, storage_memory.go, storage_file.go):

  • UpdateMeta(session, func(meta)) added to interface and both implementations
  • MemoryStorage mutates the stored meta in-place under write lock
  • FileStorage loads, mutates, and saves back under write lock

Server (server.go):

  • captureOutput cleanup, handleStop: use UpdateMeta for state transitions
  • handleRead, handleReadTUI: use UpdateMeta for cursor/position updates
  • handleResize: use UpdateMeta for dimension updates

Concurrent LoadMeta → modify → SaveMeta cycles could overwrite each
other's changes. When captureOutput cleanup saved session state, it
could clobber cursor positions written by handleRead, causing reads
to restart from position 0.

- Add UpdateMeta to OutputStorage interface (atomic read-modify-write under lock)
- Implement in MemoryStorage (mutates in-place under lock) and FileStorage (load-mutate-save under lock)
- Replace all LoadMeta/SaveMeta pairs in server.go with UpdateMeta calls
- Affects: captureOutput cleanup, handleRead, handleReadTUI, handleStop, handleResize
@schovi schovi marked this pull request as ready for review February 25, 2026 20:21
@schovi schovi merged commit 1e7f955 into main Feb 25, 2026
1 check passed
@schovi schovi deleted the fix/flaky-cursor-test branch February 25, 2026 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant