https://github.com/NetBSD/pkgsrc-wip/tree/master/actor-frame...
git clone https://github.com/NetBSD/pkgsrc --depth 1 ~/pkgsrc
git clone https://github.com/NetBSD/pkgsrc-wip --depth 1 ~/pkgsrc/wip
cd ~/pkgsrc/bootstrap
./bootstrap --unprivileged
cd ~/pkgsrc/wip/actor-model
~/pkg/bin/bmake install
~/pkg/sbin/pkg_info -L actor-model
That is all.Also made a typo. I called it actor-model in the commit message and my post above, but its real name was actor-framework. Will probably find a better name for it later.
How am I supposed to read this? It's obviously not "message passing eliminates race conditions", so perhaps it's intended to say something like "you need to design the components to avoid race conditions."
It's possible that they mean "it avoids data races by design".
You mention two very different problems.
1. Data race. It's a problem of mutation of some shared state. This problem is illuminated in the actor's approach by removing the shared state completely. Every actor has its own state and the only actor can change during handling incoming messages.
Even if we don't speak about actors and use message-passing within some other model (like CSP or Pub/Sub) then it hard to imagine how data race can happen in 1-to-1 interaction between entities in your application.
2. Deadlocks. There is no such thing as deadlock if actors use async message-passing. But there can be another problem: livelocks (https://en.wikibooks.org/wiki/Operating_System_Design/Concur...)
Or such thing as miss of a message. For example, actor A starts in state S1(A) and waits for message M1 to switch to state S2(A) where it will wait for M2. But actor B sends messages to A in reverse order: M2, then M1. If message M2 is not deferred by A, then M2 will be ignored by A in S1(A), then A switches to S2(A) and will wait for M2, but that message won't go to it.
Then again, avoid != eliminate. You can avoid hitting a deer on the road, but that doesn't mean you're able to eliminate the possibility of doing so.
There are several CAF alternatives with very different usages of C++ features:
* QP/C++: https://www.state-machine.com/qpcpp/
* SObjectizer: https://github.com/Stiffstream/sobjectizer
* actor-zeta: https://github.com/jinncrafters/actor-zeta
* rotor: https://github.com/basiliscos/cpp-rotor
At least two of them (QP/C++ and SObjectizer) are evolved and used for a longer time than CAF.
[0] https://actor-framework.readthedocs.io/en/latest/Overview.ht...
Having spent a bit of time in actor-land at the language level, I think the primary advantages of actors are:
1) making concurrency relatively easy to reason about (vs. say strict async/await, promises.. shudder, async/yield, whatever twisted does etc.).
2) more importantly, and most actor frameworks don't get this right, fault tolerance and isolated failure domains. If your actor system doesn't limit the blast radius of a failure, then it's missing one of the biggest reasons to go with actors.
What article? The actor model dates back to 70s much has been written about its various implementations and incarnations since then.
If you don't treat it like a theoretical model of computation (like Hewitt does), then what's left is various largely unrelated architectures that employ message passing, with various levels of granularity.
I don't think any claim about higher developer productivity can be made without specifying what it's being compared to.
A similar actor pattern is provided in the Python implementation of ZeroMQ Zyre: https://github.com/zeromq/pyre
* traceability of an application (or part of the application). For example, you send a message and don't see any reaction to it. Why? Was this message lost (sent nowhere)? Was it ignored by the receiver (or received by a different actor)? Was it received by the right receiver but handled incorrectly? It could be hard to find an answer, especially if there are millions of actors in your app.
* testability of your actors. Writing a unit-test for an actor can be a more complex task than testing some C++ function or class.
I think a good actor framework should provide tools for simplification of such tasks. And I can't image that those topics will sometime be covered by a C++ standard.
At best there will be in c++23 which means 2024 the time it trickles down to all relevant compilers and 2030 until you can use it in Debian stable.
That's also the time required by 32 successive 3-months javascript "zero to hero" bootcamps.