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.Actor
works withGenServer.call/2
etc but these are just another type of message - The return value of the
handle/2
callback is always the same shape. A list of outbound messages and a new state. This allows anComms.Agent
to 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.