想通过异步的方式实现一个耗时的任务,但是又想在执行的过程中了解到进度,并且不借助于数据库,目前只能想到用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()
Set an attribute to the application. The value is a dictionary or something like that. The test interface directly reads the status in this dictionary. The status in the dictionary can be updated in asynchronous tasks.
If different browsers require different states, then use things like cookies and uids to make hashes.
Just expose an interface to show the progress, otherwise the cookie will be destroyed by you.