[erlang-questions] gen_tcp nonblocking send

Per Hedeland <>
Fri May 2 13:26:21 CEST 2008

"Valentin Micic" <> wrote:
>You're right -- I did not read it carefully enough. Your suggestion would 
>not develop a scheduling problem. However, after reading it again, I'm 
>really not sure why would O_NDEALY be such an evil thing, if it is 
>implemented as a separate function call (and not as a flag), that would 
>return a binary containing unsent octets.

But what's the point of giving that back to the application, when the
only thing the application can do with it is to keep it around until
gen_tcp says "OK, I can take some more" (an async message that the app
has to "actively" receive) - at which point the application gives it
back to gen_tcp, who may *still* not be able to send it all, and gives a
new binary back, which the application has to keep around until... Seems
to me like requiring quite a bit of complex programming for no gain.

> It would certainly help (in this 
>case not-so) intelligent queuing on the caller side -- unlike your sender 
>that needs to do pre-emptive queuing, until it receive's ack from "relay", 
>it would need to queue only unsent octets, right?

Yes, there is of course some possibility that new messages may arrive to
sender before the ack after a gen_tcp:send() that didn't "really" block
arrives. A "good" solution to that would be to (instead of the "relay"
process) have an option that made gen_tcp:send() say "this will take a
while, I'll send you a message when I'm done" instead of blocking, but
*only* in the case where it would otherwise block (as opposed to what I
called "async send", which does it always), without passing the unsent
octets back.

But again, is it worth the added complexity? Now you have a
multiple-choice sender, and to fully test it you *must* produce the
blocking scenario, whereas the simple async-send -> ack scheme always
works the same, and only requires the code that you need for the "really
blocking" case anyway. Of course there are cases where you have to deal
with complexity to get the performance you need, but then a) you should
first make sure that this really is one of those, and b) the next step
would be to get rid of the "relay" process and have gen_tcp provide the
simple async-send -> ack interface directly (after all, the relay
process is just undoing what prim_inet does).


More information about the erlang-questions mailing list