我想用Tornado编写一个简单的异步http服务器。 我不清楚如何设置回调以便在处理当前请求时释放服务器以获取其他请求。
我写的代码是:
import tornado.web
from tornado.ioloop import IOLoop
from tornado import gen
import time
class TestHandler(tornado.web.RequestHandler):
@gen.coroutine
def post(self, *args, **kwargs):
json_input = tornado.escape.json_decode(self.request.body)
print ('Now in POST. body: {}'.format(json_input))
self.perform_long_task(*args, **json_input)
@gen.coroutine
def perform_long_task(self, **params):
time.sleep(10)
self.write(str(params))
self.finish()
application = tornado.web.Application([
(r"/test", TestHandler),
])
application.listen(9999)
IOLoop.instance().start()
为了测试我试图并行发送几个POST请求:
curl -v http://localhost:9999/test -X POST -H "Content-Type:appication/json" -d '{"key1": "val1", "key2": "val2"}' &
当处理perform_long_task()时,服务器被阻止。 我需要帮助使服务器成为非阻塞服务器。
答案 0 :(得分:0)
永远不要在Tornado代码中使用time.sleep
!
请在代码中执行此操作:
class TestHandler(tornado.web.RequestHandler):
@gen.coroutine
def post(self, *args, **kwargs):
json_input = tornado.escape.json_decode(self.request.body)
print ('Now in POST. body: {}'.format(json_input))
# NOTE: yield here
yield self.perform_long_task(*args, **json_input)
@gen.coroutine
def perform_long_task(self, **params):
yield gen.sleep(10)
self.write(str(params))
# NOTE: no need for self.finish()
你不需要打电话给self.finish - 当" post" coroutine完成后,Tornado会自动完成请求。
你必须得到self.perform_long_task(),否则Tornado会在你调用" self.write()"之前提前结束你的请求。
一旦你做出这些改变,两个" curl"命令将显示您正在Tornado中进行并发处理。
答案 1 :(得分:0)
我的代码中唯一需要更改的是:
yield self.perform_long_task(* args,** json_input)
它仅适用于为异步编写的类,
使用: yield executor.submit(self.perform_long_task,* args,** json_input)
所有回复和评论都很有帮助。非常感谢!