Skip to content

server: report why connections failed; Windows fd-exhaustion pause; review follow-ups - #310

Merged
iainmcgin merged 3 commits into
mainfrom
iain/server-followups
Sep 21, 2026
Merged

iainmcgin merged 3 commits into
mainfrom
iain/server-followups

Conversation

@iainmcgin

Copy link
Copy Markdown
Collaborator

Follow-ups deferred from the connection-layering stack (#306, #307, #308, #304).

let closed = server.serve_connection(stream, info, drain).await;
match (closed.reason(), closed.error()) {
    (CloseReason::Error, Some(err)) => metrics.connection_failed(err),
    (reason, Some(err)) => metrics.drain_failed(reason, err), // failed while winding down
    (reason, None) => metrics.connection_closed(reason),
}
  • ConnectionClosed::error() / error_arc() return the error that ended a connection: always for CloseReason::Error, and for a failure while draining, whose reason stays the one that started the drain. A connection told to wind down before it picked a protocol reports no error: hyper-util returns an Interrupted "Cancelled" error there, which is matched by kind and message, so the workspace hyper-util floor is now 0.1.20 (checked against 0.1.19 and 0.1.20). ConnectionClosed keeps UnwindSafe / RefUnwindSafe through manual impls.
  • The accept loop's pause after running out of file descriptors also matches Winsock's WSAEMFILE; before, the pause never applied on Windows.
  • connectrpc::http re-exports the http crate, since the connection-extensions function takes http::Extensions.
  • The h2 dev-dependency floor is 0.4.15, which the header-list-size GOAWAY test needs.

`ConnectionClosed::error()` (and `error_arc()`, an owned `SharedSource`)
returns the error behind `CloseReason::Error`, and also an error hit
while a connection drained, whose reason stays the one that started the
drain. Metrics can now tell error kinds apart and count failed drains. A
panic in a connection-extensions function is reported the same way.

hyper-util ends a connection told to wind down before it picked a
protocol with an `Interrupted` "Cancelled" error; that is a clean close,
so `error()` stays `None` for it. The workspace hyper-util floor is
0.1.20, the version this was checked against.

`ConnectionClosed` keeps `UnwindSafe` / `RefUnwindSafe`, which the boxed
error would otherwise remove; a test now pins those traits for it, and for
`BoundServer` without TLS.

Also adds tests that request-count and idle retirement close an
undrained connection after the configured grace period, not the default.

Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>
The accept loop's pause after running out of file descriptors matched
only `EMFILE` / `ENFILE`, which Winsock never returns; it reports
`WSAEMFILE` (10024), so the pause never applied on Windows.

The serve methods now say which accept errors are transient, that
dropping the future aborts live connections, and what any other accept
error does to them; `serve_with_service` no longer suggests it
accepts a tower-layered service. The module docs say serving needs a
runtime with time enabled: the default header-read timeout already
required it, and the pause uses the same timer. The changelog entry that
joined the idle-reaping and file-descriptor fixes is split in two.

Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>
…e loop

- The guide's custom accept loop sets TCP_NODELAY as the built-in loop
  does, logs a socket that fails to move between runtimes instead of
  dropping it silently, records whether a connection failed, and says to
  pause after running out of file descriptors.
- A compile_fail doctest, with a compiling counterpart test, pins that
  the connection-extensions function sees `ConnectionInfo` read-only; the
  private alias behind it is renamed to say what it holds.
- `connectrpc::http` re-exports the `http` crate, whose `Extensions` the
  connection-extensions function takes.
- The workspace h2 floor is 0.4.15, the first release that sends GOAWAY on
  a header list far over the limit, which the header-list-size tests
  expect.

Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>
@iainmcgin
iainmcgin added this pull request to the merge queue Sep 21, 2026
Merged via the queue into main with commit faa1b90 Sep 21, 2026
14 checks passed
@iainmcgin
iainmcgin deleted the iain/server-followups branch September 21, 2026 01:18
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