gen_udp:send/4

Steven mailparmalat@REDACTED
Fri Dec 6 07:15:39 CET 2019


Thanks,

Seems like under CPU load and with a large volume of messages coming into
the process,  the selective receive will slow it down and make it look like
the udp send is taking long or not acknowledged meanwhile the
acknowledgement is somewhere in the message queue.

Steven

On Thu, Dec 5, 2019 at 9:32 PM Valentin Micic <v@REDACTED> wrote:

>
> On 05 Dec 2019, at 18:39, Steven <mailparmalat@REDACTED> wrote:
>
> Hi,
>
> We have a situation where gen_udp:send/4 does not return ok and it just
> hangs and the process is waiting indefinitely.
>
> e.g.
>  {current_function,{prim_inet,sendto,4}},
>  {initial_call,{proc_lib,init_p,5}},
>  {status,running},
>  {message_queue_len,*15363062*},
>
>
> It appears that your server (e.g. process that is calling gen_udp:send/4)
> has way to many messages on its process queue — thus gen_udp:send/4 hanging
> is probably a symptom and not necessarily the cause.
>
> Could it be that your server itself employs a selective receive for the
> incoming events/requests processing, e.g.
>
> main_loop()
> ->
>     receive
>          {“Some pattern”, _}   -> gen_udp:send(…);
>          “Some other pattern”  -> do_something else(…)
>          _        -> ignore;
>     after SomeTime             -> do_soemthing_different()
>     end,
>    main_loop()
> .
>
> The construct above will slow message processing and that may account for
> more than 15,000,000 messages reported to be on your server's message queue.
> In my view, selective receive is a bad idea for server-side
> implementation. Server should rather use something like this:
>
> main_loop()
> ->
>        receive
> Msg      -> process_msg( Msg )
>       after SomeTime -> do_something_different()
>       end,
>       main_loop()
> .
>
> process_msg( {“Some pattern”, _} )  -> gen_udp:send(…);
> process_msg( “Some other pattern” ) -> do_something_else(…);
> process_msg( _ )                    -> ignore.
>
> This will always keep server’s process queue reasonably empty, thus, even
> when server  uses a function that hides a selective receive, such function
> will come back reasonably quickly.
> Kind regards
>
> V/
>
>
> The send buffer size on the socket is around 200KB.
>
> 3> inet:getopts(S, [sndbuf]).
> {ok,[{sndbuf,212992}]}
>
> The UDP socket doesn't receive any incoming packets so it is used for
> sending only. Running R21-3 with redhat 7.5. Would like to ask the group
> under which conditions will the port not come back with inet_reply? I
> assume if the sndbuf is full then it should come back with enobufs or
> some sort but it should be quick enough to flush the sndbuf to interface.
>
> In prim_inet:sendTo/4, it always expect inet reply from OS but it never
> comes and never times out.
>
> try erlang:port_command(S, PortCommandData) of
>                         true ->
>                             receive
>                                 {inet_reply,S,Reply} ->
>                                     ?DBG_FORMAT(
>                                        "prim_inet:sendto() -> ~p~n",
> [Reply]),
>                                     Reply
>                             end
>                     catch
>
> Thanks
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20191206/21cf200b/attachment.htm>


More information about the erlang-questions mailing list