3 ms·
Some downsides. The term blocking isn't well defined. How slow does an operation have to be to be considered blocking? There are no rules. Fetching google.com/
by mike_hearn 4y ago
Some downsides.
The term blocking isn't well defined. How slow does an operation have to be to be considered blocking? There are no rules. Fetching google.com/robots.txt is by universal agreement a blocking operation. Reading a file from the filesystem is considered blocking in JS but may not be in other languages, especially given that very fast disks like Optane or modern NVMe Flash can be only an order of magnitude or two slower than RAM. Taking a lock may or may not be considered blocking. Computing pi to a trillion digits would usually not be considered blocking because it doesn't make any async OS API calls, even though it might cause long delays before it returns, but if the author chose to implement it as an async iterator then it could be considered blocking.
Worse, async vs not async is about latency requirements of the caller, but the function author can't know that. If you're in a UI thread doing 60fps animation maybe even reading a file would be too slow, but if you're in a script then it doesn't matter at all and you'd rather have the simpler code. You're calling the same function, the only thing that changed is the performance requirements of the user.
So "potential to block" is to some extent a makework problem that occurs in JS because V8 isn't thread safe, and V8 isn't thread safe because JS isn't, because it was designed for the web which is a kind of UI toolkit. Such toolkits are almost never thread safe because it's too much hassle to program a thread safe renderer and would make it too slow, so that browser-specific implementation constraint propagates all over the JS ecosystem.
Final major problem: some languages use async hype as an excuse to not properly support threads at all, but that's often the only way to fully exploit the capabilities of multicore hardware. If your language only does async you'll always be restricted to a single core and you have to hope your use case parallelizes embarrassingly well at the top level.
If you have threads then this whole problem just goes away. That's the core argument that Java makes with Project Loom. Instead of introducing colored functions everywhere with poorly defined and inconsistent rules over which color to use, just make threads work better. Suddenly the binary async/not async distinction becomes irrelevant.
Still, there's a good reason most languages don't do the Loom approach. It's a massive PITA to implement. The Java guys are doing it because of their heavy investment in advanced VMs, and because the Java ecosystem only rarely calls out to native code. It'd be a lot harder in an ecosystem that had less of a focus on "purity".
- jakear 4y ago> The term blocking isn't well defined. How slow does an operation have to be to be considered blocking? There are no rules. The rule is very simple IMO, I already described it: if other execution can run while you wait for the value, it's blocking. (Edit: to be specific, other observable execution, so in your thread with write access to state you can see) > Worse, async vs not async is about latency requirements of the caller, I disagree. To me, async vs not async is about interruptibility. As you already mentioned, the code that computes a trillion digits of Pi is async if its interruptible, and not async if it isn't. If you're in a UI thread doing 60fps animation, async vs not async isn't really all that relevant (barring the slight inherent overhead in calling an async function). What you need is a profiler to tell you where you have a non-interruptible block consuming your 16ms. The compiler can't know this a priori, unless you make significant restrictions to the type of code you write (no unbounded loops, for instance). > Such toolkits are almost never thread safe because it's too much hassle to program a thread safe renderer and would make it too slow, so that browser-specific implementation constraint propagates all over the JS ecosystem. From here on you seem to not be aware of the fantastic recent developments in WebWorkers, it is now quite easy to spin up worker threads in JS, which communicate with the main thread via message passing.
- adql 4y ago> The rule is very simple IMO, I already described it: if other execution can run while you wait for the value, it's blocking. (Edit: to be specific, other observable execution, so in your thread with write access to state you can see) is gmtime() blocking ? Technically it needs to ask kernel to get the time so it has same potential to block as any other call > As you already mentioned, the code that computes a trillion digits of Pi is async if its interruptible, and not async if it isn't. Very bad definition as either * every single code is because kernel can always reschedule thread to do something else * none of the compute code is if language runtime can't interrupt it (old versions of Go had that behaviour for tight loops IIRC) * every of compute code is if language can arbitrarily interrupt it. > From here on you seem to not be aware of the fantastic recent developments in WebWorkers, it is now quite easy to spin up worker threads in JS, which communicate with the main thread via message passing. That's entirely worse approach as sharing any data structures is impossible and where mutex would be enough you're now shoveling tons of data around. It's workaround at best It's like saying "my language is multithreaded because we started many processess and communicate via redis"...