Skip to main content

DirectoryClient

Trait DirectoryClient 

Source
pub trait DirectoryClient: Send + Sync {
    // Required methods
    fn resolve_grpc_service<'life0, 'life1, 'async_trait>(
        &'life0 self,
        service_name: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<ServiceEndpoint, Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;
    fn resolve_rest_service<'life0, 'life1, 'async_trait>(
        &'life0 self,
        gear_name: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<ServiceEndpoint, Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;
    fn get_openapi_spec<'life0, 'life1, 'async_trait>(
        &'life0 self,
        gear_name: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<String, Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;
    fn list_instances<'life0, 'life1, 'async_trait>(
        &'life0 self,
        gear: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<ServiceInstanceInfo>, Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;
    fn list_all_instances<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<ServiceInstanceInfo>, Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             Self: 'async_trait;
    fn register_instance<'life0, 'async_trait>(
        &'life0 self,
        info: RegisterInstanceInfo,
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             Self: 'async_trait;
    fn deregister_instance<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        gear: &'life1 str,
        instance_id: &'life2 str,
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             Self: 'async_trait;
    fn send_heartbeat<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        gear: &'life1 str,
        instance_id: &'life2 str,
    ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             Self: 'async_trait;

    // Provided method
    fn resolve_by_labels<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        gear: &'life1 str,
        selector: &'life2 LabelSelector,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<ServiceInstanceInfo>, Error>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             Self: 'async_trait { ... }
}
Expand description

Directory API trait for service discovery and instance management

This trait defines the contract for interacting with the gear directory. It can be implemented by:

  • A local implementation that delegates to GearManager
  • A gRPC client for out-of-process gears

Required Methods§

Source

fn resolve_grpc_service<'life0, 'life1, 'async_trait>( &'life0 self, service_name: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<ServiceEndpoint, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Resolve a gRPC service by its logical name to an endpoint

Source

fn resolve_rest_service<'life0, 'life1, 'async_trait>( &'life0 self, gear_name: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<ServiceEndpoint, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Resolve a REST endpoint (HTTP base URL) for a gear by its name.

Returns the base URL (e.g. http://billing:8080) that callers use to make REST requests to the resolved gear.

Source

fn get_openapi_spec<'life0, 'life1, 'async_trait>( &'life0 self, gear_name: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<String, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Retrieve the OpenAPI spec (JSON) published by a gear.

Source

fn list_instances<'life0, 'life1, 'async_trait>( &'life0 self, gear: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<ServiceInstanceInfo>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

List all service instances for a given gear.

Entries are spec-free: only the openapi_spec_hash is carried, never the full OpenAPI document, so a multi-instance response stays bounded regardless of spec size. Callers fetch the document out-of-band via get_openapi_spec; the hash lets a consumer detect a spec change without inlining N copies of the document.

An endpoint-less instance is still returned (endpoint/rest_endpoint = None, never an empty-URI sentinel): no-endpoint, not an error. Only list_all_instances, which needs a dialable URI, drops such entries.

Source

fn list_all_instances<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<ServiceInstanceInfo>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

List every service instance across all registered gears.

Used by the edge gateway to discover which gears (and their REST endpoints) to reverse-proxy. This is a lightweight discovery snapshot. Like every enumeration path, it is spec-free: entries carry only the openapi_spec_hash, never the full OpenAPI document, even when the backing store holds a stored specification. The edge fetches a gear’s document once, on first discovery, via get_openapi_spec.

The returned instances also do not carry labels: every implementation applies ServiceInstanceInfo::without_labels so the snapshot omits them identically regardless of transport. Labels drive the targeted resolve_by_labels path, not this snapshot.

Source

fn register_instance<'life0, 'async_trait>( &'life0 self, info: RegisterInstanceInfo, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Register a new gear instance with the directory

Source

fn deregister_instance<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, gear: &'life1 str, instance_id: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Deregister a gear instance (for graceful shutdown)

Source

fn send_heartbeat<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, gear: &'life1 str, instance_id: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Send a heartbeat for a gear instance to indicate it’s still alive

Provided Methods§

Source

fn resolve_by_labels<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, gear: &'life1 str, selector: &'life2 LabelSelector, ) -> Pin<Box<dyn Future<Output = Result<Vec<ServiceInstanceInfo>, Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Resolve instances of gear whose labels satisfy selector.

Matching is equality-AND (k8s matchLabels): an instance matches iff it carries every (key, value) pair in the selector; an empty selector matches every instance of the name.

The returned set is not health-filtered — matched instances are returned regardless of readiness/heartbeat state, each carrying its instance_id, labels, endpoints, and live state. Applying liveness policy (e.g. keeping only InstanceState::is_serving) is the caller’s responsibility.

Nor is it endpoint-filtered: a matched instance that advertises no endpoint yet is still returned (endpoint/rest_endpoint = None) — no-endpoint, not an error — so the caller can fall back rather than have the match silently hidden.

Returned entries are spec-free on every implementation — the full OpenAPI document is omitted (only its hash is carried), so the polled resolve payload stays bounded; the caller fetches documents via get_openapi_spec. This holds regardless of whether the selector is empty. The default body enumerates via list_instances and filters in-process; transport-backed clients (e.g. the gRPC client) override it to push the selector server-side.

Label-based selection is effectively out-of-process only. Labels are published from the OoP serve path’s configuration (oop_http.labels); the in-process registration path (grpc-hub start phase / run_directory_register_phase) has no label source, so an in-process gear carries no labels and a non-empty selector never matches it. This matches the deployment model: shards/peers are distinct instances (separate pods/processes), which is inherently the OoP topology.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§