acpmux: an upload for a peer's chat waits for a reconnecting link instead of failing

Merged
TE
5d ago
+140-0

Leo, 2026-11-01, after pasting a 17 s mp4 into a chat on a lane VM: the first upload failed, the chip showed Retry, and "i had to retry to get it to load???".

The Mac's acpmux log from that moment shows peer_unreachable for that peer ("SSH connection refused", request not sent), with the VM at load ~85. acpmux forwards _acpmux/file_put* for a peer's chat and refused it at once while the link was reconnecting. The refusal marks the peer wanted, so the link came back within seconds, and that is why the Retry worked.

What changed

server/peer_forward.rs: a file upload for a chat on a peer whose link is down (file_put, file_put_begin, _chunk, _finish, _status) now wants the peer and waits up to 30 s for the link before it goes. The peer's next connect attempt comes within 1 s (peer_wanted.rs). The app gives each call 120 s. The wait listens to the peer's settled connect attempts (no polling) and ends when the client leaves. A link still down after 30 s is refused as before. Binary upload frames (server/upload_frames.rs) do not wait: a frame holds back every later message on the app's connection, and the upload's begin already waited.

Follow-ups: a peer removed or stopped during the wait refuses after the 30 s instead of at once; an upload that would be refused for its params waits first.

Companion web fix: the composer waits for an uploading file before sending, and retries a failed upload on its own (separate PR, lane/upload-first-send).

Red / green

testcommandbase (red)head (green)
a_file_sent_while_the_peers_link_reconnects_waits_for_it_and_landscmux-ci test -- cargo test -p acpmux --test file_put (from cmux-tui/)pendingpending

The test puts a relay in front of the peer and cuts it. The upload is sent while the link is down, and the relay comes back 1.5 s later. On base the reply is peer_unreachable; at the head the file lands on the peer.

Observed / Not run

  • Pending: the run above.
  • Not run: a live send to a lane VM in a DEV build.

risk: normal. Only upload calls for a peer's chat whose link is down change: they wait up to 30 s instead of failing at once.

Changelog

  • Fixed: a file sent to a chat on another machine while its link reconnects waits for the link and arrives, instead of failing until Retry.

Agent session: agent session

🤖 Generated with Claude Code


Summary by cubic

Fixes file uploads to a peer's chat failing immediately when that peer's link is reconnecting. A file sent while the link is down now waits up to 30 seconds for it to come back and lands, instead of needing a manual Retry.

  • file_put and its begin, chunk, finish, and status methods wait for the link; binary upload frames do not, since a frame would hold back every later message on the connection.
  • The wait ends when the client disconnects, and a link still down after 30 seconds is refused as before.
  • Adds a test that cuts a TCP relay in front of a peer and confirms the upload lands once the link returns.