Skip to content

feat(insights): Add timeout to image optimization analysis#614

Merged
NicoHinderling merged 2 commits intomainfrom
feat/image-optimization-timeout
May 8, 2026
Merged

feat(insights): Add timeout to image optimization analysis#614
NicoHinderling merged 2 commits intomainfrom
feat/image-optimization-timeout

Conversation

@NicoHinderling
Copy link
Copy Markdown
Contributor

Add a 300-second deadline to BaseImageOptimizationInsight.generate() that
stops 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:

  • Pending futures are cancelled so queued work doesn't start
  • A timed_out flag is set on ImageOptimizationInsightResult so consumers
    can distinguish "no optimizable images" from "analysis was cut short"
  • Partial results collected before the timeout are still returned
  • An empty result with timed_out=True is returned if no images passed the
    savings threshold before the deadline (previously this silently returned None)

The timed_out field defaults to False on the model so existing serialized
data deserializes correctly.

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>
@NicoHinderling NicoHinderling marked this pull request as ready for review May 8, 2026 19:17
@sentry
Copy link
Copy Markdown
Contributor

sentry Bot commented May 8, 2026

📲 Install Builds

iOS

🔗 App Name App ID Version Configuration
HackerNews com.emergetools.hackernews 3.8 (1) Release

Android

🔗 App Name App ID Version Configuration
Hacker News com.emergetools.hackernews 1.0.2 (13) Release

⚙️ launchpad-test-android Build Distribution Settings

Comment thread src/launchpad/size/insights/apple/image_optimization.py
Copy link
Copy Markdown
Member

@trevor-e trevor-e left a comment

Choose a reason for hiding this comment

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

  • cursors comment


results: List[OptimizableImageFile] = []
timed_out = False
completed = 0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: is completed helpful here vs len(results)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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]:
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.

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.ts
  • web/src/components/InsightsDisplay.tsx

Did we get this right? 👍 / 👎 to inform future reviews.

@NicoHinderling NicoHinderling merged commit 587004f into main May 8, 2026
22 checks passed
@NicoHinderling NicoHinderling deleted the feat/image-optimization-timeout branch May 8, 2026 21:35
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0259e3a. Configure here.

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