ねじれた Web で http POST 要求を処理する次のリソースがあります。
class RootResource(Resource):
isLeaf = True
def errback(self, failure):
print "Request finished with error: %s"%str(failure.value)
return failure
def write_response_happy(self, result):
self.request.write('HAPPY!')
self.request.finish()
def write_response_unhappy(self, result):
self.request.write('UNHAPPY!')
self.request.finish()
@defer.inlineCallbacks
def method_1(self):
#IRL I have many more queries to mySQL, cassandra and memcache to get final result, this is why I use inlineCallbacks to keep the code clean.
res = yield dbpool.runQuery('SELECT something FROM table')
#Now I make a decision based on result of the queries:
if res: #Doesn't make much sense but that's only an example
self.d.addCallback(self.write_response_happy) #self.d is already available after yield, so this looks OK?
else:
self.d.addCallback(self.write_response_unhappy)
returnValue(None)
def render_POST(self, request):
self.request = request
self.d = self.method_1()
self.d.addErrback(self.errback)
return server.NOT_DONE_YET
root = RootResource()
site = server.Site(root)
reactor.listenTCP(8002, site)
dbpool = adbapi.ConnectionPool('MySQLdb', host='localhost', db='mydb', user='myuser', passwd='mypass', cp_reconnect=True)
print "Serving on 8002"
reactor.run()
ab ツール (apache utils から) を使用して、5 つの POST リクエストを次々とテストしました。
ab -n 5 -p sample_post.txt http://127.0.0.1:8002/
正常に動作します!
次に、同じ 5 つの POST リクエストを同時に実行しようとしました。
ab -n 5 -c 5 -p sample_post.txt http://127.0.0.1:8002/
ここでエラーが発生します: exceptions.RuntimeError: Request.finish が呼び出された後、リクエストで Request.write が呼び出されました。私は何を間違っていますか?