%% @doc A simple gen_event backend used to monitor mailbox size and %% switch log messages between synchronous and asynchronous modes. %% A gen_event handler is used because a process getting its own mailbox %% size doesn't involve getting a lock, and gen_event handlers run in their %% parent's process. -module(rumBackendThrottle). -behaviour(gen_event). -include("eRum.hrl"). -export([ init/1 , handle_call/2 , handle_event/2 , handle_info/2 , terminate/2, code_change/3 ]). -record(state, { sink :: atom(), hwm :: non_neg_integer(), window_min :: non_neg_integer(), async = true :: boolean() }). init([{sink, Sink}, Hwm, Window]) -> rumConfig:set({Sink, async}, true), {ok, #state{sink = Sink, hwm = Hwm, window_min = Hwm - Window}}. handle_call(get_loglevel, State) -> {ok, {mask, ?LOG_NONE}, State}; handle_call({set_loglevel, _Level}, State) -> {ok, ok, State}; handle_call(_Request, State) -> {ok, ok, State}. handle_event({mWriteLog, _Message}, State) -> {message_queue_len, Len} = erlang:process_info(self(), message_queue_len), case {Len > State#state.hwm, Len < State#state.window_min, State#state.async} of {true, _, true} -> %% need to flip to sync mode rumConfig:set({State#state.sink, async}, false), {ok, State#state{async = false}}; {_, true, false} -> %% need to flip to async mode rumConfig:set({State#state.sink, async}, true), {ok, State#state{async = true}}; _ -> %% nothing needs to change {ok, State} end; handle_event(_Event, State) -> {ok, State}. handle_info(_Info, State) -> {ok, State}. %% @private terminate(_Reason, _State) -> ok. %% @private code_change(_OldVsn, State, _Extra) -> {ok, State}.