I banged my head against the wall with this one for a while before I found the problem.
Steps to reproduce:
- Request is made to FastAPI which dispatches a starting X process. The request immediately returns a payload letting the client know the asynchronous process has started.
- The actual work is then done in an
asyncio.Task which then dispatches a X process is complete afterwords.
- Any dispatched events in the
Task are never received
What is actually happening:
The issue is on dispatcher.py line 57. Starting in Python 3.7, asyncio.Task copies the current context from contextvars into the Task. When line 57 is reached, the code is told the event will be dispatched in the middleware as part of the request since the request was active at the time the Task was created. In actuality, these events end up in the void as they should have been dispatched via _dispatch_as_task.
For now, anywhere an event needs to be dispatch within a Task, I import fastapi_events.in_req_res_cycle into the code and run in_req_res_cycle.set(None). This forces _dispatch() to process these events via _dispatch_as_task.
Edit: updated the link to include the specific commit revision
I banged my head against the wall with this one for a while before I found the problem.
Steps to reproduce:
asyncio.Taskwhich then dispatches a X process is complete afterwords.Taskare never receivedWhat is actually happening:
The issue is on dispatcher.py line 57. Starting in Python 3.7,
asyncio.Taskcopies the current context fromcontextvarsinto theTask. When line 57 is reached, the code is told the event will be dispatched in the middleware as part of the request since the request was active at the time theTaskwas created. In actuality, these events end up in the void as they should have been dispatched via_dispatch_as_task.For now, anywhere an event needs to be dispatch within a
Task, I importfastapi_events.in_req_res_cycleinto the code and runin_req_res_cycle.set(None). This forces_dispatch()to process these events via_dispatch_as_task.Edit: updated the link to include the specific commit revision