pesto + mod_wsgi = RuntimeError: response has not been started, fix example

246 views
Skip to first unread message

Mateusz Korniak

unread,
Oct 20, 2010, 11:42:30 AM10/20/10
to python...@googlegroups.com
I started using pesto with apache mod_wsgi.
Though it works great with _one_ thread per process, with many threads starts
producing errors [1],[2].
Tested both with repo and latest stable versions.
To me , looks like pesto creates one instance of PestoWSGIApplication and use
it to keep start_response function, which works great if we get another WSGI
call _after_ we finish handling previous request.
This not case for mod_wsgi.
Proposed change [3] fixes problem for me, although resulting code looks ugly
to me ;) I think current PestoWSGIApplication implementation should be split
to PestoWSGIApplication (containing static data) and
PestoWSGIApplicationWrapper containing data specific to given request.
I am not darcs user, so I send modified version of pesto/core.py from current
repository.

Both cases can be tested by using simple wsgi app [4] and apache's ab [5].

Hope it hels, regards,


[1]:
mod_wsgi (pid=2367): Exception occurred processing WSGI script
'/home/services/httpd/html/matkor.beauty.ant.vpn/pesto_wsgi_test.py'.
RuntimeError: response has not been started

[2]:
mod_wsgi (pid=2512): Exception occurred processing WSGI script
'/home/services/httpd/html/matkor.beauty.ant.vpn/pesto_wsgi_test.py'.
Traceback (most recent call last):
File "/home/services/httpd/html/matkor.beauty.ant.vpn/pesto/core.py", line
99, in next
self._content_iter = response(self.environ, self.start_response)
File "/home/services/httpd/html/matkor.beauty.ant.vpn/pesto/response.py",
line 232, in __call__
self.headers,
RuntimeError: request object has expired


[3]:
def __call__(self, environ, start_response):
"""
WSGI callable - take ``pesto_app`` and adapt it to the WSGI interface.
"""
"""
# Previous version of code
self._content_iter = None
self.environ = environ
self.start_response = start_response
self.request = Request(environ)
return self
"""
# We need PestoWSGIApplication instance for each request we get
# as it may have different environ and start_response values.
# Especially in multi thread environment like mod_wsgi
wrapper = PestoWSGIApplication(self._pesto_app)
wrapper._app_args = self._app_args
wrapper._app_kwargs = self._app_kwargs
wrapper.environ = environ
wrapper.start_response = start_response
wrapper.request = Request(environ)
return wrapper


[4]:
def handler(request):
time.sleep(random.random())
return pesto.Response([
"<html><body><h1>def
handler(request):</h1><h2>matkor.beauty.ant.vpn, pesto version:
%r</h2></body></html>" % (pesto.__version__, )
])

application = pesto.to_wsgi(handler)

[5]:
ab -n 1000 -c 10 -d http://site.of.test/

--
Mateusz Korniak

core.py

Oliver Cope

unread,
Oct 21, 2010, 1:33:40 PM10/21/10
to python...@googlegroups.com
Thanks for the patch!
I'll review it as soon as I get a chance and get your fix into the code
base soon.

Olly.

Reply all
Reply to author
Forward
0 new messages