summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2011-01-26 16:12:13 +0000
committerSimon MacMullen <simon@rabbitmq.com>2011-01-26 16:12:13 +0000
commitcfca23b81c44262977f879ec53e6bfac0792c8b8 (patch)
treefa32bd7e589ea9eb277f791ab619a1aaa896f172
parent2357faab24e32a9bf84529949c907276abc9f7e6 (diff)
downloadrabbitmq-server-cfca23b81c44262977f879ec53e6bfac0792c8b8.tar.gz
rabbitmqctl status is not adequate to wait for the server as it can return
successfully when the vm has started but not the app. The app can then fail. Therefore introduce a new command to wait for the app to start. Note that this subcommand contains a timeout to wait for the VM to start, but will wait indefinitely for the app to start once the VM has.
-rw-r--r--docs/rabbitmqctl.1.xml22
-rw-r--r--packaging/common/rabbitmq-server.init15
-rw-r--r--src/rabbit_control.erl26
3 files changed, 48 insertions, 15 deletions
diff --git a/docs/rabbitmqctl.1.xml b/docs/rabbitmqctl.1.xml
index bd9fee7d..5c090e5a 100644
--- a/docs/rabbitmqctl.1.xml
+++ b/docs/rabbitmqctl.1.xml
@@ -158,6 +158,28 @@
</varlistentry>
<varlistentry>
+ <term><cmdsynopsis><command>wait</command></cmdsynopsis></term>
+ <listitem>
+ <para>
+ Wait for the RabbitMQ application to start.
+ </para>
+ <para>
+ This command will wait for the RabbitMQ application to
+ start at the node. As long as the Erlang node is up but
+ the RabbitMQ application is down it will wait
+ indefinitely. If the node itself goes down, or takes too
+ long to come up, it will fail.
+ </para>
+ <para role="example-prefix">For example:</para>
+ <screen role="example">rabbitmqctl wait</screen>
+ <para role="example">
+ This command will return when the RabbitMQ node has
+ started up.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><cmdsynopsis><command>status</command></cmdsynopsis></term>
<listitem>
<para>
diff --git a/packaging/common/rabbitmq-server.init b/packaging/common/rabbitmq-server.init
index 54fd39b7..8ef1000b 100644
--- a/packaging/common/rabbitmq-server.init
+++ b/packaging/common/rabbitmq-server.init
@@ -22,7 +22,6 @@ DAEMON=/usr/sbin/${NAME}
CONTROL=/usr/sbin/rabbitmqctl
DESC=rabbitmq-server
USER=rabbitmq
-TIMEOUT=10
ROTATE_SUFFIX=
INIT_LOG_DIR=/var/log/rabbitmq
@@ -40,7 +39,7 @@ start_rabbitmq () {
set +e
nohup $DAEMON > ${INIT_LOG_DIR}/startup_log \
2> ${INIT_LOG_DIR}/startup_err &
- wait_for_rabbitmq
+ $CONTROL wait >/dev/null 2>&1
case "$?" in
0)
echo SUCCESS
@@ -59,18 +58,6 @@ start_rabbitmq () {
fi
}
-wait_for_rabbitmq() {
- WAITED=0
- while [ $WAITED != $TIMEOUT ]; do
- if status_rabbitmq quiet ; then
- return 0
- fi
- sleep 1
- WAITED=`expr $WAITED + 1`
- done
- return 1
-}
-
stop_rabbitmq () {
set +e
status_rabbitmq quiet
diff --git a/src/rabbit_control.erl b/src/rabbit_control.erl
index 80483097..a7d07b0f 100644
--- a/src/rabbit_control.erl
+++ b/src/rabbit_control.erl
@@ -20,6 +20,7 @@
-export([start/0, stop/0, action/5, diagnostics/1]).
-define(RPC_TIMEOUT, infinity).
+-define(WAIT_FOR_VM_TIMEOUT, 5000).
-define(QUIET_OPT, "-q").
-define(NODE_OPT, "-n").
@@ -297,7 +298,30 @@ action(list_permissions, Node, [], Opts, Inform) ->
VHost = proplists:get_value(?VHOST_OPT, Opts),
Inform("Listing permissions in vhost ~p", [VHost]),
display_list(call(Node, {rabbit_auth_backend_internal,
- list_vhost_permissions, [VHost]})).
+ list_vhost_permissions, [VHost]}));
+
+action(wait, Node, [], _Opts, Inform) ->
+ Inform("Waiting for ~p", [Node]),
+ wait_for_application(Node, ?WAIT_FOR_VM_TIMEOUT).
+
+wait_for_application(_Node, NodeTimeout) when NodeTimeout =< 0 ->
+ {badrpc, nodedown};
+
+wait_for_application(Node, NodeTimeout) ->
+ case call(Node, {application, which_applications, []}) of
+ {badrpc, nodedown} -> wait_for_application0(Node, NodeTimeout - 1000);
+ {badrpc, _} = E -> E;
+ Apps -> case proplists:is_defined(rabbit, Apps) of
+ %% We've seen the node up; if it goes down
+ %% die immediately.
+ false -> wait_for_application0(Node, 0);
+ true -> ok
+ end
+ end.
+
+wait_for_application0(Node, NodeTimeout) ->
+ timer:sleep(1000),
+ wait_for_application(Node, NodeTimeout).
default_if_empty(List, Default) when is_list(List) ->
if List == [] ->