ginepro
offers an enriched tonic Channel
using a pluggable service discovery
to periodcally update the active set of gRPC
servers.
Simple example
#[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")
.channel();
let tester_client = TesterClient::new(load_balanced_channel);
}
[LoadBalancedChannel
] also allows plugging in a different implementation of [LookupService
].
use ginepro::{LookupService, ServiceDefinition};
use std::collections::HashSet;
use std::net::SocketAddr;
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.
#[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.
.
#[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
exposes the function
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.