Skip to content

Serialize chat index cursor updates - #205

Merged
nickjalbert merged 3 commits into
laude-institute:mainfrom
dajiaohuang:fix/serialize-chat-index-update
Oct 6, 2026
Merged

nickjalbert merged 3 commits into
laude-institute:mainfrom
dajiaohuang:fix/serialize-chat-index-update

Conversation

@dajiaohuang

@dajiaohuang dajiaohuang commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Two history readers can snapshot the same index offset before either obtains the lock. When the later reader eventually acquires the lock, it appends the range that the first reader already indexed, duplicating messages. Acquire the existing per-index lock before reading the offset or deciding to rebuild, and release it after the update.

Closes #204.

Validation: a new bounded regression runs two actual chat history processes against a temporary trajectory. A stat shim pauses the first reader at the offset boundary while the other reader completes; all indexing and filesystem writes use production code. The original version indexes message m2 twice; the fix indexes each message once, advances the cursor and releases the lock. The new regression and existing index-rebuild/history/sent scripts all pass on Ubuntu: 4 scripts, including 82 existing checks. git diff --check passes. Current-commit CI is pending; macOS and live identity execution were not tested locally.

@nickjalbert nickjalbert left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@nickjalbert
nickjalbert merged commit ebbf24d into laude-institute:main Oct 6, 2026
17 checks passed
nickjalbert added a commit that referenced this pull request Oct 6, 2026
…ed updates

A reader killed with SIGKILL while holding messages.jsonl.lock left the
index stuck until an operator reset it, and since #205 every history,
pending, or sent read takes the lock.

The holder now records its pid, pid namespace, and start time in
<lock>/owner. The next reader takes the lock over when that process is
gone. A running holder, or one in another pid namespace, keeps its lock.
A lock with no owner record is taken over after 60 seconds.

The offset record now ends with the sizes of the three index files after
the last completed update. Before indexing, each file is cut back to its
recorded size, so rows from a killed update are indexed once. The record
is written by rename, and a rebuild records its restart before emptying
the files. Old four-field records upgrade in passing with no rebuild.

index-reset --offline accepts a lock that holds only the owner record
and refuses when the recorded holder is still running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

Serialize chat index offset reads with updates

2 participants