Сетевой уровень Ejabberd не работает

Я знаю, что сервер ejabberd эффективен и разработан для обеспечения высокой производительности и отказоустойчивости, но я не понимаю, почему я вижу, что его модули слушателей обрабатывают соединения последовательно, в книге Джо Армстронга я вижу, что параллельные серверы работают следующим образом:

      {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) ->
....

Но в слушателе EJABBERD с именем ejabberd_listener.erl механизм прослушивания прост: у супервизора есть дочерние элементы рабочих, и каждый дочерний элемент представляет прослушиватель модуля с его параметрами прослушивания (порт, сетевой протокол, ip,...), есть 4 или 5 дочерних элементов. и все дочерние элементы запускают одну из двух функций при запуске: TCP или UDP, и последняя представляет функцию прослушивания для входящих подключений, и когда соединение принимается и создается Socket, прослушиватель передал Socket в качестве аргумента функции запуска Модуль и продолжайте принимать другие соединения, самая важная часть кода:

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

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,.... );

Совершенно ясно, что это последовательный слушатель, и он работает медленнее, чем параллельный, так почему же они не используют параллельный механизм для большей эффективности и производительности? Может быть, я что-то испортил, или это потому, что это версия сообщества, и вам нужно изменить код, так что кто имел опыт работы с Erlang и Ejabberd, может мне помочь, пожалуйста?

1 ответ

Решение

Оба варианта фактически параллельны. называет start функции в модуле слушателя, что, по крайней мере, в случае ejabberd_c2s заканчивается звонком xmpp_stream_in:start, который запускает новый процесс gen_server. В ejabberd_listener затем процесс можно позвонить gen_tcp:accept снова ждем очередного входящего соединения.

Фрагмент из книги Джо Армстронга делает все наоборот: он порождает новый процесс для приема дальнейших входящих соединений и обрабатывает текущее соединение в существующем процессе. Непонятно (по крайней мере, для меня), что любой из этих способов более эффективен, чем другой.

Другие вопросы по тегам