Skip to content

feat(tonic-xds): add transport-generic build_transport_channel - #2785

Closed
LYZJU2019 wants to merge 1 commit into
grpc:masterfrom
LYZJU2019:lyzju2019/xds-generic-build-path
Closed

feat(tonic-xds): add transport-generic build_transport_channel#2785
LYZJU2019 wants to merge 1 commit into
grpc:masterfrom
LYZJU2019:lyzju2019/xds-generic-build-path

Conversation

@LYZJU2019

Copy link
Copy Markdown
Contributor

What

Adds XdsChannelBuilder::build_transport_channel, a transport-generic build path that wires the xDS routing → retry → load-balancing stack over a caller-provided MakeConnector and returns a type-erased, cloneable Send + Sync tower::Service. The existing gRPC channel becomes the special case of this shared stack.

This is an additive, non-breaking change — no existing public API changes behavior, and the gRPC connect path and all gRPC tests are untouched.

Why

Follow-up to the xDS transport-generalization work (#2750, #2751, #2776). Downstream users that speak a non-gRPC transport (e.g. plain HTTP) need to drive the same xDS routing/retry/LB machinery with their own per-endpoint connector, without reimplementing the stack.

Details

  • Shared core: extracted a private build_stack that both the gRPC and generic paths call; the gRPC path (build_from_cache) is now a thin caller. Also extracted load_bootstrap / build_xds_runtime helpers. The cert-provider registry stays gRPC-only (built before the bootstrap node is consumed, so the generic path never pays for it).
  • Body flow: the retry engine converts Request<B>Request<SharedBody<B>> so a request can be cloned for replay; a post_retry_map bridges back to the body the per-endpoint service expects. gRPC rewraps into a tonic body (unchanged); the generic path's connector accepts SharedBody<B> directly (identity map).
  • Public retry seam: made RetryClassifier, RetryConfig, RetryBackoffConfig, and is_retryable_connection_error public so non-gRPC transports can plug their own retry logic. Retry behavior is threaded into build_transport_channel as a classifier + RetryConfig; the internal RetryPolicy (and its tower::retry::Policy impl) stays private to keep the public surface minimal.
  • check-external-types: allowlisted shared_http_body — the caller's connector accepts a SharedBody-wrapped body.

Testing

  • New e2e test (xds_channel_e2e_transport_generic_routes_to_backend) drives the generic path end-to-end through the mock control plane, using a custom RetryClassifier + a SharedBody-accepting connector written entirely against the public API.
  • Build/test/doc with -D warnings (400 tests + 4 doctests), clippy, rustfmt, and check-external-types --all-features all pass.

Add `XdsChannelBuilder::build_transport_channel`, a transport-generic
build path that wires the xDS routing -> retry -> load-balancing stack
over a caller-provided `MakeConnector` and returns a type-erased,
cloneable `Send + Sync` tower service. The gRPC channel becomes the
special case of this shared stack.

Refactor channel.rs to share a single private `build_stack` core between
the gRPC and generic paths, and extract `load_bootstrap` /
`build_xds_runtime` helpers. The cert-provider registry stays gRPC-only.

Make the retry seam public so non-gRPC transports can plug their own
retry logic: `RetryClassifier`, `RetryConfig`, `RetryBackoffConfig`, and
`is_retryable_connection_error`. Retry behavior is threaded into
`build_transport_channel` as a classifier + config; the internal
`RetryPolicy` stays private.

Allowlist `shared_http_body` for check-external-types: the caller's
connector accepts a `SharedBody`-wrapped body so requests can be cloned
for retries.
@LYZJU2019

Copy link
Copy Markdown
Contributor Author

Superseded by #2786, which reworks the retry configuration to be control-plane-driven: instead of a static RetryConfig parameter, build_transport_channel now takes a Fn(&RouteConfigMetadata) -> Option<RetryConfig> closure and a background task hot-swaps the config from RouteConfiguration updates.

@LYZJU2019 LYZJU2019 closed this Jul 31, 2026
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