4 ms·
The majority of the complexity is in the library/executor, rather than in callers. We have an implementation at my company which is now being widely rolled out
by rhaen 1y ago
The majority of the complexity is in the library/executor, rather than in callers. We have an implementation at my company which is now being widely rolled out and it's a pretty dramatic readability win to convert callback based codes to nearly-straight line coroutine code.
- quietbritishjim 1y agoThat's very promising. Boost ASIO seemed to be the first serious coroutine library for C++ and that seemed complex to use (I'm saying that as a long-time user of its traditional callback API) but that's perhaps not surprising given that it had to fit with its existing API. But then there was a library (I forget which) posted to HN that was supposed to be a clean fresh coroutine library implementation and that still seems more complex than ASIO and callbacks - it seemed like you needed to know practically every underlying C++ coroutine concept. But maybe there just needed to be time for libraries to mature a bit.
- spacechild1 1y agoI was just going to mention ASIO. > and that seemed complex to use Actually. I found it pretty straightforward. I switched from callbacks to coroutines un my personal project and it is a massive win! Now I can write simple loops instead of nested callbacks. Also, most state can now stay in local variables.
- monkeyelite 1y agoThere is another way to write code which lets you write simple loops and isn’t coroutines. Blocking code.
- spacechild1 1y agoSure, but then you need one thread per socket, which has its own set of problems (most notably, the need for thread synchronization). I definitely prefer async + coroutines over blocking + thread-per-socket.
- horizion2025 1y agoJava's new philosophy (in "Loom" - in production OpenJDK now) seems to be virtual threads that are cheap and can therefore be plentiful compared to native threads. This allows you to write the code in the old way without programmer-visible async.
- spacechild1 1y agoOk, but virtual threads still need thread synchronization.
- monkeyelite 1y agowhich isn't a problem unless you are abusing threads. If you avoid synchronization, like javascript then you also don't get pre-emption or parallelism.
- spacechild1 1y ago> which isn't a problem unless you are abusing threads. Well, some people would call this a problem (or downside). Many real-world programs need to access shared state or exchange data between client. This is significantly less error prone if everything happens on a single thread. > If you avoid synchronization, like javascript then you also don't get pre-emption or parallelism. When we are talking about networking, most of the time is spent waiting for I/O. We need concurrency, but there's typically no need for actual CPU level parallelism. I'm not saying that we shouldn't use threads at all - on the contrary! -, but we should use them where they make sense. In some cases we can't even avoid it (e.g. audio). A typical modern desktop application, for example, would have the UI on the main thread, all the networking on a network thread, audio on an audio thread, expensive calculations on a worker thread (pool), etc. IMO it just doesn't make sense to complicate things by having one thread per socket when all the networking can easily be served by a single thread.
- monkeyelite 1y ago
- quietbritishjim 1y agoBut the great thing about async (at least it's the killer feature for me) is the really top notch support for cancellation. You can also typically create and join async tasks more easily than spawning and joining threads.