#erlang #elixir #ejabberd #scalability #erlang-otp
Вопрос:
Как определено в книге Джо, параллельный TCP — сервер обрабатывает соединения, подобные этому :
{ok, Listen}=gen_tcp:listen(....),
spawn(fun() ->parallel(Listen) end).
parallel(Listen) ->
{ok, Socket}=gen_tcp:accept(Listen),
spawn(fun() ->parallel(Listen) end),
doSomething(Socket).
doSomething(....) ->
....
Это логика, когда слушатель принимает соединение, он создает процесс для прослушивания новых входящих соединений, прежде чем обрабатывать это принятое соединение, это правило параллелизма, хорошо.
в модуле EJABBERD ejabberd_listener.erl, который представляет сетевой уровень сервера, вот что я нашел:
case listen_tcp(Port, SockOpts) of
{ok, ListenSocket} ->
....
accept(ListenSocket, Module, State, Sup, Interval, Proxy),
....
accept(ListenSocket, Module,... ) ->
case gen_tcp:accept(ListenSocket) of
{ok, Socket} ->
%%%% a lot of work
....
accept(ListenSocket, Module,.... );
Итак, это последовательный прослушиватель, и он работает медленнее, чем параллельный, так почему же они не используют параллельный механизм для повышения эффективности и производительности ? я новичок в ejabberd и, возможно, что-то упущу
Ответ №1:
Я предполагаю, что вы говорите об этом коде: [1].
В этом случае, если вы посмотрите более внимательно, немного дальше, функция start_connection
называется[2]. Внутри этой функции используется динамический супервизор и добавляется дочерний элемент [3]. Вы здесь не используете spawn
примитив, но он абстрактен supervisor:start_child
функцией[4].
Короче говоря, да, каждое соединение обрабатывается одновременно, за исключением того, что здесь каждый процесс добавляется в динамический супервизор вместо простых процессов, созданных примитивом spawn.