microsoft / microsoft/AzureTRE
API Background tasks created with asyncio.create_task could be garbage collected
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 235
- Forks
- 192
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 13
Description
Describe the bug
Background tasks created with asyncio.create_task are not managed or retained
Description
Background tasks started during the FastAPI application lifespan are created using asyncio.create_task() but are not stored or managed. This results in tasks being unreferenced, which can lead to premature garbage collection, lost exceptions, and uncontrolled shutdown behaviour.
Problem
The code previously used:
asyncio.create_task(deploymentStatusUpdater.receive_messages())
asyncio.create_task(airlockStatusUpdater.receive_messages())
Issues with this approach:
- No strong references to tasks
- Tasks may be garbage collected while still running
- No lifecycle management
- Tasks are not cancelled or awaited during shutdown
- Unobserved exceptions
- Failures inside tasks are silently ignored
- Potential shutdown warnings
- e.g.
Task was destroyed but it is pending!
- e.g.
Impact
- Background workers may terminate unexpectedly
- Errors in long-running tasks can go unnoticed
- Application shutdown may be unreliable or produce warnings
- Difficult to debug production issues due to lack of visibility
Expected behaviour
- Background tasks should:
- Be strongly referenced
- Be tied to the FastAPI application lifecycle
- Be cancelled and awaited on shutdown
- Have exceptions logged with full context
Suggested fix
Track and manage tasks via app.state, for example:
app.state.background_tasks = set()
task = asyncio.create_task(worker())
app.state.background_tasks.add(task)
task.add_done_callback(app.state.background_tasks.discard)
And on shutdown:
tasks = list(app.state.background_tasks)
for task in tasks:
task.cancel()
await asyncio.gather(*tasks, return_exceptions=True)
Additional notes
- Tasks should also handle
asyncio.CancelledErrorinternally for clean shutdown. - Naming tasks can significantly improve observability and debugging.
Steps to reproduce
I have not noticed any times this has happened in practice
Azure TRE release version (e.g. v0.14.0 or main):
main
Deployed Azure TRE components - click the (i) in the UI:
latest
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Locate the FastAPI application lifespan code containing the two asyncio.create_task calls and inspect how startup and shutdown are handled. Implement the expected task retention, cancellation, awaiting, and exception visibility described in the issue, including clean handling of asyncio.CancelledError. Done means the workers remain referenced during runtime and shut down without pending-task warnings.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- fastapi, python
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100