[erlang-questions] gen_tcp nonblocking send
Igor Ribeiro Sucupira
Thu May 1 21:52:17 CEST 2008
On Thu, May 1, 2008 at 4:22 PM, Per Hedeland <> wrote:
> "Valentin Micic" <> wrote:
> >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.
> But that was precisely what he *wanted*: the possibility to note the
> problem and deal with it "elsewhere" (i.e. his sender will maintain its
> own queue and eliminate useless data there).
> >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.
> You didn't read my suggestion carefully enough - try again.
> >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).
> IMO, exposing O_NDELAY/O_NONBLOCK at the Erlang level would be a huge
I'm in almost perfect agreement with you. I don't even see why
O_NDELAY would make Daniel's program easier to implement (well...
maybe I'm missing something...).
But, how do you deal with the situation (definitely not Daniel's case)
in which you just want to NOT send the message if the buffer is full
("Oh... system overload... nevermind... I don't want to make the
situation worst... I'll come back when I have something
send_timeout wouldn't be of help here.
> Networking (and many other "interactions with the environment")
> is so simple in Erlang because it just hides all the gory details that
> you get immediately thrown in your face when using a C interface to the
> same functionality. And when you really need some functionality provided
> by the gory-details interface but not by the Erlang counterpart, there's
> often a nice Erlangish way to achieve it, that just wouldn't be possible
> at the gory-details and/or C level.
> This case is an excellent illustration of that - in Erlang, you don't
> want a send() that says "sorry, I only managed to send N bytes of your
> complex nested list/binary structure, you need to re-send the rest" -
> but you might want a send() that doesn't block, but just sends you a
> message when it's done. Which is exactly what my "relay" process
> suggestion implements, and which *could* be provided as a standard
> gen_tcp(3) API function - but it's probably an uncommon enough need that
> doing that isn't motivated.
More information about the erlang-questions