[erlang-questions] UDP socket - ealready ERROR

Bogdan Andu bog495@REDACTED
Wed Dec 9 09:16:31 CET 2015


After more tests the basic questions that remains ..

Is there a way to have more than one process be blocked
in gen_udp:recv/2 call as this seems to not be possible right now.

Sequentially works as expected, but when when I try to spawn another process
that makes and attempt to execute gen_udp:recv/2 while the first process
already does
gen_udp:recv/2 , the second process gives elready error. This means that 2
process
cannot concurrently do gen_udp:recv/2 .

In scenario with socket {active, once} or {active, true} there is only one
process that can
receive the message from socket (the one that does gen_udp:open/2 ),
and for multi-threaded applications this quickly can become a bottleneck.
In this case, however, elready error disappears of course.
.
I tried both variants and both have disavantages.

Is there an idiom for designing a udp concurrent server in Erlang?
So far, it seems impossible.

/Bogdan

On Tue, Dec 8, 2015 at 5:24 PM, Guilherme Andrade <g@REDACTED> wrote:

> Hi,
>
> On 08/12/15 11:18, Bogdan Andu wrote:
>
> [...]
>
>     MpsConn = {mps_conn_fsm,{mps_conn_fsm, start_link, [Sock,
> SslRecvTimeout, false]},
>             temporary, 5000, worker, [mps_conn_fsm]},
>
>     {ok, {{simple_one_for_one, 0, 1}, [MpsConn]}}.
>
> [...]
>
>
> mps_dbg@REDACTED)1>
> (mps_dbg@REDACTED)1> mps_conn_sup:start_child().
> {ok,<0.62.0>}
> (mps_dbg@REDACTED)2> mps_conn_sup:start_child().
> {ok,<0.64.0>}
>
>
> Here is the culprit: you're binding the socket only *once* in the
> supervisor[1], which will be its controlling process, and then launching
> two workers which will try both to read from the same socket (which they
> cannot do because they don't control it) and then close it (which, if
> execution were to even reach that point, wouldn't also be what I imagine
> you most likely intend because you would end up closing the same socket
> twice.)
>
> One solution is to remove the socket from the child spec and move the
> socket binding to the worker code.
>
> In any case, if it were me, I would first try to have a single binding
> process which receives the datagrams and launches workers, and avoid
> overload by combining the {active, N}[2] flow with whichever backpressure
> metric your system would signal; there's no particular advantage to having
> multiple bindings over the same port - you won't really end up processing
> multiple flows at once as if they were multiple gen_tcp accepted sockets.
>
> On a final note, I would also advise against executing potentially
> blocking operations on OTP processes' init/1 and make it asynchronous
> instead (e.g. by casting an initialisation request to itself) or you'll
> risk choking up the supervision tree.
>
>
> [1]: http://www.erlang.org/doc/man/supervisor.html#id242517
> [2]: http://www.erlang.org/doc/man/inet.html#setopts-2
>
> --
> Guilherme
> http://www.gandrade.net/
> PGP: 0x602B2AD8 / B348 C976 CCE1 A02A 017E 4649 7A6E B621 602B 2AD8
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20151209/a3730e92/attachment.htm>


More information about the erlang-questions mailing list