Live data from Hacker News

What async promised and what it delivered

causality.blog

211–220 of 317 posts

Re: What async promised and what it delivered

#211
post #129

Earlier quoted context omitted.

> 1.On a system that is handling 10k concurrent requests, the 10GB of RAM is going to be a fraction of what is installed. My example (and the c10k problem) is 10k concurrent connections, not 10k concurrent requests. > 2. It's not 10GB of RAM anyway, it's 10GB of address space. It still only gets faulted into real RAM when it gets used. Yes, and that's both memory and cpu usage that isn't needed when using a better co…

> Yes, and that's both memory and cpu usage that isn't needed No, it literally is not. The "memory" is just entries in a page table in the kernel and MMU. It shouldn't worry you at all. Nor is the CPU used by the kernel to manage those threads going to be necessarily less efficient than someone's handrolled async runtime. In fact given it gets more eyes... likely more. The sole argument I can see is just avoiding a h…

> > Yes, and that's both memory and cpu usage that isn't needed No, it literally is not. The "memory" is just entries in a page table in the kernel and MMU. It shouldn't worry you at all.

Only if you never free one of those stacks. TLB flushes can be quite expensive.

Re: What async promised and what it delivered

#212
> This is a promise (JavaScript) or future (Java, Rust, etc). The concept dates to Baker and Hewitt in 1977, but it took the C10K pressure of the 2010s to push it into mainstream programming.

Almost. JavaScript adopted async because it was a programming language designed to slot into someone else's event loop. Other programming languages, at least on the server, that needed lightweight threading didn't bother with any of this, they just shipped their own managed stacks. But UI code practically demands to own its own event loop and requires everything else live as callbacks inside of it. And JavaScript, because it was designed to live in a browser, inherited these same semantics.

Re: What async promised and what it delivered

#213

> OS threads are expensive: an operating system thread typically reserves a megabyte of stack space and takes roughly a millisecond to create. It's typically less than a hundred kilobytes and (on the systems I've benchmarked using std::thread) it takes 60usec (wall time in userspace) to create and destroy a thread. Threads have gotten so fast that paying the async function coloring price makes very little sense for m…

Its the stack space allocated to each thread that prevents you from spawning more than a thousand threads. Strategies like a thread per network connection do not scale.

I regularly spawn several thousands of threads in the C++ servers I write, and they perform well. At least 40% of FAANG companies just reduce the size of their per-thread stacks. "Thread per-connection" works just fine, and when you need to go faster, thread pools work even better without coloring all your functions.

There is an extremely small set of domains where simple threading doesn't suffice, and async/await is too high a price to pay across the entire software ecosystem just to slightly optimize those domains.

Re: What async promised and what it delivered

#215

Earlier quoted context omitted.

In my experience people complain about it because they are coming from a blocking first mindset. They're trying to shoehorn async calls into an inherently synchronous structure. A while back I just started leaning in. I write a lot of Python at work, and anytime I have to use a library that's relies on asyncio, I just write the entire damn app as an asynchronous one. Makes function coloring a non-issue. If I'm in a s…

> Makes function coloring a non-issue. Yes, having to rewrite literally all of your code because you need to use an async function somewhere is an issue. An even bigger issue is that now you have two (incompatible!) versions of literally every library dependency.

I'm usually writing applications, not libraries, so it's a non-issue for me.

I was talking about when writing from scratch.

Re: What async promised and what it delivered

#216
post #96

Earlier quoted context omitted.

I mean Java's Loom feels like the 'ultimate' example of the latter for the _ordinary_ programmer, in that it effectively leaves you just doing what looks like completely normal threads however you so please, and it all 'just works'.

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.

Re: What async promised and what it delivered

#217
post #176

Earlier quoted context omitted.

Yeah, none of this makes sense to me. Allocating memory for stack space is not expensive (and the default isn't even 1MB??) because you're just creating a VMA and probably faulting in one or two pages. They also say: >The system spends time managing threads that could be better spent doing useful work. What do they think the async runtime in their language is doing? It's literally doing the same thing the kernel woul…

doesn't a async runtime have more knowledge about the tasks than the OS about the threads?

Not the runtime per se, but cooperative scheduling has the advantage that tasks do not yield at adverse code points, e.g., right before giving up a lock, or performing an I/O request. Of course the lack of preemption has it's own downsides, but with thread-per-request you tend to run into tail latency issues much earlier than context switching overhead.

Re: What async promised and what it delivered

#218
post #87

> Language designers who studied the async/await experience in other ecosystems concluded that the costs of function coloring outweigh the benefits and chose different paths. Not really. The author provides Go as evidence, but Go's CSP-based approach far predates the popularity of async/await. Meanwhile, Zig's approach still has function coloring, it's just that one color is "I/O function" and the other is "non-I/O f…

Or use OCaml 5 which has a full algebraic effects system that solves the function coloring problem while still being highly performant.

How do they solve it?

Re: What async promised and what it delivered

#220
post #87

> Language designers who studied the async/await experience in other ecosystems concluded that the costs of function coloring outweigh the benefits and chose different paths. Not really. The author provides Go as evidence, but Go's CSP-based approach far predates the popularity of async/await. Meanwhile, Zig's approach still has function coloring, it's just that one color is "I/O function" and the other is "non-I/O f…

In my experience people complain about it because they are coming from a blocking first mindset. They're trying to shoehorn async calls into an inherently synchronous structure. A while back I just started leaning in. I write a lot of Python at work, and anytime I have to use a library that's relies on asyncio, I just write the entire damn app as an asynchronous one. Makes function coloring a non-issue. If I'm in a s…

>In my experience people complain about it because they are coming from a blocking first mindset. They're trying to shoehorn async calls into an inherently synchronous structure.

There's no "inherently synchronous structure", at least not in Javascript. The nature is synchronous, asynchronous is an illusion built on top of it. Which is why you can easily block an "asynchronous" program:

  while (true) {} 
on any async function will do.

JavaScript execution is synchronous on a single call stack. That's why they added Workers which is different to async.

Rust's Tokio and co are also blocking. You need threads to get something that's not an inherently synchronous with merely a facade or cooperative asychronicity.

Post reply on HN