-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
adds async stream rfc #2996
adds async stream rfc #2996
Conversation
Signed-off-by: Nell Shamrell <nellshamrell@gmail.com>
Co-authored-by: Florian Gilcher <florian.gilcher@asquera.de>
Co-authored-by: Florian Gilcher <florian.gilcher@asquera.de>
Co-authored-by: Waffle Lapkin <waffle.lapkin@gmail.com>
Co-authored-by: kennytm <kennytm@gmail.com>
Co-authored-by: Taiki Endo <te316e89@gmail.com>
Signed-off-by: Nell Shamrell <nellshamrell@gmail.com>
We discussed this amongst the lang team at some point and concluded that this does not require @rust-lang/lang signoff. I've tagged it for @rust-lang/libs. |
Also cc @rust-lang/wg-async-foundations |
👍 to adding Also: could we please standardize a method for converting from Iterator to Stream? That may not be able to use IntoStream (because a blanket impl for Iterator would conflict with more specific impls people may want to write), but having a function that takes an |
Signed-off-by: Nell Shamrell <nellshamrell@gmail.com>
Signed-off-by: Nell Shamrell <nellshamrell@gmail.com>
@joshtriplett The conversation around whether to add
@joshtriplett |
@yoshuawuyts To clarify, neither of those comments was intended as a blocker to this RFC. I think it makes sense to add a minimal implementation of |
Information about converting an iterator to a stream has been added :) |
I finally got around to reading, this looks pretty good, I think including next is +1. I would really really like to see Another example of Thanks a ton @nellshamrell and other for pushing this through 😄 |
I'm not sure where to comment on this, but given that this RFC discusses With the idea that the single liftime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some minor typos, please check it out, I'm not a native speaker there might be mistakes.
That's an amazing job by the way, really like reading the rfc. Hope it would be approved soon.
@LucioFranco I covered that earlier in the thread #2996 (comment):
I see We're both part of the Async Foundations WG, and we've had the privilege of being able to set the direction of this RFC. And that was a success; we have consensus on everything included here! I think now is the time to ensure what's in this RFC is accurate, but not seek to expand its scope with subjects we then newly need to find consensus on. |
To ensure I understand, the role of while let Some(foo) = stream.try_next().await? {
} as opposed to this? while let Some(foo) = stream.try_next().await {
let foo = foo?;
} Hmm, I'm torn. I agree with @yoshuawuyts that we should avoid increasing the scope of the RFC in general, which is intentionally targeted. But I also think that the point of including I would want to hold the line against other forms of "scope creep", the only reason I can see to consider |
Thinking on it more, I think what I'd prefer is to leave the RFC unaltered, land it, and consider |
@yoshuawuyts sure, I am pretty sure I voiced my opinion during that period. It's also my fault for not pushing it harder, I got busy and that happens. I still don't follow your argument you referenced with iterators. I think Streams are not 1:1 with iterators but I rest my case. @nikomatsakis right, I think most streams I have worked with return some sort of result so avoiding the first example in favor of the second is much nicer. I think its fine to punt on this for now, just knowing that I think this is extremely useful. My question then is, what does that path look like to add |
The alternative to while let Some(foo) = stream.next().await.transpose()? {
} which is a pattern I've started using with fallible iterators as well, having to use a |
|
Re: the use of the Maybe I realise that while let Ok(msg) = channel.receive_next().await {
// Handle message...
}
impl<M> Channel<M> {
fn receive_next(&mut self) -> impl Future<Output = Result<M, RecvError>> { /* ... */ }
} It creates short lived |
consider `next`, which when called, returns a future which yields | ||
`Option<Item>`. | ||
|
||
The future returned by `next` will yield `Some(Item)` as long as there are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The future returned by
next
will yieldSome(Item)
as long as there are elements
How does this play with fuse
considering the future exhausted after the first Poll::Ready
? Is the idea that you can either rely on that implementation detail for next
and continue to pull items using the same future or get a new one after the previous next
resolved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @KodrAus - the answer on this one is I honestly don't know. I'm happy to include a note that this will need to be considered in the eventual RFC and implementation of the next
method. Would that be sufficient, since this is in the Future Possibilities section?
} | ||
``` | ||
|
||
## Initial impls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found myself wanting to see the contents of the More Usage Examples section here first after we defined our Counter
to see what it's like to interact with on the consuming side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @KodrAus - I intentionally did not include the consuming side here since the next
method has been moved to the "Future Possibilities" section. I felt including that here would introduce more confusion about what is and is not covered by this RFC.
@rust-lang/libs I've dropped a link to the FCP in the OP here, since it's gotten quite buried. |
Perhaps this is the case, but I think it would be a shame for This also means that there is no longer a natural duality between |
Hello @rust-lang/libs :) For those of you who have not yet approved FCP in this comment - are there any concerns you have or is there anything blocking approving this for FCP? |
@zesterer thank you for your comments, they encouraged us to think even more carefully about the design of this feature. I am going to leave the design as it is now as a minimal viable implementation, but we have your concerns about channels recorded here for future reference. I have no doubt we will be opening more RFCs around Async streams in the near future and we will certainly keep your concerns in mind. Thank you again, the community input and context is vital to any RFC. |
Add `core::stream::Stream` [[Tracking issue: rust-lang#79024](rust-lang#79024)] This patch adds the `core::stream` submodule and implements `core::stream::Stream` in accordance with [RFC2996](rust-lang/rfcs#2996). The RFC hasn't been merged yet, but as requested by the libs team in rust-lang/rfcs#2996 (comment) I'm filing this PR to get the ball rolling. ## Documentatation The docs in this PR have been adapted from [`std::iter`](https://doc.rust-lang.org/std/iter/index.html), [`async_std::stream`](https://docs.rs/async-std/1.7.0/async_std/stream/index.html), and [`futures::stream::Stream`](https://docs.rs/futures/0.3.8/futures/stream/trait.Stream.html). Once this PR lands my plan is to follow this up with PRs to add helper methods such as `stream::repeat` which can be used to document more of the concepts that are currently missing. That will allow us to cover concepts such as "infinite streams" and "laziness" in more depth. ## Feature gate The feature gate for `Stream` is `stream_trait`. This matches the `#[lang = "future_trait"]` attribute name. The intention is that only the APIs defined in RFC2996 will use this feature gate, with future additions such as `stream::repeat` using their own feature gates. This is so we can ensure a smooth path towards stabilizing the `Stream` trait without needing to stabilize all the APIs in `core::stream` at once. But also don't start expanding the API until _after_ stabilization, as was the case with `std::future`. __edit:__ the feature gate has been changed to `async_stream` to match the feature gate proposed in the RFC. ## Conclusion This PR introduces `core::stream::{Stream, Next}` and re-exports it from `std` as `std::stream::{Stream, Next}`. Landing `Stream` in the stdlib has been a mult-year process; and it's incredibly exciting for this to finally happen! --- r? `````@KodrAus````` cc/ `````@rust-lang/wg-async-foundations````` `````@rust-lang/libs`````
Gentle ping to @rust-lang/libs - this only needs one more approval for FCP! |
Approving on behalf of withoutboats, as per rust-lang/team#526. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
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. |
FCP has been complete for a bit over a month now, is something else missing for this to be merged? |
No! I thought I did the merge! Maybe I forgot to push? |
Hmm, maybe I removed the merge commit or something. I'm not sure why github doesn't show this as merged but .. it is. Going to close! |
Looks like a rebase instead of a merge, and GitHub only "understands" command-line PR merging if the exact original commits are included (i.e. if it's a merge or fast-forward, not rebase or squash). |
Yeah I guess I rebased without realizing it. Oh well! |
|
||
Unfortunately, async methods in traits are not currently supported, | ||
and there [are a number of challenges to be | ||
resolved](https://rust-lang.github.io/wg-async-foundations/design_notes/async_fn_in_traits.html) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Broken link
with them. | ||
|
||
Unfortunately, the use of poll does mean that it is harder to write | ||
stream implementations. The long-term fix for this, discussed in the [Future possiblilities](future-possibilities) section, is dedicated [generator syntax]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Broken link
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any chance you can open a PR with fixes?
Recently tokio got a first stable release and many libraries & applications already migrated to the newest version. This changes upgrades tokio version to 1.0.2: * Tokio renamed some of its features, e.g `rt-util` and `rt-core` now combined into `rt`. * `stream` feature got extracted to a separate crate [tokio-stream](https://docs.rs/tokio-stream/0.1.2/tokio_stream), waiting for eventual `Stream` landing to the Rust std library. [RFC](rust-lang/rfcs#2996) [TODO] Actix's integration test_actix_ws_integration test still fails due to, I guess, async rt is not being initialized. Apart from that, the tests are green. Please feel free to take over this effort.
Rendered
Pre-RFC Discussions
Draft 1
Draft 2
Draft 3
Draft 4
Signed-off-by: Nell Shamrell nellshamrell@gmail.com
Current FCP: #2996 (comment)
Status: merged