Skip to content

fix: use AsyncSession in fetch_parsing_status to prevent event loop blocking#651

Open
LakshmiSravyaVedantham wants to merge 1 commit intopotpie-ai:mainfrom
LakshmiSravyaVedantham:fix/async-session-parsing-controller
Open

fix: use AsyncSession in fetch_parsing_status to prevent event loop blocking#651
LakshmiSravyaVedantham wants to merge 1 commit intopotpie-ai:mainfrom
LakshmiSravyaVedantham:fix/async-session-parsing-controller

Conversation

@LakshmiSravyaVedantham
Copy link
Copy Markdown

@LakshmiSravyaVedantham LakshmiSravyaVedantham commented Feb 25, 2026

Summary

Fixes #639

fetch_parsing_status was declared async but used a synchronous SQLAlchemy Session, which blocks the event loop on every database call. Under concurrent load this serializes requests and degrades API performance.

Changes

  • Changed fetch_parsing_status in parsing_controller.py to accept AsyncSession instead of Session
  • Added await to the db.execute(project_query) call inside the method
  • Updated the /parsing-status/{project_id} route in parsing_router.py to inject AsyncSession via get_async_db instead of the synchronous get_db
  • Updated the /parsing-status POST route in parsing_router.py the same way, since fetch_parsing_status_by_repo already expected AsyncSession

Reference

The adjacent fetch_parsing_status_by_repo method in the same file already implements this pattern correctly and was used as the reference implementation. Both methods now follow the same async database access pattern.

Testing

  • Verified the method signature matches the async pattern used throughout the codebase
  • The get_async_db dependency is already defined in app/core/database.py and used by other routes
  • No new dependencies were introduced

Summary by CodeRabbit

  • Refactor
    • Enhanced database operations for parsing status endpoints with improved asynchronous handling to optimize performance and responsiveness.

…locking

The fetch_parsing_status method was declared async but used a synchronous
SQLAlchemy Session, blocking the event loop on every call. Under concurrent
load this causes request queuing and degraded performance.

Updated to use AsyncSession with proper await on all database operations,
consistent with the existing fetch_parsing_status_by_repo implementation
in the same file.

Also updated the /parsing-status/{project_id} route in parsing_router.py
to inject AsyncSession via get_async_db instead of the synchronous get_db,
and updated the /parsing-status POST route similarly since
fetch_parsing_status_by_repo already expected AsyncSession.

Fixes potpie-ai#639
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 25, 2026

Walkthrough

The pull request converts synchronous database session usage to asynchronous patterns in the parsing status endpoints. The fetch_parsing_status method signature is updated from Session to AsyncSession, and database execution calls are now awaited, with corresponding changes propagated to router endpoint dependencies.

Changes

Cohort / File(s) Summary
Controller Async Update
app/modules/parsing/graph_construction/parsing_controller.py
Updated fetch_parsing_status method to accept AsyncSession instead of Session and changed db.execute() call to await db.execute() for non-blocking database access.
Router Dependency Injection
app/modules/parsing/graph_construction/parsing_router.py
Updated get_parsing_status and get_parsing_status_by_repo endpoint signatures to use AsyncSession via get_async_db dependency instead of synchronous Session via get_db; added imports for AsyncSession and get_async_db.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • dhirenmathur

Poem

🐰 No more blocking hops for our async friend,
From sync to await, the event loop won't bend,
DB calls now swift on the FastAPI stream,
Sessions made async—a non-blocking dream! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: converting blocking synchronous DB calls to asynchronous AsyncSession usage in fetch_parsing_status to prevent event loop blocking.
Linked Issues check ✅ Passed The PR implements all coding requirements from issue #639: changes fetch_parsing_status to use AsyncSession instead of Session, adds await to db.execute calls, and updates router dependencies to use get_async_db for AsyncSession injection.
Out of Scope Changes check ✅ Passed All changes are directly related to converting blocking DB calls to async in the parsing status flow, aligning with issue #639 requirements without introducing unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/modules/parsing/graph_construction/parsing_controller.py (1)

397-434: ⚠️ Potential issue | 🔴 Critical

Fix ParseHelper and ProjectService to handle AsyncSession correctly.

