Setting of TCP Receive buffer size and Flow Control in producer/consumer
Scenario: TCP Receive Buffer on twisted HTTP server using the twisted application framework. And its behavior when set up as producer/consumer. (1) Would like to set the receive buffer size on socket. One way to do this would be to create a derived class of TCPServer (or SSLServer) and set the buffer size and use derived class server in the .tac file. Would like to know if there is any sample code for such usage? For example, in which method of the derived class would one set the receive buffer size? (2) When an incoming http POST request is acting as a producer of data, which is tied to a consumer resource (some other connection), how can I control the incoming tcp window size, if the consumer has paused consuming? I presume the incoming network data will keep piling up in the 'huge' tcp buffer eventually advertising a 'tcp zero window' to the network peer of the data producer, AND the server ends up using up a large amount of memory for the paused connection. Is there an alternative? I realize that the TCP protocol inhibits 'reducing of an already advertised receive window', but I am wondering if pauseProducing() on an http channel could do something to at least prevent the tcp window size from increasing any further? Thank you, Arun
On Mar 12, 2013, at 3:15 AM, A Desai <ardesai@yahoo.com> wrote:
Scenario: TCP Receive Buffer on twisted HTTP server using the twisted application framework. And its behavior when set up as producer/consumer.
(1) Would like to set the receive buffer size on socket. One way to do this would be to create a derived class of TCPServer (or SSLServer) and set the buffer size and use derived class server in the .tac file. Would like to know if there is any sample code for such usage? For example, in which method of the derived class would one set the receive buffer size?
You don't need to subclass these classes; and in any event, it wouldn't help, TCPServer and SSLServer don't have connections of their own, they're services that hold listening sockets, not connected sockets. If you want to set an option unsupported by Twisted, "transport.getHandle()" will give you the Python socket object (on those reactors which use socket objects internally, which is most of them). You can just set SO_RCVBUF on that socket from your Protocol class. Also, this ticket may be of interest to you: <https://twistedmatrix.com/trac/ticket/4089>. Tuning send and receive buffers should be more explicitly supported by Twisted.
(2) When an incoming http POST request is acting as a producer of data, which is tied to a consumer resource (some other connection), how can I control the incoming tcp window size, if the consumer has paused consuming? I presume the incoming network data will keep piling up in the 'huge' tcp buffer eventually advertising a 'tcp zero window' to the network peer of the data producer, AND the server ends up using up a large amount of memory for the paused connection. Is there an alternative? I realize that the TCP protocol inhibits 'reducing of an already advertised receive window', but I am wondering if pauseProducing() on an http channel could do something to at least prevent the tcp window size from increasing any further?
I don't know that much about window scaling, but won't the fact that the application isn't receiving any data from the kernel automatically prevent the window from scaling any bigger? -glyph
I penned the questions at 3am, so please punt my second question since it is half-baked. Found some time this afternoon to revisit bulk-data flow discussion in Steven's book. The first question still applies though. Using the protocol's transport object, I can fetch the SO_RCVBUF value on the 'accepted' connection and even set the SO_SNDBUF value. However, since TCP Window scaling is enabled by default, it is my understanding that the SO_RCVBUF has to be set before the listen() call is invoked. The .tac file passes the TCPServer object to application/service framework, which in turn calls the listener. So I am wondering if I have to derive a subclass of TCPServer and somehow set the SO_RCVBUF value before the application framework invokes listen(); i.e. drill down to the Port object where it calls createInternetSocket()? On Mar 12, 2013, at 3:15 AM, A Desai <ardesai@yahoo.com> wrote: Scenario: TCP Receive Buffer on twisted HTTP server using the twisted application framework. And its behavior when set up as producer/consumer.
(1) Would like to set the receive buffer size on socket. One way to do this would be to create a derived class of TCPServer (or SSLServer) and set the buffer size and use derived class server in the .tac file. Would like to know if there is any sample code for such usage? For example, in which method of the derived class would one set the receive buffer size?
You don't need to subclass these classes; and in any event, it wouldn't help, TCPServer and SSLServer don't have connections of their own, they're services that hold listening sockets, not connected sockets. If you want to set an option unsupported by Twisted, "transport.getHandle()" will give you the Python socket object (on those reactors which use socket objects internally, which is most of them). You can just set SO_RCVBUF on that socket from your Protocol class. Also, this ticket may be of interest to you: <https://twistedmatrix.com/trac/ticket/4089>. Tuning send and receive buffers should be more explicitly supported by Twisted. (2) When an incoming http POST request is acting as a producer of data, which is tied to a consumer resource (some other connection), how can I control the incoming tcp window size, if the consumer has paused consuming? I presume the incoming network data will keep piling up in the 'huge' tcp buffer eventually advertising a 'tcp zero window' to the network peer of the data producer, AND the server ends up using up a large amount of memory for the paused connection. Is there an alternative? I realize that the TCP protocol inhibits 'reducing of an already advertised receive window', but I am wondering if pauseProducing() on an http channel could do something to at least prevent the tcp window size from increasing any further?
I don't know that much about window scaling, but won't the fact that the application isn't receiving any data from the kernel automatically prevent the window from scaling any bigger? -glyph
On Mar 12, 2013, at 9:04 PM, A Desai <ardesai@yahoo.com> wrote:
Using the protocol's transport object, I can fetch the SO_RCVBUF value on the 'accepted' connection and even set the SO_SNDBUF value. However, since TCP Window scaling is enabled by default, it is my understanding that the SO_RCVBUF has to be set before the listen() call is invoked. The .tac file passes the TCPServer object to application/service framework, which in turn calls the listener. So I am wondering if I have to derive a subclass of TCPServer and somehow set the SO_RCVBUF value before the application framework invokes listen(); i.e. drill down to the Port object where it calls createInternetSocket()?
You'd need to actually subclass tcp.Server, an implementation mechanism that we would really like to deprecate :). Really, the right way to do this is to contribute a fix to the ticket I linked, and do it directly next to the listen() call within Twisted :). -glyph
Let me think about it. ________________________________ From: Glyph <glyph@twistedmatrix.com> To: A Desai <ardesai@yahoo.com> Cc: Twisted Web World <twisted-web@twistedmatrix.com> Sent: Wednesday, March 13, 2013 11:33 AM Subject: Re: [Twisted-web] Setting of TCP Receive buffer size and Flow Control in producer/consumer On Mar 12, 2013, at 9:04 PM, A Desai <ardesai@yahoo.com> wrote: Using the protocol's transport object, I can fetch the SO_RCVBUF value on the 'accepted' connection and even set the SO_SNDBUF value. However, since TCP Window scaling is enabled by default, it is my understanding that the SO_RCVBUF has to be set before the listen() call is invoked. The .tac file passes the TCPServer object to application/service framework, which in turn calls the listener. So I am wondering if I have to derive a subclass of TCPServer and somehow set the SO_RCVBUF value before the application framework invokes listen(); i.e. drill down to the Port object where it calls createInternetSocket()?
You'd need to actually subclass tcp.Server, an implementation mechanism that we would really like to deprecate :). Really, the right way to do this is to contribute a fix to the ticket I linked, and do it directly next to the listen() call within Twisted :). -glyph
participants (2)
-
A Desai
-
Glyph