Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
## 2026-02-19 - [Frontend Download Optimization]
**Learning:** Using `fetch` + `blob` to download large files (500MB+) in browser JavaScript causes significant memory spikes and potential crashes.
**Action:** Always prefer direct link downloads (creating a hidden `<a>` tag) for large file downloads. Implemented `triggerDownload` utility in `api.ts` to handle this centrally with backend compatibility checks.

## 2025-05-23 - Avoid Reading Files for Size Validation in Async Python
**Learning:** Iterating over `UploadFile.file` (a `SpooledTemporaryFile`) to check file size is a synchronous operation that blocks the event loop, causing severe performance degradation (e.g., 1s block for 50MB file).
**Action:** Always use `file.file.seek(0, 2)` and `file.file.tell()` to determine size in O(1) time without reading content. Ensure to reset the file pointer with `await file.seek(0)` afterwards.
13 changes: 7 additions & 6 deletions backend/src/api/conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,16 +201,17 @@ async def validate_file_size(file: UploadFile) -> tuple[bool, str]:
Returns:
Tuple of (is_valid, error_message)
"""
# Read file to check size
total_size = 0
for chunk in file.file:
total_size += len(chunk)
if total_size > MAX_UPLOAD_SIZE:
return False, f"File size exceeds {MAX_UPLOAD_SIZE // (1024 * 1024)}MB limit"
# Check size using seek/tell (O(1) instead of O(N) read)
# file.file is a SpooledTemporaryFile which supports seek/tell synchronously
file.file.seek(0, 2)
file_size = file.file.tell()

# Reset file pointer
await file.seek(0)

if file_size > MAX_UPLOAD_SIZE:
return False, f"File size exceeds {MAX_UPLOAD_SIZE // (1024 * 1024)}MB limit"

return True, ""


Expand Down