Skip to content

Instantly share code, notes, and snippets.

@cstorey
Last active December 11, 2015 01:48
Show Gist options
  • Save cstorey/4525930 to your computer and use it in GitHub Desktop.
Save cstorey/4525930 to your computer and use it in GitHub Desktop.
The tribulations of finding parallels between actors and objects in Erlang.

It's quite easy to draw parallels between the Alan Kay's definition of objects (ie: the important part is messaging) and actors as found in Erlang (independent processes communicating via messages). And one parallel seems to be between the supervisor, and factories (as supervisors are responsible for the lifecycle of it's child processes, as a factory can be for objects, I think).

So, if you have processes A and B supervised by S, but B needs to send messages to A, then it might seem like a good idea to dynamically create both in Module:start_link, eg:

-module(something_sup).

-behavior(supervisor).

start_link() ->
  {ok, Sup} = supervisor:start_link(?MODULE, []),
  {ok, APid} = supervisor:start_child(Sup, {a_child, {a_child_mod, start_link, []}, transient, infinity, worker, []}),
  {ok, BPid} = supervisor:start_child(Sup, {b_child, {b_child_mod, start_link, [APid]}, transient, infinity, worker, []}),
  {ok, Sup}.

init() ->
  {ok,{{one_for_all,0,1},[]}}.

But that breaks subtly if A or B fails and are restarted, as A will be restarted, but then B will be restarted with the old pid of A, ie: the pid of a process that is now dead.

Somehow, I'd forgotten that start_link's job was to start the supervisor up, not to act as a callback to create processes. It's possible to work around by locally registering A with a name (effectively a constant reference to a varying pid), and passing the name in rather than the pid, but it took me a little while to figure out what (wrong) assumptions I was making.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment