Python wsgi behind nginx: yield not behaving as expected

Hi,
I want to run wsgi python code on a web server behind nginx. The server
needs to respond quickly to an http request, then continue to do some
(slow) work after responding. Python’s yield statement seems to fit the
bill, as follows:

def application(environ, start_response):
output = get_response_quickly(environ)

start_response(‘200 OK’,[(‘Content-type’,
‘text/plain’),(‘Content-Length’, str(len(output)))])

yield output
do_slow_work()

If I run this wsgi in a standalone python server (I tried wsgiref,
fapws, uwsgi), the caller receives the output immediately (after
get_response_quickly()), as desired. Great. However, if I run any of
these servers behind nginx, the caller doesn’t receive a response until
after do_slow_work() – thus defeating the purpose.

Is there a way to make this pattern work with nginx? Or is there a
better way in general to respond quickly but continue work, without
manually creating python threads / other clumsiness?

Thanks,
Matt

On Thu, Nov 03, 2011 at 12:08:49AM -0700, Matt Starcrest wrote:

If I run this wsgi in a standalone python server (I tried wsgiref, fapws,
uwsgi), the caller receives the output immediately (after get_response_quickly()),
as desired. Great. However, if I run any of these servers behind nginx, the caller
doesn’t receive a response until after do_slow_work() – thus defeating the
purpose.

Is there a way to make this pattern work with nginx? Or is there a better way in
general to respond quickly but continue work, without manually creating python
threads / other clumsiness?

In nginx-1.0.9 or nginx-1.1.5 you can try
uwsgi_buffering off;
or
sgi_buffering off;
depending on protocol. In any modern enough nginx version you can use
proxy_buffering off;

There is no way currently to disable buffering of FastCGI servers.


Igor S.

Looks like that solved it! Thanks Igor!


From: Igor S. [email protected]
To: [email protected]
Sent: Thursday, November 3, 2011 12:12 AM
Subject: Re: python wsgi behind nginx: yield not behaving as expected

On Thu, Nov 03, 2011 at 12:08:49AM -0700, Matt Starcrest wrote:

If I run this wsgi in a standalone python server (I tried wsgiref, fapws,
uwsgi), the caller receives the output immediately (after get_response_quickly()),
as desired. Great. However, if I run any of these servers behind nginx, the caller
doesn’t receive a response until after do_slow_work() – thus defeating the
purpose.

Is there a way to make this pattern work with nginx? Or is there a better way in
general to respond quickly but continue work, without manually creating python
threads / other clumsiness?

In nginx-1.0.9 or nginx-1.1.5 you can try
uwsgi_buffering off;
or
sgi_buffering off;
depending on protocol. In any modern enough nginx version you can use
proxy_buffering off;

There is no way currently to disable buffering of FastCGI servers.


Igor S.

On Thu, Nov 03, 2011 at 12:48:30AM -0700, Matt Starcrest wrote:

Looks like that solved it! Thanks Igor!

Please note, that any “…_buffering off” disables caching,
so you can set it exactly on locations which should be cached:

location /some/page {
…_buffering off;
}

output = get_response_quickly(environ)
In nginx-1.0.9 or nginx-1.1.5 you can try
Igor S.


nginx mailing list
[email protected]
nginx Info Page


nginx mailing list
[email protected]
nginx Info Page


Igor S.