[erlang-questions] gen_tcp nonblocking send

Daniel Ginsburg <>
Thu May 1 01:01:43 CEST 2008


Dave Smith wrote:
> It is my understanding that gen_tcp:send never blocks, since it's just
> queuing up a message for the process handling the socket.  If I had to
> guess, I'd say that under the covers it's queuing up the data using
> the driver_enq (see ERTS erl_driver) and then when the socket is ready
> to write, the VM pushes that data into the socket (since all sockets
> are non-blocking in the VM, or so I would presume).
>
> Hope that helps...
>
> D.
>
>   
Well, gen_tcp:send does block, and it is quite easy to verify it.

If gen_tcp:send would never block by always queueing send-request, it 
would be even worse, because such behavior would give no backpressure to 
fast sender and make request queue to build up possibly indefinitely.

One way or another, it doesn't solve my problem. Let me expand a little 
bit on it.

What I have is a protocol which basically sends {key, value} over TCP 
connection. Set of keys is large but limited. Receiver is not really 
interested to hear all the changes of value for a particular key, it 
just wants to know the most recent values for a key. It is also very 
important to communicate changes of value for any key as fast as possible.

In case when receiver is able to cope with the load, the best tactic is 
to send all the changes as soon as they occur. But when receiver is 
overloaded (or there's network congestion), there's important 
optimization. If we have {k1, val1} sitting in queue and there's another 
update for that key, we can, instead of adding it to the queue, simply 
replace {k1, val1} with {k1, val2}. Thus saving network resources and 
reducing load on receiver. In order to do that, I need to keep my own 
queue and I need a way to know when it is safe to start dequeuing pairs 
and send them to the socket.

Now I deal with the situation by use of hold-off timer. When I send a 
pair with key k1, I start a timer, and until the timer expires, all the 
updates for that key are delayed, unnecessary ones are dropped and 
replaced with the most recent version. It does help with overload, but 
it also delays updates when there's no overload or congestion.



More information about the erlang-questions mailing list