Skip to content

Commit

Permalink
Hibernate ejabberd_receiver and ejabberd_c2s on every occassion.
Browse files Browse the repository at this point in the history
  • Loading branch information
kzemek committed Apr 24, 2018
1 parent 963e0a3 commit 8a18db6
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 36 deletions.
28 changes: 14 additions & 14 deletions src/ejabberd_c2s.erl
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,8 @@ do_open_session(Acc, JID, StateData) ->
{stop, normal, NextStateData} -> % error, resume not possible
c2s_stream_error(mongoose_xmpp_errors:stream_internal_server_error(), NextStateData),
{stop, Acc1, NStateData};
{_, _, NextStateData, _} ->
Result when is_tuple(Result) ->
NextStateData = element(3, Result),
do_open_session_common(Acc1, JID, NextStateData)
end
end.
Expand Down Expand Up @@ -992,12 +993,6 @@ session_established({xmlstreamelement, El}, StateData) ->

%% We hibernate the process to reduce memory consumption after a
%% configurable activity timeout
session_established(timeout, StateData) ->
%% TODO: Options must be stored in state:
Options = [],
proc_lib:hibernate(p1_fsm_old, enter_loop,
[?MODULE, Options, session_established, StateData]),
fsm_next_state(session_established, StateData);
session_established({xmlstreamend, _Name}, StateData) ->
send_trailer(StateData),
{stop, normal, StateData};
Expand Down Expand Up @@ -1094,18 +1089,18 @@ resume_session({xmlstreamelement, _}, StateData) ->
<<"session in resume state cannot accept incoming stanzas">>),
maybe_send_element_safe(StateData, Err),
maybe_send_trailer_safe(StateData),
{next_state, resume_session, StateData, hibernate};
maybe_hibernate({next_state, resume_session, StateData});

%%-------------------------------------------------------------------------
%% ignore mod_ping closed messages because we are already in resume session
%% state
resume_session(closed, StateData) ->
{next_state, resume_session, StateData, hibernate};
maybe_hibernate({next_state, resume_session, StateData});
resume_session(timeout, StateData) ->
{next_state, resume_session, StateData, hibernate};
maybe_hibernate({next_state, resume_session, StateData});
resume_session(Msg, StateData) ->
?WARNING_MSG("unexpected message ~p", [Msg]),
{next_state, resume_session, StateData, hibernate}.
maybe_hibernate({next_state, resume_session, StateData}).


%%----------------------------------------------------------------------
Expand Down Expand Up @@ -2579,15 +2574,15 @@ fsm_next_state_gc(StateName, PackedStateData) ->
%% @doc fsm_next_state: Generate the next_state FSM tuple with different
%% timeout, depending on the future state
fsm_next_state(session_established, StateData) ->
{next_state, session_established, StateData, ?C2S_HIBERNATE_TIMEOUT};
maybe_hibernate({next_state, session_established, StateData});
fsm_next_state(StateName, StateData) ->
{next_state, StateName, StateData, ?C2S_OPEN_TIMEOUT}.


%% @doc fsm_reply: Generate the reply FSM tuple with different timeout,
%% depending on the future state
fsm_reply(Reply, session_established, StateData) ->
{reply, Reply, session_established, StateData, ?C2S_HIBERNATE_TIMEOUT};
maybe_hibernate({reply, Reply, session_established, StateData});
fsm_reply(Reply, StateName, StateData) ->
{reply, Reply, StateName, StateData, ?C2S_OPEN_TIMEOUT}.

