-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Consider adding a TypedExecutor trait #625
Comments
I'm wondering if, instead of adding a new trait, we could make the current pub trait Executor<T = Box<Future<Item = (), Error = ()> + Send>> {
fn spawn(&mut self, future: T) -> Result<(), SpawnError>;
} I also think that this would be backwards compatible. @hawkw could you try making the above change and see if our stack compiles? (we need our own crater). |
I've made the change @carllerche described in #625 (comment) in a branch, and so far, it at least seems to be backwards-compatible within I'm going to do some additional testing against the rest of the stack, such as My two cents: I think this is an excellent idea --- potentially we can reduce a lot of code duplication, hopefully without making a breaking API change. |
An update: I've tested the branch I linked above against As a side note, |
@seanmonstar has made good progress figuring out how this would fit together in a library. Libraries like hyper need to spawn tasks that are composed of futures provided by the user. Hyper would like to be able to use the threaded runtime when the user tasks are The proposed strategy for this case is as follows: Assuming that a library takes a user provided future of type struct MyLibTask<T> { ... }
impl<T> Future for MyLibTask<T> { ... } The The library then defines a new trait, with a blanket implementation. The trait is part of the library's public API. use tokio_executor::TypedExecutor;
/// Documentation explaining that the user should pass in either Tokio's threaded
/// runtime's executor or the current_thread's runtime's executor depending on if
/// `T` is `Send` or `!Send`.
pub trait MyLibExecutor<T>: TypedExecutor<MyLibTask<T>> { }
impl<T, E: TypedExecutor<MyLibTask<T>> MyLibExecutor<T> for E { } Then, the library accepts impl Builder {
fn executor<T, E: MyLibExecutor<T>>(self, executor: E) -> Self { ... }
}
// Usage
my_lib::Builder::new()
.executor(exec)
.build() |
nvm: the blanket impl is private. we do prevent users from implementing their own custom executor that only takes certain futures, but that's probably not so important. |
If I'd say I'm looking forward to see this |
Motivation
The current executor trait requires that spawned tasks are
Send
. This prevents libraries from being able to spawn while supporting the!Send
use case.Proposal
The following trait would be added to
tokio-executor
:This trait would be in addition to the curreent
Executor
trait.The concurrent runtime would have the following implementation:
The
currrent_thread
runtime would have:Then, libraries that require spawning tasks would be able to be generic over this
TypedExecutor
:This way, users of the library are not forced to make
T: Send
.Open questions
Should there be blanket implementations between
Executor
andTypedExecutor
? If so, what direction should they go?Should there also be a
LocalExecutor
trait is the same asExecutor
but accepts tasks that are not!Send
?Follow up
Add
spawn_handle
: #638Refs: #446, hyperium/hyper#1670
The text was updated successfully, but these errors were encountered: