Skip to content

refactor: replace async_helpers with BackgroundTasks and remove run_async_task

Merge Request

Overview

This MR refactors the async execution mechanism by removing the custom async helper (async_helpers.py) and replacing it with FastAPI’s built-in BackgroundTasks. This change improves reliability and eliminates event loop related errors.

What does this MR do and why?

Previously, the project used a custom utility (run_async_task) to execute async functions from sync contexts using manual event loop handling and threads. This approach was fragile and caused issues like "RuntimeError: This event loop is already running".

This MR replaces that implementation with FastAPI BackgroundTasks, ensuring safe background execution without blocking the API response and improving maintainability.

Changes Made

  • Removed app/utils/async_helpers.py
  • Removed all usages of run_async_task
  • Added BackgroundTasks in route layer
  • Removed all usages of asyncio.run()
  • Removed _broadcast_queue_update_sync() (sync fallback)
  • Updated async execution to pass coroutine directly using background_tasks.add_task()
  • Made background_tasks mandatory across service functions
  • Updated consultation_queue_service.py to support background_tasks
  • Updated doctor_service.py to propagate background_tasks
  • Updated route files to inject and pass BackgroundTasks
  • Simplified test assertions using call_args.args[:3]
  • Updated existing tests to include BackgroundTasks
  • Removed async_helpers related tests
  • Verified no remaining references to async_helpers

Technical Details

Root Cause: Custom async helper manually handled event loops and threads, leading to instability and runtime errors.

Fix: Replaced custom async handling with FastAPI BackgroundTasks by passing coroutine functions directly, avoiding manual event loop control.

Flow: Route → BackgroundTasks → Service → Async Broadcast

Type of Change

  • 🐛 Bug fix
  • New feature
  • 💥 Breaking change
  • 📝 Documentation update
  • ️ Refactor (no functional changes)
  • Performance improvement
  • 🧪 Test update
  • 🔧 Configuration change
  • 🚨 Security fix
  • 🗑️ Deprecation

Related Issues / References

Screenshots or Screen Recordings

  • assign-doctor API tested successfully
  • queue updates verified
  • image

How to Validate Locally

  1. Start server: docker compose up --build

  2. Login and get token

  3. Call: POST /api/v1/doctors/assign-doctor

  4. Verify: GET /api/v1/queue/all

Expected:

  • Patient assigned successfully
  • Queue updated correctly
  • No async errors in logs

Testing Done

  • API endpoint tests passing

Test Cases Covered:

Scenario Expected Result Status
Assign doctor Success response
Queue update Patient appears in queue
Async handling No event loop error

Test Commands Run: pytest

Code Quality Checklist

  • No duplicate code
  • Clean refactor
  • No unused imports
  • BackgroundTasks used correctly
  • No API changes
  • No runtime async errors

Documentation

  • README.md updated
  • API docs updated

Known Limitations / Technical Debt

  • Uses FastAPI BackgroundTasks for async execution; can be extended with anyio if advanced async control is required in future

Additional Notes

  • No changes to business logic
  • Fully backward compatible
  • Implementation follows FastAPI async best practices

MR Acceptance Checklist

  • Code works as intended
  • No bugs introduced
  • Clean and maintainable code
Edited by Vandana reddy Balannagari

Merge request reports

Loading