[Libwebsockets] [1357004006:1893] ERR: Unable to spill ext 2819 vs 1448

"Andy Green (林安廸)" andy at warmcat.com
Fri Apr 12 07:17:16 CEST 2013


On 12/04/13 13:10, the mail apparently from Gregory Junker included:
> On Thu, Apr 11, 2013 at 9:53 PM, "Andy Green (林安廸)" <andy at warmcat.com
> <mailto:andy at warmcat.com>> wrote:
>
>     On 12/04/13 05:42, the mail apparently from Gregory Junker included:
>
>         On Thu, Apr 11, 2013 at 1:56 PM, Gregory Junker
>         <ggjunker at gmail.com <mailto:ggjunker at gmail.com>
>         <mailto:ggjunker at gmail.com <mailto:ggjunker at gmail.com>>> wrote:
>
>              On Tue, Apr 2, 2013 at 5:55 PM, "Andy Green (林安廸)"
>              <andy at warmcat.com <mailto:andy at warmcat.com>
>         <mailto:andy at warmcat.com <mailto:andy at warmcat.com>>> wrote:
>
>
>                  Currently lws takes action to reserve OS buffers for each
>                  connection of the size of the read buffer for the
>         protocol to
>                  stop this happening.
>
>
>              I may simply be missing where this happens, but I am not
>         seeing any
>              evidence of this in the code as of yesterday's HEAD -- can
>         you point
>              me to where this is happening?
>
>
>         OK NM I see it now (the SOL_SNDBUF commit that went in on 23
>         March). But
>         either it is not "taking" (regardless the absence of error
>         condition on
>         setsockopt call) or there is something else involved in the
>         send() call
>         in lws_issue_raw refusing to send more than 272K of my data:
>
>         [1365712303:0963] PARSER: libwebsocket_parse sees parsing complete
>         [1365712303:0963] PARSER: lws_parse calling handshake_04
>         [1365712303:0963] PARSER: issuing resp pkt 159 len
>         [1365712303:0963] PARSER: written 13 bytes to client
>         [1365712303:0963] INFO: Allocating RX buffer 16777238
>         [1365712303:0963] PARSER: accepted v13 connection
>         [1365712303:0972] PARSER: spill on aaas
>         [1365712303:0973] PARSER: written 87 bytes to client
>         [1365712303:0996] PARSER: spill on aaas
>         [1365712303:1001] PARSER: written 50762 bytes to client
>         [1365712303:1005] PARSER: written 47120 bytes to client
>         [1365712303:1008] PARSER: written 23576 bytes to client
>         [1365712303:1008] PARSER: written 3152 bytes to client
>         [1365712303:1009] PARSER: written 2736 bytes to client
>         [1365712303:1010] PARSER: written 1384 bytes to client
>         [1365712303:1011] PARSER: written 3152 bytes to client
>         [1365712303:1011] PARSER: written 2736 bytes to client
>         [1365712303:1012] PARSER: written 1384 bytes to client
>         [1365712303:1012] PARSER: spill on aaas
>         [1365712303:1151] ERR: Unable to spill ext 1722426 vs 278528
>         ...
>
>         it looks like the default for wmem_max is 128K and setting it to
>         16MB
>         sorts this out for me....but....that's not a feasible option.
>
>         Can we just make non-blocking behavior optional, and allow the
>         previous
>         blocking behavior? None of this was an issue previously for me,
>         and I do
>         not see any way for my server code to handle this condition, since
>         libwebsocket_write simply returns -1 when this write fails.
>         Additionally, forcing non-blocking behavior on send() is introducing
>         exactly the problem I am trying to avoid with atomic send()/recv()
>         behavior.
>
>
>     I think your problems boil down to trying to give huge packets to
>     the OS to send and it can't cope with it.
>
>     Why don't you use the FIN / CONTINUATION stuff with a send size of
>     around 2K.
>
>
>
> Because as I said, this approach with a 13MB texture send (or even
> vertex data in the hundreds of KB) takes enormously unacceptable time to
> complete (since it depends on repeated trips through the service() loop.

Who said anything about that?  There is an api to check if the send 
socket is choked.  You may loop sending 2K chunk while the socket is not 
choked.

Look at the code to send http files in output.c

	while (!lws_send_pipe_choked(wsi)) {

we keep the socket buffer in the OS stuffed, one step from choked, 
without blocking and giving high performance.  We only exit from that 
when it's about to block, and we get back to it as soon as it has any 
space for another chunk - not when it's empty.

> The 4K buffer size was bad enough on the receive side for fragmented
> frames -- I should make it take twice as long?
>
> I fail to understand what is wrong with allowing blocking socket
> behavior if the user wants it -- this worked just fine before the
> non-blocking change was made. Why was the decision made to go solely
> non-blocking?

Because lws has always been singlethreaded, the stuff tacked on to make 
it look workable from another thread could not be reliable.

Please take the advice above and you will get a good result.

-Andy




More information about the Libwebsockets mailing list