[erlang-questions] gen_tcp nonblocking send

Igor Ribeiro Sucupira igorrs@REDACTED
Thu May 1 02:44:32 CEST 2008


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

Igor.



More information about the erlang-questions mailing list