My last task before the GSoC hard pencils down date on Monday is an
attempt at a solution to ticket #7581. The essential issue is that a
lot of middleware requires access to the whole of
HttpResponse.content, but this prevents streaming responses (to
prevent timeouts).

To allow for streaming responses, I have created a special
HttpResponse class, HttpResponseStreaming, which does not consume
generators/iterators until it is specifically instructed to, and which
only uses certain middleware. See changeset 11449 for my attempt at it
on my branch. It has pretty extensive documentation on which
middleware do work with it and brief instructions for adapting third-
party middleware to that end.

I imagine that some or much of this changeset will be controversial,
which is why I am posting it here. I think it provides a good balance
of not overcomplicating HttpResponse to handle both streaming and
normal responses, as well as only making minor changes to
core.handlers.base and some response middleware to make the whole
thing groovy. It works very well in my tests. However, I agree with
Malcolm's assessment that it is not quite a "slam-dunk" solution.

One bit of advice I am looking for is what people's opinions are on
the use of isinstance versus hasattr to determine functionality. I am
personally partial to hasattr, because it covers subclasses, but I do
not know what the community tends to go towards. Right now, in
core.handlers.base on my branch, I am using both to deal with
selective application of response middleware, but I would like to
choose one or the other.

Tai (Mr Machine) suggests that perhaps we should have HttpResponse
ALWAYS consume data passed to it on init (which it already does on my
branch), and have HttpStreamingResponse throw an exception when it is
not passed an iterator. I think this is reasonable, because there is
no point to using the semi-crippled (with respect to middleware)
HttpStreamingResponse if you don't take advantage of its main goal.

>From his email to me: "If we can be sure HttpResponseStreaming always
has an iterator for content, middleware can just check if the response
is an instance of HttpResponseStreaming rather than checking for the
`content_generator` attribute, and if so, it can access/replace the
public `content_generator` attribute directly."

This also has some relevance to my hasattr/isinstance question from
earlier. I think I agree with trying to keep the _container/content as
an iterator, which would make replacing the generator a bit less
confusing than it is now (for an example, see the regression test in
the changeset).

I look forward to your input.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to