29 ms·
Async-std: an async port of the Rust standard library
- lachlan-sneff 7y agoThere is further discussion about this library on the rust subreddit: https://www.reddit.com/r/rust/comments/cr85pp/announcing_asyncstd_beta_an_async_port_of_the/ https://www.reddit.com/r/rust/comments/cr85pp/announcing_asy...
- evmar 7y agoIn case anyone else was curious how you create nonblocking file I/O, it appears to use threads. I am curious if the number of threads is unbounded, or if they have a bounded set but accept deadlocks, or if there is a third option other than those two that I am unaware of.
- slovenlyrobot 7y agoio_uring grew support for buffered IO in recent kernels, so we should have widespread support for this in userspace circa 2025
- monocasa 7y agoOr just detect it and swap out the implementation. Less than a year until an Ubuntu LTS that has it.
- slovenlyrobot 7y agoI should have written 2035 to make the sarcasm a little clearer :)
- dmytroi 7y agoExcept that io_uring is threads running in kernel. There is no true async I/O on most (if not all) current platforms - it's all threads, either in user space or in kernel space. Sometimes even deliberately, for example polling disk will give better latency compared to waiting for IRQ.
- slovenlyrobot 7y agoAFAIK Windows handles truly asynchronous buffered IO in some circumstances, but I feel once you're past the point of managing the abstraction or caring about its internal details, it doesn't really matter if there is a tiny chunk of dedicated stack in the kernel, that's a problem for the OS
- dmytroi 7y agoYes, IOCP looks like true async I/O most of the time. While in reality it will block if file is cached, in cases if code tries to read something like 100+ MB at a time ReadFile calls can take 200ms+. So most "async I/O" frameworks have to wrap IOCP into a user space thread ...
- for_xyz 7y agoOr disable caching for specified file when calling CreateFile API https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew https://docs.microsoft.com/en-us/windows/win32/api/fileapi/n...
- dboreham 7y agoAlso VMS..
- wahern 7y agoIOCP uses a pool of quasi-kernel threads (i.e. schedulable entity with a contiguous stack for storing state) with polling, very much like how io_uring and other incarnations of AIO in the Linux kernel work; and for that matter it's not unlike how purely user space AIO implementations work. The benefit of IOCP and io_uring is there's one less buffer copying operation. The biggest benefit of IOCP, really, is that it's a blackbox that you can depend on, and one that everybody is expected to depend upon. So it can be whatever you want it to be ;)
- Matthias247 7y ago> OCP uses a pool of quasi-kernel threads Is there any further documentation for it? I would have expected there doesn't need to be a real stack. Only state-machines for all the IO entities (like sockets) which get advanced whenever an outside event (e.g. interrupt) happens and which then signal the IO completion towards userspace. Didn't expect that it's necessary to keep stacks around.
- layoutIfNeeded 7y agoNon-blocking I/O via threads? That’s what we used to call blocking I/O :D
- rmgraham 7y agoAre those really the only options? I'm trying to wrap my head around how using a fixed size thread pool for I/O automatically implies deadlocks but I just can't. Unless the threads block on completion until their results are consumed instead of just notifying and then taking the next task.. I can definitely imagine blocking happening while waiting for a worker to be available, though. Did you mean simply blocking instead of deadlock?
- spullara 7y agoN threads, with N readers waiting for a message that will only come if the N+1 reader (still in the queue) gets a message first.
- nine_k 7y agoBut sure one must use an output queue, not synchronously wait for the consumer to consume a result?
- spullara 7y agoThe N + 1 readers are all reading different sockets, blocked.
- rmgraham 7y agoThank you for humoring me. I had to sleep on it, but I can see it now. Seems like it would require a really bad design or more likely bad actors (remotes leaving dead sockets open), but it would definitely be possible. The same scenarios would lead to resource exhaustion if the thread pool wasn't bounded.
- Argorak 7y agoNote that the implementation of the runtime itself is subject to change. It's currently an unbounded threadpool. https://github.com/async-rs/async-std/pulls?utf8=%E2%9C%93&q=is%3Apr+author%3Aspacejam+is%3Aclosed+thread https://github.com/async-rs/async-std/pulls?utf8=%E2%9C%93&q...
- davidhyde 7y agoGreat library, well done. In case anyone was wondering this is not a [no_std] crate even though it can be used as a replacement for std library calls. I guess it (obviously) can't be since it interfaces with the operating system so much.
- Argorak 7y agoProject member here. It exports stdlib types (like io::Error) where appropriate so that libraries working with these can stay compatible, so `no_std` is not really an option. The underlying library (async-task) is essentially core + liballoc, just no one made the effort to spell that out, yet.
- davidhyde 7y ago> It exports stdlib types (like io::Error) Excellent, good to know!
- thethirdone 7y agoWould there be any benefit to making a `no_std` option? I can't think of a situation you would want async std and have including std be a problem.
- jeremyjh 7y agoThe benefit would be you would be making it impossible to wreck your scheduler by calling sync I/O functions in an async task.
- Argorak 7y agoI wouldn't rely on that. Next step, someone binds to a blocking database driver and you are back at square 1 again. This is definitely not rigorous. I would love to see a lint for known-blocking constructs in async contexts, though: https://github.com/rust-lang/rust-clippy/issues/4377 https://github.com/rust-lang/rust-clippy/issues/4377 Also, having explicit imports and types that name collide helps there for once.
- Un1corn 7y agoThis remind me of the blog post "What Color is Your Function?"[0], they had to create a different library that is the same as the standard library but with async functions. I thought Rust had other, better ways to create non-blocking code so I don't understand why to use async instead. [0] https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...
- pohl 7y agoThe caller of the function knows nothing about what happens within the body of the function. (Is it just doing computation, or is it doing I/O?). The async keyword is how the author of the function makes it explicit that caller should choose when to await the result. Isn't the alternative WCiYF is proposing to allow the caller to treat any function asynchronously, while having no way to discern whether doing so might be counterproductive?
- Argorak 7y agoRust async functions are also different here. They don't run the code, they create a Future structure in it's initial state. Contrary to e.g. JavaScript, it doesn't start to run until you end up putting it on an executor. So the actual function call does something very different from what happens in other languages. It's sometimes called "cold futures".
- aphexairlines 7y agoSounds similar to what the Scala ecosystem calls Tasks. https://monix.io/docs/3x/eval/task.html#introduction https://monix.io/docs/3x/eval/task.html#introduction https://github.com/traneio/arrows#using-task https://github.com/traneio/arrows#using-task
- Argorak 7y agoIt's similar in some ways, yes. As always, details and labels differ.
- jedisct1 7y agoHow does it balance tasks across CPU cores? The thing I like in Go is that I don’t have to worry about that, it’s all automatic.
- pythonist 7y agoI am wondering that also, scheduler is of most importance. Go is such a joy to work with.
- Argorak 7y agoIt does the scheduling for you. That's why all Futures put onto task through `async_std::task` must be `Send`. That's Rust parlance for "can be safely migrated between threads". It's not Go, but we know what people like about Go. <3
- pcwalton 7y agoIn Rust you use async/await with a scheduler like mio that will automatically do that for you as well.
- littlestymaar 7y agoHas preemptive scheduling landed in Go ? Because last time I worked with it (Go 1.10) it was still cooperative and you had to worry about it otherwise you could get bitten badly.
- 2bitencryption 7y agoI must be dumb, because every time I dive into async/await, I feel like I reach an epiphany about how it works, and how to use it. Then a week later I read about it again and totally lost all understanding. What do I gain if I have code like this [0], which has a bunch of `.await?` in sequence? I know .await != join_thread(), but doesn't execution of the current scope of code halt while it waits for the future we are `.await`-ing to complete? I know this allows the executor to go poll other futures. But if we haven't explicitly spawned more futures concurrently, via something like task::spawn() or thread::spawn(), then there's nothing else the cpu can possible do in our process? [0] https://github.com/async-rs/async-std/blob/master/examples/tcp-client.rs https://github.com/async-rs/async-std/blob/master/examples/t...
- Argorak 7y agoIn small examples like this, you don't gain anything. For the sake of the example, we just run one task. But you _could_ run 100 with them. And at each of those `awaits`, they could schedule differently. For a more complex networked application, we have the tutorial here: https://github.com/async-rs/a-chat https://github.com/async-rs/a-chat
- pvorb 7y agoWouldn't it make more sense to show an example that actually takes advantage of async/await? I don't get why they are using examples that need a disclaimer like you can run 100 jobs for this to make sense. So it should include that in the example (and it should probably do something that makes sense if it's run a hundred times).
- esotericn 7y agoThe example is intended for you to be able to implement it, not as a showcase. I think the expectation with Rust async-await at the moment is likely that people are familiar with async syntax from other languages e.g. Python - it's not even in beta yet, you need to be running nightly to get the syntax.
- 7y ago
- rammy1234 7y agoAnything Rust gets the post to number 1 spot. What makes Rust special that other programming languages don't enjoy ?
- brians 7y agoA possibility to displace C and Java. Features like Haskell—destructuring bind, useful type system. Performance like C, including no GC.
- monocasa 7y agoDeterministic memory and object deallocation combined with memory safety, and a vibrant open ecosystem.
- pradn 7y ago1) It's built in large part by Mozilla, which enjoys special love as an OSS company. 2) Rust provides tangible benefits (memory/concurrency safety) over existing languages in an important niche (performance-sensitive programs). 3) The community is nice and talented so it's fun to see what they're up to.
- ggregoire 7y agoStrong static typing with types inference. Memory allocation manually handled, no garbage collector. C-like performances. Makes it a good option when reliability and performance matter (think web browser, database or anything at the OS level).
- hathawsh 7y agoRust is very ambitious and unusually successful at reaching its ambitions. It's efficient like C/C++, but safer. It's modern like Go, but more expressive and open to metaprogramming. It's often as readable as a scripting language, but doesn't depend on garbage collection. It's a young rising star originating from a great company.
- hu3 7y ago> often as readable as a scripting language I beg to differ. If anything, Rust is often cited as being hard to read.
- jedisct1 7y agoThe documentation is great, and the API documentation includes examples for many functions. This is really appreciable. Thank you for that!
- Argorak 7y agoThank you! :)
- mintplant 7y agoHow does this relate to Tokio [0]? Why should I choose this new library instead? [0] https://github.com/tokio-rs/tokio https://github.com/tokio-rs/tokio
- Arnavion 7y agoIf all you needed from tokio was tokio::net, then async-std could work as a replacement for raw TCP stuff. If you needed the higher-level stuff from tokio like codecs then you'd not have those. Also, anything from the tokio ecosystem like hyper would not work with async-std. Edit: I originally had a first paragraph which was wrong. I mistakenly thought std::net::TcpListener is supposed to impl Read / Write.
- Argorak 7y ago> async-std has the equivalent of std::net::TcpListener, however it does not appear to actually impl AsyncRead / AsyncWrite. So as of now you can't do anything with it. TcpStream does impl them, at least. It does implement AsyncRead and Write, because anything with `Read` and `Write` implements it: https://docs.rs/async-std/0.99.3/async_std/io/trait.Read.html#implementors https://docs.rs/async-std/0.99.3/async_std/io/trait.Read.htm... (that's sadly a little backwards by rustdoc) The problem is that tokio has their _own_ versions of the AsyncRead and Write traits. Hyper can best be used with `async_std` through `surf`: https://github.com/rustasync/surf https://github.com/rustasync/surf
- Arnavion 7y ago>It does implement AsyncRead and Write, because anything with `Read` and `Write` implements it: https://docs.rs/async-std/0.99.3/async_std/io/trait.Read.html#implementors https://docs.rs/async-std/0.99.3/async_std/io/trait.Read.htm... (that's sadly a little backwards by rustdoc) >impl<T: AsyncRead + Unpin + ?Sized> Read for T { That's saying that anything that impls futures::AsyncRead impls async_std::io::Read. async_std::net::TcpListener does not impl AsyncRead. (Compare with TcpStream and File which do.) >Hyper can best be used with `async_std` through `surf`: https://github.com/rustasync/surf https://github.com/rustasync/surf Sure. You also don't need surf since you can directly use futures's compat executor wrapper around tokio's. The point is that you can't use stuff like hyper without the tokio executor being involved.
- bfrog 7y agovery cool! Now we need a dpdk equivalent to really blow away expectations people have of what is fast
- limsup 7y agoIt looks great. But it's odd that they do not cite Tokio. I know this isn't an academic paper, but come on have some professional curtesy and discuss the contributions made in prior art.
- ShinTakuya 7y agoApologies if I'm misunderstanding things here, I'm just now getting back into Rust after a couple of years of not using it. Did Tokio really inspire this library that much?
- rough-sea 7y agoAbsolutely. The whole std::future interface has been borne out of years of careful attempts to actually make these abstractions work in real life. async-std didn’t come from a vacuum. It’s a incremental improvement on tokio that benefits from being able to greenfield on top of the newly changed and standardized future trait. Carl Lerche and the rest of the Tokio contributors deserve a citation.