feat(insights): Add timeout to image optimization analysis#614
feat(insights): Add timeout to image optimization analysis#614NicoHinderling merged 2 commits intomainfrom
Conversation
Large apps with thousands of images can cause the image optimization insight to run for several minutes. Add a 300-second deadline that cancels pending futures and returns partial results with a timed_out flag so callers can distinguish between "no optimizable images" and "analysis was cut short." Co-Authored-By: Claude <noreply@anthropic.com>
📲 Install BuildsiOS
Android
|
|
|
||
| results: List[OptimizableImageFile] = [] | ||
| timed_out = False | ||
| completed = 0 |
There was a problem hiding this comment.
nit: is completed helpful here vs len(results)?
There was a problem hiding this comment.
iirc The completed counter tracks all processed futures (including failures and below-threshold images), while len(results) only counts optimization candidates
Guard the deadline check with `completed < len(files)` so that a complete analysis run is not misreported as partial when elapsed time happens to exceed the timeout threshold. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| ) | ||
| timed_out: bool = Field(False, description="Whether analysis was cut short due to timeout") | ||
|
|
||
| def get_file_paths(self) -> List[str]: |
There was a problem hiding this comment.
Bug: The frontend does not handle the new timed_out field for image optimization insights, leading to a misleading UI when an analysis times out.
Severity: MEDIUM
Suggested Fix
Update the ImageOptimizationInsightResult interface in web/src/utils/dataConverter.ts to include the timed_out field. Modify the InsightsDisplay.tsx component to check this field and render a warning message indicating that the analysis timed out and results are incomplete.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: src/launchpad/size/models/insights.py#L218
Potential issue: The backend `ImageOptimizationInsightResult` model was updated to
include a `timed_out` boolean field to signal when an analysis is cut short. However,
the corresponding frontend TypeScript interface and React component were not updated to
consume this new field. Consequently, if an analysis times out, especially before
processing any files, the frontend receives `total_savings=0` and an empty
`optimizable_files` array. It then incorrectly displays a "No savings" message,
misleading the user into thinking the analysis completed successfully when it actually
timed out.
Also affects:
web/src/utils/dataConverter.tsweb/src/components/InsightsDisplay.tsx
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 0259e3a. Configure here.
| with ThreadPoolExecutor(max_workers=min(self._MAX_WORKERS, len(files))) as executor: | ||
| future_to_file = {executor.submit(self._analyze_image_optimization, f): f for f in files} | ||
| for future in as_completed(future_to_file): | ||
| completed += 1 |
There was a problem hiding this comment.
Deadline not enforced while blocked in as_completed
Low Severity
The as_completed(future_to_file) call has no timeout parameter, so __next__() blocks indefinitely waiting for the next future. The deadline check on line 91 only runs after a future completes. If all _MAX_WORKERS running futures are slow (e.g. processing very large images), the code remains stuck inside as_completed well past the 300-second deadline. Passing a timeout to as_completed and catching TimeoutError would enforce the deadline even while waiting.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 0259e3a. Configure here.


Add a 300-second deadline to
BaseImageOptimizationInsight.generate()thatstops processing images when the timeout is reached. This prevents the image
optimization insight from blocking the entire analysis pipeline for several
minutes on large apps with thousands of images (e.g. 3000+ asset catalog entries).
When the deadline fires:
timed_outflag is set onImageOptimizationInsightResultso consumerscan distinguish "no optimizable images" from "analysis was cut short"
timed_out=Trueis returned if no images passed thesavings threshold before the deadline (previously this silently returned
None)The
timed_outfield defaults toFalseon the model so existing serializeddata deserializes correctly.