Live data from Hacker News

Asynchronous IO: the next billion-dollar mistake?

yorickpeterse.com

111–120 of 165 posts

Re: Asynchronous IO: the next billion-dollar mistake?

#111
post #71
post #54

Earlier quoted context omitted.

No, the hardware is frequently inherently asynchronous. You write some memory and then the hardware consumes the prepared data asynchronously, in parallel, until it informs you in some manner that the operation is complete (usually either a asynchronous interrupt, or asynchronous write to a location you are polling). You can do whatever you want after preparing the data without waiting for completion. That is a inher…

Hardware is even-driven not asynchronous (the event-driven paradigm is an asynchronous paradigm, but I assume here you mean asynchronous as in async/await)

async/await is just a syntax built on top of an event driven architecture. Even at the highest level, this is backed by an event loop.

Use of an event loop is the original asynchronous application design.

Re: Asynchronous IO: the next billion-dollar mistake?

#112
post #36

> Now imagine a parallel universe where instead of focusing on making asynchronous IO work, we focused on improving the performance of OS threads such that one can easily use hundreds of thousands of OS threads without negatively impacting performance I actually can't imagine how that would ever be accomplished at the OS level. The fact that each thread needs its own stack is an inherent limiter for efficiency, as sw…

> But at the programming language level the compiler does have insight into the dependencies of your continuation This is really the key point - coupled with the fact that certain I/O operations are just inherently asynchronous. The TX/RX queues in NICs are an async, message passing interface - regardless of whether you're polling descriptors or receiving completion interrupts. So really, async I/O is the natural abs…

It’s been said that the only sync I/O behaviour in software is the interrupt handler in the top half of your kernel (or equivalent). Everything else, at every other layer, however you contextualise it or write the API, is in actuality some variant of polling.

Re: Asynchronous IO: the next billion-dollar mistake?

#113
I think async vs threads is about completely different trade-off. Nowadays all operating systems so preemptive scheduling, but green threads (and all async by the extent) use cooperative scheduling. I believe most of discussion here is actually about pros and cons of those scheduling models.

one exception is I think cancellation model, but I'm only aware about rust that does it that way, all other runtimes will happily run your green thread until it finishes or cancel by itself similarly that you do with synchronous code.

Re: Asynchronous IO: the next billion-dollar mistake?

#114

Async IO is not only about creating sockets and spawning threads. Idea of async IO is that the world is not controlled by your CPU. There are network, storage, sound devices that might and will take time to produce the result and the CPU has to wait for it. I feel like there is a big misunderstanding about what async IO is and what problem it solves.

Doesn't message passing capture this essence better?

Message passing, channels, thread pool, callbacks, polling - there are many ways to implement async IO and async computation in general.

Re: Asynchronous IO: the next billion-dollar mistake?

#115
The author appears to contradict the very issue they argue, by presenting languages such as Go, Erlang or their own toy language. These languages hide the async / await constructs that are present in languages like Rust, Swift or Typescript. The former languages and runtimes have no function colouring problems, when working within their own SDKs. There are trade offs, and these “async” languages tend to be a bit more awkward when interacting with OS frameworks.

Re: Asynchronous IO: the next billion-dollar mistake?

#116
post #10

Asynchronous IO isn't about efficiency. The approach the author takes with their language is just threads, but scheduled in userland. This model allows a decoupling of the performance characteristics of runtime threads from OS threads - which can sometimes be beneficial - but essentially, the programming model is fundamentally still synchronous. Asynchronous programming with async/await is about revealing the time di…

> Take cancellation for example: cancelling tasks under the synchronous programming model requires passing a context object through every part of your code that might call down into an IO operation. Does it? Wouldn’t you just kill the thread in the synchronous model?

You'd interrupt it using something like Java's interrupt model. That doesn't require any context object (the Thread is itself the context) and works correctly with (synchronous) I/O operations.

The big problem with InterruptedException is that it's checked, and developers often don't know what to do with it so tend to swallow it or retry. There isn't necessarily a solid discipline about how to handle interruption in every library. But that is of course an orthogonal problem that you'd have with any sufficiently pervasive cancellation scheme.

