我正在尝试将Flask的当前请求上下文复制到gevent线程中,以便我可以使用这些thred中的原始请求上下文进行日志记录。
我在下面提到了链接。
http://flask.pocoo.org/docs/0.12/api/#flask.copy_current_request_context
使用装饰器@copy_current_request_context
在我只生成1个gevent线程时工作正常。但是如果我生成多个线程,则会引发异常。似乎每个线程都从其他线程推送的堆栈弹出错误的上下文。
AssertionError: Popped wrong app context. (<flask.ctx.AppContext object at 0x7f57983b7ba8> instead of <flask.ctx.AppContext object at 0x7f57983be9b0>
以下是我想要做的示例代码:
def index(items):
@copy_current_request_context
def do_some_work(item):
# do some work
threads = [gevent.spawn(do_some_work, item) for item in items]
gevent.joinall(threads)
有什么方法可以解决这个问题吗?
答案 0 :(得分:0)
你可以这样做:
top = flask.globals._request_ctx_stack.top
# copy the request context
reqctx = top.copy()
def do_some_work(item):
# Here the context stack is not the same as above, since do_some_work
# is called in a greenlet, the stack returned is empty.
flask.globals._request_ctx_stack.push(reqctx)
# ----------- do your work here -----------------
flask.globals._request_ctx_stack.pop() # very important to do this, or your memory will explose
threads = [gevent.spawn(do_some_work, item) for item in items]
更好的版本是推送&#39;推送&#39;并且&#39; pop&#39;对上下文管理器的操作,我允许你这样做