"CSP message-passing fundamentally involves a rendezvous between the processes involved in sending and receiving the message, i.e. the sender cannot transmit a message until the receiver is ready to accept it."
it not that strict in a practice. In dependency of implementation of CSP there can be CSP-channels with limited and unlimited capacity. If channels with limited capacity are used then some kind of rendezvous is necessary only on attempt to write a new message to a full channel. In that case process-writer will be blocked until process-reader read some messages from the channel.
If size-unlimited channels are used then interaction of CSP-processes will be asynchronous (just like in Actor Model).
There is another important difference (but it also depends on implementation details): CSP-processes are always proactive. They can do something even if there is no messages to read and process.
Otherwise actors are reactive (usually). They react only to incoming messages and do nothing if there is no new message in they inboxes.
This especially true for cases when actors are implemented as objects with callbacks (for example it is true for Akka, CAF, SObjectizer, QP/C++, Orleans and so on).
But there can be implementations of Actor Model where an actor has to call some kind `receive` primitive to get an incoming message. For example it is Erlang programming language and Just::Thread Pro Actor Edition library for C++.
Their definitions are distinct -- and at least at a surface level, quite different.[1] They have different abstract interfaces. From a practical point of view, if you're going to use them for programming, it's safe to say that they're not "the same." However, you do see some overlap in practical implementations: for example some actor systems have first-class channel or mailbox abstractions, whereas the pure Actor model has no such entities. People talk about implementing actors in Go, but Go is a CSP-based system.
You can ask whether the models are somehow equivalent (isomorphic?), or to what degree can you express one model in the other. Last time I checked, that is a fairly deep rabbit hole -- you'd need a solid grasp of the theory of equivalence of concurrent programs (e.g. pi-calculus) to answer the question properly.
Also don't forget that the Erlang team claim to have never heard of Hewitt's actor model, so Erlang-inspired actor systems are potentially distinct from (Hewitt, Agha et. al.) Actor Model systems.
I've looked into CAF, but haven't used it yet, is anyone using it successfully in a production environment? And what is the comparison with Erlang? My impression is that Erlang has better error handling capabilities, but CAF should be a bit faster, but was curious about a comparison from someone more knowledgeable.
There are at least QP/C++ [2] and SObjectizer [3].
All three frameworks are used in production, especially QP/C++.
Error handling in C++ actor frameworks is a different topic than such handling in Erlang or other safe language. Because if you do something like division by 0 or deference of null pointer in your C++ actor you will have a different result: in the best case the whole your application will crush, not just one actor.
8 comments
[ 3.1 ms ] story [ 23.7 ms ] thread"CSP message-passing fundamentally involves a rendezvous between the processes involved in sending and receiving the message, i.e. the sender cannot transmit a message until the receiver is ready to accept it."
it not that strict in a practice. In dependency of implementation of CSP there can be CSP-channels with limited and unlimited capacity. If channels with limited capacity are used then some kind of rendezvous is necessary only on attempt to write a new message to a full channel. In that case process-writer will be blocked until process-reader read some messages from the channel.
If size-unlimited channels are used then interaction of CSP-processes will be asynchronous (just like in Actor Model).
There is another important difference (but it also depends on implementation details): CSP-processes are always proactive. They can do something even if there is no messages to read and process.
Otherwise actors are reactive (usually). They react only to incoming messages and do nothing if there is no new message in they inboxes.
This especially true for cases when actors are implemented as objects with callbacks (for example it is true for Akka, CAF, SObjectizer, QP/C++, Orleans and so on).
But there can be implementations of Actor Model where an actor has to call some kind `receive` primitive to get an incoming message. For example it is Erlang programming language and Just::Thread Pro Actor Edition library for C++.
You can ask whether the models are somehow equivalent (isomorphic?), or to what degree can you express one model in the other. Last time I checked, that is a fairly deep rabbit hole -- you'd need a solid grasp of the theory of equivalence of concurrent programs (e.g. pi-calculus) to answer the question properly.
Also don't forget that the Erlang team claim to have never heard of Hewitt's actor model, so Erlang-inspired actor systems are potentially distinct from (Hewitt, Agha et. al.) Actor Model systems.
[1] https://arild.github.io/csp-presentation/#1
There are at least QP/C++ [2] and SObjectizer [3].
All three frameworks are used in production, especially QP/C++.
Error handling in C++ actor frameworks is a different topic than such handling in Erlang or other safe language. Because if you do something like division by 0 or deference of null pointer in your C++ actor you will have a different result: in the best case the whole your application will crush, not just one actor.
[1] https://www.slideshare.net/YauheniAkhotnikau/actor-model-and... [2] https://www.state-machine.com/qpcpp/ [3] https://stiffstream.com/en/products/sobjectizer.html