Re: Asynchronous IO: the next billion-dollar mistake?

#117
My interpretation of what the author wants, is essentially lightweight threads in the kernel, standardised a lá POSIX , that every proglang could use as a primitive.

That'd be sweet if this were a well understood problem. Unfortunately, we're still finding the sweet spot between I/O Cs CPU bound tasks, "everything is a file" clashing with async network APIs and mostly sync file APIs, and sending that research to the kernel would mean having improvements widely distributed in 5 years or more, and would set back the industry decades, if not centuries. We learned this much already with the history of TCP and the decision of keeping QUIC in userspace.

Re: Asynchronous IO: the next billion-dollar mistake?

#118

Somewhat controversial take: the current threads implementation is usually already performant enough for most use cases. The actual reason why we don't use them to handle more than a few thousand concurrent operations is that, at least in Linux, threads are scheduled and treated very similarly to processes. E.g. if a single process with 3000 threads gets bottlenecked on some syscall, etc, your system load average wil…

Linux ps doesn't show threads (by default). That was true decades ago before NPTL but hasn't been the case for a long time.

The reason not to use kernel threads for everything is RAM utilization.

Re: Asynchronous IO: the next billion-dollar mistake?

#119
post #10

Asynchronous IO isn't about efficiency. The approach the author takes with their language is just threads, but scheduled in userland. This model allows a decoupling of the performance characteristics of runtime threads from OS threads - which can sometimes be beneficial - but essentially, the programming model is fundamentally still synchronous. Asynchronous programming with async/await is about revealing the time di…

> Take cancellation for example: cancelling tasks under the synchronous programming model requires passing a context object through every part of your code that might call down into an IO operation. Does it? Wouldn’t you just kill the thread in the synchronous model?

Anything that makes cancellation decisions from the outside of a black box is unsound. You are asking the programmer of the thing being cancelled to program in such a way, that the impact on the world outside abides by all invariants no matter where the cancellation happens.

For threads, that an impossible ask. Thread cancellation is a big no-no. Just never do that. Sibling's mention of leaks and deadlocks are just examples of things that can go wrong.

Task cancellation in async has the same issues. Less so, maybe much less so, because every space between two awaits acts as a no-cancellation-zone, but it's still a very suspect thing to do.

Re: Asynchronous IO: the next billion-dollar mistake?

#120
post #51
post #40

Earlier quoted context omitted.

> It's a simple, clean model - no need for locks. Nit: You can very easily have race conditions in async JS. There are all sorts of Mutex-style structures for async.

That's really interesting. Care to share a link to 1 or 2 real world examples of this that you've seen? Or even better, examples of how one would write such locks in JS that would be effective against these type of race conditions?

Advanced JS is a pain for that reason. Any interaction with a "slow" API, even doing cryptographic operations (super common inside libraries), can introduce points at which literally anything can change and in particular a point where new UI events can be triggered. So it's like concurrency but without any of the tools to manage it: you call a function, and by the time it returns arbitrary unrelated stuff may have executed.

I've encountered quite a few programmers over the years who think the absence of tools like locking or concurrent data structures is a feature, that they don't need them because async is simpler. Wrong. They're not unneeded, they're just missing, like many other basic APIs you'd expect that are missing inside browsers.

In standard GUI programming you're in control of the event loop and can decide whether to block it or not. This is a powerful tool for correctness. If you need to do a slow IO in response to a button being clicked you can just do it. The user may see the button freeze in the depressed state for a moment if their filesystem is being slow, for example, but they won't suffer data corruption or correctness issues, just a freeze. If you don't want the UI to freeze you can kick off a separate thread and then use mutexes or actor messaging to implement coordination, doing the extra work that surfaces the possible interactions and makes you work out what should happen.

In the browser environment there's none of that. You have to find other ways to disable the event loop, like by disabling all the UI the user could interact with once an interation starts, or - more commonly - just ignore race conditions and let the app break if the user does something unexpected. It's partly for this reason that web apps always seem so fragile.

And don't get me started on the situation w.r.t. database concurrency ... how many developers really understand DB locking and tx isolation levels?

Post reply on HN