3 ms·
I think it's worth understanding why you need Arc and RwLock here. If the compiler fails to type check because a future is not Send, it means that the future's
by duped 3y ago
I think it's worth understanding why you need Arc and RwLock here.
If the compiler fails to type check because a future is not Send, it means that the future's context holds onto some state that is not safe to be sent to a different thread. For example, holding a reference to something on the stack across an await point. If it fails because something is not Sync, it means the future's context holds onto some state that is potentially accessed concurrently from multiple threads.
If you write your async code such that it does not have these concurrency bugs then you don't have a problem. Arc is a convenient way to make something that is Send and RwLock is a convenient way to make something Sync. You can also fix your code by not introducing concurrency bugs.
This isn't perfect though because the errors are often cryptic. You can have a function that is fine in one context completely break when called in another with "future is not send". And good luck identifying where the bug is and how to fix it.
As for constructing a future directly, sure you can do that. But keep in mind Rust futures aren't promises that just wrap some .then callback. They are types that implement the Future trait which has a method .poll that takes self by Pin and a Waker object to prevent the underlying data from being moved and invalidating references as well as wake other pending futures. If that sounds complex, it is, because async in Rust is actually super complicated and the syntactic sugar does a massive amount of work.
- vacuity 3y agoThe lengths that the Rust devs went through to minimize the overhead of async/await is impressive but also horrifying. And unfortunately, async/await certainly isn't a zero-overhead abstraction if you consider ergonomics/learnability. I wonder if it can evolve without breaking backwards compatibility.