Skip to content

fix(connect): the face knows the server's limit before the client's first call, and tells it its own - #117

Merged
antoinetoussaint-byte merged 1 commit into
mainfrom
fix/connect-server-settings
Oct 26, 2026
Merged

antoinetoussaint-byte merged 1 commit into
mainfrom
fix/connect-server-settings

Conversation

@antoinetoussaint-byte

Copy link
Copy Markdown
Contributor

Follow-ups m1 and m2 from review r77 of #110, which has merged. This is the whole change.

What changes

  • m1: early calls got the face's reset instead of the server's refusal. The face started reading the client at once. A call opened before the server's first SETTINGS frame arrived therefore hit the face's own default limit and got ENHANCE_YOUR_CALM. If the face had waited, the server would have refused it itself with REFUSED_STREAM, which is safe to retry. The face now reads the server's connection preface (its SETTINGS frame, within read_timeout) before it reads anything from the client.
  • m2: a server that advertises no limit now has the face's added to its first SETTINGS. grpcio's default advertises no SETTINGS_MAX_CONCURRENT_STREAMS. In that case the face adds DEFAULT_MAX_OPEN_CALLS (1000) to the server's first SETTINGS frame, so a client that follows HTTP/2 queues its calls within what the face enforces. The client acknowledges that one frame as the server's, so the server sees the single ACK it expects.
    • Effect: 1100 concurrent calls on one grpc.aio channel are now all answered. Before, 1000 were answered and 100 were reset.

Classification: fix, in the face, which owns this behaviour.

Tests

These fail on main:

  • test_a_server_advertising_no_limit_is_given_the_faces
  • test_the_client_is_read_once_the_servers_limit_is_known: the server's limit is 2 and arrives 0.3 s after three calls. The third call reaches the server untouched.
  • test_a_burst_past_the_limit_queues_and_loses_no_call: 1100 out of 1100 answered.

Also new: test_a_server_limit_reaches_the_client_untouched.

The suite's fake gRPC servers now open with SETTINGS, as a real server's preface does.

Checks

🤖 Generated with Claude Code

…irst call, and tells it its own

Follow-ups m1 and m2 of review r77 on #110:

- m1: the relay read the client at once, so a call opened before the
  server's first SETTINGS met the face's default (ENHANCE_YOUR_CALM) where
  the server would have refused it itself, retry-safe. The relay now reads
  the server's connection preface (its SETTINGS frame, bounded by
  read_timeout) before it reads the client.
- m2: a server that advertises no SETTINGS_MAX_CONCURRENT_STREAMS (grpcio's
  default) has the face's DEFAULT_MAX_OPEN_CALLS added to its first SETTINGS,
  so a client that keeps to HTTP/2 queues its calls within what the face
  enforces. The client acknowledges that one frame as the server's, so the
  server sees the ACK it expects. 1100 calls on one grpc.aio channel are now
  all answered (1000 before, the rest reset).

Tests: test_a_server_advertising_no_limit_is_given_the_faces,
test_the_client_is_read_once_the_servers_limit_is_known and
test_a_burst_past_the_limit_queues_and_loses_no_call fail on main;
test_a_server_limit_reaches_the_client_untouched. The fake servers in the
suite now open with SETTINGS, as a server's preface does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antoinetoussaint-byte
antoinetoussaint-byte merged commit 097a4fc into main Oct 26, 2026
4 checks passed
antoinetoussaint-byte added a commit that referenced this pull request Oct 26, 2026
fix(connect): the minors of #111 and #117's reviews
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.

1 participant