Expand description
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;
use std::convert::TryInto;
// Create a load balanced channel with the default lookup implementation.
let load_balanced_channel = LoadBalancedChannel::builder(("my.hostname", 5000))
.channel()
.await
.expect("failed to construct LoadBalancedChannel");
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;
// 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;
use std::convert::TryInto;
// Create a load balanced channel with a dummy lookup implementation.
let load_balanced_channel = LoadBalancedChannel::builder(("my.hostname", 5000))
.lookup_service(DummyLookupService)
.channel()
.await
.expect("failed to construct LoadBalancedChannel");
let tester_client = TesterClient::new(load_balanced_channel);
}
For systems with higher churn, the probe interval can be lowered.
#[tokio::main]
async fn main() {
use ginepro::{LoadBalancedChannel, LoadBalancedChannelBuilder};
use shared_proto::pb::tester_client::TesterClient;
use std::convert::TryInto;
let load_balanced_channel = LoadBalancedChannelBuilder::new_with_service(("my.hostname", 5000))
.dns_probe_interval(std::time::Duration::from_secs(3))
.channel()
.await
.expect("failed to construct LoadBalancedChannel");
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;
use std::convert::TryInto;
let load_balanced_channel = LoadBalancedChannel::builder(("my.hostname", 5000))
.timeout(std::time::Duration::from_secs(10))
.channel()
.await
.expect("failed to construct LoadBalancedChannel");
let tester_client = TesterClient::new(load_balanced_channel);
}
It’s also possible to eagerly resolve the service endpoints once before
LoadBalancedChannel
is constructed.
.
#[tokio::main]
async fn main() {
use ginepro::{LoadBalancedChannel, ResolutionStrategy};
use shared_proto::pb::tester_client::TesterClient;
use std::time::Duration;
use std::convert::TryInto;
let load_balanced_channel = LoadBalancedChannel::builder(("my.hostname", 5000))
.timeout(std::time::Duration::from_secs(10))
.resolution_strategy(ginepro::ResolutionStrategy::Eager {
timeout: Duration::from_secs(20),
})
.channel()
.await
.expect("failed to construct LoadBalancedChannel");
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.
Structs§
- Implements
LookupService
by using DNS queries to lookupServiceDefinition::hostname
. - Implements tonic
GrpcService
for a client-side load balancedChannel
(usingThe Power of Two Choices
). - Builder to configure and create a
LoadBalancedChannel
. - Defines a gRPC service with a
hostname
and aport
. The hostname will be resolved to the concrete ips of the service servers.
Enums§
- Enumerates the different domain name resolution strategies that the
LoadBalancedChannelBuilder
supports.
Traits§
- Interface that provides functionality to acquire a list of ips given a valid host name.