In my view and experience, the actor model and the CSP model of Go and others (which is also very similar to Flow-Based Programming (FBP) if using buffered channels), can actually fit together very nicely, with each of them sitting at different abstraction levels:
- The actor model for high-level coordination and communication
- CSP and/or FBP at the low-level, for high performance processing.
The reason for this is mainly that CSP/FBP inherently supports blocking channels between processes when processes are busy (or channels are full for FBP), thus providing implicit backpressure. This can simplify low-level programming a lot, since you don't need to worry about over-filled mailboxes or overbooked CPUs. OTOH, for communication e.g. across a cluster, this becomes problematic since you can't rely on the same level of integrity of the network connections ... meaning that the very communication-intensive nature of CSP/FBP might be less of a good fit.
Thus in my view, the actor model would fit better for communicating between services which are internally implemented e.g. with CSP/FBP.
It will be interesting to see whether Pony manages to fill more than just the coordination role. Given its much higher raw-crunching performance, perhaps that is the case. I'm a little worried about the lack of implicit back-pressure (due to the actor model), but let's see.
Perhaps because of its high-performance, back-pressure won't be too costly to implement anyway? One can hope. Would be nice with a language that can encompass both programming paradigms, and be suited for the full spectrum between low-level crunching and high-level coordination and communication.
the actor model in Erlang and (recently!) in Pony implements something even better: explicit backpressure by deprioritizing senders to busy mailboxes. The model can do this because it includes the scheduler in its scope, which doesn't happen in CSP.
I, too, have a bit of experience with backpressure implementations in both Erlang and Pony. Erlang's "penalize the sender" doesn't work in many cases, so I'm not surprised that it's being removed. Erlang's remote distribution implementation & messaging semantics are Mostly Great but is definitely not Perfect.
1. Head-of-line blocking caused by congestion on the single TCP connection used for message transmission between any two Erlang nodes. This can cause major problems for apps control vs. data plane design, such as Riak and Lasp. Work on Partisan (https://github.com/lasp-lang/partisan) appears to be a substantial improvement.
2. If the single remote distribution TCP connection between two nodes is broken, then the first Erlang process to send a message to the remote node is, hrrm, well, borrowed/co-opted by the BEAM VM to connect the new TCP session. IIRC that process is marked unrunnable by the scheduler until the connection is set up or perhaps there's an error. If that process is really important to the functioning of your app, for example, an important system manager in the control plane of the app, then you have a very difficult-to-diagnose latency Heisenbug to cope with.
'penalize the sender' has the benefit of being very clean; it doesn't work in >1 machine distributed cases, but then neither do go or pony yet. I'm surprised to discover that it's being removed. I wonder what the thinking is for the local case.
I’ve heard speculation that it really only helped scheduler efficiency and this didn’t apply all that well on SMP schedulers and has finally been removed since non-SMP builds are no longer supported.
As for Pony, their actor model doesn’t support selectively receiving messages so their queue handling may have some different trades to make there, as well as interaction with primitives like promises (which are used where Erlang would prefer a ref tagged receive clause). Spooneybarger has done work on backpressure in Pony so maybe he or other Wallaroo labs people can elaborate.
My reply would be that while both Pony and Erlang are actor model languages, the semantics are quite different.
I never speak of either being better than the other. Rather, they are different. I'm an expert on backpressure in Pony, not so much in Erlang, so I'll leave it at that.
Well, and I was so busy writing this down that I didn't realize that is exactly a very good motivation for what was just done here: integrating Wallaroo with Go - Congrats! :D
- The actor model for high-level coordination and communication
- CSP and/or FBP at the low-level, for high performance processing.
The reason for this is mainly that CSP/FBP inherently supports blocking channels between processes when processes are busy (or channels are full for FBP), thus providing implicit backpressure. This can simplify low-level programming a lot, since you don't need to worry about over-filled mailboxes or overbooked CPUs. OTOH, for communication e.g. across a cluster, this becomes problematic since you can't rely on the same level of integrity of the network connections ... meaning that the very communication-intensive nature of CSP/FBP might be less of a good fit.
Thus in my view, the actor model would fit better for communicating between services which are internally implemented e.g. with CSP/FBP.
I wrote a post about this, some time ago:
http://bionics.it/posts/flowbased-vs-erlang-message-passing
It will be interesting to see whether Pony manages to fill more than just the coordination role. Given its much higher raw-crunching performance, perhaps that is the case. I'm a little worried about the lack of implicit back-pressure (due to the actor model), but let's see.
Perhaps because of its high-performance, back-pressure won't be too costly to implement anyway? One can hope. Would be nice with a language that can encompass both programming paradigms, and be suited for the full spectrum between low-level crunching and high-level coordination and communication.