rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.35k stars 12.72k forks source link

[Stabilization] Future APIs #59725

Closed withoutboats closed 5 years ago

withoutboats commented 5 years ago

Feature name: futures_api Stabilization target: 1.36.0 Tracking issue: #59113 Related RFCs:

I propose that we stabilize the futures_api feature, making the Future trait available on stable Rust. This is an important step in stabilizing the async/await feature and providing a stable, ergonomic, zero-cost abstraction for async IO in Rust.

The futures API was first introduced as a part of the std library prior to 1.0. It was removed from std shortly after 1.0, and was developed outside of std in an external crate called futures, first released in 2016. Since that time, the API has undergone significant evolution.

All the APIs being stabilized are exposed through both core and std.

The future Module

We shall stabilize these items in the future module:

We do not stabilize the other items in this module, which are implementation details of async/await as it currently exists that are not intended to be stabilized.

The task Module

We shall stabilize these items in the task module:

Notice: Late Changes to the API

We have decided to merge the future-proofing changes proposed in #59119 to leave room for some potential extensions to the API after stabilization. See further discussion on that issue.

Notes on Futures

The poll-based model

Unlike other languages, the Future API in Rust uses a poll based execution model. This follows a back and forth cycle involving an executor (which is responsible for executing futures) and a reactor (which is responsible for managing IO events):

Eventually, the future returns ready instead of pending, indicating that the future has completed.

Pinning

The Future trait takes self by Pin<&mut Self>. This is based on the pinning APIs stabilized in 1.33. This contract allows implementers to assume that once a future is being polled, it will not be moved again. The primary benefit of this is that async items can have borrows across await points, desugared into self-referential fields of the anonymous future type.

Changes proposed in this stabilization report

std has unsafe constructors following both names, from_raw is more specific than new_unchecked (its a constructor taking the "raw" type which is possibly invalid, asserting that this instance is valid).

The most common waker implementation is to be an arc of the task which re-enqueues itself when the waker is woken; to implement this by reference, you must clone the arc and put it on the queue. But most uses of wake drop the waker as soon as they call wake. This results in an unnecessary atomic reference increment and decrement; instead we now provide by a by-value and by-reference implementation, so users can use the form most optimal for their situation.

Moderation note

The futures APIs have been discussed at enormous length over the past 3 years. Every aspect of the API has been debated, reviewed and considered by the relevant teams and the Rust community as a whole. When posting to this thread, please make a good faith effort to review the history and see if your concern or proposal has been posted before, and how and why it was resolved.

cramertj commented 5 years ago

@pnkfelix did you mean to stop FCP with that comment? I'm happy to work on fixing #60069-- it's a frankly trivial implementation bug, and I don't think FCP for this issue should be delayed by it.

cramertj commented 5 years ago

A fix is ready in https://github.com/rust-lang/rust/pull/60088.

pnkfelix commented 5 years ago

@cramertj my goal was to register a blocking issue. I did not mean for the FCP timer to be reset (that is, I did not realize that would be a consequence of filing such a concern), but I did want to ensure that the future API's would not be stabilized with that issue outstanding.

cramertj commented 5 years ago

Yeah, I'm not sure we have a lever for that unfortunately. It seems like what you'd want is to issue a blocking concern on the stabilization PR so that that PR can only be merged once the issue is fixed, but I don't think we have a mechanism for that at the moment other than leaving a comment.

lnicola commented 5 years ago

Will the timer resume after the concern is marked as resolved, or will it reset to 10 days?

cramertj commented 5 years ago

@lnicola The current behavior is set to reset to 10 days. However, I think there's consensus around stabilizing at the end of the original FCP provided that #60088 lands first.

Centril commented 5 years ago

Yep. Remember that rfcbot is a tool. We don't have to always follow the bot to the letter.

lnicola commented 5 years ago

60088 has landed.

golddranks commented 5 years ago

It has now been 10 days since the final comment period started.

Centril commented 5 years ago

@pnkfelix Can you checkout https://github.com/rust-lang/rust/pull/60088 to see if you are happy?

pnkfelix commented 5 years ago

@rfcbot resolve async-fn-should-not-be-allowed

rfcbot commented 5 years ago

:bell: This is now entering its final comment period, as per the review above. :bell:

shengsheng commented 5 years ago

@rfcbot another ten days?

cramertj commented 5 years ago

nah, now we get to ignore rfcbot ;)

Centril commented 5 years ago

Stabilization PR was merged. Leaving this issue open to let FCP complete naturally. Closing when that happens.

ohsayan commented 5 years ago

@Centril How far is 1.36.0 from roll-out?

Mathspy commented 5 years ago

@sntdevco https://forge.rust-lang.org

rfcbot commented 5 years ago

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

The RFC will be merged soon.