Skip to content

fix(api): non-blocking asyncio.sleep in lifespan db-retry backoff (#140) - #142

Draft
Jovonni wants to merge 1 commit into
masterfrom
fix/async-sleep-lifespan
Draft

fix(api): non-blocking asyncio.sleep in lifespan db-retry backoff (#140)#142
Jovonni wants to merge 1 commit into
masterfrom
fix/async-sleep-lifespan

Conversation

@Jovonni

@Jovonni Jovonni commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

What

The FastAPI startup lifespan retried init_db() with a blocking time.sleep(retry_delay) inside an async def. That blocks the event loop for the full backoff window on every failed attempt, so anything sharing the loop from the first instant (health/readiness probes) can be delayed while the DB is reconnecting.

Swaps it for await asyncio.sleep(retry_delay) (non-blocking), and adds import asyncio at module top.

Why

Flagged in #140 — small, correct one-liner with a real (if narrow) impact on startup responsiveness.

Tests

New regression subsuite core/tests/test_lifespan_async.py:

  • static guard — the lifespan source contains no time.sleep and uses await asyncio.sleep
  • functional — init_db() fails once then succeeds; asserts the retry path awaits the non-blocking sleep exactly once (event loop never blocks)

Runs under the existing core/tests/ pytest suite in CI.

Closes #140

The startup lifespan retried init_db() with a blocking time.sleep()
inside an async function, which stalls the event loop during db
reconnection — delaying readiness/health probes that share the loop.
Switch to await asyncio.sleep() and add a regression test suite.

Closes #140
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

time.sleep() inside async lifespan — intentional or worth switching to await asyncio.sleep()?

1 participant