Tether

Struct Tether 

Source
pub struct Tether<C: Connector, R> { /* private fields */ }
Expand description

A wrapper type which contains the underlying I/O object, it’s initializer, and resolver.

This in the main type exposed by the library. It implements AsyncRead and AsyncWrite whenever the underlying I/O object implements them.

Calling things like read_buf will result in the I/O automatically reconnecting if an error is detected during the underlying I/O call.

§Example

§Basic Resolver

Below is an example of a basic resolver which just logs the error and retries

struct MyResolver;

impl<C> Resolver<C> for MyResolver {
    fn disconnected(&mut self, context: &Context, _: &mut C) -> PinFut<Action> {
        println!("WARN(disconnect): {:?}", context);

        // always immediately retry the connection
        Box::pin(async move { Action::AttemptReconnect })
    }
}

let stream = Tether::connect_tcp("localhost:8080", MyResolver).await?;

// Regardless of which half detects the disconnect, a reconnect will be attempted
let (read, write) = tokio::io::split(stream);

§Specialized Resolver

For more specialized use cases we can implement Resolver only for certain connectors to give us extra control over the reconnect process.

struct MyResolver;

type Connector = TcpConnector<SocketAddrV4>;

impl Resolver<Connector> for MyResolver {
    fn disconnected(&mut self, context: &Context, conn: &mut Connector) -> PinFut<Action> {
        // Because we've specialized our resolver to act on TcpConnector for IPv4, we can alter
        // the address in between the disconnect, and the reconnect, to try a different host
        conn.get_addr_mut().set_ip(Ipv4Addr::LOCALHOST);
        conn.get_addr_mut().set_port(8082);

        // always immediately retry the connection
        Box::pin(async move { Action::AttemptReconnect })
    }
}

§Note

Currently, there is no way to obtain a reference into the underlying I/O object. And the only way to reclaim the inner I/O type is by calling Tether::into_inner.

Implementations§

Source§

impl<A, R> Tether<TcpConnector<A>, R>
where R: Resolver<TcpConnector<A>>, A: 'static + ToSocketAddrs + Clone + Send + Sync,

Source

pub async fn connect_tcp(address: A, resolver: R) -> Result<Self, Error>

Helper function for building a TCP connection

Source§

impl<P, R> Tether<UnixConnector<P>, R>
where R: Resolver<UnixConnector<P>>, P: AsRef<Path>,

Source

pub async fn connect_unix(path: P, resolver: R) -> Result<Self, Error>

Helper function for building a Unix socket connection

Source§

impl<C: Connector, R> Tether<C, R>

Source

pub fn resolver(&self) -> &R

Returns a reference to the inner resolver

Source

pub fn connector(&self) -> &C

Returns a reference to the inner connector

Source

pub fn context(&self) -> &Context

Returns a reference to the context

Source§

impl<C, R> Tether<C, R>
where C: Connector, R: Resolver<C>,

Source

pub fn new(connector: C, io: C::Output, resolver: R) -> Self

Construct a tether object from an existing I/O source

§Warning

Unlike Tether::connect, this method does not invoke the resolver’s established method. It is generally recommended that you use Tether::connect.

Source

pub fn new_with_config( connector: C, io: C::Output, resolver: R, config: Config, ) -> Self

Source

pub fn set_config(&mut self, config: Config)

Overrides the default configuration of the Tether object

Source

pub fn into_inner(self) -> C::Output

Consume the Tether, and return the underlying I/O type

Source

pub async fn connect(connector: C, resolver: R) -> Result<Self, Error>

Connect to the I/O source, retrying on a failure.

Source

pub async fn connect_without_retry( connector: C, resolver: R, ) -> Result<Self, Error>

Connect to the I/O source, bypassing Resolver::unreachable implementation on a failure.

This does still invoke Resolver::established if the connection is made successfully. To bypass both, construct the IO source and pass it to Self::new.

Trait Implementations§

Source§

impl<C, R> AsyncRead for Tether<C, R>
where C: Connector + Unpin, C::Output: AsyncRead + Unpin, R: Resolver<C> + Unpin,

Source§

fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<()>>

Attempts to read from the AsyncRead into buf. Read more
Source§

impl<C, R> AsyncWrite for Tether<C, R>
where C: Connector + Unpin, C::Output: AsyncWrite + Unpin, R: Resolver<C> + Unpin,

Source§

fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize, Error>>

Attempt to write bytes from buf into the object. Read more
Source§

fn poll_flush( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<(), Error>>

Attempts to flush the object, ensuring that any buffered data reach their destination. Read more
Source§

fn poll_shutdown( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<(), Error>>

Initiates or attempts to shut down this writer, returning success when the I/O connection has completely shut down. Read more
Source§

fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize, Error>>

Like poll_write, except that it writes from a slice of buffers. Read more
Source§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored implementation. Read more

Auto Trait Implementations§

§

impl<C, R> Freeze for Tether<C, R>
where C: Freeze, <C as Connector>::Output: Freeze, R: Freeze,

§

impl<C, R> !RefUnwindSafe for Tether<C, R>

§

impl<C, R> Send for Tether<C, R>
where C: Send, <C as Connector>::Output: Send, R: Send,

§

impl<C, R> !Sync for Tether<C, R>

§

impl<C, R> Unpin for Tether<C, R>
where C: Unpin, <C as Connector>::Output: Unpin, R: Unpin,

§

impl<C, R> !UnwindSafe for Tether<C, R>

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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