anchor.diff:  % Keep a key-table in memory with multiple erl instances, one
   % master (single point of failure) and multiple slaves - robust
   % to a failure in the slaves.
  +%
  +% The master process mediates key retrieval by handing on key requests
  +% to a randomly chosen slave. The client retries is a slave fails to respond
  +% in a timely manner.
  +%
  +% To handle recovery, the master process monitors slaves to detect their termination.
  +% When a new slave comes online it assigns another slave to replicate itself (while
  +% still handling client requests). The new slave does not respond to queries until
  +% replication has been achieved.
   
   -module(distkt).
   -export([start_master/0, start_slave/0, 
  -setv/2, getv/1, key_master/1, slave_key_server/1, list_slaves/0]).
  +setv/2, getv/1, key_master/1, slave_key_server/1, list_slaves/0,
  +    replication_process/3]).
   
   % Client functions - set and get key values
   list_slaves() ->
  
positive.code: % Slave routines
  start_slave() ->
      master_process() ! { slave_connect, self() },
      Table = ets:new(keytable, [private]),
      slave_key_server(Table).
  
  master_process() ->
      % Figure out the master process
      { distkt, list_to_atom(string:join(["master", "@", net_adm:localhost()], ""))}.
  
  slave_key_server(Table) ->
      receive
          { ReturnPid, getv, Key} ->
              slave_get_value(Table, ReturnPid, Key);     
          { setv, Key, Value } ->
              slave_set_key_value(Table, Key, Value)
      end,
      slave_key_server(Table).
  
  slave_get_value(Table, ReturnPid, Key) ->
      reply_to_lookup(ReturnPid, Key, ets:lookup(Table, Key)).
  
negative.code:             set_slave_key_value(Nodes, Key, Value),
              key_master(Nodes);
          { slave_connect, Pid } ->
              choice(Nodes) ! { replicate, Pid },
              key_master(slave_connected(Nodes, Pid));
          { Pid, list_slaves } ->
              Pid ! { list_slaves, Nodes },
  