diff options
author | Francesco Mazzoli <francesco@rabbitmq.com> | 2012-10-25 13:10:45 +0100 |
---|---|---|
committer | Francesco Mazzoli <francesco@rabbitmq.com> | 2012-10-25 13:10:45 +0100 |
commit | aebd72c8238c559ce976a05854012f99b0a06783 (patch) | |
tree | 85c992615b26440852642635c78e2f26bc0f489e | |
parent | ae460017f0daaa84377151fc717795f9ca5699e3 (diff) | |
parent | c419fcc1d934827226df2493a9f100e2f8d72933 (diff) | |
download | rabbitmq-server-aebd72c8238c559ce976a05854012f99b0a06783.tar.gz |
merge default
-rw-r--r-- | src/rabbit_amqqueue_process.erl | 8 | ||||
-rw-r--r-- | src/rabbit_mnesia.erl | 72 | ||||
-rw-r--r-- | src/rabbit_runtime_parameters.erl | 12 |
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()). |