diff options
| author | Simon MacMullen <simon@rabbitmq.com> | 2012-10-15 15:37:32 +0100 |
|---|---|---|
| committer | Simon MacMullen <simon@rabbitmq.com> | 2012-10-15 15:37:32 +0100 |
| commit | 27ed7815d8e52a5c8ca9e6d9cc9920622add4ba7 (patch) | |
| tree | de3f01608bdeacdf7dda4726fdeca233b907ba0f | |
| parent | c280fa22b043a39a9bf1ef9a0fd20409b7d4b5ed (diff) | |
| download | rabbitmq-server-git-27ed7815d8e52a5c8ca9e6d9cc9920622add4ba7.tar.gz | |
Subscribe to system events, receive inconsistent_database.
| -rw-r--r-- | src/rabbit_mnesia.erl | 12 | ||||
| -rw-r--r-- | src/rabbit_node_monitor.erl | 38 |
2 files changed, 43 insertions, 7 deletions
diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl index 870692282f..b07ac7d4c3 100644 --- a/src/rabbit_mnesia.erl +++ b/src/rabbit_mnesia.erl @@ -320,10 +320,20 @@ status() -> [{nodes, (IfNonEmpty(disc, cluster_nodes(disc)) ++ IfNonEmpty(ram, cluster_nodes(ram)))}] ++ case mnesia:system_info(is_running) of - yes -> [{running_nodes, cluster_nodes(running)}]; + yes -> RunningNodes = cluster_nodes(running), + [{running_nodes, cluster_nodes(running)}, + {partitions, mnesia_partitions(RunningNodes)}]; no -> [] end. +mnesia_partitions(Nodes) -> + {Replies, _BadNodes} = rpc:multicall( + Nodes, rabbit_node_monitor, partition, []), + case [Reply || Reply = {_, R} <- Replies, R =/= none] of + [] -> none; + List -> List + end. + is_clustered() -> AllNodes = cluster_nodes(all), AllNodes =/= [] andalso AllNodes =/= [node()]. diff --git a/src/rabbit_node_monitor.erl b/src/rabbit_node_monitor.erl index 026aa3624e..77aea36417 100644 --- a/src/rabbit_node_monitor.erl +++ b/src/rabbit_node_monitor.erl @@ -24,6 +24,7 @@ write_cluster_status/1, read_cluster_status/0, update_cluster_status/0, reset_cluster_status/0]). -export([notify_node_up/0, notify_joined_cluster/0, notify_left_cluster/1]). +-export([partition/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, @@ -32,6 +33,8 @@ -define(SERVER, ?MODULE). -define(RABBIT_UP_RPC_TIMEOUT, 2000). +-record(state, {monitors, partition}). + %%---------------------------------------------------------------------------- -ifdef(use_specs). @@ -50,6 +53,8 @@ -spec(notify_joined_cluster/0 :: () -> 'ok'). -spec(notify_left_cluster/1 :: (node()) -> 'ok'). +-spec(partition/0 :: () -> consistent | {atom(), node()}). + -endif. %%---------------------------------------------------------------------------- @@ -168,10 +173,23 @@ notify_left_cluster(Node) -> ok. %%---------------------------------------------------------------------------- +%% Server calls +%%---------------------------------------------------------------------------- + +partition() -> + gen_server:call(?SERVER, partition, infinity). + +%%---------------------------------------------------------------------------- %% gen_server callbacks %%---------------------------------------------------------------------------- -init([]) -> {ok, pmon:new()}. +init([]) -> + {ok, _} = mnesia:subscribe(system), + {ok, #state{monitors = pmon:new(), + partition = none}}. + +handle_call(partition, _From, State = #state{partition = Partition}) -> + {reply, {node(), Partition}, State}; handle_call(_Request, _From, State) -> {noreply, State}. @@ -179,9 +197,10 @@ handle_call(_Request, _From, State) -> %% Note: when updating the status file, we can't simply write the %% mnesia information since the message can (and will) overtake the %% mnesia propagation. -handle_cast({node_up, Node, NodeType}, Monitors) -> +handle_cast({node_up, Node, NodeType}, + State = #state{monitors = Monitors}) -> case pmon:is_monitored({rabbit, Node}, Monitors) of - true -> {noreply, Monitors}; + true -> {noreply, State}; false -> rabbit_log:info("rabbit on node ~p up~n", [Node]), {AllNodes, DiscNodes, RunningNodes} = read_cluster_status(), write_cluster_status({add_node(Node, AllNodes), @@ -191,7 +210,8 @@ handle_cast({node_up, Node, NodeType}, Monitors) -> end, add_node(Node, RunningNodes)}), ok = handle_live_rabbit(Node), - {noreply, pmon:monitor({rabbit, Node}, Monitors)} + {noreply, State#state{ + monitors = pmon:monitor({rabbit, Node}, Monitors)}} end; handle_cast({joined_cluster, Node, NodeType}, State) -> {AllNodes, DiscNodes, RunningNodes} = read_cluster_status(), @@ -210,12 +230,18 @@ handle_cast({left_cluster, Node}, State) -> handle_cast(_Msg, State) -> {noreply, State}. -handle_info({'DOWN', _MRef, process, {rabbit, Node}, _Reason}, Monitors) -> +handle_info({'DOWN', _MRef, process, {rabbit, Node}, _Reason}, + State = #state{monitors = Monitors}) -> rabbit_log:info("rabbit on node ~p down~n", [Node]), {AllNodes, DiscNodes, RunningNodes} = read_cluster_status(), write_cluster_status({AllNodes, DiscNodes, del_node(Node, RunningNodes)}), ok = handle_dead_rabbit(Node), - {noreply, pmon:erase({rabbit, Node}, Monitors)}; + {noreply, State#state{monitors = pmon:erase({rabbit, Node}, Monitors)}}; + +handle_info({mnesia_system_event, {inconsistent_database, Context, Node}}, + State) -> + {noreply, State#state{partition = {Context, Node}}}; + handle_info(_Info, State) -> {noreply, State}. |
