在Flask应用中创建、管理和终止后台任务
我正在开发一个Flask网页应用,用户可以在里面启动和管理一些进程。这些进程会进行一些比较复杂的计算,可能需要几天的时间。在进程运行的时候,它会把一些部分结果保存到文件中,以便后续使用。
当用户启动一个新进程时,我会创建一个新的线程,并把这个线程的句柄保存在Flask的全局变量flask.g里。
def add_thread(thread_handle):
ctx = app.app_context()
threads = flask.g.get("threads", [])
threads.append(thread_handle)
g.threads = threads
ctx.push()
之后,当需要的时候,用户可以终止这个长时间运行的进程。
def kill_thread(idx):
ctx = app.app_context()
threads = flask.g.get("threads", [])
threads.pop(idx).terminate()
g.threads = threads
ctx.push()
我必须使用ctx.push()来存储线程的列表,这样在下一个请求时,这个列表就可以使用了。但是这样做在添加新线程时会抛出关于应用上下文的异常。
Traceback (most recent call last):
File "/Users/mirobeka/.virtualenvs/cellular/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/mirobeka/.virtualenvs/cellular/lib/python2.7/site-packages/flask/app.py", line 1825, in wsgi_app
ctx.auto_pop(error)
File "/Users/mirobeka/.virtualenvs/cellular/lib/python2.7/site-packages/flask/ctx.py", line 374, in auto_pop
self.pop(exc)
File "/Users/mirobeka/.virtualenvs/cellular/lib/python2.7/site-packages/flask/ctx.py", line 366, in pop
app_ctx.pop(exc)
File "/Users/mirobeka/.virtualenvs/cellular/lib/python2.7/site-packages/flask/ctx.py", line 178, in pop
% (rv, self)
AssertionError: Popped wrong app context. (<flask.ctx.AppContext object at 0x10fb99c50> instead of <flask.ctx.AppContext object at 0x10fa60150>)
这让我觉得这个解决方案有点不太对劲,可能在后续开发中会遇到麻烦。我在考虑把线程句柄存储在文件或数据库中,但锁对象是不能被序列化的。
有没有什么设计模式可以用来管理我所描述的这些活跃的Python对象呢?
2 个回答
0
或者可以使用 rq
,我觉得它比 celery
简单十倍。如果你在那遇到类似的问题,我在这里发布了我的解决方案 这里。
4
你最好使用 celery
(celeryproject.org)来处理这类任务。它在实际生产环境中被广泛使用,所以后续开发时不会遇到死胡同。它提供了管理后台任务所需的一切功能,还有很多其他的好处。这里有关于如何 将它与flask结合使用 的介绍。