我正在构建flask web应用程序,用户可以在其中启动和管理进程。这些过程正在进行一些繁重的计算(甚至可能是几天)。当进程正在运行时,它会将部分结果保存到文件中以便使用。
因此,当用户启动新进程时,我会生成新线程并将线程句柄保存到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对象的设计模式,比如我在描述?
答案 0 :(得分:3)
您最好使用celery
(celeryproject.org)来完成此类任务。它在生产环境中被大量使用,不用担心后期开发中的死胡同。它拥有管理后台任务所需的一切,还有更多。这是integrate it with flask的方式。
答案 1 :(得分:0)
或者使用rq
,它比celery
简化10倍。如果您在那里遇到类似的问题-我已发布了解决方案here。