Home > other >  Ejabberd network layer is not performant
Ejabberd network layer is not performant

Time:10-12

I know that ejabberd server is efficient and designed for high performance and fault tolerance but i don't understand why i see that it's listeners modules handle connections sequentially, in the Joe Armestrong's book i see that parallel servers works like this :

{ok, Listen}=gen_tcp:listen(....),
spawn(fun() ->parallel(Listen) end).

parallel(Listen) ->
{ok, Socket}=gen_tcp:accept(Listen),
spawn(fun() ->parallel(Listen) end),
handling(Socket).

handling(Socket) ->
....

But in EJABBERD listener named ejabberd_listener.erl the mechanism of listening is simple :a supervisor had workers children and each child represents a module listener with it's listening options (port, network protocole, ip,...) , there are 4 or 5 children and all children run one of two functions at start : TCP or UDP and this last represents the listen function for incoming connections, and when a connection is accepted and a Socket is created, the listener passed the Socket as an argument to the start function of the Module and continue to accept other connections, the most important part of code is :

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

init_tcp(PortIP, Module, Opts, SockOpts, Port, IPS) ->

%% Some of work
.... 

ListenSocket = listen_tcp(PortIP, Module, SockOpts, Port, IPS), 

%% Some of work
.... 

accept(ListenSocket, Module,.... ), 

%% Some of work
.... 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

listen_tcp(....) ->

Res = gen_tcp:listen(....),

%% Some of work
.... 

case Res of {ok, ListenSocket} ->Listensocket;

%% Some of work
.... 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

accept(ListenSocket, Module,... ) ->

case gen_tcp:accept(ListenSocket) of
    {ok, Socket} ->

%% Some of work
....

Module:start(....,Socket,....),

%% Some of work
.... 

accept(ListenSocket, Module,.... );

It's very clear that this is a sequential listener and it runs slower than parallel, so why they don't use the parallel mechanism for more efficiency and performance ? may be i mess something or this is because it's community edition and you need to modify code, so who had experience with Erlang and Ejabberd can help me please ?

CodePudding user response:

Both variants are in fact parallel. ejabberd_listener calls the start function in the listener module, which at least in the case of ejabberd_c2s ends up calling xmpp_stream_in:start, which starts a new gen_server process. The ejabberd_listener process is then free to call gen_tcp:accept again, waiting for another incoming connection.

The snippet from Joe Armstrong's book does it the other way around: it spawns a new process to accept further incoming connections, and handles the current connection in the existing process. It's not clear (to me, at least) that either way is necessarily more performant than the other.

  • Related