Hacker News new | past | comments | ask | show | jobs | submit login

Seems like a good development. I've been doing Node.js for last few years after letting go of Java. But there's something uneasy about async/await. For one thing it's difficult to debug how the async functions interact.



Debugging asynchronicity is complex in any language, no? Blocking endpoints are mostly irrelevent because it alters the temporal flow of things, which makes your code executed in debug mode not 100% « isomorphic » with your code executed in run mode.


That's seamless though. So if you have a failure you get a single stack trace that includes everything. In JS the debuggers sometimes glue stack traces together which works for basic stuff but incurs a major runtime overhead and doesn't work for production failures.

Locally the concept of multi-threaded debugging is easier than async-await since a single flow typically maps to a single thread and you can just step over it. If something happens asynchronously it's just IO and you can ignore that part. As far as you're concerned it's just one thread that you're stepping over/into. Variable context, scope etc. are maintained the same and passed seamlessly.


I'm trying to understand what exactly is different about debugging async/await vs. debugging threads. Isn't making an async-call the same as starting a new thread, from the programmer's point of view?

In my environment the WebStorm debugger I can debug async-calls in which I have halted in the stack. But I can not inspect the variable-values in the earlier "trace" that started the async-call.

Is it just a matter of debugger capabilities or is there something that makes thread-based debugging fundamentally less confusing?

Ah maybe I get it. When starting an async-call to read a file for instance the value of variables is no longer available in the callback. Whereas in a (real) thread they are, because from my point of view the thread was simply "sleeping" while the IO was happening. When the IO is over I back in the same context except I now have the read file-contents available for my inspection.

So, reading a file in a thread-based system does NOT require you to start a new thread, whereas in async-await you essentially do have to create a new async-context (which is like a new thread) to read a file. No?


WebStorm is indeed amazing. It takes separate stack traces and glues them together which means it needs to keep old stack traces in memory then constantly compare the objects passed along to figure out which stack to glue where.

As I said, it's problematic for production. So in the IDE you can indeed see the glued stack but in the browser... Or on the server...

Then there's the context. Since glued stack traces could be in-theory separate threads (at least in Java async calls) you might get weird behaviors where values of objects across the stack can be wildly different.

And no. You don't have a separate thread doing the IO. That's exactly the idea Loom is solving. Javas traditional stream IO is thread based. But we have a faster underlying implementation in NIO which uses the native select calls. The idea here is that a thread receives a callback when the connection has data waiting and can wait for data. This means the system can wake up the thread as needed, very efficiently. So there's no additional thread.


Yes I think I got that. I was not saying that Java creates a new thread for every IO operation but that async/await in JavaScript etc. must do something like starting a new "pseudo-thread". And that is why debugging in Java is easier - because it doesn't need to start a new thread. That's what I was trying to understand. Thanks.


Debugging is hard regardless of the concurrency model but building an understanding of what the code is supposed to be doing is way easier when the code reads sequentially versus async.

As far as debugging changing the scheduling of the program, it's not so bad when the tooling evolves out of the concurrency model, which I imagine will happen once virtual threads catch on in java. For example, in erlang, you can trace processes on a running system by pid, and basically get a sequence diagram of execution with messages between processes and function calls within a process, as well as the actual terms themselves. Because execution doesn't pause, you can even do it in production (if you're careful...). So while it's not a traditional debugger, in the "pause execution here" sense, it's still a way to inspect the system that fits well into an actor model. If such a thing doesn't exist in java already, I'm sure it will soon.


So can you actually see a diagram showing one process sending a message to another? Doesn't it become a rather large diagram easily?


Yes, and yes can become big, but you can scope it to certain processes, function calls, modules, pattern matches, etc, etc. So it's fine if you know what you're doing.

Legend has it that a major cell network was briefly taken offline due to a poorly thought out trace on a production system.


No?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: