Crate ginepro[][src]

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;

    // 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.

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.

#[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.

Structs

DnsResolver

Implements LookupService by using DNS queries to lookup ServiceDefinition::hostname.

LoadBalancedChannel

Implements tonic GrpcService for a client-side load balanced Channel (using The Power of Two Choices).

LoadBalancedChannelBuilder

Builder to configure and create a LoadBalancedChannel.

ServiceDefinition

Defines a gRPC service with a hostname and a port. The hostname will be resolved to the concrete ips of the service servers.

Traits

LookupService

Interface that provides functionality to acquire a list of ips given a valid host name.