Skip to content

Instantly share code, notes, and snippets.

@ryankurte
Last active April 10, 2019 23:10
Show Gist options
  • Save ryankurte/7c3268155764dd25a1e2bf68c07d498d to your computer and use it in GitHub Desktop.
Save ryankurte/7c3268155764dd25a1e2bf68c07d498d to your computer and use it in GitHub Desktop.
use futures::{future, Future, sync::oneshot};
use tokio::spawn;
/// AsyncWait implements a `.wait()` equivalent that works from any contex.
/// This is required because at some point in the past `.wait()` stopped doing this,
/// and thus calling it in a polling context causes everything to lock up.
/// see: https://github.com/tokio-rs/tokio-core/issues/182 and related issues.
/// ``` norun
/// // This will block forever if run in the main thread context
/// let _client = TcpConnection::<JsonCodec<Request, Response>>::new(&addr, JsonCodec::new()).wait().unwrap();
/// // This will work in the expected manner and return once connection has completed
/// let _client = TcpConnection::<JsonCodec<Request, Response>>::new(&addr, JsonCodec::new()).async_wait().unwrap();
/// ```
pub trait AsyncWait<I, E> {
fn async_wait(self) -> Result<I, E>;
}
impl <F, I, E> AsyncWait<I, E> for F
where
F: Future<Item=I, Error=E> + Send + 'static,
I: Send + 'static,
E: Send + 'static,
{
fn async_wait(self) -> Result<I, E> {
let (tx, rx) = oneshot::channel::<Result<I, E>>();
spawn(self.then(|res| tx.send(res) ).map(|_v| () ).map_err(|_e| () ));
rx.wait().unwrap()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment