Live data from Hacker News

Async-std: an async port of the Rust standard library

async.rs

81–90 of 238 posts

Re: Async-std: an async port of the Rust standard library

#81

Anything Rust gets the post to number 1 spot. What makes Rust special that other programming languages don't enjoy ?

Rust 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.

Re: Async-std: an async port of the Rust standard library

#82
post #52

I 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…

In 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

Wouldn'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).

Re: Async-std: an async port of the Rust standard library

#83
post #54

I 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…

Yeah if there are no other futures spawned, then the await is going to cause the app to just sit there until the future completes. It's got nothing better to do. If there was another future spawned then the await would cause the runtime to sit there until either of the futures completed. The code would attend to the first future that completes intil that hits an await.

And where it all comes together is when async lets us write concurrent functions that compose together well in a way that functions that can block on IO and lock acquision do not.

Re: Async-std: an async port of the Rust standard library

#84
post #5

This 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-...

There are ways to get around this, the way that I have done it in Nim is via a `multisync` macro:

    proc readLine(s: Socket | AsyncSocket): Future[string] {.multisync.} =
      while true:
        let c = await s.recv(1)
        case c
        of '\n':
          return
        else:
          result.add(c)
This is equivalent to defining two `readLine` procedures, one performing synchronous IO and accepting a `Socket` and another performing asynchronous IO and accepting an `AsyncSocket`. It works very well in practice.

Re: Async-std: an async port of the Rust standard library

#85

Earlier quoted context omitted.

None of the 5 points in that article about callbacks in 2015 node.js apply to async in Rust. The Rust people spent years agonizing over their version of async and applied a lot of lessons learned from implementations in other languages. https://news.ycombinator.com/item?id=20676641 It's trivial to turn async into sync in Rust. You can use ".poll", "executor::block_on", et cetera. Turning sync into async is harder in…

> that would have been hard to do 5 years ago. Five years ago Rust still had green threads. Literally every standard library I/O function was async, and the awaits were always written for you with no effort. Its literally taken five years to get back to an alpha thats not as good, and we'll still have to wait for a new ecosystem to built on top of it. I know not everyone writes socket servers and so forcing the old m…

> Its literally taken five years to get back to an alpha thats not as good

The new I/O system is better in several ways. First, as you acknowledged, not everyone writes servers that need high scalability. M:N has no benefit for those users, and it severely complicates FFI. Second, async is faster than M:N because it compiles to a state machine: you don't have a bunch of big stacks around.

Re: Async-std: an async port of the Rust standard library

#86

How 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.

In Rust you use async/await with a scheduler like mio that will automatically do that for you as well.

Re: Async-std: an async port of the Rust standard library

#87

Earlier quoted context omitted.

None of the 5 points in that article about callbacks in 2015 node.js apply to async in Rust. The Rust people spent years agonizing over their version of async and applied a lot of lessons learned from implementations in other languages. https://news.ycombinator.com/item?id=20676641 It's trivial to turn async into sync in Rust. You can use ".poll", "executor::block_on", et cetera. Turning sync into async is harder in…

> that would have been hard to do 5 years ago. Five years ago Rust still had green threads. Literally every standard library I/O function was async, and the awaits were always written for you with no effort. Its literally taken five years to get back to an alpha thats not as good, and we'll still have to wait for a new ecosystem to built on top of it. I know not everyone writes socket servers and so forcing the old m…

I do Rust since 2013. It did actually had two half-baked runtimes as a compile time mode.

It also was constantly crashing and had weird semantic issues. I very much prefer the current state, even if I'm a bit sad that async/await has taken us so long.

Re: Async-std: an async port of the Rust standard library

#88
post #32

Earlier quoted context omitted.

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.

That’s what I like about Go. You write sync code, but because Go routines aren’t OS threads they operate with the efficency of async code.

> You write sync code, but because Go routines aren’t OS threads they operate with the efficency of async code.

No, they don't. Goroutines have stacks, while Rust async code does not. Go has to start stacks small and copy and grow them dynamically because it doesn't statically know how deep your call stack is going to get, while async/await compiles to a state machine, which allows for up-front allocation. Furthermore, Go's M:N scheduling imposes significant costs in other places, such as FFI.

Besides, for the vast majority of apps, OS threads are not significantly different from goroutines in terms of efficiency. Rust doesn't have a GIL and per-thread startup time and memory usage are very low. It only starts to matter once you have a lot of threads—as in, tens of thousands of clients per second—and in that case it's mostly stack size that is the limiting factor.

Re: Async-std: an async port of the Rust standard library

#89
post #32

Earlier quoted context omitted.

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.

AFAIK, that's just for file I/O, which doesn't really work well with epoll.

Correct. It's also common practice.

Re: Async-std: an async port of the Rust standard library

#90
post #76

Earlier quoted context omitted.

The benefit would be you would be making it impossible to wreck your scheduler by calling sync I/O functions in an async task.

I 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 Also, having explicit imports and types that name collide helps there for once.

How would you have a blocking database library that doesn't use the standard library?
Post reply on HN