私はgeventwsgiを使用してcherrypyアプリケーションを実行し、リクエストハンドラーでいくつかのブロッキングgevent呼び出しを実行しています。単一のリクエストを行うと、ブロッキング呼び出しは期待どおりに機能し、一部のブロッキングリソース(他のプロセスへのパイプ)の使用を並列化できます。複数のリクエストを実行すると問題が発生し、cherrypyはこの例外をスローする内部サーバーエラーを返します。
[23/Mar/2012:17:50:35] Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/CherryPy-3.2.2-py2.7.egg/cherrypy/_cpwsgi.py", line 170, in trap
return func(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/CherryPy-3.2.2-py2.7.egg/cherrypy/_cpwsgi.py", line 97, in __call__
return self.nextapp(environ, start_response)
File "/usr/local/lib/python2.7/site-packages/CherryPy-3.2.2-py2.7.egg/cherrypy/_cpwsgi.py", line 385, in tail
return self.response_class(environ, start_response, self.cpapp)
File "/usr/local/lib/python2.7/site-packages/CherryPy-3.2.2-py2.7.egg/cherrypy/_cpwsgi.py", line 232, in __init__
outstatus = r.output_status
AttributeError: 'Response' object has no attribute 'output_status'
私は問題をコアに減らしました、そして次の簡単なアプリケーションは毎回問題を再現します:
import cherrypy
import gevent
from gevent import wsgi
class BugServer(object):
@cherrypy.expose
def index(self):
gevent.sleep(2)
return 'dummy foo'
if __name__ == "__main__":
app = cherrypy.tree.mount(BugServer(), '/')
wsgi.WSGIServer(('', 27726), app).serve_forever()
それをテストするために、3つのリクエストを同時に起動する次のスクリプトを使用しました。
import httplib
import threading
def make_req(host):
conn = httplib.HTTPConnection(host)
conn.request("GET", "/")
return conn.getresponse()
threads = []
for i in range(3):
t = threading.Thread(target=make_req, args=('192.168.128.7:27726',), kwargs={})
t.start()
threads.append(t)
for t in threads:
t.join()
バグを見つけるためにcherrypyまたはgevent(wsgi)ライブラリを掘り下げる必要があるかどうかはわかりません。wsgiサーバーにspawn=Noneを設定すると、リクエストでリソース呼び出しをブロックするためにグリーンレットを使用するという目的に反することになり、とにかく機能しません。
助言がありますか?ありがとう。