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

Rename "task" to "future" in futures API #1087

Closed
MajorBreakfast opened this issue Jul 14, 2018 · 9 comments
Closed

Rename "task" to "future" in futures API #1087

MajorBreakfast opened this issue Jul 14, 2018 · 9 comments

Comments

@MajorBreakfast
Copy link
Contributor

MajorBreakfast commented Jul 14, 2018

This week I explored the code of the futures 0.1's task system. I realized that in futures 0.1 a task was this thing:

pub struct Task {
    id: usize,
    unpark: TaskUnpark,
    events: UnparkEvents,
}

In 0.3 the most similar thing to this is the context. In 0.1 there was of course always a future associated with each task. There's so much existing meaning attached to what a task is. It should be seriously considered whether we want to continue using the term "task" in 0.3. In 0.3, basically what we call a "task" is just a static future with output () that is spawned. We could use the term "task" for it, but should we?

Specifically I'd like to change these occurrences from "task" to "future":

https://github.com/rust-lang/rust/blob/ccade97544d34f42c37fc27fe8c7edba05d3eddb/src/libcore/task/executor.rs#L32

https://github.com/rust-lang/rust/blob/ccade97544d34f42c37fc27fe8c7edba05d3eddb/src/libcore/task/executor.rs#L79

Edit: Heh... and the core::task module is of course also called "task". It was decided to make it an extra module because it is planned that it should contain shared code between stream and future. And "A task is a ()-producing async value", i.e. a future. Considering this, the name seems not so suitable.

@seanmonstar
Copy link
Contributor

I can't tell if your edit is saying the proposed changes to futures is not so suitable, or the existing name of task.

For the initial question, I think keeping task makes is nicer. A task is the concept of a unit of work being driven by an executor. It can't be an arbitrary future, it has to be one that yields nothing. It also represents streams and sinks and IO and whatever. So task seems more appropriate.

@MajorBreakfast
Copy link
Contributor Author

MajorBreakfast commented Jul 16, 2018

@seanmonstar It seems that you're using a different definition for what a "task" is. I was under the impression that a task has to be a future. This was based on "A task is a ()-producing async value" (executor.rs) because "async value" is a synonym for "future".

I can't tell if your edit is saying the proposed changes to futures is not so suitable, or the existing name of task.

The latter: I'm saying that "task" isn't a good name for the module. If the term "task" already refers to a future driven by an executor, then it does't make sense to reuse it as the name for a module that contains shared functionality between the stream and future modules.


I always disliked the term "task" because it is so imprecise: What exact condition has to be met for a future to become a task? Let's define it as a "top level" future run by an a executor. Considering that LocalPool is just a thin wrapper around FuturesUnordered, is every future in FuturesUnordered then also a task? FutureUnordered does however neither require a static lifetime nor () as output. So, no? Does associating a waker with the future turn it into a task? Or is every future that is polled a task? Why is "top level" significant?

The term "task" is used everywhere in the docs and code comments, but when I want to place my finger on its meaning, I can't do it. So, what exactly is a "task" supposed to be and why do we need a special name for it? If it were up to me there would be no tasks and just polled/executed futures.

(Although, internally I would like to use the term "task" for the{ future, exec, wake_handle } struct in thread_pool.rs. ATM I can't because the future inside it is currently called a task. A task field within a Task struct wouldn't make sense...)

@MajorBreakfast
Copy link
Contributor Author

MajorBreakfast commented Jul 16, 2018

Also the term "task system" comes up from time to time. What does it mean? How is it different from an "executor"? I do understand what it means. But, my understanding is rather vague. If I had to define precisely what it means, e.g. describe what the difference to an executor is, I would have to pass.

In the past weeks I've touched a lot of code in the futures crate's 0.3 branch. The fact that I still cannot come up with a definition for "task" that can be consistently applied is bothering me...

@carllerche
Copy link
Member

Im not sure what is difficult, a task is the future spawned on an executor.

You could imagine a separate Task trait with a blanket impl for futures with the write sig.

@MajorBreakfast
Copy link
Contributor Author

MajorBreakfast commented Jul 17, 2018

Im not sure what is difficult, a task is the future spawned on an executor.

@carllerche I opened this issue because I think that the terminology isn't meaningful. Please don't be too annoyed with me asking such questions. All I want is good API design. The issue at hand is not whether it is "difficult", instead it is about why we should want a special name for a future that has no particularly special properties. Being Future<Output = ()> + Send + 'static shouldn't warrant a special term.

You could imagine a separate Task trait with a blanket impl for futures with the write sig.

What would be the purpose of that trait? If it pulls its weight, why don't we have it already? (I read “write sig.” → “right sig.”)

@carllerche
Copy link
Member

I’m not annoyed. I just don’t understand the confusion which makes it hard to respond. I was asking you to elaborate more give my clarification.

Tokio will most likely introduce a Task trait. It will include additional fns to provide more integration with the executor.

@MajorBreakfast
Copy link
Contributor Author

MajorBreakfast commented Jul 17, 2018

@carllerche In that case, here are some concrete questions:

  • Why is in 0.3 the future the task? In 0.1 the task was more like the container that contains the execution environment for a future. The param that I would like to change to "future" is even called "future" in 0.1 https://github.com/tokio-rs/tokio/blob/c17ecb53e7b8be7182198f91010d4c3dc3295126/tokio-executor/src/lib.rs#L137
  • What is the difference between "task system" and the executor? Why do we have two terms? This question is also about why the module in libcore is named "task" not "executor".
  • What methods would be on the task trait you mention? Which types would implement it?

@MajorBreakfast
Copy link
Contributor Author

This PR changes the parameter/fields mentioned above from "task" to "future" and updates the explanations accordingly:

rust-lang/rust#52610

@MajorBreakfast
Copy link
Contributor Author

The PR was merged and the change has been announced in the blog post for alpha 2

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

3 participants