summaryrefslogtreecommitdiff
path: root/src/couch_stats/src/couch_stats_process_tracker.erl
blob: c53f0f887fef282e12d136342bfa77f4b84ca8dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License. You may obtain a copy of
% the License at
%
%   http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
% License for the specific language governing permissions and limitations under
% the License.

-module(couch_stats_process_tracker).
-behaviour(gen_server).

-export([
    track/1,
    track/2
]).

-export([
    start_link/0,
    init/1,
    handle_call/3,
    handle_cast/2,
    handle_info/2,
    code_change/3,
    terminate/2
]).

-record(st, {}).

-spec track(any()) -> ok.
track(Name) ->
    track(self(), Name).

-spec track(pid(), any()) -> ok.
track(Pid, Name) ->
    gen_server:cast(?MODULE, {track, Pid, Name}).

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

init([]) ->
    ets:new(?MODULE, [named_table, public, set]),
    {ok, #st{}}.

handle_call(Msg, _From, State) ->
    error_logger:error_msg("~p received unknown call ~p", [?MODULE, Msg]),
    {noreply, State}.

handle_cast({track, Pid, Name}, State) ->
    couch_stats:increment_counter(Name),
    Ref = erlang:monitor(process, Pid),
    ets:insert(?MODULE, {Ref, Name}),
    {noreply, State};
handle_cast(Msg, State) ->
    error_logger:error_msg("~p received unknown cast ~p", [?MODULE, Msg]),
    {noreply, State}.

handle_info({'DOWN', Ref, _, _, _} = Msg, State) ->
    case ets:lookup(?MODULE, Ref) of
        [] ->
            error_logger:error_msg(
                "~p received unknown exit; message was ~p", [?MODULE, Msg]
            );
        [{Ref, Name}] ->
            couch_stats:decrement_counter(Name),
            ets:delete(?MODULE, Ref)
    end,
    {noreply, State};
handle_info(Msg, State) ->
    error_logger:error_msg("~p received unknown message ~p", [?MODULE, Msg]),
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.