Skip to content

Commit 6355c29

Browse files
committed
fix: wrap sync DB calls in executor for authenticated endpoints
- GitHub OAuth status endpoint: wrap store.get_token() in executor - User repos endpoint: wrap pin_store.list_states() in executor - Archived repos endpoint: wrap pin_store.list_archived() in executor - Prevents blocking async event loop with synchronous SQLAlchemy queries - Fixes 10-second timeout issue on authenticated endpoints
1 parent a843c23 commit 6355c29

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

commitly-backend/app/api/github.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,16 @@ async def github_status(
5757
current_user: ClerkClaims = Depends(require_clerk_auth),
5858
session: Session = Depends(get_db),
5959
):
60-
store = GitHubTokenStore(session)
61-
record = store.get_token(current_user["sub"])
60+
import asyncio
61+
62+
# Wrap sync DB call in executor to avoid blocking event loop
63+
def get_status():
64+
store = GitHubTokenStore(session)
65+
return store.get_token(current_user["sub"])
66+
67+
loop = asyncio.get_event_loop()
68+
record = await loop.run_in_executor(None, get_status)
69+
6270
if record is None:
6371
return OAuthStatusResponse(connected=False)
6472
return OAuthStatusResponse(

commitly-backend/app/api/roadmap.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,12 @@ async def list_user_repositories(
214214
current_user: ClerkClaims = Depends(require_clerk_auth),
215215
service: RoadmapService = Depends(get_roadmap_service),
216216
) -> list[UserRepoStateResponse]:
217-
return await service.list_user_repos(get_user_id(current_user))
217+
import asyncio
218+
219+
# Wrap sync DB call in executor to avoid blocking event loop
220+
user_id = get_user_id(current_user)
221+
loop = asyncio.get_event_loop()
222+
return await loop.run_in_executor(None, lambda: service._pin_store.list_states(user_id))
218223

219224

220225
@router.post("/sync/{owner}/{repo}", response_model=UserRepoStateResponse)
@@ -263,7 +268,12 @@ async def list_archived_repositories(
263268
current_user: ClerkClaims = Depends(require_clerk_auth),
264269
service: RoadmapService = Depends(get_roadmap_service),
265270
) -> list[UserRepoStateResponse]:
266-
return await service.list_archived_repos(get_user_id(current_user))
271+
import asyncio
272+
273+
# Wrap sync DB call in executor to avoid blocking event loop
274+
user_id = get_user_id(current_user)
275+
loop = asyncio.get_event_loop()
276+
return await loop.run_in_executor(None, lambda: service._pin_store.list_archived(user_id))
267277

268278

269279
@router.post("/{owner}/{repo}/rating", response_model=RatingResponse)

0 commit comments

Comments
 (0)