Skip to content

⚡ Bolt: Fix blocking I/O in async endpoint#6

Merged
RohanExploit merged 2 commits into
mainfrom
bolt-async-io-fix-7293520402018783653
Jun 14, 2026
Merged

⚡ Bolt: Fix blocking I/O in async endpoint#6
RohanExploit merged 2 commits into
mainfrom
bolt-async-io-fix-7293520402018783653

Conversation

@google-labs-jules

Copy link
Copy Markdown
Contributor

⚡ Bolt: Offload blocking I/O in async endpoint

💡 What:
Refactored the create_issue endpoint in backend/main.py to run blocking file write operations and synchronous database commits in a separate thread using asyncio.to_thread.

🎯 Why:
The original implementation performed synchronous file I/O (shutil.copyfileobj) and database operations (db.commit) directly within an async def endpoint. In FastAPI, this blocks the main event loop, preventing the server from handling other concurrent requests while these operations complete.

📊 Impact:
Prevents the server from freezing during file uploads or database waits. While difficult to measure with small loads/files, this is a critical architectural fix for scalability and responsiveness under load.

🔬 Measurement:
Verified with a concurrent benchmark script (benchmark.py) sending 3 simultaneous requests. The server handled them successfully without errors, and the logic now adheres to FastAPI best practices for async endpoints.


PR created automatically by Jules for task 7293520402018783653 started by @RohanExploit

- Offload synchronous file I/O and SQLAlchemy database operations to thread pool using `asyncio.to_thread`.
- Prevents blocking the main event loop during image uploads and DB commits.
- Improves concurrency for the `create_issue` endpoint.
@google-labs-jules

Copy link
Copy Markdown
Contributor Author

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!


For security, I will only act on instructions from the user who triggered this task.

New to Jules? Learn more at jules.google/docs.

@RohanExploit RohanExploit marked this pull request as ready for review December 22, 2025 08:33
Copilot AI review requested due to automatic review settings December 22, 2025 08:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the create_issue endpoint to offload blocking I/O operations to separate threads using asyncio.to_thread(), preventing the FastAPI event loop from blocking during file writes and database commits.

Key Changes:

  • Wrapped file I/O operations in a save_file() function executed via asyncio.to_thread()
  • Wrapped database operations in a save_to_db() function executed via asyncio.to_thread()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread backend/main.py
Comment on lines +71 to +83
def save_to_db():
new_issue = Issue(
description=description,
category=category,
image_path=image_path,
source="web"
)
db.add(new_issue)
db.commit()
db.refresh(new_issue)
return new_issue

new_issue = await asyncio.to_thread(save_to_db)

Copilot AI Dec 22, 2025

Copy link

Choose a reason for hiding this comment

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

The database session db is not thread-safe and should not be used across threads. SQLAlchemy sessions are bound to the thread that created them. When save_to_db() executes in a separate thread via asyncio.to_thread(), it uses the db session that was created in the main event loop thread, which can lead to undefined behavior, connection errors, or data corruption.

Instead, create a new database session within the save_to_db() function that will be used exclusively in that thread. You can import SessionLocal from backend.database and instantiate a new session inside the function, ensuring proper closure with a try-finally block.

Copilot uses AI. Check for mistakes.
Comment thread backend/main.py
Comment on lines +63 to +66
# Offload blocking file I/O to a thread
def save_file():
with open(image_path, "wb") as buffer:
shutil.copyfileobj(image.file, buffer)

Copilot AI Dec 22, 2025

Copy link

Choose a reason for hiding this comment

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

The image.file object (a SpooledTemporaryFile from UploadFile) is being accessed in a separate thread. FastAPI's UploadFile is designed to work with async code and may have issues when the underlying file object is accessed from a different thread than where the UploadFile was created.

A safer approach is to read the file contents in the main async context first, then pass the bytes to the thread for writing. Alternatively, ensure the file object's position is properly managed and consider using image.file.read() before passing to the thread.

Suggested change
# Offload blocking file I/O to a thread
def save_file():
with open(image_path, "wb") as buffer:
shutil.copyfileobj(image.file, buffer)
# Read the uploaded file in the async context to avoid accessing
# the underlying UploadFile.file from a separate thread.
image_data = await image.read()
# Offload blocking file I/O to a thread
def save_file():
with open(image_path, "wb") as buffer:
buffer.write(image_data)

Copilot uses AI. Check for mistakes.
@RohanExploit RohanExploit added ECWoC26 Elite Coders winter of Code and removed ECWoC26 Elite Coders winter of Code labels Jan 14, 2026
@RohanExploit RohanExploit merged commit 49b7dfc into main Jun 14, 2026
5 of 6 checks passed
@RohanExploit RohanExploit temporarily deployed to bolt-async-io-fix-7293520402018783653 - vishwaguru-backend PR #6 June 14, 2026 05:33 — with Render Destroyed
@netlify

netlify Bot commented Jun 14, 2026

Copy link
Copy Markdown

Deploy Preview for fixmybharat canceled.

Name Link
🔨 Latest commit 230da63
🔍 Latest deploy log https://app.netlify.com/projects/fixmybharat/deploys/6a2e3d33ba4545000833a29b

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.

2 participants