comms v0.1.0 Comms.Actor behaviour
A behaviour module for implementing general purpose actors.
A Comms.Actor is designed to allow easy implementation of the actor model.
Example
defmodule Ping do
use Comms.Actor
@impl Comms.Actor
def handle({:ping, pid}, state) do
{[{pid, :pong}], state}
end
end
{:ok, p} = Comms.Actor.start_link(Ping, nil)
send(p, {:ping, self()})
flush()
# => :pong
Actor Model
An actor is a computational entity that, in response to a message it receives, can concurrently:
- send a finite number of messages to other actors;
- create a finite number of new actors;
- designate the behavior to be used for the next message it receives.
There is no assumed sequence to the above actions and they could be carried out in parallel.
The Comms.Actor behavior is a replacement for GenServer that more closely follows these principles.
- There is only one callback to deal with incomming messages,
handle/2.Comms.Actorworks withGenServer.call/2etc but these are just another type of message - The return value of the
handle/2callback is always the same shape. A list of outbound messages and a new state. This allows anComms.Agentto send any number of replies rather than 1 or 0 that is the case for GenServers.
Gen messages
Calls and cast from the GenServer module etc are just wrappers around the erlang :gen module.
A proccess implementing Comms.Actor can respond to these like normal messages.
defmodule PairUp do
use Comms.Actor
def start_link do
Comms.Actor.start_link(__MODULE__, :none)
end
@impl Comms.Actor
def handle({:"$gen_call", from, {:pair, pid}}, :none) do
{[], {:waiting, from, pid}}
end
def handle({:"$gen_call", from2, {:pair, pid2}}, {:waiting, from1, pid1}) do
messages = [
{from2, {:other, pid1}},
{from1, {:other, pid2}},
]
{messages, :none}
end
end
Link to this section Summary
Types
Location where an actor can direct messages too
The payload of a sent or received message
Response to a
Any value that an actor maintains between receiving messages
Functions
Starts a Comms.Actor process without links (outside of a supervision tree)
Starts a Comms.Actor process linked to the current process
Link to this section Types
Location where an actor can direct messages too.
The payload of a sent or received message
Response to a
Any value that an actor maintains between receiving messages
Link to this section Functions
start(module(), any(), GenServer.options()) :: GenServer.on_start()
Starts a Comms.Actor process without links (outside of a supervision tree).
See start_link/3 for more information.
start_link(module(), any(), GenServer.options()) :: GenServer.on_start()
Starts a Comms.Actor process linked to the current process.
The arguments for this are identical to GenServer.start_link/3 and should be used for reference docs.