Skip to content

feat(grpc): add server-side Listener and Transport traits#2725

Open
sauravzg wants to merge 2 commits into
sauravz/dyn-server-credsfrom
sauravz/server-transport-api
Open

feat(grpc): add server-side Listener and Transport traits#2725
sauravzg wants to merge 2 commits into
sauravz/dyn-server-credsfrom
sauravz/server-transport-api

Conversation

@sauravzg

@sauravzg sauravzg commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Server-owned connection lifecycle and graceful shutdown:

  • Server accepts connections from a Listener and manages their lifecycle. Each accepted Transport is bound to a handler via Transport::serve(), which returns a GracefulConnection future that the Server polls and can shut down cooperatively.

  • Graceful shutdown follows a pattern combining the tonic Server API with hyper's graceful shutdown guide (https://hyper.rs/guides/0.14/server/graceful-shutdown/).

  • ListenerAddress provides a type-safe, downcastable address for listeners, analogous to Go's net.Addr.

Runtime API changes:

  • Runtime trait gains tcp_listener() and unix_listener() methods (doc(hidden)) that return EndpointListener (pub(crate)).
  • EndpointListener trait (pub(crate)) wraps accept() and local_addr() for server-side listening sockets.
  • Tokio implementations: TokioTcpListener, TokioUnixListener.
  • New address module (rt::address) with ListenerAddress trait and impls for SocketAddr and UnixListenerAddress.

Breaking changes:

  • Server::serve() now takes &impl Listener (sealed) instead of the previous ServerListener. The old ServerListener returned a pre-assembled ServerCall with constructed streams; the new Listener yields raw Transport objects and stream construction moves into Transport::serve().

  • serve_with_shutdown() is pub(crate) pending a design decision on whether the shutdown signal should be per-listener or per-server.

New public API surface:

  • Dyn versions of handler, recvstream (pub) - Same as client so should be okay
  • ListenerAddress trait (pub) — network(), as_any() - Needs to be public because it'll be exposed eventually
  • Listener trait (pub, sealed) — accept(), local_addr()
  • InMemoryServingConnection (pub)
  • ListenerAddress impl for std::net::SocketAddr
  • Runtime::tcp_listener(), Runtime::unix_listener() (doc(hidden))
  • Transport trait (pub, doc(hidden), private token) — serve()
  • GracefulConnection trait (pub, doc(hidden), private token) — graceful_shutdown()
  • UnixListenerAddress (pub(crate))
  • InMemoryListenerAddress (crate-private)
  • EndpointListener trait (pub(crate))

Open Questions:

  • local_addrs may need to be updated to be errorable(contrary to our previous discussion), tonic's API is errorable and we currently do an expect.
  • shutdown per listener vs shutdown on server
  • The use of associated types creates annoying issues of sealing and private token since dependent types need to be made public.

sauravzg added 2 commits July 7, 2026 16:52
Mirror the ChannelCredentials dyn-compat treatment from upstream PR #2703:
- Remove associated type Output<I> and generic accept<Input>
- Use BoxEndpoint and #[async_trait] for object safety
- Delete DynServerCredentials bridge trait (dyn_wrapper.rs)
- Update LocalServerCredentials and RustlsServerCredendials impls
Server-owned connection lifecycle and graceful shutdown:

- Server accepts connections from a Listener and manages their
  lifecycle. Each accepted Transport is bound to a handler via
  Transport::serve(), which returns a GracefulConnection future
  that the Server polls and can shut down cooperatively.

- Graceful shutdown follows a pattern combining the tonic Server
  API with hyper's graceful shutdown guide
  (https://hyper.rs/guides/0.14/server/graceful-shutdown/).

- ListenerAddress provides a type-safe, downcastable address for
  listeners, analogous to Go's net.Addr.

Runtime API changes:

- Runtime trait gains tcp_listener() and unix_listener() methods
  (doc(hidden)) that return EndpointListener (pub(crate)).
- EndpointListener trait (pub(crate)) wraps accept() and
  local_addr() for server-side listening sockets.
- Tokio implementations: TokioTcpListener, TokioUnixListener.
- New address module (rt::address) with ListenerAddress trait
  and impls for SocketAddr and UnixListenerAddress.

Breaking changes:

- Server::serve() now takes &impl Listener (sealed) instead of
  the previous ServerListener. The old ServerListener returned a
  pre-assembled ServerCall with constructed streams; the new
  Listener yields raw Transport objects and stream construction
  moves into Transport::serve().

- serve_with_shutdown() is pub(crate) pending a design decision
  on whether the shutdown signal should be per-listener or
  per-server.

New public API surface:

- Listener trait (pub, sealed) — accept(), local_addr()
- Transport trait (pub, doc(hidden), private token) — serve()
- GracefulConnection trait (pub, doc(hidden), private token)
  — graceful_shutdown()
- ListenerAddress trait (pub) — network(), as_any()
- ListenerAddress impl for std::net::SocketAddr
- UnixListenerAddress (pub(crate))
- InMemoryServingConnection (pub)
- InMemoryListenerAddress (crate-private)
- EndpointListener trait (pub(crate))
- Runtime::tcp_listener(), Runtime::unix_listener() (doc(hidden))
@sauravzg sauravzg requested a review from dfawley July 8, 2026 04:12
@sauravzg sauravzg force-pushed the sauravz/dyn-server-creds branch from 78b7f20 to 1ff57ef Compare July 8, 2026 06:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant