Earlier quoted context omitted.
> It's trivial to turn async into sync in Rust. You can use ".poll", "executor::block_on", et cetera. Is it 0-cost abstraction? I mean, is `sync_read` will compile to the same code like `async_read.poll`? Because turning sync into async is kind of trivial as well: just spawn new thread for that sync block.
That's a tricky question. My understanding is that while it's (in theory, modulo compiler bugs and features) a 0-cost abstraction over different underlying system APIs, those different underlying system APIs aren't necessarily the same cost. For example, if I'm trying to read from a socket in the synchronous world, I just issue the `read` system call. But in the async world I'm going to do quite a bit more: - Create…
Async-std: an async port of the Rust standard library
41–50 of 238 posts
Re: Async-std: an async port of the Rust standard library
#42Earlier quoted context omitted.
> Turning sync into async is harder in any language. Elixir's Task module (in the stdlib): future = Task.async(fn -> do_something_here end) ...do_other_things... result = Task.await(future, timeout) Mixing it with the Enum library makes concurrency dead-simple (got I a junior dev dispatching concurrent tasks in scripts with confidence), at the expense of an ugly nested double lambda. some_list_of_values |> Enum.map(f…
Does Elixer overload IO operations to be async in async contexts? Because that is largely why you cannot just wrap sync code in an async block and call it a day - once it hits a system call the thread is paused but the scheduler cannot tell that it should be dequeued. This is largely why Python async took so long to mature, because so much inbuilt functionality was making IO operations transparently using core sync i…
Console IO operations are actually message call to a "global group leader" which performs the operation, so they are async (and atomic). This can sometimes be confusing if an operation (such as logging) has a bunch of middlemen with an IO operation as a side effect. It's worth the atomicity, though, so none of your IO calls are interrupted by another IO call. Also, if you run a command on a remote node which dispatches IO as part of its own process, the IO will be forwarded back to its group leader (which is on your local node), which is useful for introspecting into another VM.
Disk IO is also different; each open file descriptor effectively gets its own "thread" that you send IO messages to. There are ways to bind a file descriptor directly to your current "thread", but you "have to be more careful when you do that" - you do that if performance is more important (and I have done this, it's not terrible if you are careful).
Network IO is also different; the erlang VM kind of has its own network stack, if you will, but you can set up a socket to be its own "thread" or you can bind a socket into a thread so that network packets get turned into erlang messages.
Handling blocking is all done for you by the VM, which is preemptive and tries to give threads fair share of the VM time.
When people say that programming the erlang VM is like doing everything in its own os, they aren't kidding. Except unlike linux, where your communications are basically limited, you get to interact with your processes via structured data types with coherent language (and also IPC calls are way cheaper than OS processes).
> Does Elixer overload IO operations to be async in async contexts?
Maybe the right way to answer this is: When in Elixir, presume everything is async.
Re: Async-std: an async port of the Rust standard library
#43Earlier quoted context omitted.
This incurs runtime overhead and boilerplate, so while it’s not as hard as other languages, it’s still harder.
like what, a few microseconds? What are you doing where you're awaiting for things in parallel where that matters? HPC? We're dispatching things that take on the order of minutes. Typically a local network request has 10-20 milliseconds of latency on our office LAN, so whatever. Clean and comprehensible code with very little boilerplate is more important when I'm reviewing my junior's code.
Re: Async-std: an async port of the Rust standard library
#44This 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-...
The 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…
It's sometimes called "cold futures".
Re: Async-std: an async port of the Rust standard library
#45The thing I like in Go is that I don’t have to worry about that, it’s all automatic.
Re: Async-std: an async port of the Rust standard library
#46What 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/t...
Re: Async-std: an async port of the Rust standard library
#47Earlier quoted context omitted.
like what, a few microseconds? What are you doing where you're awaiting for things in parallel where that matters? HPC? We're dispatching things that take on the order of minutes. Typically a local network request has 10-20 milliseconds of latency on our office LAN, so whatever. Clean and comprehensible code with very little boilerplate is more important when I'm reviewing my junior's code.
Well, thats a hard sell for Rust because it specifically advertises itself as a C++ replacement which means no overhead or runtime.
Re: Async-std: an async port of the Rust standard library
#48Great 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.
Project 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.
Excellent, good to know!
Re: Async-std: an async port of the Rust standard library
#49Earlier quoted context omitted.
> It's trivial to turn async into sync in Rust. You can use ".poll", "executor::block_on", et cetera. Is it 0-cost abstraction? I mean, is `sync_read` will compile to the same code like `async_read.poll`? Because turning sync into async is kind of trivial as well: just spawn new thread for that sync block.
Spawning a new thread for an operation is not async in the sense people typically mean. For an async IO library, you would expect it to be using async IO primitives like epoll, not just wrapping blocking operations in a thread.
Re: Async-std: an async port of the Rust standard library
#50Great 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.
Project 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.