[erlang-questions] gen_tcp nonblocking send

Igor Ribeiro Sucupira <>
Thu May 1 02:44:32 CEST 2008

On Wed, Apr 30, 2008 at 8:01 PM, Daniel Ginsburg <> wrote:
> 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.

I don't think it's safe to set a send_timeout and then keep sending
data after a timeout occurs.

Your best option is probably to wait until the server has received the
current key/value you're sending.
After the operation is completed, you can, of course, send the most
recent value of the key, supposing it has been updated.


More information about the erlang-questions mailing list