Live data from Hacker News

What async promised and what it delivered

causality.blog

231–240 of 317 posts

Re: What async promised and what it delivered

#231
post #216

Earlier quoted context omitted.

Java has gone full circle. Java had green threads in 1997, removed them in 2000 and brought them back properly now as virtual threads. I'm kinda glad they've sat out the async mania, with virtual threads/goroutines, the async stuff just feels like lipstick on a pig. Debugging, stacktrackes etc. are just jumbled.

They stopped at the Promises level with CompletableFuture that lead to "colored frameworks" like WebMVC vs. WebFlux in Spring.

Who is they? Java has moved past those promise based API and avoided async/await mistake.

Re: What async promised and what it delivered

#232
post #133

Earlier quoted context omitted.

Now you are comparing single threaded code with multi threaded, which is a completely different axis to async vs sync. Just take a look at C#'s async, where you have both async and multi threading, with all the possible combinations of concurrency bugs you can imagine.

Of course I'm comparing them. Threading and async are two solutions to the same problem: How do you write high performance event driven systems like network services? How do you solve the C10K problem (or more recently the C10M problem)? If you use a thread per connection (or green threads like Go), you don't also need async. If you have async (eg nodejs), you can get great performance without threads. You're right t…

You wrote:

> The job wouldn’t have been done. They would have needed threads. And mutexes. And spin locks. And atomics. And semaphores. And message queues. And - in my opinion - the result would have been a much worse language.

My point is that you do need mutexes, spin locks, etc with async as well, given that you have a multi threaded platform. So no, we have basically 2x2 stuff we are talking about with very different properties (async/sync x single/multi threaded).

Re: What async promised and what it delivered

#233
post #58

Earlier quoted context omitted.

Function coloring does not mean that functions take parameters and have return values. Result is not a color. You can call a function that returns a Result from any other function. Errors as return values do not color a function, they're just return values. Async functions are colored because they force a change in the rest of the call stack, not just the caller. If you have a function nested ten levels deep and it c…

If you are ten nested functions deep in sync code and want to call an async function you could always choose to block the thread to do it, which stops the async color from propagating up the stack. That's kind of a terrible way to do it, but it's sort of the analog of ignoring errors when that innermost function becomes fallible. So I don't buy that async colors are fundamentally different.

[deleted]

Re: What async promised and what it delivered

#234

No mention of Novell Netware. This was a solved problem decades ago and Windows had it for almost as long. The next decade will be a proliferation of hackers having fun with io_uring coming up with all sorts of patterns.

> No mention of Novell Netware. This was a solved problem decades ago and Windows had it for almost as long.

Solved at the OS layer, sure. This article is about solving it at the language layer.

It's been solved for a long time at the OS layer. I mean, didn't VAX have something like overlapped IO in 1980? Unix had asynchronous IO as well with `select`.

Re: What async promised and what it delivered

#235
post #47

Earlier quoted context omitted.

> Green threads are a very controversial design choice that even JVM backed out of. Did they? Project Loom has stabilized around Java 21, no?

Virtual Threads aren't quite the same as green threads (they don't block the OS thread) and they work extremely well now.

That's interesting because I remember people talking about Rust green threads as M:N mapping, which seems to be the only difference.

Re: What async promised and what it delivered

#236
post #61

Earlier quoted context omitted.

> It degrades API surfaces to the worst case :Send+Sync+'static because APIs have to be prepared to run on multithreaded executors This isn't true at all. The Send+Sync+'static is basically the limitation of tokio::spawn https://emschwartz.me/async-rust-can-be-a-pleasure-to-work-w... Change the executor, and the bound changes.

I think they mean tokio::spawn’s signature forces libraries that want to be easy to use with it to expose send+sync APIs (and thus use Arc+Mutex internally)

See what they wrote:

> Async ruined Rust for me, even though I write exactly the kind of highly concurrent servers to which it's supposed to be perfectly suited. It degrades API

It refers to async in Rust, and everyone else is responding as if it is talking about async in Rust. That's a mischaracterization. You don't have to use the Tokio executor.

It's a bit like saying, "Graphics in Rust are ruined. I need to use Vulkan to make my game."

No, you don't. If your use case is unique enough, use something else. There are bindings for OpenGL, DirectX, etc.

Re: What async promised and what it delivered

#237
Unfortunately, asynchronous programming is almost always discussed in terms of network I/O. However, there are many more use cases for concurrency. Coroutines can be extremely useful for modelling state machines or any kind of process that happens over time. Everytime you need to do X, then wait for N (milli)seconds, then do Y, etc., coroutines provide a very ergonomic solution. If your language supports stackful coroutines (e.g. Lua or Ruby), you don't even need to color your functions: you can just write regular functions that yield back to the scheduler anywhere in the call stack.

To give a concrete example: computer music languages, such as SuperCollider, need concurrency to implement musical scheduling. Imagine a musical sequence where you play a note, wait N beats, play another note, etc. Often you want to play many such sequences simultaneously. Stackful coroutines provide a very elegant solution to this problem. Every independent musical sequence can be modelled by a coroutine that yields everytime it needs to wait. The yielded value is interpreted by the scheduler as a delta time after which the function should be resumed. In this sense, SuperCollider users have been doing async programming since the early 2000s, long before it became mainstream.

Re: What async promised and what it delivered

#238
post #202

Earlier quoted context omitted.

In Rust debugging and stacktraces are perfectly fine because async/futures compile to a perfect state machine.

They are not perfectly fine. If a task panics then you will get the right stack trace, but there is no way to get a stack trace for a task that’s currently waiting. (At least not without intrusive hacks.)

Would this be considered an intrusive hack?

https://docs.rs/tokio/latest/%20tokio/runtime/struct.Handle....

Re: What async promised and what it delivered

#239
post #42

Async ruined Rust for me, even though I write exactly the kind of highly concurrent servers to which it's supposed to be perfectly suited. It degrades API surfaces to the worst case :Send+Sync+'static because APIs have to be prepared to run on multithreaded executors, and this infects your other Rust types and APIs because each of these async edges is effectively a black hole for the borrow checker. Don't get me star…

I do Rust without async and I'm happier for it. But yes, once you go dining on other people's crates you definitely get the impression that you have to, because tokio gets its fingerprints all over everything. But also there are non-thread stealing runtimes that don't require Send/Sync on the Future. Just nobody uses them. Because Rust is the language that tokio ate.

> But also there are non-thread stealing runtimes that don't require Send/Sync on the Future.

Which ones ?

Re: What async promised and what it delivered

#240
post #239

Earlier quoted context omitted.

I do Rust without async and I'm happier for it. But yes, once you go dining on other people's crates you definitely get the impression that you have to, because tokio gets its fingerprints all over everything. But also there are non-thread stealing runtimes that don't require Send/Sync on the Future. Just nobody uses them. Because Rust is the language that tokio ate.

> But also there are non-thread stealing runtimes that don't require Send/Sync on the Future. Which ones ?

Monio and Glommio

https://github.com/bytedance/monoio

https://github.com/DataDog/glommio

Post reply on HN