1%% -------------------------------------------------------------------
2%% Copyright (c) 2007-2010 Basho Technologies, Inc.  All Rights Reserved.
3%% Copyright (c) 2018-2021 VMware, Inc. or its affiliates.  All rights reserved.
4%%
5%% This file is provided to you under the Apache License,
6%% Version 2.0 (the "License"); you may not use this file
7%% except in compliance with the License.  You may obtain
8%% a copy of the License at
9%%
10%%   https://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing,
13%% software distributed under the License is distributed on an
14%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15%% KIND, either express or implied.  See the License for the
16%% specific language governing permissions and limitations
17%% under the License.
18%%
19%% -------------------------------------------------------------------
20
21-module(rabbit_sysmon_minder).
22
23-behaviour(gen_server).
24
25%% API
26-export([start_link/0]).
27
28%% gen_server callbacks
29-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
30         terminate/2, code_change/3]).
31
32-record(state, {}).
33
34%%%===================================================================
35%%% API
36%%%===================================================================
37
38%%--------------------------------------------------------------------
39%% @doc
40%% Starts the server
41%%
42%% @spec start_link() -> {ok, Pid} | ignore | {error, Error}
43%% @end
44%%--------------------------------------------------------------------
45start_link() ->
46    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
47
48%%%===================================================================
49%%% gen_server callbacks
50%%%===================================================================
51
52%%--------------------------------------------------------------------
53%% @private
54%% @doc
55%% Initializes the server
56%%
57%% @spec init(Args) -> {ok, State} |
58%%                     {ok, State, Timeout} |
59%%                     ignore |
60%%                     {stop, Reason}
61%% @end
62%%--------------------------------------------------------------------
63init([]) ->
64    %% Add our system_monitor event handler.  We do that here because
65    %% we have a process at our disposal (i.e. ourself) to receive the
66    %% notification in the very unlikely event that the
67    %% sysmon_handler has crashed and been removed from the
68    %% sysmon_handler gen_event server.  (If we had a supervisor
69    %% or app-starting process add the handler, then if the handler
70    %% crashes, nobody will act on the crash notification.)
71    rabbit_sysmon_handler:add_handler(),
72    {ok, #state{}}.
73
74%%--------------------------------------------------------------------
75%% @private
76%% @doc
77%% Handling call messages
78%%
79%% @spec handle_call(Request, From, State) ->
80%%                                   {reply, Reply, State} |
81%%                                   {reply, Reply, State, Timeout} |
82%%                                   {noreply, State} |
83%%                                   {noreply, State, Timeout} |
84%%                                   {stop, Reason, Reply, State} |
85%%                                   {stop, Reason, State}
86%% @end
87%%--------------------------------------------------------------------
88handle_call(_Request, _From, State) ->
89    Reply = ok,
90    {reply, Reply, State}.
91
92%%--------------------------------------------------------------------
93%% @private
94%% @doc
95%% Handling cast messages
96%%
97%% @spec handle_cast(Msg, State) -> {noreply, State} |
98%%                                  {noreply, State, Timeout} |
99%%                                  {stop, Reason, State}
100%% @end
101%%--------------------------------------------------------------------
102handle_cast(_Msg, State) ->
103    {noreply, State}.
104
105%%--------------------------------------------------------------------
106%% @private
107%% @doc
108%% Handling all non call/cast messages
109%%
110%% @spec handle_info(Info, State) -> {noreply, State} |
111%%                                   {noreply, State, Timeout} |
112%%                                   {stop, Reason, State}
113%% @end
114%%--------------------------------------------------------------------
115handle_info({gen_event_EXIT, rabbit_sysmon_handler, _}, State) ->
116    %% SASL will create an error message, no need for us to duplicate it.
117    %%
118    %% Our handler should never crash, but it did indeed crash.  If
119    %% there's a pathological condition somewhere that's generating
120    %% lots of unforseen things that crash core's custom handler, we
121    %% could make things worse by jumping back into the exploding
122    %% volcano.  Wait a little bit before jumping back.  Besides, the
123    %% system_monitor data is nice but is not critical: there is no
124    %% need to make things worse if things are indeed bad, and if we
125    %% miss a few seconds of system_monitor events, the world will not
126    %% end.
127    timer:sleep(2*1000),
128    rabbit_sysmon_handler:add_handler(),
129    {noreply, State};
130handle_info(_Info, State) ->
131    {noreply, State}.
132
133%%--------------------------------------------------------------------
134%% @private
135%% @doc
136%% This function is called by a gen_server when it is about to
137%% terminate. It should be the opposite of Module:init/1 and do any
138%% necessary cleaning up. When it returns, the gen_server terminates
139%% with Reason. The return value is ignored.
140%%
141%% @spec terminate(Reason, State) -> void()
142%% @end
143%%--------------------------------------------------------------------
144terminate(_Reason, _State) ->
145    ok.
146
147%%--------------------------------------------------------------------
148%% @private
149%% @doc
150%% Convert process state when code is changed
151%%
152%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
153%% @end
154%%--------------------------------------------------------------------
155code_change(_OldVsn, State, _Extra) ->
156    {ok, State}.
157