gen_udp:send/4

Valentin Micic v@REDACTED
Thu Dec 5 20:32:49 CET 2019


> 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/20191205/2ae61d64/attachment.htm>


More information about the erlang-questions mailing list