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