Cluster: the inbound connection setup sends the registrations snapshot within heartbeat_interval
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- rust
- Domain
- distributed-systems
Research direction
Read tellus/src/cluster/peer.rs around run_accepted (357–486), then compare the dialing-side snapshot flow around 1005–1010 and 1094. Check how the setup timeout encloses the registrations snapshot and where inbound readers are started. Done means registrations can be sent without the heartbeat timeout dropping the connection, and the timeout failure is logged at warning level with the peer.
Written by the indexing model from the issue text.
Description
run_accepted (peer.rs 357-470) wraps the whole establishment of an inbound connection in timeout(heartbeat_interval, ..) (361): the handshake, the reply, the member snapshot, the reachability snapshot and, for a Member handshake, every frame of the registrations snapshot (450-457). Each frame goes out through write_all (quic.rs 495-516), which waits for QUIC flow control, and the registrations snapshot is bounded only by the caps of 2^20 registrations and 64 MiB (receptionist.rs 35-38). So the setup succeeds only if one heartbeat interval, 1 s by default, carries the node's whole registry.
What happens when it does not:
- The timeout returns at 475 with
debug!("timed out establishing inbound connection")and drops the connection. Nothing is logged above debug level: a frame which fails to send is a warning (454), a setup which runs out of time is not. - The dialer has already received the reply handshake, which is sent before the snapshots (429-436), so its own setup succeeds and its writers start. About a second later the connection is gone, which it notices at its next write, and it reconnects with backoff, for good, since a member's address is retried forever (772-783).
- The accepting node never spawns
read_streamsfor such a connection (486), so it records no heartbeat from the dialer beyond what it reads on its own dialed connection's setup frames (Liveness::trackrecords one only when it first arms a detector,failure.rs442-451). It marks every peer unreachable and, underKeepMajority, downs itself as the minority afterafter. - Connections established before the registry grew stay up, so the failure shows on later connections only: after a network blip, a restart, or when a new member joins.
How large is too large: a registration costs about 17 bytes plus its share of the key (group_len, receptionist.rs 770). One second carries about 100 MB at 1 Gbit/s, so on a LAN only a registry near the cap is affected; about 12 MB at 100 Mbit/s, some 600,000 registrations; about 1 MB at 10 Mbit/s, some 60,000. The dialing side has no such bound: it hands its snapshot to the lane's slot (lanes.rs 209), which the control writer drains outside any timeout (peer.rs 1005-1010, write_snapshot at 1094).
The timeout exists so that an unauthenticated dialer cannot pin the task (355-356), which the handshake exchange needs; the snapshots were swept into it. docs/cluster.md states the bound for the joiner reading the member snapshot (149-150) and calls the caps "safety caps, not a sizing target" (1225), without saying that connection setup must carry the snapshot in one heartbeat interval.
What I'd do:
- Send the registrations snapshot after the timeout scope, e.g. right before
supersede_inbound_reader(486), or through a slot like the dialing side. The member and reachability snapshots are small and bounded and can stay inside. - Log the setup timeout at warn level with the peer, like the other establishment failures around it.
That every setup timeout is heartbeat_interval is a separate point, in #268. I'm happy to do 1 and 2 if you agree, no hurry, after 0.6 and whenever it suits the backlog.
- Dominant language
- Rust
- Stars
- 37
- Forks
- 1
- Avg merge
- 6h 36m
- Merged PRs (30d)
- 123
Getting set up
- Ships a Dockerfile or Docker Compose file
- No pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from tellus-rs/tellus
-
fix(cluster): keep a panicking encode of a remote reply from failing the responderPossibly taken @cosmir17 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
tellus-rs/tellus#312 · 2 comments ·
Maintainers usually reply within 1 day
-
docs: document the PostgreSQL store's schema for applications managing their ownPossibly taken @cosmir17 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
tellus-rs/tellus#310 · 2 comments ·
Maintainers usually reply within 1 day
-
documentation question
Difficulty 2/5 1-3 hours Newbie friendliness 60/100
Maintainers usually reply within 1 day
-
good first issue test
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 42/100
tellus-rs/tellus#311 · 2 comments ·
Maintainers usually reply within 1 day
All issues in tellus-rs/tellus
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
ElectronicWave/Elemental#252 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
area:mcp effort:low P5 source:agent
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
jlcodes99/cockpit-tools#3103 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
eliasstravik/herdr-projects#1032 ·