1 -module(beam_stats_producer).
3 -include("beam_stats.hrl").
5 -behaviour(gen_server).
14 %% gen_server callbacks
24 %% ============================================================================
26 %% ============================================================================
28 -define(SIGNAL_PRODUCTION , beam_stats_production_signal).
31 { consumers = ordsets:new() :: ordsets:ordset(pid())
34 %% ============================================================================
36 %% ============================================================================
39 gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
41 -spec subscribe(pid()) ->
44 gen_server:cast(?MODULE, {subscribe, PID}).
46 -spec unsubscribe(pid()) ->
49 gen_server:cast(?MODULE, {unsubscribe, PID}).
51 %% ============================================================================
52 %% gen_server callbacks (unused)
53 %% ============================================================================
55 handle_call(_Request, _From, State) ->
56 ?METHOD_SHOULD_NOT_BE_USED(handle_call, State).
58 code_change(_OldVsn, State, _Extra) ->
61 terminate(_Reason, _State) ->
64 %% ============================================================================
65 %% gen_server callbacks
66 %% ============================================================================
69 ok = schedule_first_production(),
70 Consumers = ordsets:new(),
71 {ok, #state{consumers=Consumers}}.
73 handle_cast({subscribe, PID}, #state{consumers=Consumers1}=State) ->
74 Consumers2 = ordsets:add_element(PID, Consumers1),
75 {noreply, State#state{consumers=Consumers2}};
77 handle_cast({unsubscribe, PID}, #state{consumers=Consumers1}=State) ->
78 Consumers2 = ordsets:del_element(PID, Consumers1),
79 {noreply, State#state{consumers=Consumers2}}.
81 handle_info(?SIGNAL_PRODUCTION, #state{consumers=ConsumersSet}=State) ->
82 ConsumersList = ordsets:to_list(ConsumersSet),
83 ok = collect_and_push_to_consumers(ConsumersList),
84 ok = schedule_next_production(),
87 %% ============================================================================
89 %% ============================================================================
91 -spec schedule_first_production() ->
93 schedule_first_production() ->
94 _ = self() ! ?SIGNAL_PRODUCTION,
97 -spec schedule_next_production() ->
99 schedule_next_production() ->
100 ProductionInterval = beam_stats_config:production_interval(),
101 _ = erlang:send_after(ProductionInterval, self(), ?SIGNAL_PRODUCTION),
104 -spec collect_and_push_to_consumers([pid()]) ->
106 collect_and_push_to_consumers(Consumers) ->
107 BEAMStats = beam_stats:collect(),
108 Push = fun (Consumer) -> gen_server:cast(Consumer, BEAMStats) end,
109 lists:foreach(Push, Consumers).