Wait for rexi_server before adding a node

The race condition between a nodeup event and rexi_server starting was
causing some superfluous errors. This just waits for rexi_server to boot
before notifying mem3_sync_nodes.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/commit/af18b14a
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/tree/af18b14a
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mem3/diff/af18b14a

Branch: refs/heads/import
Commit: af18b14aa272eb72637d9d6448016b2591316d42
Parents: 187c798
Author: Paul J. Davis <paul.joseph.da...@gmail.com>
Authored: Tue Sep 25 17:05:27 2012 -0500
Committer: Paul J. Davis <paul.joseph.da...@gmail.com>
Committed: Tue Sep 25 22:24:58 2012 -0500

----------------------------------------------------------------------
 src/mem3.app.src        |  2 +-
 src/mem3_sync_event.erl | 39 +++++++++++++++++++++++++++++++++------
 2 files changed, 34 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-mem3/blob/af18b14a/src/mem3.app.src
----------------------------------------------------------------------
diff --git a/src/mem3.app.src b/src/mem3.app.src
index bdc2d49..5a3f790 100644
--- a/src/mem3.app.src
+++ b/src/mem3.app.src
@@ -10,5 +10,5 @@
         mem3_sync_nodes,
         mem3_sup
     ]},
-    {applications, [kernel, stdlib, sasl, crypto, mochiweb, couch, twig]}
+    {applications, [kernel, stdlib, sasl, crypto, mochiweb, couch, rexi, twig]}
 ]}.

http://git-wip-us.apache.org/repos/asf/couchdb-mem3/blob/af18b14a/src/mem3_sync_event.erl
----------------------------------------------------------------------
diff --git a/src/mem3_sync_event.erl b/src/mem3_sync_event.erl
index a1afd79..440fb8c 100644
--- a/src/mem3_sync_event.erl
+++ b/src/mem3_sync_event.erl
@@ -38,12 +38,9 @@ handle_call(_Request, State) ->
     {ok, ok, State}.
 
 handle_info({nodeup, Node}, State) ->
-    case lists:member(Node, mem3:nodes()) of
-    true ->
-        mem3_sync_nodes:add([Node]);
-    false ->
-        ok
-    end,
+    Nodes0 = lists:usort(drain_nodeups([Node])),
+    Nodes = lists:filter(fun(N) -> lists:member(N, mem3:nodes()) end, Nodes0),
+    wait_for_rexi(Nodes, 5),
     {ok, State};
 
 handle_info({nodedown, Node}, State) ->
@@ -58,3 +55,33 @@ terminate(_Reason, _State) ->
 
 code_change(_OldVsn, State, _Extra) ->
     {ok, State}.
+
+drain_nodeups(Acc) ->
+    receive
+        {nodeup, Node} ->
+            drain_nodeups([Node | Acc])
+    after 0 ->
+        Acc
+    end.
+
+wait_for_rexi([], _Retries) ->
+    ok;
+wait_for_rexi(Waiting, Retries) ->
+    % Hack around rpc:multicall/4 so that we can
+    % be sure which nodes gave which response
+    Msg = {call, erlang, whereis, [rexi_server], group_leader()},
+    {Resp, _Bad} = gen_server:multi_call(Waiting, rex, Msg, 1000),
+    Up = [N || {N, P} <- Resp, is_pid(P)],
+    NotUp = Waiting -- Up,
+    case length(Up) > 0 of
+        true ->
+            mem3_sync_nodes:add(Up);
+        false -> ok
+    end,
+    case length(NotUp) > 0 andalso Retries > 0 of
+        true ->
+            timer:sleep(1000),
+            wait_for_rexi(NotUp, Retries-1);
+        false ->
+            ok
+    end.

Reply via email to