summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Klishin <michael@clojurewerkz.org>2015-12-04 07:28:02 +0300
committerMichael Klishin <michael@clojurewerkz.org>2015-12-04 07:28:02 +0300
commitb191f452afaf832d5093077f463df82c9f522f20 (patch)
tree087f53fe362f65817c36f9c44b7e255a05aaa5cf
parent3c6425ff65229c4c0241358cde5629b4a5de364b (diff)
parent6b61f74ea78a0dcd99bda2fa6846d3d19824baad (diff)
downloadrabbitmq-server-git-b191f452afaf832d5093077f463df82c9f522f20.tar.gz
Merge branch 'stable'
-rwxr-xr-xscripts/rabbitmq-server3
-rw-r--r--src/rabbit_mirror_queue_coordinator.erl17
2 files changed, 16 insertions, 4 deletions
diff --git a/scripts/rabbitmq-server b/scripts/rabbitmq-server
index 71a6530321..69c2b7ff6c 100755
--- a/scripts/rabbitmq-server
+++ b/scripts/rabbitmq-server
@@ -161,7 +161,8 @@ if [ 'x' = "x$RABBITMQ_ALLOW_INPUT" -a -z "$detached" ]; then
start_rabbitmq_server "$@" &
# Block until RabbitMQ exits or a signal is caught.
- wait
+ # Waits for last command (which is start_rabbitmq_server)
+ wait $!
else
start_rabbitmq_server "$@"
fi
diff --git a/src/rabbit_mirror_queue_coordinator.erl b/src/rabbit_mirror_queue_coordinator.erl
index 77a145a9cf..1679767286 100644
--- a/src/rabbit_mirror_queue_coordinator.erl
+++ b/src/rabbit_mirror_queue_coordinator.erl
@@ -369,6 +369,8 @@ handle_cast(request_depth, State = #state { depth_fun = DepthFun }) ->
handle_cast({ensure_monitoring, Pids}, State = #state { monitors = Mons }) ->
noreply(State #state { monitors = pmon:monitor_all(Pids, Mons) });
+handle_cast({delete_and_terminate, {shutdown, ring_shutdown}}, State) ->
+ {stop, normal, State};
handle_cast({delete_and_terminate, Reason}, State) ->
{stop, Reason, State}.
@@ -416,13 +418,22 @@ handle_msg([CPid], _From, request_depth = Msg) ->
ok = gen_server2:cast(CPid, Msg);
handle_msg([CPid], _From, {ensure_monitoring, _Pids} = Msg) ->
ok = gen_server2:cast(CPid, Msg);
-handle_msg([CPid], _From, {delete_and_terminate, _Reason} = Msg) ->
- ok = gen_server2:cast(CPid, Msg),
+handle_msg([_CPid], _From, {delete_and_terminate, _Reason}) ->
+ %% We tell GM to stop, but we don't instruct the coordinator to
+ %% stop yet. The GM will first make sure all pending messages were
+ %% actually delivered. Then it calls handle_terminate/2 below so the
+ %% coordinator is stopped.
+ %%
+ %% If we stop the coordinator right now, remote slaves could see the
+ %% coordinator DOWN before delete_and_terminate was delivered to all
+ %% GMs. One of those GM would be promoted as the master, and this GM
+ %% would hang forever, waiting for other GMs to stop.
{stop, {shutdown, ring_shutdown}};
handle_msg([_CPid], _From, _Msg) ->
ok.
-handle_terminate([_CPid], _Reason) ->
+handle_terminate([CPid], Reason) ->
+ ok = gen_server2:cast(CPid, {delete_and_terminate, Reason}),
ok.
%% ---------------------------------------------------------------------------