ParseHelper(db) receives an AsyncSession at line 425, but ParseHelper.__init__ is typed to accept a sync Session and passes it to ProjectService. The problem manifests in check_commit_status(): it calls await self.project_manager.get_project_from_db_by_id(project_id), which internally invokes ProjectService.get_project_by_id() — a method that uses db.query(Project).filter(...).first(). AsyncSession does not support the .query() method; it only supports select() with await db.execute(). This will raise an AttributeError at runtime.

Either update ParseHelper and ProjectService to accept and work with AsyncSession using async patterns, or pass a sync Session instead of AsyncSession to ParseHelper.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/modules/parsing/graph_construction/parsing_controller.py` around lines
397 - 434, ParseHelper is being constructed with an AsyncSession but its
__init__ and downstream ProjectService still expect a sync Session, causing
AttributeError when ProjectService.get_project_by_id uses db.query(...); update
ParseHelper.__init__ to accept AsyncSession (or overload) and refactor
ProjectService methods used by ParseHelper (e.g., get_project_by_id,
get_project_from_db_by_id) to use async SQLAlchemy patterns: replace
.query()/.filter()/first() with select(Project).where(...), call await
db.execute(...) and use result.scalars().first(), mark methods async and await
their calls (e.g., check_commit_status -> await
project_manager.get_project_from_db_by_id), and adjust type hints from Session
to AsyncSession; alternatively, if you prefer sync flow, ensure you pass a sync
Session into ParseHelper instead of AsyncSession.
🧹 Nitpick comments (1)
app/modules/parsing/graph_construction/parsing_router.py (1)

29-30: Ruff B008 warnings are false positives for FastAPI dependency injection.

Depends(...) in argument defaults is the canonical FastAPI DI pattern and Ruff B008 is a well-known false positive here. The same pattern is used on pre-existing lines (e.g., Line 20, Line 21, Line 39) without suppression. If the project enforces Ruff strictly, consider adding a project-level B008 ignore for FastAPI router files, or inline # noqa: B008 comments — but this is consistent with the existing codebase style.

Also applies to: 38-38

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/modules/parsing/graph_construction/parsing_router.py` around lines 29 -
30, Ruff B008 flags are false positives for FastAPI dependency injection in
parsing_router.py; update the dependency argument lines that use Depends (e.g.,
the parameters using AsyncSession with get_async_db and
user=Depends(AuthService.check_auth), and the other occurrence around line 38)
to suppress B008 consistently with the codebase by adding an inline noqa comment
(“# noqa: B008”) to those function parameter lines or alternatively add a
project-level ignore for B008 for FastAPI router files so the Depends(...)
patterns are not reported.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@app/modules/parsing/graph_construction/parsing_controller.py`:
- Around line 397-434: ParseHelper is being constructed with an AsyncSession but
its __init__ and downstream ProjectService still expect a sync Session, causing
AttributeError when ProjectService.get_project_by_id uses db.query(...); update
ParseHelper.__init__ to accept AsyncSession (or overload) and refactor
ProjectService methods used by ParseHelper (e.g., get_project_by_id,
get_project_from_db_by_id) to use async SQLAlchemy patterns: replace
.query()/.filter()/first() with select(Project).where(...), call await
db.execute(...) and use result.scalars().first(), mark methods async and await
their calls (e.g., check_commit_status -> await
project_manager.get_project_from_db_by_id), and adjust type hints from Session
to AsyncSession; alternatively, if you prefer sync flow, ensure you pass a sync
Session into ParseHelper instead of AsyncSession.

---

Nitpick comments:
In `@app/modules/parsing/graph_construction/parsing_router.py`:
- Around line 29-30: Ruff B008 flags are false positives for FastAPI dependency
injection in parsing_router.py; update the dependency argument lines that use
Depends (e.g., the parameters using AsyncSession with get_async_db and
user=Depends(AuthService.check_auth), and the other occurrence around line 38)
to suppress B008 consistently with the codebase by adding an inline noqa comment
(“# noqa: B008”) to those function parameter lines or alternatively add a
project-level ignore for B008 for FastAPI router files so the Depends(...)
patterns are not reported.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0711ea and a23ff18.

📒 Files selected for processing (2)
  • app/modules/parsing/graph_construction/parsing_controller.py
  • app/modules/parsing/graph_construction/parsing_router.py

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.

[Bug/Performance]: Inconsistent async DB usage in fetch_parsing_status causes blocking calls

1 participant