tornado 4.x 之后,官方搞了自己的协程,弄了一个Future之类的。
以前用他的异步一直也就是弄弄AsyncHTTPClient什么的,甚是浅显。
但是作为一个新时代的四有青年,生在红旗下,长在春风里,怎么能满足于此呢对不对。
于是我定了一个这样的需求:
tornado接受请求 -> 后端消耗若干时间执行任务
要求是接受请求是异步的
查了一些资料写了这样的代码:
main.py
# coding:utf-8
import tornado.ioloop
import tornado.web
from tornado.gen import coroutine
from tornado.web import asynchronous
import tasync
class MainHandler(tornado.web.RequestHandler):
@coroutine
#@asynchronous
def get(self):
print('Hi')
result = yield tasync.async()
self.write("%s" % result )
class MainHandler2(tornado.web.RequestHandler):
def get(self):
self.write('test')
application = tornado.web.Application([
(r"/", MainHandler),
(r"/a", MainHandler2),
])
if __name__ == "__main__":
application.listen(8888)
print('Started.')
tasync.init()
tornado.ioloop.IOLoop.instance().start()
tasync.py
# coding:utf-8
import time
import threading
from functools import partial
from tornado.ioloop import IOLoop
from tornado.concurrent import Future
count = 1
future_dict = {}
def async(*args, **kwargs):
global count
future = Future()
callback = kwargs.pop("callback", None)
if callback:
IOLoop.instance().add_future(future, lambda future: callback(future.result()))
future_dict[count] = [future, time.time()]
count += 1
return future
def init():
interval = 0.3
io_loop = IOLoop.instance()
def the_loop():
while True:
t = time.time()
for k, v in future_dict.items():
if t - v[1] >= 5:
io_loop.add_callback(_on_result, k, v[0])
del future_dict[k]
time.sleep(interval)
threading.Thread(target=the_loop, args=()).start()
def _on_result(result, future):
print(result, time.time())
future.set_result(result)
上面俩文件复制下来就可以跑,py2/3皆可。
这个代码做了这样一件事情:
我的代码有两个url,/ 是我预设的异步点, /a 是一个调试页面。
访问/ 的话,程序应该在5秒钟后返回。
程序分为两个线程:tornado主线程,任务轮询线程(完成任务后给ioloop发消息)
但问题是这样的:
访问/,立即访问/a : /页面在等待状态,/a页面响应,正常。
访问/,立即再开另一页面访问/,第二张页面居然被阻塞了!
你们看一下日志就明白:
Started.
Hi
1436887952.72
Hi
1436887958.91
Hi是 / 接受请求,输出时间是回调完成。
我表示非常不解,求解惑。
PS: 我知道单以这个需求而论,tornado-celery是可用的,但是tcelery满足不了我其他的需求,所以不考虑。另外就主要是知其然知其所以然了。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.