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

Make AsyncStream Sync even if the inner future is not #115

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

swlynch99
Copy link

@swlynch99 swlynch99 commented Mar 4, 2025

There's an old issue (#28) that asked for this and was closed because a &self method was added to AsyncStream in #40. The issue has a pretty good description of why I would like this.

However, if we copy the SyncWrapper type from the internals thread mentioned in that issue then we can use it to wrap the future within AsyncStream and get the whole thing to implement Sync.

The tradeoff is that it is no longer possible to print the debug representation of the inner generator as that would require a shared reference to the future. I don't believe it is currently possible to create an AsyncStream that actually implements Debug using the public API of the crate (as async blocks do not implement Debug) but I figure this is a trade-off worth bringing up. As a middle-ground it might be possible to use some hacks to only format the inner type when it implements Sync.

The AsyncStream has a few methods that that take &self so we don't
necessarily want to unconditionally impl Send for it. However, we only
access the inner future by calling Future::poll.

We can then make AsyncStream Send in a way that is more obviously safe
by wrapping the inner stream in SyncWrapper from [0]. This gets the same
effect (AsyncStream<T> is Sync) but uses only unsafe blocks that are
more obviously safe.

[0]: https://internals.rust-lang.org/t/what-shall-sync-mean-across-an-await/12020/2
@swlynch99
Copy link
Author

I think the test failures are due to changes in rust 1.85 and not this PR (looks like async yield is now maybe available behind #![feature(coroutines)]). If you would like I can submit a PR to update the trybuild reference files.

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

Successfully merging this pull request may close these issues.

1 participant