【Flask】AssertionError: Popped wrong app context.
現象:
Traceback (most recent call last):
File "src\\gevent\\greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run
File "************\venv\lib\site-packages\flask\ctx.py", line 157, in wrapper
return f(*args, **kwargs)
File "************\venv\lib\site-packages\flask\ctx.py", line 464, in __exit__
self.auto_pop(exc_value)
File "************\venv\lib\site-packages\flask\ctx.py", line 452, in auto_pop
self.pop(exc)
File "************\venv\lib\site-packages\flask\ctx.py", line 438, in pop
app_ctx.pop(exc)
File "************\venv\lib\site-packages\flask\ctx.py", line 241, in pop
assert rv is self, "Popped wrong app context. (%r instead of %r)" % (rv, self)
AssertionError: Popped wrong app context. (<flask.ctx.AppContext object at 0x000001DD7CF510F0> instead of <flask.ctx.AppContext object at 0x000001DD7CFBA5C0>)
2023-05-31T02:26:16Z <Greenlet at 0x1dd7cf79048: handle_data(<Queue at 0x1dd7cf7de80>, sid_spaces={'ws': <geventwebsocket.websocket.WebSocket object)> failed with AssertionError
- 在處理完畢相關事情,外部連接斷開時,移除對棧中本次協程上下文
- 不影響業務邏輯。
原因分析:
在一次請求事件中,使用gevent進行異步非阻塞任務,并使用copy_current_request_context進行request、g等上下文拷貝傳遞,結束時app上下文不存在,引發app棧移除失敗
- 使用時條件:flask、gevent、copy_current_request_context
解決辦法:
- 解決策略:在創建協程時,拷貝request的等上下文之前,應創建app上下文
- 方案:
def copy_current_app_context(f):
from flask.globals import _app_ctx_stack
tx = _app_ctx_stack.top
def wrapper(*args, **kwargs):
with tx:
return f(*args, **kwargs)
return wrapper
copy_current_app_context 要在 request、g等拷貝前,即:copy_current_request_context

浙公網安備 33010602011771號