无法将当前的烧瓶请求上下文复制到多个gevent线程

时间:2018-02-15 18:35:52

标签: python flask gevent

我正在尝试将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)

有什么方法可以解决这个问题吗?

1 个答案:

答案 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;对上下文管理器的操作,我允许你这样做