-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat(tonic-xds): grpc channel builder #2584
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 6 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
8a75a43
feat(tonic-xds): grpc channel builder
YutaoMa b86f497
tonic-xds: integration test example
YutaoMa 719895b
style: fmt & clippy
YutaoMa bea5af3
fix: add resources back to stack after rebase
YutaoMa d9b43f9
fix: ignore deprecation warning in latest envoy-types
YutaoMa 0d0cac0
fix: ignore SafeRegexMatch deprecation
YutaoMa 1351fe5
feat(tonic-xds): block rpc until valid route config
YutaoMa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| //! Example: send gRPC requests through an xDS-aware channel. | ||
| //! | ||
| //! Builds an xDS channel, then sends HelloRequest RPCs through it in a loop. | ||
| //! The channel discovers endpoints via the xDS management server and | ||
| //! load-balances across them. | ||
| //! | ||
| //! # Prerequisites | ||
| //! | ||
| //! 1. Start one or more greeter backends: | ||
| //! ```sh | ||
| //! PORT=50051 cargo run -p tonic-xds --example greeter_server | ||
| //! ``` | ||
| //! | ||
| //! 2. Start an xDS control plane (e.g., go-control-plane) configured to | ||
|
YutaoMa marked this conversation as resolved.
Outdated
|
||
| //! return LDS/RDS/CDS/EDS pointing at the greeter backends. | ||
| //! | ||
| //! # Configuration | ||
| //! | ||
| //! - `GRPC_XDS_BOOTSTRAP` — path to a bootstrap JSON file, **or** | ||
| //! - `GRPC_XDS_BOOTSTRAP_CONFIG` — inline bootstrap JSON | ||
| //! - `XDS_TARGET` — xDS target URI (default: `xds:///my-service`) | ||
| //! | ||
| //! # Usage | ||
| //! | ||
| //! ```sh | ||
| //! GRPC_XDS_BOOTSTRAP_CONFIG='{"xds_servers":[{"server_uri":"localhost:18000"}],"node":{"id":"test"}}' \ | ||
| //! cargo run -p tonic-xds --example channel | ||
| //! ``` | ||
|
|
||
| use tonic_xds::testutil::proto::helloworld::{HelloRequest, greeter_client::GreeterClient}; | ||
| use tonic_xds::{XdsChannelBuilder, XdsChannelConfig, XdsUri}; | ||
|
|
||
| #[tokio::main] | ||
| async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
| let target_str = std::env::var("XDS_TARGET").unwrap_or_else(|_| "xds:///my-service".into()); | ||
| let target = XdsUri::parse(&target_str)?; | ||
|
|
||
| println!("Building xDS channel for target: {target_str}"); | ||
|
|
||
| let channel = XdsChannelBuilder::new(XdsChannelConfig::new(target)).build_grpc_channel()?; | ||
|
|
||
| let mut client = GreeterClient::new(channel); | ||
|
|
||
| println!("Channel built. Sending requests (Ctrl-C to stop)...\n"); | ||
|
|
||
| for i in 1.. { | ||
| tokio::time::sleep(tokio::time::Duration::from_secs(5)).await; | ||
|
YutaoMa marked this conversation as resolved.
Outdated
|
||
|
|
||
| let request = HelloRequest { | ||
| name: format!("request-{i}"), | ||
| }; | ||
|
|
||
| match client.say_hello(request).await { | ||
| Ok(response) => { | ||
| println!("[{i}] Response: {}", response.into_inner().message); | ||
| } | ||
| Err(status) => { | ||
| eprintln!("[{i}] Error: {status}"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| //! Example: standalone gRPC greeter server for testing xDS. | ||
| //! | ||
| //! Starts a greeter backend on a given port. Point your xDS control plane's | ||
| //! EDS config at this server's address, then use the `channel` example to | ||
| //! send requests through the xDS channel. | ||
| //! | ||
| //! # Usage | ||
| //! | ||
| //! ```sh | ||
| //! # Start a backend on port 50051 (default): | ||
| //! cargo run -p tonic-xds --example greeter_server | ||
| //! | ||
| //! # Start on a custom port: | ||
| //! PORT=50052 cargo run -p tonic-xds --example greeter_server | ||
| //! | ||
| //! # Start multiple backends: | ||
| //! PORT=50051 cargo run -p tonic-xds --example greeter_server & | ||
| //! PORT=50052 cargo run -p tonic-xds --example greeter_server & | ||
| //! ``` | ||
|
|
||
| use tonic::transport::Server; | ||
| use tonic::{Request, Response, Status}; | ||
| use tonic_xds::testutil::proto::helloworld::{ | ||
| HelloReply, HelloRequest, | ||
| greeter_server::{Greeter, GreeterServer}, | ||
| }; | ||
|
|
||
| struct MyGreeter { | ||
| addr: String, | ||
| } | ||
|
|
||
| #[tonic::async_trait] | ||
| impl Greeter for MyGreeter { | ||
| async fn say_hello( | ||
| &self, | ||
| request: Request<HelloRequest>, | ||
| ) -> Result<Response<HelloReply>, Status> { | ||
| let name = request.into_inner().name; | ||
| println!("Received request: name={name}"); | ||
| Ok(Response::new(HelloReply { | ||
| message: format!("Hello {name} from {}", self.addr), | ||
| })) | ||
| } | ||
| } | ||
|
|
||
| #[tokio::main] | ||
| async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
| let port = std::env::var("PORT").unwrap_or_else(|_| "50051".to_string()); | ||
| let addr: std::net::SocketAddr = format!("0.0.0.0:{port}").parse()?; | ||
|
|
||
| println!("Greeter server listening on {addr}"); | ||
|
|
||
| Server::builder() | ||
| .add_service(GreeterServer::new(MyGreeter { | ||
| addr: addr.to_string(), | ||
| })) | ||
| .serve(addr) | ||
| .await?; | ||
|
|
||
| Ok(()) | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.