Skip to content
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 providing a way to spawn tasks using a thread-local. #830

Closed
carllerche opened this issue Mar 2, 2018 · 3 comments
Closed

Consider providing a way to spawn tasks using a thread-local. #830

carllerche opened this issue Mar 2, 2018 · 3 comments

Comments

@carllerche
Copy link
Member

carllerche commented Mar 2, 2018

Currently, the strategy for spawning is to require a &mut Context. This means the free spawn function does not actually spawn, but returns a future that spawns when it is polled.

This creates a number of ergonomic issues.

Spawning in a function.

First, this currently is a Tokio example:

fn process(socket: TcpStream) {
    let connection = // stuff
    spawn(connection);
}

listener.incoming().for_each(|socket| {
    process(socket);
    // do other work
});

Moving to the proposed solution, this becomes:

fn process(socket: TcpStream) -> Box<Future<Item = (), Error = ()> + Send> {
    let connection = // stuff
    Box::new(spawn(connection))
}

listener.incoming().for_each(|socket| {
    process(socket).and_then(|_| {
        // do other work
    })
});

Spawning on Drop.

The second problem is that it becomes impossible to spawn in implementations of drop. This is a problem as one pattern for dealing with dropping types that require further async processing to "finalize" is to spawn the finalization logic in a new task. This pattern becomes no longer possible, instead forcing all types to impl a poll_close strategy. This isn't really great as this becomes something that must be threaded through all layers.

Imagine type Foo implements trait Hello and Bar<T: Hello>. Currently, the above strategy can be used to perform any finalization logic necessary without Bar having to opt-in to running this logic before it drops. However, this is no longer possible requiring the addition of some PollClose trait....

Thread-local solution.

Using a thread-local to store the ref to the executor solves both problems.

@cramertj
Copy link
Member

cramertj commented Mar 2, 2018

I think the ergonomic issues around returning a future rather than having a function that resolves immediately will be mostly alleviated by async/await. However, the Drop issue is more interesting. I imagine with language-level async/await support we could add an AsyncDrop trait, which would be useful for more than just this particular case.

cc @withoutboats

carllerche added a commit to tokio-rs/tokio that referenced this issue Mar 2, 2018
Currently, `tokio::spawn` matched the `spawn` function from futures 0.2.
However, this adds additional ergonomic overhead and removes the ability
to spawn from a drop fn. See rust-lang/futures-rs#830.

This patch switches the behavior to access the thread-local variable
referencing the default executor directly in the `spawn` function.
carllerche added a commit to tokio-rs/tokio that referenced this issue Mar 2, 2018
Currently, `tokio::spawn` matched the `spawn` function from futures 0.2.
However, this adds additional ergonomic overhead and removes the ability
to spawn from a drop fn. See rust-lang/futures-rs#830.

This patch switches the behavior to access the thread-local variable
referencing the default executor directly in the `spawn` function.
@aturon
Copy link
Member

aturon commented Mar 21, 2018

I'm going to close this for the time being, as per @cramertj's comment, and given that Tokio currently has a workaround. We can revisit this as needed later on, when things with async/await are more clear.

@aturon aturon closed this as completed Mar 21, 2018
@seanmonstar
Copy link
Contributor

Wouldn't this be possible to tap the current executor thanks to the Enter API?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants