6 ms·
Asynchronous Programming in Rust book
- cjohansson 8y agoSounds like an interesting book, the Rust Programming Language book was a great read (https://doc.rust-lang.org/stable/book/ https://doc.rust-lang.org/stable/book/)
- Dowwie 8y agoThis book is largely a work in progress, still -- note all of the TODO's. Async-await designs have to stabilize before the rest is done.
- amelius 8y agoAlso known as: collaborative multitasking.
- est31 8y agoThere isn't too much activity on this book [1] but I definitely think that more documentation about async programming in Rust is needed. Just recently I wanted to do something in async Rust and it's just such a PITA. I'm writing Rust since 3-4 years now and async throws me back to those first days where I didn't know how to cope with the error messages. Hopefully async/await syntax will improve this experience, but even then I think that documentation is needed. The futures crate is severely underdocumented. I'd love to have an example snippet next to each combinator etc. [1]: https://github.com/rust-lang/async-book/commits/master https://github.com/rust-lang/async-book/commits/master
- steveklabnik 8y agoThere's just been too much change too quickly. When it settles down, it'll get documented.
- etxm 8y agoThe documentation is asynchronous. I’ll show myself out.
- agumonkey 8y agoawait oriented pedagogy
- logicalshift 8y agoHi, you might be interested in a crate I wrote called desync: https://docs.rs/desync/0.3.0/desync/ https://docs.rs/desync/0.3.0/desync/ - it provides a very simple yet expressive API for performing asynchronous operations and has full support for the futures crate. It can be learned really quickly. Desync takes a slightly different approach to asynchronous programming: instead of being based around the idea of scheduling operations on threads, and then synchronising data across those threads, it's based on the idea of scheduling operations on data. There's only two basic operations: 'desync' runs an operation on some data in the background, and 'sync' runs one synchronously. All operations are run in order and 'sync' returns a value so it's a way to retrieve data from an asynchronous operation. It's sort of like setting up some threads with some data protected by a mutex and sending results between them using mpsc channels, except without the need to build any of the scaffolding. ('sync' also makes borrowing data from one task to use in another effortless)
- shadowmint 8y agoIs it just me, or is the fact that the most important part: https://rust-lang.github.io/async-book/getting_started/state_of_async_rust.html https://rust-lang.github.io/async-book/getting_started/state... Is missing, somewhat ironic? Feels very much like the state of async matches the state of the guide. :P What is the state of async? Is it close? Is it still changing with the futures 0.3-beta not finalized? Are we six months away? A year?
- portmanteaufu 8y agoYou can track the progress of the remaining issues here: https://areweasyncyet.rs/ https://areweasyncyet.rs/
- shadowmint 8y agoI know, but I still struggle to get a handle on the state of it really. What is going on with futures 0.3? Why is everyone still using 0.1? How does that relate to these issues? It superficially appears like the whole async story is still in a concept stage...
- thramp 8y ago> What is going on with futures 0.3? Why is everyone still using 0.1? Futures 0.3 uses nightly only-features that are landing in Rust within (hopefully) the next two releases of Rust. Namely, Futures 0.3 is a way to experiment with async programming using the async/await syntax. > Why is everyone still using 0.1? Futures 0.3 is still in flux—but settling down in recent weeks—and is relying on nightly-only features. Futures 0.1 is used heavily in Hyper and Tokio, but we intend to move to Futures 0.3/std::future::Future when they're available on stable or shortly thereafter. (The Tokio and Hyper projects take backwards compatibility _extremely_ seriously.) (Disclaimer: I help maintain Tokio/Hyper, but am nowhere near are prolific as the main authors.)
- leshow 8y ago> What is going on with futures 0.3? Why is everyone still using 0.1? AFAIK becaue tokio isn't upgrading until some issues are ironed out. As long as tokio is on 0.1 the rest of the community will be on 0.1 too.
- kingosticks 8y agoI think I'm correct in saying you don't need tokio for async but it seems all non-toy code uses it. Are there any alternatives to tokio out there for writing real async code or is the idea to build everything on it? As if it was std, but it's not... right?
- bugmen0t 8y agoIf you need less abstractions over protocols, you might look into [mio](https://github.com/carllerche/mio https://github.com/carllerche/mio).
- steveklabnik 8y agoSorta, kinda. One big example of when you wouldn't use Tokio is when you don't have an operating system. Tokio is a good, default choice, but some projects may have different needs.
- bluejekyll 8y agoThere are systems that for various reasons can't use Tokio. In my own projects, I know there are people who need things to be generic across any executor implementation, as they can't use Tokio. Tokio itself is great though, so if you have no strong reason not to use it, I'd recommend it.
- Tarean 8y agoThis approach to async programming feels like a much more leaky abstraction than the 'it's basically semaphores' stuff for m:n threads. Though being able to do so much as a library is nice. How does async translate calls to other async functions? Is refactoring into smaller async functions less efficient? If not, how does it deal with (possibly indirect) recursive function calls? Does it give up or select a loop breaker? And what is the purpose of the pingpong between executor->Waker->push onto executor? I am also still unsure what the approach to multithreading might be. Multiple executors with work stealing or one dispatch executor with worker threads or something else still?
- leshow 8y ago> How does async translate calls to other async functions? Is refactoring into smaller async functions less efficient? I believe it builds the calls up into one larger future, so it shouldn't be any less efficient. I can't answer any of the other questions with any certainty.
- steveklabnik 8y ago> How does async translate calls to other async functions? There's nothing special going on. Remember, async on a function is something like async fn function(argument: &str) -> usize { to fn function(argument: &str) -> impl Future<Item=usize> { so, when you call an async function, you get a Future back. That's true even if it's inside of another async function. > If not, how does it deal with (possibly indirect) recursive function calls? Recursive calls to async functions will fail to compile: https://github.com/rust-lang/rust/issues/53690 https://github.com/rust-lang/rust/issues/53690 That said, see that discussion; the trait object form will probably eventually work. Heavy recursion isn't generally Rust's style, since we don't have guaranteed TCO, so you threaten to overflow the stack and panic. > Is refactoring into smaller async functions less efficient? That's a complicated question. It really depends. I don't think it should be, thanks to inlining, but am not 100% sure. > And what is the purpose of the pingpong between executor->Waker->push onto executor? Right now, the best resource is https://boats.gitlab.io/blog/post/wakers-i/ https://boats.gitlab.io/blog/post/wakers-i/ and https://boats.gitlab.io/blog/post/wakers-ii/ https://boats.gitlab.io/blog/post/wakers-ii/ > I am also still unsure what the approach to multithreading might be. You have options! Tokio now does multiple executors with work-stealing by default, in my understanding.
- arve0 8y agoHow much performance is gained by going async instead of blocking threads on modern hardware? Skimmed through https://vorner.github.io/async-bench.html https://vorner.github.io/async-bench.html. If I understand it correctly, one get about twice the performance with async. Is this correct? Seems like a compromise (code complexity vs performance) not worth taking.
- asdkhadsj 8y agoNot to over simplify, but when you say code complexity, are you referring to the code you read? Like, the dev UX? If so, I'd argue that long term once async/await have landed properly, the code largely looks and behaves the same. With that said, I've not even used it yet, because I've got no clue when this is landing enough that I can reasonably use it.. and I'm on Nightly lol.
- arve0 8y ago> are you referring to the code you read? Yes, the code the developer needs to read, write and understand. I'm not familiar of how async/await will be in Rust, but I guess some code differences/complexities can be: 1. Make sure, manually(?), that all things are async / non-blocking. 2. Implementing Future.poll / wrapping types in Future? (What is Pin? ref https://rust-lang.github.io/async-book/execution/future.html https://rust-lang.github.io/async-book/execution/future.html) 3. Async polution, a function that uses async must be async too? 4. Setup some scheduler that maintain how many concurrent async operations one thread has? 5. More verbose error-messages / stack-traces?
- hobofan 8y ago> 3. Async polution, a function that uses async must be async too? Coming from JS, that's a non-problem in Rust. You can easily make a function blocking by creating a event loop and resolving the future you get from another function in it. So when I refactor my code to be async, I'm starting by making a single function async, and the moving the event loop from function to function, until as much of the code is async as I want.