1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
//! `ginepro` offers an enriched tonic [`Channel`](tonic::transport::Channel) using a pluggable service discovery //! to periodcally update the active set of `gRPC` servers. //! //! # Simple example //! //! ```rust //! #[tokio::main] //! async fn main() { //! use ginepro::LoadBalancedChannel; //! use shared_proto::pb::tester_client::TesterClient; //! //! // Create a load balanced channel with the default lookup implementation. //! let load_balanced_channel = LoadBalancedChannel::builder(("my_hostname", 5000)) //! .await //! .expect("failed to read system conf") //! .channel(); //! //! let tester_client = TesterClient::new(load_balanced_channel); //! } //! ``` //! //! [`LoadBalancedChannel`] also allows plugging in a different implementation of [`LookupService`]. //! //! ```rust //! use ginepro::{LookupService, ServiceDefinition}; //! use std::collections::HashSet; //! use std::net::SocketAddr; //! //! // This does nothing //! struct DummyLookupService; //! //! #[async_trait::async_trait] //! impl LookupService for DummyLookupService { //! async fn resolve_service_endpoints( //! &self, //! _definition: &ServiceDefinition, //! ) -> Result<HashSet<SocketAddr>, anyhow::Error> { //! Ok(HashSet::new()) //! } //! } //! //! #[tokio::main] //! async fn main() { //! use ginepro::LoadBalancedChannel; //! use shared_proto::pb::tester_client::TesterClient; //! //! let load_balanced_channel = LoadBalancedChannel::builder(("my_hostname", 5000)) //! .await //! .expect("failed to read system conf") //! .lookup_service(DummyLookupService) //! .channel(); //! //! let tester_client = TesterClient::new(load_balanced_channel); //! } //! ``` //! For systems with lower churn, the probe interval can be lowered. //! //! ```rust //! #[tokio::main] //! async fn main() { //! use ginepro::{LoadBalancedChannel, LoadBalancedChannelBuilder}; //! use shared_proto::pb::tester_client::TesterClient; //! //! let load_balanced_channel = LoadBalancedChannelBuilder::new_with_service(("my_hostname", 5000)) //! .await //! .expect("failed to read system conf") //! .dns_probe_interval(std::time::Duration::from_secs(3)) //! .channel(); //! //! let tester_client = TesterClient::new(load_balanced_channel); //! } //! ``` //! //! It's also possible to associate a timeout for every new endpoint that the //! [`LoadBalancedChannel`] tries to connect to. //! . //! //! ```rust //! #[tokio::main] //! async fn main() { //! use ginepro::LoadBalancedChannel; //! use shared_proto::pb::tester_client::TesterClient; //! //! let load_balanced_channel = LoadBalancedChannel::builder(("my_hostname", 5000)) //! .await //! .expect("failed to read system conf") //! .timeout(std::time::Duration::from_secs(10)) //! .channel(); //! //! let tester_client = TesterClient::new(load_balanced_channel); //! } //! ``` //! //! # Internals //! The tonic [`Channel`](tonic::transport::Channel) exposes the function //! [`balance_channel`](tonic::transport::Channel::balance_channel) which returnes a bounded channel through which //! endpoint changes can be sent. //! `ginepro` uses this message passing mechanism to report when servers are added and removed. mod balanced_channel; mod dns_resolver; mod lookup_service; mod service_definition; mod service_probe; pub use balanced_channel::*; pub use dns_resolver::*; pub use lookup_service::*; pub use service_definition::*;