You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
BaseCloudAI.analyze_image is implemented by three providers. #1205 moved the AWS implementation's local-file read off the event loop. The Azure and Google implementations still call blocking open(...).read() directly inside async def, so the calling task holds the event loop for the entire duration of a synchronous disk read.
Both sites are on the local file branch only; the http:///https:// branches hand the URL to the SDK and are unaffected.
While the loop is blocked, every other coroutine in the process is stalled — not just the caller. On a cold page cache, a network filesystem, or a large frame dump, a single read can stall the loop for tens to hundreds of milliseconds.
Reachability evidence
Reported honestly, because it constrains the claim this issue can make:
analyze_image is not currently reachable from an HTTP route. cloud_ai_routes.py is mounted in main.py:173 but exposes only /analyze/video, /analyze/batch, and /analyze/multi-provider. There is no image endpoint.
grep -rn "analyze_image" src/ returns only the three provider definitions plus the abstract declaration in base.py:108. There are no in-tree callers.
Therefore this is a library-surface defect on a public, abstract-contract method, not a live production hot path. No production latency claim is made.
What does justify the change:
analyze_image is part of the BaseCloudAI public contract (base.py:108), so it is callable by any consumer of the integration package.
perf(cloud-ai): run AWS Rekognition boto3 calls off the event loop #1205 already established that this exact defect, in this exact method, is worth fixing — it was merged for AWSRekognition. Leaving two of three implementations blocking makes the contract inconsistent: identical calls have different event-loop safety depending on which provider is configured.
The fix is mechanical, has a merged in-repo precedent to copy, and carries no behavioural change.
Acceptance criteria
Azure and Google local-file reads execute in a worker thread, not on the event loop.
Returned bytes are byte-for-byte identical to today for the same input.
The http/https branches are untouched.
Regression tests prove the read runs on a non-loop thread, asserted by thread identity rather than wall-clock timing.
Existing TestAzureVisionPrepareImageInput and TestGoogleCloudAIAnalyzeImage tests pass unmodified.
No new dependencies.
Proposed fix
Reuse the pattern merged in #1205 (aws_rekognition.py:109-112, :487): a module-level _read_file_bytes(path) -> bytes helper invoked via await asyncio.to_thread(...).
Problem
BaseCloudAI.analyze_imageis implemented by three providers. #1205 moved the AWS implementation's local-file read off the event loop. The Azure and Google implementations still call blockingopen(...).read()directly insideasync def, so the calling task holds the event loop for the entire duration of a synchronous disk read.AzureVision._prepare_image_inputsrc/youtube_extension/integrations/cloud_ai/providers/azure_vision.pyopen(image_url, 'rb').read()GoogleCloudAI.analyze_imagesrc/youtube_extension/integrations/cloud_ai/providers/google_cloud.pyopen(image_url, 'rb').read()Both sites are on the local file branch only; the
http:///https://branches hand the URL to the SDK and are unaffected.While the loop is blocked, every other coroutine in the process is stalled — not just the caller. On a cold page cache, a network filesystem, or a large frame dump, a single read can stall the loop for tens to hundreds of milliseconds.
Reachability evidence
Reported honestly, because it constrains the claim this issue can make:
analyze_imageis not currently reachable from an HTTP route.cloud_ai_routes.pyis mounted inmain.py:173but exposes only/analyze/video,/analyze/batch, and/analyze/multi-provider. There is no image endpoint.grep -rn "analyze_image" src/returns only the three provider definitions plus the abstract declaration inbase.py:108. There are no in-tree callers.What does justify the change:
analyze_imageis part of theBaseCloudAIpublic contract (base.py:108), so it is callable by any consumer of the integration package.AWSRekognition. Leaving two of three implementations blocking makes the contract inconsistent: identical calls have different event-loop safety depending on which provider is configured.Acceptance criteria
http/httpsbranches are untouched.TestAzureVisionPrepareImageInputandTestGoogleCloudAIAnalyzeImagetests pass unmodified.Proposed fix
Reuse the pattern merged in #1205 (
aws_rekognition.py:109-112,:487): a module-level_read_file_bytes(path) -> byteshelper invoked viaawait asyncio.to_thread(...).