[erlang-questions] Troubling gen_tcp.send/3 performance

zxq9 <>
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