Re: Dumping the request body on write in CherryPyWSGIServer

144 views
Skip to first unread message

Daniel Dotsenko

unread,
Aug 10, 2012, 2:55:32 PM8/10/12
to cherryp...@googlegroups.com
See (especially section on .write() ) :

http://python.org/dev/peps/pep-3333/#buffering-and-streaming 

Summary:

Don't use write()

Alternatives are, unfortunately, complex. I recommend to go for full-blown generator as any in-between (inline yield's) solution will quickly become small for you.

To simulate generator "in-line" try:

    start_response(..., ...)
    ...
    yield "snippet"
    ...
    yield "some more"
    ...
    return ['rest', 'of', 'response']

But real solution is make a looping generator class and just return it (after start_response(... ))

I wish I could give you a simple example of smart generator, but there is no simple example of smart generator that I know. This is relatively there: http://jimmyg.org/blog/2009/using-yield-statements-in-wsgi-middleware-can-be-very-harmful.html but does not show parallel stream processing.

I use one such parallel stream-processing generator in git_http_backend.py (https://github.com/dvdotsenko/git_http_backend.py) Works well against CherryPy's WSGI server. (The generator itself is in subprocessio.py - wraps call to git into subprocess and relays back command output realtime without caching the data to drive.) 

Daniel.

On Tuesday, August 7, 2012 12:52:12 PM UTC-7, Yash Parghi wrote:
Hi -

I'm new to WSGI and CherryPy, and I'm trying to understand why CherryPyWSGIServer reads and discards the request body when my app first calls write(). The code snippet that does this is footnote [1] below from CherryPyWSGIServer (we're using 3.1.1, but the behavior looks the same in later versions).

This is what's happening in our app, as best I can tell:
1. an unchunked request comes in with a large body and a Content-Length header
2. my app starts reading the body from wsgi.input
3. at some arbitrary point mid-read, my app sends back a progress update to the client via write() (which is, as far as cherrypy is concerned, just some plain old bytes)
4. cherrypy consumes the rest of the request body as part of sending the response headers before sending the data passed to write().

I see the rationale in the CherryPyWSGIServer code, from the HTTP 1.1 spec -- "the server SHOULD NOT close the transport connection until it has read the entire request" -- but I don't see how that entails reading and discarding the request on the first write, since the connection isn't being closed at that point. Can anyone clarify/expand?

If that rationale stands for whatever reason, how _should_ my app use write() without discarding the remainder of the request? Do I need to make sure the entire request body has been read before I ever call write()? Is that a WSGI expectation?

Thanks a lot -
Yash


[1]
if (not self.close_connection) and (not self.chunked_read):
    # Read any remaining request body data on the socket.
    ...

Yash Parghi

unread,
Aug 14, 2012, 11:18:21 AM8/14/12
to cherryp...@googlegroups.com
Thanks for the explanation, Daniel. Though I don't think it justifies this specific behavior of CherryPy's, it seems in practice that we shouldn't put too much stock in write()'s behavior in general. I'll look into yielding instead of write() -- more than anything else, I depend on write for its implicit immediacy in sending data to the client, so if yielding doesn't send the data across the wire "soon enough" for the client's user experience, I'll have to stick with write().

- Yash

Robert Brewer

unread,
Aug 14, 2012, 2:40:23 PM8/14/12
to cherryp...@googlegroups.com

The short answer is: if you use yield and set "response.stream = True" for that URL, that tells all of CherryPy "don't buffer the output", in which case it behaves very much like write(). See http://docs.cherrypy.org/stable/progguide/streaming.html

 

 

Robert Brewer

fuma...@aminus.org

 

--
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/cherrypy-users/-/Tt3Zg6vkh9sJ.
To post to this group, send email to cherryp...@googlegroups.com.
To unsubscribe from this group, send email to cherrypy-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cherrypy-users?hl=en.

Reply all
Reply to author
Forward
0 new messages