The actor model is nicely described by Gul Agha on his technical report, "Actors: a model of concurrent computation in distributed systems".
On page 49 he explains the "become" command:
become <expression>
After calling "become X", an actor will forward all his messages to another actor's mailbox (X).
I'm not sure, however, how this is implemented (it it's implemented at all) in languages like Erlang and Scala. Is it somethign I have to code manually? What about efficiency? Agha shows an implementation of a stack using message-passing. Every time a pop or push is performed, one more forwarding link is added to some actor... After hundreds of thousands of operations, I'd expect such an implementation to spend too much time forwarding messages and not doing actual work, unless some nice optimizations were performed under the hood.
So my question is: how is forwarding (or "become") implemented in typical actor languages like Erlang, Scala (and libraries for other languages)?
Carl Hewitt took the idea and created the actor model. Years later, these same ideas of message passing would influence Erlang to create an implementation of the actor model as well. Erlang is often quoted as the first & most successful implementation of the actor model.
The actor model is characterized by inherent concurrency of computation within and among actors, dynamic creation of actors, inclusion of actor addresses in messages, and interaction only through direct asynchronous message passing with no restriction on message arrival order.
The Actor model adopts the philosophy that everything is an actor. This is similar to the everything is an object philosophy used by some object-oriented programming languages, but differs in that object-oriented software is typically executed sequentially, while the Actor model is inherently concurrent.
Use of actors allows us to: Enforce encapsulation without resorting to locks. Use the model of cooperative entities reacting to signals, changing state, and sending signals to each other to drive the whole application forward. Stop worrying about an executing mechanism which is a mismatch to our world view.
It isn't directly implemented in Erlang, but you could write a trivial become
function that receives a message, forwards it to another process and then calls itself:
become(Pid) ->
receive
Msg -> Pid ! Msg
end,
become(Pid).
(An industrial-strength version of this might need to deal with signals and other odds and ends, but this is the essence of it.)
Calling become(Pid)
would effectively turn the calling process into process Pid
from the outside world's perspective.
This doesn't address the problems you highlight, with repeated calls to become
causing growth of forwarding chains. However, this doesn't generally occur in Erlang, and I'm not sure how Erlang's processes map onto the Actor model.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With