[ejabberd] 100 mb per c2s connection (+patch)

Mickael Remond mickael.remond at process-one.net
Mon Mar 30 21:52:46 MSD 2009


Hello Anton,

The socket send timeout and disconnection features was only going to be
pushed in ejabberd 2.1, because the send timeout API require a recent
Erlang R12 version.
Fully supporting that API will require dropping support for Erlang R11.
This is the type of thing we have pushed to customer however that have
made the switch to R12 and that will go into 2.1 version.

Anton Belyaev wrote:

> Hello,
>
> I've been investigating why ejabberd spends so much memory and found
> out that some connections consumed >100 mb.
>
> All the large connections were blocked on socket send operation.
> Recently EJAB-746 was fixed, introducing a 15 sec timeout on socket
> send. The problem has still remained for me, nevertheless. In
> ejabberd_c2s module results of socket send are not examined at all, so
> if client just does not read the socket, c2s process will block every
> 15 seconds on every message.
>
> My application (component) sends a message to every user once 3
> seconds. So, such client session will grow their message queue very
> fast. And ejabberd crashed with out-of-mem.
>
> To aid this I wrote a simple patch (attached), which drops session if
> socket send times out.
>
> Discussion: why results of socket send are not handled in ejabberd_c2s
> at all? Or such errors are handled somewhere else?
>
> Thanks.
> Anton.
>
> --- ejabberd_c2s.erl.orig	2009-03-28 20:37:04.000000000 +0300
> +++ ejabberd_c2s.erl	2009-03-28 20:41:07.000000000 +0300
>>> -1258,26 +1258,31 @@
> if Pass == exit -> catch send_text(StateData, ?STREAM_TRAILER), {stop,
> 	normal, StateData}; Pass -> Attrs2 =
> 	jlib:replace_from_to_attrs(jlib:jid_to_string(From),
> 	jlib:jid_to_string(To), NewAttrs), FixedPacket = {xmlelement,
> 	Name, Attrs2, Els}, Text = xml:element_to_string(FixedPacket),
> 	- send_text(StateData, Text), -
> 	ejabberd_hooks:run(user_receive_packet, -
> 	StateData#state.server, - [StateData#state.jid, From, To,
> 	FixedPacket]), - ejabberd_hooks:run(c2s_loop_debug, [{route,
> 	From, To, Packet}]), - fsm_next_state(StateName, NewState);
> +	    case send_text(StateData, Text) of
> +            {error, timeout} ->
> +                ?INFO_MSG("Socket send timed out for ~p, stopping", [StateData#state.user]),
> +                {stop, normal, StateData};
> +            _ ->
> +                ejabberd_hooks:run(user_receive_packet,
> +                                   StateData#state.server,
> +                                   [StateData#state.jid, From, To, FixedPacket]),
> +                ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]),
> +                fsm_next_state(StateName, NewState)
> +        end;
> 	true ->
> 	    ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]),
> 	    fsm_next_state(StateName, NewState)
> end;
> handle_info({'DOWN', Monitor, _Type, _Object, _Info}, _StateName, StateData)
> when Monitor == StateData#state.socket_monitor ->
> {stop, normal, StateData};
> handle_info(Info, StateName, StateData) ->
> ?ERROR_MSG("Unexpected info: ~p", [Info]),
> fsm_next_state(StateName, StateData).
> _______________________________________________
> ejabberd mailing list
> ejabberd at jabber.ru
> http://lists.jabber.ru/mailman/listinfo/ejabberd

-- 
Mickaël Rémond
 http://www.process-one.net/


More information about the ejabberd mailing list