ForkJoinLayer

Struct ForkJoinLayer 

Source
pub struct ForkJoinLayer<A, B> {
    pub left: A,
    pub right: B,
}
Expand description

Fork-join composition layer that tries both left and right concurrently.

Created by the & operator on Policy<L> types: Policy(A) & Policy(B) produces Policy<ForkJoinLayer<A, B>>.

Both services are called concurrently, and the first successful result is returned. If both fail, an error is returned (currently the left error, but this may change).

This implements the “happy eyeballs” pattern commonly used for IPv4/IPv6 racing, cache racing, or trying multiple backends simultaneously.

§Example

use ninelives::prelude::*;
use std::time::Duration;
use tower_layer::Layer;

// Race two caches - use whichever responds first
let cache_a = Policy(TimeoutLayer::new(Duration::from_millis(100))?);
let cache_b = Policy(TimeoutLayer::new(Duration::from_millis(100))?);
let _policy = cache_a & cache_b;
// Tries both concurrently, returns first Ok result

§IPv4/IPv6 Happy Eyeballs Example

use ninelives::prelude::*;
use std::time::Duration;
use tower_layer::Layer;

// Try IPv4 and IPv6 in parallel
let ipv4_path = Policy(TimeoutLayer::new(Duration::from_millis(300))?);
let ipv6_path = Policy(TimeoutLayer::new(Duration::from_millis(300))?);
let _policy = ipv4_path & ipv6_path;

Fields§

§left: A

The left strategy (tried concurrently with right)

§right: B

The right strategy (tried concurrently with left)

Trait Implementations§

Source§

impl<A: Clone, B: Clone> Clone for ForkJoinLayer<A, B>

Source§

fn clone(&self) -> ForkJoinLayer<A, B>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<A: Debug, B: Debug> Debug for ForkJoinLayer<A, B>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<S, A, B> Layer<S> for ForkJoinLayer<A, B>
where S: Clone + Send + 'static, A: Layer<S>, B: Layer<S>, A::Service: Send + 'static, B::Service: Send + 'static,

Source§

type Service = ForkJoinService<<A as Layer<S>>::Service, <B as Layer<S>>::Service>

The wrapped service
Source§

fn layer(&self, service: S) -> Self::Service

Wrap the given service with the middleware, returning a new service that has been decorated with the middleware.

Auto Trait Implementations§

§

impl<A, B> Freeze for ForkJoinLayer<A, B>
where A: Freeze, B: Freeze,

§

impl<A, B> RefUnwindSafe for ForkJoinLayer<A, B>

§

impl<A, B> Send for ForkJoinLayer<A, B>
where A: Send, B: Send,

§

impl<A, B> Sync for ForkJoinLayer<A, B>
where A: Sync, B: Sync,

§

impl<A, B> Unpin for ForkJoinLayer<A, B>
where A: Unpin, B: Unpin,

§

impl<A, B> UnwindSafe for ForkJoinLayer<A, B>
where A: UnwindSafe, B: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more