Track IO deltas.
[beam_stats.git] / src / beam_stats_producer.erl
CommitLineData
caf75ed8
SK
1-module(beam_stats_producer).
2
3-include("beam_stats.hrl").
4
5-behaviour(gen_server).
6
7%% API
8-export(
9 [ start_link/0
10 , subscribe/1
11 , unsubscribe/1
4997ac36
SK
12
13 % Force production and distribution. Blocks. Mainly for testing.
14 , force_production/0
caf75ed8
SK
15 ]).
16
17%% gen_server callbacks
18-export(
19 [ init/1
20 , handle_call/3
21 , handle_cast/2
22 , handle_info/2
23 , terminate/2
24 , code_change/3
25 ]).
26
27%% ============================================================================
28%% Internal data
29%% ============================================================================
30
31-define(SIGNAL_PRODUCTION , beam_stats_production_signal).
4997ac36 32-define(FORCE_PRODUCTION , beam_stats_force_production).
caf75ed8
SK
33
34-record(state,
35 { consumers = ordsets:new() :: ordsets:ordset(pid())
b4e2333f 36 , stats_state :: beam_stats_state:t()
caf75ed8
SK
37 }).
38
4997ac36
SK
39-type state() ::
40 #state{}.
41
caf75ed8
SK
42%% ============================================================================
43%% API
44%% ============================================================================
45
46start_link() ->
47 gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
48
49-spec subscribe(pid()) ->
50 ok.
51subscribe(PID) ->
52 gen_server:cast(?MODULE, {subscribe, PID}).
53
54-spec unsubscribe(pid()) ->
55 ok.
56unsubscribe(PID) ->
57 gen_server:cast(?MODULE, {unsubscribe, PID}).
58
4997ac36
SK
59-spec force_production() ->
60 {}.
61force_production() ->
62 gen_server:call(?MODULE, ?FORCE_PRODUCTION).
63
caf75ed8
SK
64%% ============================================================================
65%% gen_server callbacks (unused)
66%% ============================================================================
67
caf75ed8
SK
68code_change(_OldVsn, State, _Extra) ->
69 {ok, State}.
70
71terminate(_Reason, _State) ->
72 ok.
73
74%% ============================================================================
75%% gen_server callbacks
76%% ============================================================================
77
78init([]) ->
79 ok = schedule_first_production(),
80 Consumers = ordsets:new(),
b4e2333f
SK
81 StatsState = beam_stats_state:new(),
82 {ok, #state{consumers=Consumers, stats_state=StatsState}}.
caf75ed8
SK
83
84handle_cast({subscribe, PID}, #state{consumers=Consumers1}=State) ->
85 Consumers2 = ordsets:add_element(PID, Consumers1),
86 {noreply, State#state{consumers=Consumers2}};
87
88handle_cast({unsubscribe, PID}, #state{consumers=Consumers1}=State) ->
89 Consumers2 = ordsets:del_element(PID, Consumers1),
90 {noreply, State#state{consumers=Consumers2}}.
91
b4e2333f
SK
92handle_call(?FORCE_PRODUCTION, _From, State1) ->
93 State2 = produce(State1),
94 {reply, {}, State2}.
4997ac36 95
b4e2333f
SK
96handle_info(?SIGNAL_PRODUCTION, #state{}=State1) ->
97 State2 = produce(State1),
caf75ed8 98 ok = schedule_next_production(),
b4e2333f 99 {noreply, State2}.
caf75ed8
SK
100
101%% ============================================================================
102%% Private
103%% ============================================================================
104
4997ac36 105-spec produce(state()) ->
b4e2333f
SK
106 state().
107produce(#state{consumers=ConsumersSet, stats_state=StatsState1}=State) ->
108 StatsState2 = beam_stats_state:update(StatsState1),
109 Stats = beam_stats_state:export(StatsState2),
4997ac36 110 ConsumersList = ordsets:to_list(ConsumersSet),
b4e2333f
SK
111 ok = push_to_consumers(Stats, ConsumersList),
112 State#state{stats_state = StatsState2}.
4997ac36 113
caf75ed8
SK
114-spec schedule_first_production() ->
115 ok.
116schedule_first_production() ->
117 _ = self() ! ?SIGNAL_PRODUCTION,
118 ok.
119
120-spec schedule_next_production() ->
121 ok.
122schedule_next_production() ->
123 ProductionInterval = beam_stats_config:production_interval(),
124 _ = erlang:send_after(ProductionInterval, self(), ?SIGNAL_PRODUCTION),
125 ok.
126
b4e2333f 127-spec push_to_consumers(beam_stats:t(), [pid()]) ->
caf75ed8 128 ok.
b4e2333f
SK
129push_to_consumers(Stats, Consumers) ->
130 Push = fun (Consumer) -> gen_server:cast(Consumer, Stats) end,
caf75ed8 131 lists:foreach(Push, Consumers).
This page took 0.040722 seconds and 4 git commands to generate.