<div><div dir="auto">Hi,</div></div><div dir="auto"><br></div><div dir="auto">It actually took a while to build to that kind of message queue size. On the upper level, there is no selective receive and incoming messages are accumulated and then send out via udp. Generally that should be relatively fast however under load, the message queue can slowly creep up leaving that prim inet sendto selective receive becoming problematic. </div><div dir="auto"><br></div><div dir="auto">Thank you for your suggestions as well, obviously keeping short message queue is the ideal situation</div><div dir="auto"><br></div><div dir="auto">Steven</div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 06 Dec 2019 at 22:00, Mikael Pettersson <<a href="mailto:mikpelinux@gmail.com">mikpelinux@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Thu, Dec 5, 2019 at 5:39 PM Steven <<a href="mailto:mailparmalat@gmail.com" target="_blank">mailparmalat@gmail.com</a>> wrote:<br>
><br>
> Hi,<br>
><br>
> We have a situation where gen_udp:send/4 does not return ok and it just hangs and the process is waiting indefinitely.<br>
><br>
> e.g.<br>
> {current_function,{prim_inet,sendto,4}},<br>
> {initial_call,{proc_lib,init_p,5}},<br>
> {status,running},<br>
> {message_queue_len,15363062},<br>
><br>
> The send buffer size on the socket is around 200KB.<br>
><br>
> 3> inet:getopts(S, [sndbuf]).<br>
> {ok,[{sndbuf,212992}]}<br>
><br>
> 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.<br>
><br>
> In prim_inet:sendTo/4, it always expect inet reply from OS but it never comes and never times out.<br>
><br>
> try erlang:port_command(S, PortCommandData) of<br>
> true -><br>
> receive<br>
> {inet_reply,S,Reply} -><br>
> ?DBG_FORMAT(<br>
> "prim_inet:sendto() -> ~p~n", [Reply]),<br>
> Reply<br>
> end<br>
> catch<br>
><br>
> Thanks<br>
<br>
I believe a (or the) problem is that the selective-receive in<br>
prim_inet:sendto/4 doesn't use the ref trick, therefore it has to scan<br>
the entire 15+ million entry message queue of the sender process<br>
looking for that inet_reply message. That is going to be very slow.<br>
(Furthermore there are other performance penalties associated with<br>
having very long message queues, see<br>
erlang:process_flag(message_queue_data, off_heap) for one possible<br>
remedy.)<br>
<br>
It would be nice if the return signalling from calling port_command<br>
could be fixed to either enable the ref trick or to not use messages<br>
at all, but until that is the case, you know that making these calls<br>
while having a long message queue is going to be expensive. We've<br>
found that it's often useful to offload such calls to temporary helper<br>
processes, that by construction have very short message queues. (The<br>
signalling between the original process and the helper should of<br>
course use the ref trick, this is non-trivial to get right.)<br>
</blockquote></div></div>