[erlang-questions] Troubling gen_tcp.send/3 performance
zxq9
zxq9@REDACTED
Mon Dec 5 03:22:59 CET 2016
On 2016年12月4日 日曜日 21:13:56 Fred Hebert wrote:
> It is and it is not. One of the interesting things with the TCP stack is
> that it sends a signal through ports, and if the send queue is full, the
> whole thing blocks; it however blocks with live data in there, and
> there's no good way to give it up.
>
> The reason is blocks that the TCP work is done over a port program,
> meaning message passing takes place:
>
> Erlang Process TCP port program
> | |
> |----------- Data ------------->|
> | |
> |<--- {inet_reply,S,Status} ----|
>
> This is roughly what takes place within the thing. This is done through
> calling erlang:port_command/2-3. The thing though is that if the buffer
> of the port program is full, you get descheduled until there's place.
>
> There's a cheat though, one we at Heroku have used in Logplex. The trick
> is to bypass the stack in critical 'must never block' circumstances and
> call port_command yourself, but by passing in the option list
> '[nosuspend]'.
>
> When you do this and the port program representing the TCP socket is
> busy, you'll get a 'false' return value indicating it failed because it
> was full (you get 'true' when it works):
>
> case erlang:port_command(Socket, Data, [nosuspend]) of
> false ->
> handle_busy(...);
> true ->
> receive
> {inet_reply, Socket, Status} -> % Status == send return
> Status
> end
> end
>
> This will let you do things like figure out the consumer side (in this
> case VLC) is too slow, and possibly give up sending a few frames and
> send newer ones later.
>
> Control flow is fun!
...and once again Fred has, by psychic divination, just supplied the
answer to a question I would have asked about one week from now.
I appreciate your knack for preemptive answer scheduling.
It allows me to remain in lurk mode most of the time.
-Craig
More information about the erlang-questions
mailing list