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.
What async promised and what it delivered
231–240 of 317 posts
Re: What async promised and what it delivered
#232Earlier 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…
> 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
#233Earlier 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.
Re: What async promised and what it delivered
#234No 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.
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
#235Earlier 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.
Re: What async promised and what it delivered
#236Earlier 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)
> 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
#237To 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
#238Earlier 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.)
https://docs.rs/tokio/latest/%20tokio/runtime/struct.Handle....
Re: What async promised and what it delivered
#239Async 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.
Which ones ?
Re: What async promised and what it delivered
#240Earlier 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 ?