Files
buzz/mobile/lib
Wes 66d5354586 fix(mobile): split channel history batches at the relay channel cap (#8342)
## Problem

The relay rejects any request that names more than 128 explicit channels
in aggregate (`MAX_EXPLICIT_CHANNEL_VALUES`,
`crates/buzz-relay/src/handlers/req.rs`). Mobile sent every active
channel in one batch:

- **Latest-message and unread catch-up batches** were rejected with `400
too many explicit channels` and fell back to websocket requests four at
a time. For 144 active channels that took about 5 s each.
- **The Huddle backing-channel query** (one filter with every
membership) was closed as `restricted: too many explicit channels` and
returned no results, so that visibility filter was effectively disabled.

On a first pairing with a large community, these serialized fallbacks
consumed most of the community switcher's 20 s landing budget. That's
one cause of "This community is taking longer to load."

## Change

- `_fetchChannelHistoryBatch` splits filters into requests whose
combined `#h` values stay within `kMaxExplicitChannelValues`, four at a
time. A deadline in any request still makes the whole batch unavailable.
Requests that fail for other reasons are collected, and one websocket
fallback runs over their filters after every request settles, so a batch
never has more than four relay requests in flight.
- `_fetchHuddleStarts` splits its parent channel IDs into REQs within
the same cap, also four at a time.

## Evidence

iPhone 18 Pro simulator (iOS 27, debug build) on a community with 411
memberships and 144 active channels, with temporary stage timing that is
not part of this PR. Eight cold launches before and after:

| Median since app start | Before | After |
| --- | --- | --- |
| Channel rows painted | 8.3 s | 4.0 s |
| Unread catch-up complete | 14.4 s | 5.1 s |

The Huddle query now returns successfully instead of being closed.

## Tests

The fake relay session now rejects over-cap requests the way the relay
does, and answers Huddle starts only for the requested parent channels.

- `channel batches stay within the relay explicit-channel cap` (129
channels): every history batch and Huddle filter is within the cap, and
a Huddle backing channel in the over-cap tail stays hidden. Fails when
either split is removed.
- `channel batches keep four relay requests in flight` (513 channels,
query bridge down): peak in-flight requests are 4 for latest-message,
unread catch-up and Huddle, and the fallback covers every channel. The
previous version of this branch measured 16, 16 and 5.
- Full mobile suite via the pre-push hook (`just mobile-check && just
mobile-test`): passes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Carl <32a2e2c9d428ee08902cab75d956da2c1d235a22d4766b0dd4138bf6e2e5db1d@buzz.block.builderlab.xyz>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 18:18:56 -06:00
..