This experiment is similar to other techniques such as the virtual actor model implemented being orleans.
https://github.com/CrowdHailer/pachyderm
I have used the term entity to refer to virtual actors, as much as possible I tried to use the term process when talking about actors as you might understand them from experience with the beam.
Example Entity
defmodule MyApp.PingPong do
use Pachyderm.Entity
def init(_id), do: nil
def activate({:ping, client}, nil), do: {[{client, :pong}], :pinged}
def activate(:pong, nil), do: {[], :ponged}
end
-
activate returns a list of two tuples consisting of another entities address and message to send AND the new state of the actor
-
If an activation fails the entity continues to exist with previous state. Because entities are effectively immortal there is no concept of linking or monitoring.
-
This model chooses consistence first, within a given entity.
This is not suitable for all parts of a system, I can imagine a structure where a set of these entities forms the data spine as part of a larger system.
Running entities.
There are only two actions that can be done with an entity.
- Send it a message
- follow and entity and receive a message every time it’s state changes
iex> alias Pachyderm.Ecosystems.LocalDisk
# Pachyderm.Ecosystems.LocalDisk
iex> alice = {MyApp.PingPong, "alice"}
# {MyApp.PingPong, "alice"}
iex> bob = {MyApp.PingPong, "bob"}
# {MyApp.PingPong, "bob"}
iex> LocalDisk.follow(alice)
# {:ok, nil}
iex> LocalDisk.follow(bob)
# {:ok, nil}
# Alice pings Bob
iex> LocalDisk.send_sync(bob, {:ping, alice})
# {:ok, :pinged}
iex> flush()
# {{MyApp.PingPong, "bob"}, :pinged}
# {{MyApp.PingPong, "alice"}, :ponged}
# :ok:
Status
At the moment this is a proof of concept for a single node but I hope to extend this shortly.
See README for more info.
At the moment I’m just looking for comments on if this is a good idea? valuable in the context of Elixir/erlang?






















