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>
impl<A, R> Tether<TcpConnector<A>, R>
Sourcepub async fn connect_tcp(address: A, resolver: R) -> Result<Self, Error>
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>
impl<P, R> Tether<UnixConnector<P>, R>
Sourcepub async fn connect_unix(path: P, resolver: R) -> Result<Self, Error>
pub async fn connect_unix(path: P, resolver: R) -> Result<Self, Error>
Helper function for building a Unix socket connection
Source§impl<C, R> Tether<C, R>
impl<C, R> Tether<C, R>
Sourcepub fn new(connector: C, io: C::Output, resolver: R) -> Self
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.
pub fn new_with_config( connector: C, io: C::Output, resolver: R, config: Config, ) -> Self
Sourcepub fn set_config(&mut self, config: Config)
pub fn set_config(&mut self, config: Config)
Overrides the default configuration of the Tether object
Sourcepub fn into_inner(self) -> C::Output
pub fn into_inner(self) -> C::Output
Consume the Tether, and return the underlying I/O type
Sourcepub async fn connect(connector: C, resolver: R) -> Result<Self, Error>
pub async fn connect(connector: C, resolver: R) -> Result<Self, Error>
Connect to the I/O source, retrying on a failure.
Sourcepub async fn connect_without_retry(
connector: C,
resolver: R,
) -> Result<Self, Error>
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> AsyncWrite for Tether<C, R>
impl<C, R> AsyncWrite for Tether<C, R>
Source§fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, Error>>
fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize, Error>>
buf into the object. Read moreSource§fn poll_flush(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), Error>>
fn poll_flush( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<(), Error>>
Source§fn poll_shutdown(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), Error>>
fn poll_shutdown( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<(), Error>>
Source§fn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[IoSlice<'_>],
) -> Poll<Result<usize, Error>>
fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize, Error>>
poll_write, except that it writes from a slice of buffers. Read moreSource§fn is_write_vectored(&self) -> bool
fn is_write_vectored(&self) -> bool
poll_write_vectored
implementation. Read more