[erlang-questions] gen_tcp nonblocking send

Valentin Micic valentin@REDACTED
Thu May 1 20:16:21 CEST 2008


As you've said -- it is a workaround. Consider that under some circumstances 
such workaround may cause problems -- think of it this way: You're not 
really solving the problem, just shifting it elsewhere.



Under normal circumstances (as you've outlined), if sender and receiver are 
not in some kind of "synchronous" engagement, in other words, if your next 
send does not depend on receiving something from a remote peer; and you have 
a "sluggish" remote receiver, your process would block once local buffer is 
full. If you change this by introducing intermediate server, as suggested --  
call it a REALY; you are not changing the fact that this RELAY will block 
when local sending buffer gets full. However, as the sending process is now 
sending "normal" Erlang messages, it will have no way of figuring out that 
RELAY's buffer is full, thus, it will keep sending, eventually clogging 
RELAY's process message queue. In my experience, once process has a few 
hundred thousands of such messages in its queue, Erlang scheduling starts 
having problems (actually, this is largely due to the CPU utilization, but 
there is a relationship), hence you are degrading performance of other 
processes as well.



OTOH, if one assumes that O_NDELAY would return immediately once the local 
buffer is full, this would help solving the problem you're referring to, by 
allowing a programmer to find the most suitable solution to a given 
problem - anything from immediate disconnection/reconnection to some form of 
internal buffering (which, mind you, cost only in terms of memory, and not 
so much in CPU cycles).



I could understand the problems around introduction of O_NDELAY, e.g. how to 
communicate to client that only N octets were sent, and that rest should be 
resent. Well, maybe introducing a separate function, say 
gen_tcp:non_blocking_send,  that would return a binary consisting of unsent 
octets (or empty binary if all has been sent), might not be so far fetched 
(hint, hint).



V.

----- Original Message ----- 
From: "Daniel Ginsburg" <dg@REDACTED>
To: "Valentin Micic" <valentin@REDACTED>
Cc: "Per Hedeland" <per@REDACTED>; <erlang-questions@REDACTED>
Sent: Thursday, May 01, 2008 4:03 PM
Subject: Re: [erlang-questions] gen_tcp nonblocking send


> On 01.05.2008 17:50 Valentin Micic wrote:
>
>> Does this mean that O_NDELAY is not supported in Erlang? Not even as an 
>> undocumented feature? ;-)
>>
>
> Internally, sockets are non-blocking (see 
> erts/emulator/drivers/common/inet_drv.c), but as far as I understand, 
> gen_tcp and all the underlying libraries like prim_inet expose only 
> blocking send API to erlang processes.
>
> There's nice workaround, as Per suggested. I tried it, and it works like 
> charm (thanks again, Per!).
>
> There's also unresolved problem with hot code upgrade for blocked process, 
> but for me this is a minor issue.
>
> -- 
> dg
> 




More information about the erlang-questions mailing list