Expand Down Expand Up @@ -3106,7 +3101,7 @@ maybe_enter_resume_session(_SMID, #state{} = SD) ->
_TRef ->
SD
end,
{next_state, resume_session, NSD, hibernate}.
maybe_hibernate({next_state, resume_session, NSD}).

maybe_resume_session(NextState, El, StateData) ->
case {xml:get_tag_attr_s(<<"xmlns">>, El),
Expand Down Expand Up @@ -3353,3 +3348,8 @@ setup_accum(Acc, StateData) ->
Server = StateData#state.server,
mongoose_acc:update(Acc, #{server => Server, user => User}).

maybe_hibernate(Result) ->
case process_info(self(), message_queue_len) of
{_, 0} -> erlang:append_element(Result, hibernate);
_ -> Result
end.
43 changes: 21 additions & 22 deletions src/ejabberd_receiver.erl
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@
timeout}).
-type state() :: #state{}.

-define(HIBERNATE_TIMEOUT, 90000).

%%====================================================================
%% API
%%====================================================================
Expand Down Expand Up @@ -141,7 +139,7 @@ init([Socket, SockMod, Shaper, MaxStanzaSize]) ->
%% Description: Handling call messages
%%--------------------------------------------------------------------
handle_call(get_socket, _From, #state{socket = Socket} = State) ->
{reply, {ok, Socket}, State, ?HIBERNATE_TIMEOUT};
maybe_hibernate({reply, {ok, Socket}, State});
handle_call({starttls, TLSOpts}, From, #state{parser = Parser,
socket = TCPSocket} = State) ->
%% the next message from client is part of TLS handshake, it must
Expand All @@ -161,7 +159,7 @@ handle_call({starttls, TLSOpts}, From, #state{parser = Parser,
%% handshake. such call is simply ignored by just_tls backend.
case ejabberd_tls:recv_data(TLSSocket, <<"">>) of
{ok, TLSData} ->
{noreply, process_data(TLSData, NewState), ?HIBERNATE_TIMEOUT};
maybe_hibernate({noreply, process_data(TLSData, NewState)});
{error, Reason} ->
?WARNING_MSG("tcp_to_tls failed with reason ~p~n", [Reason]),
{stop, normal, NewState}
Expand All @@ -177,11 +175,11 @@ handle_call({compress, ZlibSocket}, _From,
sock_mod = ejabberd_zlib},
case ejabberd_zlib:recv_data(ZlibSocket, "") of
{ok, ZlibData} ->
{reply, ok, process_data(ZlibData, NewState), ?HIBERNATE_TIMEOUT};
maybe_hibernate({reply, ok, process_data(ZlibData, NewState)});
{error, inflate_size_exceeded} ->
apply(gen_fsm(), send_event,
[C2SPid, {xmlstreamerror, <<"child element too big">>}]),
{reply, ok, NewState, ?HIBERNATE_TIMEOUT};
maybe_hibernate({reply, ok, NewState});
{error, inflate_error} ->
{stop, normal, ok, NewState}
end;
Expand All @@ -190,10 +188,10 @@ handle_call({become_controller, C2SPid}, _From, State) ->
NewState = StateAfterReset#state{c2s_pid = C2SPid},
activate_socket(NewState),
Reply = ok,
{reply, Reply, NewState, ?HIBERNATE_TIMEOUT};
maybe_hibernate({reply, Reply, NewState});
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State, ?HIBERNATE_TIMEOUT}.
maybe_hibernate({reply, Reply, State}).

%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
Expand All @@ -203,11 +201,11 @@ handle_call(_Request, _From, State) ->
%%--------------------------------------------------------------------
handle_cast({change_shaper, Shaper}, State) ->
NewShaperState = shaper:new(Shaper),
{noreply, State#state{shaper_state = NewShaperState}, ?HIBERNATE_TIMEOUT};
maybe_hibernate({noreply, State#state{shaper_state = NewShaperState}});
handle_cast(close, State) ->
{stop, normal, State};
handle_cast(_Msg, State) ->
{noreply, State, ?HIBERNATE_TIMEOUT}.
maybe_hibernate({noreply, State}).

%%--------------------------------------------------------------------
%% Function: handle_info(Info, State) -> {noreply, State} |
Expand All @@ -226,8 +224,7 @@ handle_info({Tag, _TCPSocket, Data},
[data, xmpp, received, encrypted_size], size(Data)),
case ejabberd_tls:recv_data(Socket, Data) of
{ok, TLSData} ->
{noreply, process_data(TLSData, State),
?HIBERNATE_TIMEOUT};
maybe_hibernate({noreply, process_data(TLSData, State)});
{error, _Reason} ->
{stop, normal, State}
end;
Expand All @@ -236,17 +233,16 @@ handle_info({Tag, _TCPSocket, Data},
[data, xmpp, received, compressed_size], size(Data)),
case ejabberd_zlib:recv_data(Socket, Data) of
{ok, ZlibData} ->
{noreply, process_data(ZlibData, State),
?HIBERNATE_TIMEOUT};
maybe_hibernate({noreply, process_data(ZlibData, State)});
{error, inflate_size_exceeded} ->
apply(gen_fsm(), send_event,
[C2SPid, {xmlstreamerror, <<"child element too big">>}]),
{noreply, State, ?HIBERNATE_TIMEOUT};
maybe_hibernate({noreply, State});
{error, inflate_error} ->
{stop, normal, State}
end;
_ ->
{noreply, process_data(Data, State), ?HIBERNATE_TIMEOUT}
maybe_hibernate({noreply, process_data(Data, State)})
end;
handle_info({Tag, _TCPSocket}, State)
when (Tag == tcp_closed) or (Tag == ssl_closed) ->
Expand All @@ -255,18 +251,15 @@ handle_info({Tag, _TCPSocket, Reason}, State)
when (Tag == tcp_error) or (Tag == ssl_error) ->
case Reason of
timeout ->
{noreply, State, ?HIBERNATE_TIMEOUT};
maybe_hibernate({noreply, State});
_ ->
{stop, normal, State}
end;
handle_info({timeout, _Ref, activate}, State) ->
activate_socket(State),
{noreply, State, ?HIBERNATE_TIMEOUT};
handle_info(timeout, State) ->
proc_lib:hibernate(gen_server, enter_loop, [?MODULE, [], State]),
{noreply, State, ?HIBERNATE_TIMEOUT};
maybe_hibernate({noreply, State});
handle_info(_Info, State) ->
{noreply, State, ?HIBERNATE_TIMEOUT}.
maybe_hibernate({noreply, State}).

%%--------------------------------------------------------------------
%% Function: terminate(Reason, State) -> void()
Expand Down Expand Up @@ -421,3 +414,9 @@ gen_server_call_or_noproc(Pid, Message) ->
end.

gen_fsm() -> p1_fsm.

maybe_hibernate(Result) ->
case process_info(self(), message_queue_len) of
{_, 0} -> erlang:append_element(Result, hibernate);
_ -> Result
end.

0 comments on commit 8a18db6

Please sign in to comment.