Read on in a thread from where reading is, not from its root #255

Merged
littlefox merged 4 commits from issue-251-thread-walk into main 2026-10-22 01:50:50 +00:00
Owner

Closes #251
Closes #259

In threads mode, every step listed the whole thread from its root (one get-text-stat per round trip, up to 2 000) and then looked for the first unread text. Now ReadState::thread_at remembers the text last read; the next unread is looked for after it (below, next siblings, ancestors' next siblings), and only if nothing is unread there, from the root. Both stop at the first unread text, and a post's replies are fetched together. thread_root no longer stops 64 steps up.

Measured with tools/perf.sh (#225, merged in here for that), 300 steps along the 1 500-long chain, 30 ms each way:

baseline after
slowest step 13 822 ms 127 ms
server calls 3 448 901 (−74 %)
step p50 115 ms 105 ms

Also #259: commands.spec's skip-tree test turns read-by-seen off (a slow runner read the comment by seeing it before the skip).

Verified: new devserver test long_chain_reading (121-text chain, at most 12 calls a step; the old code took 126 in one step, checked); all 15 devserver tests incl. thread_reading, reading_order, related_first and the mute tests pass; full e2e suite on three profiles 326 passed, 1 flaky (mute.spec on iPhone, a lost click, noted on #229); lint.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8

Closes #251 Closes #259 In threads mode, every step listed the whole thread from its root (one `get-text-stat` per round trip, up to 2 000) and then looked for the first unread text. Now `ReadState::thread_at` remembers the text last read; the next unread is looked for after it (below, next siblings, ancestors' next siblings), and only if nothing is unread there, from the root. Both stop at the first unread text, and a post's replies are fetched together. `thread_root` no longer stops 64 steps up. Measured with `tools/perf.sh` (#225, merged in here for that), 300 steps along the 1 500-long chain, 30 ms each way: | | baseline | after | |---|---|---| | slowest step | 13 822 ms | 127 ms | | server calls | 3 448 | 901 (−74 %) | | step p50 | 115 ms | 105 ms | Also #259: commands.spec's skip-tree test turns read-by-seen off (a slow runner read the comment by seeing it before the skip). Verified: new devserver test `long_chain_reading` (121-text chain, at most 12 calls a step; the old code took 126 in one step, checked); all 15 devserver tests incl. `thread_reading`, `reading_order`, `related_first` and the mute tests pass; full e2e suite on three profiles 326 passed, 1 flaky (mute.spec on iPhone, a lost click, noted on #229); lint. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
Measure first: a big meeting, a perf spec and a desktop memory run
Some checks failed
ci / e2e (push) Has started running
packaging / fedora (pull_request) Has started running
ci / check (push) Successful in 10m3s
packaging / arch (pull_request) Successful in 14m58s
ci / desktop (push) Successful in 19m39s
packaging / nix (pull_request) Successful in 22m28s
packaging / debian (pull_request) Successful in 26m4s
packaging / release (pull_request) Has been cancelled
c5abe1fe63
0.6 is about performance (D-057), and every fix should come with a
before/after number. tools/perf.sh seeds a big meeting (NEOKOM_SEED_PERF:
~2 800 texts, a 1 500-long chain, 300 more channels, 2 500 letters) on a
lyskomd kept in memory, puts 30 ms each way between relay and server,
and runs e2e/perf/perf.spec.ts in Chromium: memory (JS heap and the
app's wasm), DOM nodes, main-thread time, long tasks, frames while
scrolling, step times and server calls. tools/desktop-perf.sh measures
the desktop app's RSS and idle CPU. tools/perf-table.py compares runs.

The app exposes its wasm memory and the session's call count to the page
for this; Chromium shows no WebSocket frames sent from wasm.

Refs #225

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
In threads mode, every step listed the whole thread from its root, one
text stat per round trip, and then looked for the first unread text. In
a 1 500-long chain the first step made ~1 500 sequential calls (12 s and
more over a real network). Now the engine keeps the text last read in the
thread and looks after it: below it, then its next siblings, then its
ancestors' next siblings; only if nothing is unread there, from the root.
Both stop at the first unread text and fetch a post's replies together.
thread_root no longer stops 64 steps up.

The devserver test long_chain_reading reads a 121-text chain and allows
at most 12 calls a step; the old code took 126 in one step.

Closes #251

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
Perf: a scenario for reading cards by scrolling past them
All checks were successful
ci / check (push) Successful in 11m50s
packaging / arch (pull_request) Successful in 16m51s
ci / desktop (push) Successful in 20m13s
packaging / debian (pull_request) Successful in 25m40s
ci / e2e (push) Successful in 34m34s
packaging / fedora (pull_request) Successful in 39m40s
packaging / nix (pull_request) Successful in 39m13s
packaging / release (pull_request) Has been skipped
91bc19544c
Reading with space marks few cards by being seen, the case #228 is
about. This scrolls slowly through a post's 120 unread replies.

Refs #225

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
Merge remote-tracking branch 'origin/issue-225-measure' into issue-251-thread-walk
Some checks failed
ci / check (push) Successful in 11m29s
packaging / arch (pull_request) Successful in 18m8s
ci / desktop (push) Successful in 19m58s
packaging / debian (pull_request) Successful in 28m32s
packaging / nix (pull_request) Successful in 31m9s
packaging / fedora (pull_request) Successful in 33m44s
packaging / release (pull_request) Has been skipped
ci / e2e (push) Failing after 35m9s
f61aa2fffd
On a slow runner the comment was read by being seen before the skip.

Refs #259

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
Merge remote-tracking branch 'origin/main' into issue-251-thread-walk
All checks were successful
packaging / debian (pull_request) Successful in 28m25s
packaging / nix (pull_request) Successful in 28m22s
ci / e2e (push) Successful in 38m29s
packaging / fedora (pull_request) Successful in 39m39s
packaging / release (pull_request) Has been skipped
ci / check (push) Successful in 13m0s
packaging / arch (pull_request) Successful in 17m10s
ci / desktop (push) Successful in 23m50s
f4d9cdcb49
littlefox referenced this pull request from a commit 2026-10-22 14:11:05 +00:00
Sign in to join this conversation.
No description provided.