-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Tracking issue for RFC 2592, futures_api #59113
Comments
The Copying comments: @cramertj Thinking more about how a downcasting strategy would work, it seems critical to me to not directly pass The reason being, when calling the future w/ the Tokio runtime context (reactor, timer, ...), this info can only stay on the stack. The handle that gets cloned to notify should not be the one that gets downcast. It would be very difficult to support this as well as confusing IMO. I suspect that the Tokio runtime context is not the only thing that should not be propagated when cloning the waker. I would strongly recommend switching back to Another example, if there is a task-local storage implementation, the necessary context would need to be passed in via the arg to Future::poll. It is also clear that task-local storage is task local and should not be sent to other tasks. The |
The |
@carllerche I didn't imagine we'd plan to add fields to that VTable in the future, but I have no opposition to future-proofing against that. I've added a bullet to the top of this issue. |
@carllerche Can you say more about what you have in mind for This is what we used to do, so I don't have any particularly strong opposition other than that it complicates the API and has unclear value at this point. If this makes you significantly more comfortable with the API I'm happy to make this change-- it doesn't seem super important to me (extra optional data can always be added through TLS just as well as optional fields of a Does anyone have a particularly good reason we shouldn't do this? If not, then I'll submit a PR since it doesn't seem like a significant enough regression in API readability to block on, and it could make future additions more ergonomic. |
@cramertj Yes, that is correct. The primary reason is forwards compatibility. There are potential additions that can be made to the API but should not be explored immediately. I demonstrated how Thread-locals do not work in environments that do not have access to thread-locals. |
Yup-- these environments often don't have threads, either, though, so |
@carllerche Do you care if it's The current usecase ( |
@cramertj Should it be As the use case for this argument is to pass "task context" into the future that is only usable from that |
|
@jethrogb |
Sorry, nevermind, I'm getting my compiler limitations confused :) |
I think another approach is add another field: |
@crlf0710 How can you be 100% sure that you have been called by your runtime, and not another one, so that it's safe to cast? Futures are interoperable, so a task could be called from various runtimes, even if the code that is current processing the task belongs to a specific runtime (e.g. Tokio). Regarding Context: I'm fine with having it. Maybe making it Regarding future-proofing vtable: It's not totally non-future proof. If we find it out there is a significant reason to change things, we can redefine Another point: As recently discussed in discourse, the way of implementing a |
@Matthias247 There's indeed unsafety, but how can one expect the |
I feel like I'm not understanding the reasoning for preferring It also seems odd to me that stdlib would consider extending std structs with random userland extensions to be the encouraged interface. This would blur the boundaries between what's part of std, and what's added by 3rd parties, which seems like a recipe for confusion. More by Boats → The only argument left for changing the Futures API would be if we were expecting a major addition to the API in std to come along. But given this API has been iterated on for the past 4 or so years, only having an argument of "forwards compatibility" seems unsatisfactory. I would like people to share exactly which extensions to stdlib futures they envision so we can have an open dialogue about them. If we fail to do this, "forwards compatibility" becomes an impenetrable argument that we all just have to accept as a truth without having a chance to explore what it means. Appendixcurrent API fn poll(mut self: Pin<&mut Self>, waker: &Waker) -> Poll<Self::Output>; proposed API fn poll(mut self: Pin<&mut Self>, context: &mut Context<'_>) -> Poll<Self::Output>; let waker = context.waker(); edit (2019-03-16) There seems to be some confusion about the appendix. The "current" API is what is currently in nightly, and the "proposed" API was taken directly from Taylor's PR to replace |
Assuming that TLS == thread local storage (and not task local storage), does using this mechanism force a task to always be run on the same thread? If so, is that a problem? If there are 10 threads and 100 tasks spread across those, would any implementation of task local storage on top of thread local storage require a hashtable-like solution, mapping a given task to its data? Would it still be easy to clean this data up when the task is dropped? |
Can't the executor set the current task-local-storage state in its thread's thread-local-storage before polling a task? A task should only be polled on one thread at a time and this state can move between threads, alongside the task. That could even be integrated in the future without executor support. Simply wrap the task in a future that sets the current storage state in TLS on its poll() method and resets it on exit. We could even handle nested tasks by remembering the old state before overwriting it. Not sure if this is a better approach than passing the state in the context, but it is nonetheless doable. |
Using thread-local state to store context is not free. In Tokio, the work of swapping out all the thread-locals before calling Also, the goal of future proofing the API is to avoid having to explore this path before stabilizing anything. current: fn poll(mut self: Pin<&mut Self>, waker: &Waker) -> Poll<Self::Output>; If worried about typing: proposed: fn poll(mut self: Pin<&mut Self>, task: &mut Task) -> Poll<Self::Output>; The cost of calling |
This was the exact same reasoning against adding an argument to In my experience building and maintaining several heavily depended on libraries, forwards-compatibility is pretty important to consider. I'm not pushing for any particular extra feature beyond waking at the moment. I do think it's early to be absolutely certain we wouldn't want additional context passed to a The ergonomics of creating a waker or context are not as important, it's only going to be done in a couple executor libraries. That it may be a little more annoying isn't reason decide we don't want anything else before knowing. |
@yoshuawuyts In the RFC thread, @brian0 suggested task spawning be made available through the |
Moderation note: This conversation about the Waker vs Context API is currently happening in two places, on the tracking issue and on a PR for a specific proposed API change. Could we please move all further discussion about replacing Waker with a further step of indirection to that PR? @jethrogb that functionality used to exist, but was removed. You can find the discussion about it here: rustasync/team#56 |
Could you provide a link to said PR for those of us who aren't currently following it? |
Future-proof the Futures API cc rust-lang#59113, @carllerche, @rust-lang/libs r? @withoutboats
Future-proof the Futures API cc rust-lang#59113, @carllerche, @rust-lang/libs r? @withoutboats
Future-proof the Futures API cc #59113, @carllerche, @rust-lang/libs r? @withoutboats
Future-proof the Futures API cc #59113, @carllerche, @rust-lang/libs r? @withoutboats
This is a tracking issue for the
std::{future, task}
RFC 2592 under the feature gatefutures_api
.Steps:
futures-preview
and some existing uses of it (Fuchsia) to the latest unstable API to ensure compatibility.RawWakerVTable
fields private and add aconst fn
constructor.Unresolved questions from FCP:
Future::poll
take&Waker
or a&Context
from which an&Waker
can be obtained?The text was updated successfully, but these errors were encountered: