想通过异步的方式实现一个耗时的任务,但是又想在执行的过程中了解到进度,并且不借助于数据库,目前只能想到用cookie的来确定,但是使用异步的方式,cookie设置总是会出现问题,注意看下面的注释
import tornado.ioloop import tornado.web import time from tornado import gen from concurrent.futures import ThreadPoolExecutor import tornado.httpclient import datetime import functools class Executor(ThreadPoolExecutor): _instance = None def __new__(cls, *args, **kwargs): if not getattr(cls, '_instance', None): cls._instance = ThreadPoolExecutor(max_workers=10) return cls._instance class MainHandler(tornado.web.RequestHandler): executor = ThreadPoolExecutor(10) @tornado.web.asynchronous @tornado.gen.coroutine def get(self): future = Executor().submit(self.sleep) response = yield tornado.gen.with_timeout(datetime.timedelta(10), future, quiet_exceptions = tornado.gen.TimeoutError ) self.finish('OK啦') @tornado.concurrent.run_on_executor def sleep(self): self.set_cookie('step1', 'value') # 这个cookie能设置 time.sleep(10) self.set_cookie('step1', 'value') # 这个cookie无法设置 if not self.get_cookie('mycookie'): self.set_cookie('mycookie', 'myvalue') print('cookie设置完毕') return 'OK啦' class TestHandler(tornado.web.RequestHandler): def get(self): if not self.get_cookie('mycookie'): self.write('没有') else: self.write('有') application = tornado.web.Application([ (r"/", MainHandler), (r"/test", TestHandler), ], debug=True) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
直接暴露一个接口出来展示进度吧,否则cookie要被你玩坏了。
给 application 设置一个属性,值是一个字典啊之类的东西,测试接口直接读这个字典里的状态。字典里的状态,可以在异步任务里更新。
如果不同的浏览器需要不同的状态,那就拿 cookie 啊 uid 之类的东西做一下 hash。