-
Notifications
You must be signed in to change notification settings - Fork 202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Non-tokio executor & timeouts #297
Comments
It is possible to use your own runtime, provided that it is within the context of Tokio. |
@vorot93 The problem with the Tokio context is twofold:
Speaking as a previous Tokio developer and somebody who has been building the async Rust ecosystem for the past several years, I have no idea how to make a "hello world" example of I read @carllerche's example you linked to, but how do you substitute Whenever the concern of Tokio's incompatibility with other libraries is brought up, the argument is that it's possible to set up the Tokio context inside other runtimes. But until the Tokio documentation shows the most basic "hello world" of how to do that, it is simply not possible to use Tokio with the rest of the async ecosystem. @vhdirk Possible runtime-agnostic solutions are |
Hey, so I spent a few minutes this morning throwing together an example of using tokio with the futures executor https://gist.github.com/LucioFranco/ec8c6617b7193fd062d1ddc32b5bb991 Most of the complexity here is making it easy to spawn the future with a global runtime. Otherwise, the main thing here is just wrapping the Hopefully, this is helpful! We could probably add this as an example to the tokio repo. |
@LucioFranco Thank you, this is the first runnable example that I've encountered! Still, I must admit that the code is quite intimidating for a 'hello world'. If I may make a few suggestions on how to improve the situation:
If you're looking for the most bang-for-buck, you could just make the following two examples:
|
@stjepang this is some great feedback! I will make sure we incorporate a lot of these ideas into tokio 0.3. Will follow up with a proper issue in tokio. Thanks! |
This is something tarpc doesn't handle very gracefully today: tokio is an optional feature, and yet tarpc uses tokio timers regardless of whether the tokio feature is enabled. Is it possible to set up just the tokio timer without setting up a full tokio runtime? |
@tikue you need something to drive the timer, in tokio we use epoll_timeout/sleep to achieve this. So you need to run the driver anyways. This is the case for every runtime. @stjepang I've opened a bunch of issues in tokio that should cover some of this. Thanks again for the feedback! |
@LucioFranco yeah totally, I know there's no getting around that :) but is there a way to set up just the timer's required runtime rather than a full tokio runtime? Sorry if this is a dumb question; I've just kinda ignored the runtime details since |
@tikue ah yes! If you look at that example I use |
Nice, thanks! |
I've experimented with replacing something like Tokio MPSC into futures and flume, but so far it fails the test by exceeding the deadline. Yet to have the idea why Anyway, if you are interested checkout https://github.com/stevefan1999-personal/tarpc/tree/patch-no-tokio |
Is it possible to add an abstraction layer for the runtime? Openraft does it in this way: pub trait AsyncRuntime: Debug + Default + PartialEq + Eq + OptionalSend + OptionalSync + 'static {
/// The error type of [`Self::JoinHandle`].
type JoinError: Debug + Display + OptionalSend;
/// The return type of [`Self::spawn`].
type JoinHandle<T: OptionalSend + 'static>: Future<Output = Result<T, Self::JoinError>>
+ OptionalSend
+ OptionalSync
+ Unpin;
/// The type that enables the user to sleep in an asynchronous runtime.
type Sleep: Future<Output = ()> + OptionalSend + OptionalSync;
/// A measurement of a monotonically non-decreasing clock.
type Instant: Instant;
/// The timeout error type.
type TimeoutError: Debug + Display + OptionalSend;
/// The timeout type used by [`Self::timeout`] and [`Self::timeout_at`] that enables the user
/// to await the outcome of a [`Future`].
type Timeout<R, T: Future<Output = R> + OptionalSend>: Future<Output = Result<R, Self::TimeoutError>> + OptionalSend;
/// Type of a thread-local random number generator.
type ThreadLocalRng: rand::Rng;
/// Spawn a new task.
fn spawn<T>(future: T) -> Self::JoinHandle<T::Output>
where
T: Future + OptionalSend + 'static,
T::Output: OptionalSend + 'static;
/// Wait until `duration` has elapsed.
fn sleep(duration: Duration) -> Self::Sleep;
/// Wait until `deadline` is reached.
fn sleep_until(deadline: Self::Instant) -> Self::Sleep;
/// Require a [`Future`] to complete before the specified duration has elapsed.
fn timeout<R, F: Future<Output = R> + OptionalSend>(duration: Duration, future: F) -> Self::Timeout<R, F>;
/// Require a [`Future`] to complete before the specified instant in time.
fn timeout_at<R, F: Future<Output = R> + OptionalSend>(deadline: Self::Instant, future: F) -> Self::Timeout<R, F>;
/// Check if the [`Self::JoinError`] is `panic`.
fn is_panic(join_error: &Self::JoinError) -> bool;
/// Get the random number generator to use for generating random numbers.
///
/// # Note
///
/// This is a per-thread instance, which cannot be shared across threads or
/// sent to another thread.
fn thread_rng() -> Self::ThreadLocalRng;
type Mpsc: Mpsc;
type MpscUnbounded: MpscUnbounded;
type Watch: Watch;
type Oneshot: Oneshot;
type Mutex<T: OptionalSend + 'static>: Mutex<T>;
} |
When using an executor that is different from tokio (in my case glib), launching a request from the client results in the following message at runtime:
It seems tokio timeouts are not compatible with other runtimes. It'd be cool if there was a runtime-agnostic solution. Peraps https://github.com/async-rs/futures-timer ?
The text was updated successfully, but these errors were encountered: