-
Notifications
You must be signed in to change notification settings - Fork 654
Proposal: Convention for which types must be used on a Task #250
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
Comments
I feel like the default is likely "needs to be used on a task" because so many things transitively call |
Right, I think this is basically what the proposal states. Part of the issue is that Tokio (and other) APIs don't clearly state this, and some examples are kind of fuzzy. The To elaborate, using my_sink.send(foo).wait(); The |
That being said... always using a |
Adding a quick thought before I forget. @aturon mentioned that in his mind, all functions are safe to call off task unless they include However, today, there are functions that don't return Another issue that I just thought of is that I have often written functions like: fn foo(&mut self) {
if my_sink.poll_complete().is_ready() {
// do some prep work
}
} In cases like this, it is not apparent by the fn foo(&mut self) -> Async<()> {
if my_sink.poll_complete().is_ready() {
// do some prep work
}
Async::Ready(())
} which is a bit silly and then the caller of the function would have to figure out what to actually do with the The original proposal in this thread has the advantage of being "opt-in", so you take an extra step to ensure that a function is safe to call off task which will (hopefully) be less error prone. /cc @aturon |
Perhaps we should consider passing a |
@liran-ringel For reference, this has been discussed here #129 |
What if parking a task didn't panic? Or in other words, park() returned an Option, so implementations can choose to not panic, and just return NotReady if there was no task when needed. |
Obviated with the explicit Context argument |
Currently, it is somewhat unclear how to use the various future types with regards to tasks.
poll
must be called on a task, but besides that, what functions are safe to call vs. not is pretty unclear. Worse, some functions which must be called on tasks may not always fail when called not on a task. These functions may "randomly" panic depending on how concurrent operations complete.Ideally, the type system could be used to enforce at compile time correct usage of future types, however I don't know how possible this is. Instead, I am proposing to clarify the usage of futures with regards to tasks using a convention:
First, please don't focus too much on the prefix
Sync
*, I am just using it for now to make the proposal. Basically, the proposal is to avoid the ambiguity by making it a rule that all future types must be used on a task. This also means that all of the functions / constructors / etc… could have adebug_assert!
that validates that they are called on a task. This should help find bugs quicker.Then, the question is how to use the various future types (
Future
,Stream
,Sink
, …) while not on a task. I propose that all of these traits include async()
fn (again, a work in progress name) that wraps the type and allows it to be used off task. For example:The same could be done for
Stream
andSink
(thoughSyncSink
is an odd name…)This would involve restructuring the APIs to setup users for success. For example, off the top of my head, Tokio's current API is something like this:
The problem here is that this API is setup to use future types off of the task. You have to know that this is not the right way to do it…
Instead, one option could be to get rid of the
Core::handle()
function, and instead do:* I am using the prefix
Sync
because future types are async, and the opposite of that is sync.The text was updated successfully, but these errors were encountered: