summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2013-03-26 17:54:00 +0000
committerSimon MacMullen <simon@rabbitmq.com>2013-03-26 17:54:00 +0000
commit46eb23b9f4b1c693c37abfdf9e55203e688f50e8 (patch)
tree70ce8d111169cc7818cf276f23ca0cb1d145e924
parent81ef7e1ba1ad331d29d697dd1fadde6dc7fc6f01 (diff)
downloadrabbitmq-server-46eb23b9f4b1c693c37abfdf9e55203e688f50e8.tar.gz
Simplistic way of selecting a winner: order by the number of connections, then the size of the partition.
-rw-r--r--src/rabbit_node_monitor.erl47
1 files changed, 28 insertions, 19 deletions
diff --git a/src/rabbit_node_monitor.erl b/src/rabbit_node_monitor.erl
index c2c81545..957a9025 100644
--- a/src/rabbit_node_monitor.erl
+++ b/src/rabbit_node_monitor.erl
@@ -283,9 +283,7 @@ handle_info({mnesia_system_event,
handle_info({autoheal_request_winner, Node},
State = #state{autoheal = {wait_for_winner_reqs,[Node], Notify},
partitions = Partitions}) ->
- %% TODO actually do something sensible to figure out who the winner is
- AllPartitions = all_partitions(Partitions),
- Winner = self(),
+ Winner = autoheal_select_winner(all_partitions(Partitions)),
rabbit_log:info("Autoheal: winner is ~p~n", [Winner]),
[{?MODULE, N} ! {autoheal_winner, Winner} || N <- Notify],
{noreply, State#state{autoheal = wait_for_winner}};
@@ -298,18 +296,17 @@ handle_info({autoheal_request_winner, Node},
handle_info({autoheal_winner, Winner},
State = #state{autoheal = wait_for_winner,
partitions = Partitions}) ->
- Node = node(Winner),
- case lists:member(Node, Partitions) of
+ case lists:member(Winner, Partitions) of
false -> case node() of
- Node -> rabbit_log:info(
- "Autoheal: waiting for nodes to stop: ~p~n",
- [Partitions]),
- {noreply,
- State#state{autoheal = {wait_for, Partitions,
- Partitions}}};
- _ -> rabbit_log:info(
- "Autoheal: nothing to do~n", []),
- {noreply, State#state{autoheal = not_healing}}
+ Winner -> rabbit_log:info(
+ "Autoheal: waiting for nodes to stop: ~p~n",
+ [Partitions]),
+ {noreply,
+ State#state{autoheal = {wait_for, Partitions,
+ Partitions}}};
+ _ -> rabbit_log:info(
+ "Autoheal: nothing to do~n", []),
+ {noreply, State#state{autoheal = not_healing}}
end;
true -> autoheal_restart(Winner),
{noreply, State}
@@ -439,17 +436,29 @@ autoheal(State) ->
_ -> wait_for_winner
end}.
+autoheal_select_winner(AllPartitions) ->
+ {_, [Winner | _]} = hd(lists:sort(
+ [{autoheal_value(P), P} || P <- AllPartitions])),
+ Winner.
+
+autoheal_value(Partition) ->
+ Connections = [Res || Node <- Partition,
+ Res <- [rpc:call(Node, rabbit_networking,
+ connections_local, [])],
+ is_list(Res)],
+ {length(lists:append(Connections)), length(Partition)}.
+
autoheal_restart(Winner) ->
rabbit_log:warning(
- "Autoheal: we were selected to restart; winner is ~p~n", [node(Winner)]),
+ "Autoheal: we were selected to restart; winner is ~p~n", [Winner]),
run_outside_applications(
fun () ->
- MRef = erlang:monitor(process, Winner),
+ MRef = erlang:monitor(process, {?MODULE, Winner}),
rabbit:stop(),
- Winner ! {autoheal_node_stopped, node()},
+ {?MODULE, Winner} ! {autoheal_node_stopped, node()},
receive
- {'DOWN', MRef, process, Winner, _Reason} -> ok;
- autoheal_safe_to_start -> ok
+ {'DOWN', MRef, process, {?MODULE, Winner}, _Reason} -> ok;
+ autoheal_safe_to_start -> ok
end,
erlang:demonitor(MRef, [flush]),
rabbit:start()