summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancesco Mazzoli <francesco@rabbitmq.com>2012-10-25 13:10:45 +0100
committerFrancesco Mazzoli <francesco@rabbitmq.com>2012-10-25 13:10:45 +0100
commitaebd72c8238c559ce976a05854012f99b0a06783 (patch)
tree85c992615b26440852642635c78e2f26bc0f489e
parentae460017f0daaa84377151fc717795f9ca5699e3 (diff)
parentc419fcc1d934827226df2493a9f100e2f8d72933 (diff)
downloadrabbitmq-server-aebd72c8238c559ce976a05854012f99b0a06783.tar.gz
merge default
-rw-r--r--src/rabbit_amqqueue_process.erl8
-rw-r--r--src/rabbit_mnesia.erl72
-rw-r--r--src/rabbit_runtime_parameters.erl12
3 files changed, 41 insertions, 51 deletions
diff --git a/src/rabbit_amqqueue_process.erl b/src/rabbit_amqqueue_process.erl
index 68f95778..8d05a78c 100644
--- a/src/rabbit_amqqueue_process.erl
+++ b/src/rabbit_amqqueue_process.erl
@@ -1309,11 +1309,11 @@ handle_info(drop_expired, State) ->
noreply(drop_expired_messages(State#q{ttl_timer_ref = undefined}));
handle_info(emit_stats, State) ->
- %% Do not invoke noreply as it would see no timer and create a new one.
emit_stats(State),
- State1 = rabbit_event:reset_stats_timer(State, #q.stats_timer),
- assert_invariant(State1),
- {noreply, State1, hibernate};
+ {noreply, State1, Timeout} = noreply(State),
+ %% Need to reset *after* we've been through noreply/1 so we do not
+ %% just create another timer always and therefore never hibernate
+ {noreply, rabbit_event:reset_stats_timer(State1, #q.stats_timer), Timeout};
handle_info({'DOWN', _MonitorRef, process, DownPid, _Reason},
State = #q{q = #amqqueue{exclusive_owner = DownPid}}) ->
diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl
index b2f47428..2444c0ae 100644
--- a/src/rabbit_mnesia.erl
+++ b/src/rabbit_mnesia.erl
@@ -230,7 +230,9 @@ change_cluster_node_type(Type) ->
{ok, Status} -> Status;
{error, _Reason} -> e(cannot_connect_to_cluster)
end,
- Node = case RunningNodes of
+ %% We might still be marked as running by a remote node since the
+ %% information of us going down might not have propagated yet.
+ Node = case RunningNodes -- [node()] of
[] -> e(no_online_cluster_nodes);
[Node0|_] -> Node0
end,
@@ -285,18 +287,18 @@ forget_cluster_node(Node, RemoveWhenOffline) ->
end.
remove_node_offline_node(Node) ->
- %% We want the running nodes *now*, so we don't call
- %% `cluster_nodes(running)' which will just get what's in the cluster status
- %% file.
- case {running_nodes(cluster_nodes(all)) -- [Node], node_type()} of
+ %% Here `mnesia:system_info(running_db_nodes)' will RPC, but that's what we
+ %% want - we need to know the running nodes *now*. If the current node is a
+ %% RAM node it will return bogus results, but we don't care since we only do
+ %% this operation from disc nodes.
+ case {mnesia:system_info(running_db_nodes) -- [Node], node_type()} of
{[], disc} ->
- %% Note that while we check if the nodes was the last to
- %% go down, apart from the node we're removing from, this
- %% is still unsafe. Consider the situation in which A and
- %% B are clustered. A goes down, and records B as the
- %% running node. Then B gets clustered with C, C goes down
- %% and B goes down. In this case, C is the second-to-last,
- %% but we don't know that and we'll remove B from A
+ %% Note that while we check if the nodes was the last to go down,
+ %% apart from the node we're removing from, this is still unsafe.
+ %% Consider the situation in which A and B are clustered. A goes
+ %% down, and records B as the running node. Then B gets clustered
+ %% with C, C goes down and B goes down. In this case, C is the
+ %% second-to-last, but we don't know that and we'll remove B from A
%% anyway, even if that will lead to bad things.
case cluster_nodes(running) -- [node(), Node] of
[] -> start_mnesia(),
@@ -348,7 +350,7 @@ cluster_nodes(WhichNodes) -> cluster_status(WhichNodes).
%% This function is the actual source of information, since it gets
%% the data from mnesia. Obviously it'll work only when mnesia is
%% running.
-mnesia_nodes() ->
+cluster_status_from_mnesia() ->
case mnesia:system_info(is_running) of
no ->
{error, mnesia_not_running};
@@ -368,39 +370,33 @@ mnesia_nodes() ->
disc -> nodes_incl_me(DiscCopies);
ram -> DiscCopies
end,
- {ok, {AllNodes, DiscNodes}};
+ %% `mnesia:system_info(running_db_nodes)' is safe since
+ %% we know that mnesia is running
+ RunningNodes = mnesia:system_info(running_db_nodes),
+ {ok, {AllNodes, DiscNodes, RunningNodes}};
false -> {error, tables_not_present}
end
end.
cluster_status(WhichNodes) ->
- %% I don't want to call `running_nodes/1' unless if necessary, since it's
- %% pretty expensive.
- {AllNodes1, DiscNodes1, RunningNodesThunk} =
- case mnesia_nodes() of
- {ok, {AllNodes, DiscNodes}} ->
- {AllNodes, DiscNodes, fun() -> running_nodes(AllNodes) end};
+ {AllNodes, DiscNodes, RunningNodes} = Nodes =
+ case cluster_status_from_mnesia() of
+ {ok, Nodes0} ->
+ Nodes0;
{error, _Reason} ->
- {AllNodes, DiscNodes, RunningNodes} =
+ {AllNodes0, DiscNodes0, RunningNodes0} =
rabbit_node_monitor:read_cluster_status(),
%% The cluster status file records the status when the node is
%% online, but we know for sure that the node is offline now, so
%% we can remove it from the list of running nodes.
- {AllNodes, DiscNodes, fun() -> nodes_excl_me(RunningNodes) end}
+ {AllNodes0, DiscNodes0, nodes_excl_me(RunningNodes0)}
end,
case WhichNodes of
- status -> {AllNodes1, DiscNodes1, RunningNodesThunk()};
- all -> AllNodes1;
- disc -> DiscNodes1;
- ram -> AllNodes1 -- DiscNodes1;
- running -> RunningNodesThunk()
- end.
-
-cluster_status_from_mnesia() ->
- case mnesia_nodes() of
- {ok, {AllNodes, DiscNodes}} -> {ok, {AllNodes, DiscNodes,
- running_nodes(AllNodes)}};
- {error, _} = Err -> Err
+ status -> Nodes;
+ all -> AllNodes;
+ disc -> DiscNodes;
+ ram -> AllNodes -- DiscNodes;
+ running -> RunningNodes
end.
node_info() ->
@@ -735,14 +731,6 @@ change_extra_db_nodes(ClusterNodes0, CheckOtherNodes) ->
Nodes
end.
-%% We're not using `mnesia:system_info(running_db_nodes)' directly
-%% because if the node is a RAM node it won't know about other nodes
-%% when mnesia is stopped
-running_nodes(Nodes) ->
- {Replies, _BadNodes} = rpc:multicall(Nodes,
- rabbit_mnesia, is_running_remote, []),
- [Node || {Running, Node} <- Replies, Running].
-
is_running_remote() -> {mnesia:system_info(is_running) =:= yes, node()}.
check_consistency(OTP, Rabbit) ->
diff --git a/src/rabbit_runtime_parameters.erl b/src/rabbit_runtime_parameters.erl
index 4a83e61f..49060409 100644
--- a/src/rabbit_runtime_parameters.erl
+++ b/src/rabbit_runtime_parameters.erl
@@ -39,14 +39,16 @@
-spec(clear_any/3 :: (rabbit_types:vhost(), binary(), binary())
-> ok_or_error_string()).
-spec(list/0 :: () -> [rabbit_types:infos()]).
--spec(list/1 :: (rabbit_types:vhost()) -> [rabbit_types:infos()]).
--spec(list_strict/1 :: (binary()) -> [rabbit_types:infos()] | 'not_found').
--spec(list/2 :: (rabbit_types:vhost(), binary()) -> [rabbit_types:infos()]).
--spec(list_strict/2 :: (rabbit_types:vhost(), binary())
+-spec(list/1 :: (rabbit_types:vhost() | '_') -> [rabbit_types:infos()]).
+-spec(list_strict/1 :: (binary() | '_')
+ -> [rabbit_types:infos()] | 'not_found').
+-spec(list/2 :: (rabbit_types:vhost() | '_', binary() | '_')
+ -> [rabbit_types:infos()]).
+-spec(list_strict/2 :: (rabbit_types:vhost() | '_', binary() | '_')
-> [rabbit_types:infos()] | 'not_found').
-spec(list_formatted/1 :: (rabbit_types:vhost()) -> [rabbit_types:infos()]).
-spec(lookup/3 :: (rabbit_types:vhost(), binary(), binary())
- -> rabbit_types:infos()).
+ -> rabbit_types:infos() | 'not_found').
-spec(value/3 :: (rabbit_types:vhost(), binary(), binary()) -> term()).
-spec(value/4 :: (rabbit_types:vhost(), binary(), binary(), term()) -> term()).
-spec(info_keys/0 :: () -> rabbit_types:info_keys()).