I got especially confused at the actor part, aren't actors share nothing by design?
It does to say there's only 1 actor, so I guess it has nothing to do with actors? They're talking about GenServer-like behavior within a single actor.
As I write this, I'm figuring out maybe they mean it's like a single actor GenServer sending messages to itself, where each message will update some global state. Even that though, actors don't yield inside callbacks, if you send a message it gets queued to run but won't suspend the currently running callback, so the current method will run to completion and then the next will run.
Erlang actors do single-threaded actors with serialized message processing. If I understand the article, that avoids the issue it brings up completely as you cannot have captured old state that is stale when resuming.
pwnna•1h ago
Throwing an async mutex to fix the lack of atomicity before yielding is basically telling me that "i don't know when I'm calling await in this code so might as well give up". In my experience this is strongly correlated with the original designer not knowing what they are doing, especially in languages like JavaScript. Even if they did understand the problem, this can introduce difficult-to-debug bugs and deadlocks that would otherwise not appear. You also introduce an event queue scheduling delay which can be substantial depending on how often you're locking and unlocking.
IMO this stuff is best avoided and you should just write your cooperative multi-tasking code properly, but this is does require a bit more advanced knowledge (not that advanced, but maybe for the JS community). I wish TypeScript would help people out here but it doesn't. Calling an async function (or even normal functions) does not invalidate type narrowing done on escaped variables probably for usability reasons, but is actually the wrong thing to do.
[1]: https://www.npmjs.com/package/async-mutex
michaelsbradley•1h ago
Developers should properly learn the difference between push and pull reactivity, and leverage both appropriately.
Many, though not all, problems where an async mutex might be applied can instead be simplified with use of an async queue and the accompanying serialization of reactions (pull reactivity).