Skip to content

fix(forge): cancel a vanished client's transport within seconds, not after 120 s - #334

Merged
tonibergholm-codento merged 3 commits into
mainfrom
fix/forge-tcp-keepalive
Nov 9, 2026
Merged

tonibergholm-codento merged 3 commits into
mainfrom
fix/forge-tcp-keepalive

Conversation

@tonibergholm-codento

Copy link
Copy Markdown
Collaborator

A client that disconnected mid-push could hold its git transport until the 120 s idle timeout. In about 1 run in 8 on macOS, the server never received the close: the socket stayed ESTABLISHED with empty queues, and hyper's body read saw no FIN or RST. Normal runs get a reset and cancel within about 50 ms. #316 tracked this.

The fix enables TCP keepalive on accepted sockets, with probes after 15 s of silence (server::Limits::tcp_keepalive, the same default as Go's net/http server). A probe to a vanished peer gets a reset, so the transport is cancelled. A paused but live client answers the probes. Setting keepalive is best effort: if it fails, the server logs a warning and still serves the connection.

  • The mid-pack cancel test now runs with the default 120 s transport idle timeout and a 1 s probe delay, under the usual 10 s wait.
  • New test keepalive_probes_leave_a_paused_live_client_alone: a stalled live push keeps its transport for 4 s with a 1 s probe delay.
  • docs/THREAT-MODEL.md now describes keepalive's limits. An unanswered probe follows the platform's retry defaults, so --git-idle-timeout still bounds a blackholed peer. Behind a proxy, the probes reach only the proxy.

Proof: before the fix, 2 of 6 runs took 120 s from disconnect to cleanup. After it, the slowest of 12 runs took 1.14 s. Three runs on Linux with Rust 1.96.1 pass. cargo test -p scl-forge passes (321 tests), and so do fmt and clippy (-D warnings).

Not established: why the macOS loopback close goes missing. A packet capture needed sudo. Sol's diagnosis ruled out hyper's body channel and backpressure.

Reviewed with sol-loop: 1 round with gpt-6.1-sol on high. Sol verdict: approved. gpt-6.1-sol also diagnosed the bug and prototyped the fix.

Created with Claude Opus 5.5 in T3 Code (Claude Code harness).

A client that left mid-request without a close the server received (seen
on macOS loopback in about 1 run in 8: the socket stayed ESTABLISHED and the
body read never saw FIN or RST) held its transport until the 120 s idle
timeout. Accepted sockets now enable TCP keepalive with a 15 s idle time
(Limits::tcp_keepalive), so the probes find the peer gone. Setting it is
best effort: a failure logs a warning and the connection is served.

The mid-pack cancel test now runs with the default idle timeout and a 1 s
probe delay (cleanup took at most 1.14 s over 12 runs, against 120 s in 2 of
6 before); a new test shows a paused live client survives the probes.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T11:50:27.012809Z ba4d9ea New commits
🔒 Security Review ✅ Completed 2026-11-09T11:52:15.670558Z ba4d9ea New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ae3ddcdf-8dc3-4b7c-8940-c5940efd97ae
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@tonibergholm-codento
tonibergholm-codento merged commit 220e9db into main Nov 9, 2026
12 checks passed
@tonibergholm-codento
tonibergholm-codento deleted the fix/forge-tcp-keepalive branch November 9, 2026 12:03
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.

2 participants