Problem
RealVideoProcessor performs its result-cache disk I/O inline inside async def methods. Every call runs blocking filesystem and JSON work directly on the event loop thread, stalling all concurrently-served requests for the duration.
| Method |
Blocking calls (on main) |
_load_from_cache (real_video_processor.py:73-96) |
Path.exists(), Path.stat(), open(), json.load() |
_save_to_cache (real_video_processor.py:98-115) |
open(), json.dump() |
The payloads are full video analyses (metadata + transcript + AI analysis), so json.load/json.dump are not trivial — serialization cost scales with transcript length. _load_from_cache sits on the hot path of every process_video() call, so the stall is paid on both cache hits and misses.
_load_from_cache additionally splits exists() → stat() → open() into three separate filesystem calls, leaving a TOCTOU window where the entry can be evicted between the existence check and the read.
Reachability evidence
Production entrypoint is youtube_extension.main:app (Dockerfile:93 — CMD python -m uvicorn youtube_extension.main:app ...).
main.py:192 app.include_router(api_v1_router)
backend/api/v1/router.py:678 POST endpoint process_video_v1
-> router.py:693 await video_processing_service.process_video_basic(...)
-> services/video_processing_service.py:132 processor = self.get_video_processor()
-> services/video_processing_service.py:84 self.video_processor_factory.create_processor("auto")
-> containers/service_container.py:257 get_video_processor(processor_type)
-> backend/video_processor_factory.py:74 return RealVideoProcessor()
-> services/video_processing_service.py:137 await processor.process_video(video_url)
-> services/real_video_processor.py:145/274 _load_from_cache / _save_to_cache
RealVideoProcessor is selected by video_processor_factory.get_video_processor() in two reachable ways:
- Explicit configuration —
VIDEO_PROCESSOR_TYPE=real (video_processor_factory.py:44-47). This is a supported deployment knob, wired as a container env var in scripts/archive/service.yaml:61.
- Automatic fallback — if constructing
EnhancedVideoProcessor raises, the factory falls through to RealVideoProcessor (video_processor_factory.py:66-74). This is the degraded-mode path, i.e. exactly when the service is already unhealthy and least able to absorb event-loop stalls.
Note: backend/real_api_endpoints.py also calls this processor, but it is not currently mounted by main.py and is therefore excluded from this reachability claim.
Acceptance criteria
Tracking context
- Defect class: blocking disk + JSON I/O executed inline on the asyncio event loop.
- Component:
youtube_extension.backend.services.real_video_processor.
- Reachability: reachable on the
POST /api/v1/process-video path whenever RealVideoProcessor is selected — either explicitly via VIDEO_PROCESSOR_TYPE=real, or as the degraded-mode fallback when EnhancedVideoProcessor fails to construct. RealVideoProcessor is the configured-or-fallback processor, not the default.
- Risk if unfixed: every concurrent request stalls for the duration of the cache read/write; worst impact lands in the fallback path, when the service is already unhealthy.
- Blast radius of the fix: 2 files, no dependency change, no observable behavior change; TOCTOU window narrowed, not eliminated; no schema/format change.
- Current validation: governance,
test, trivy, and coverage are green on fd5a6b2c5918a5a23ebfb5746c88788babbe4238; CodeRabbit review is still queued.
Campaign sequencing
This is item 1 of 10 in a sequenced performance campaign against event-loop-blocking calls in this service. Remaining items target cloud_ai provider image reads, intelligent_cache Redis fan-out, database_optimizer SQLite connects, and deployment_manager subprocess verification.
Problem
RealVideoProcessorperforms its result-cache disk I/O inline insideasync defmethods. Every call runs blocking filesystem and JSON work directly on the event loop thread, stalling all concurrently-served requests for the duration.main)_load_from_cache(real_video_processor.py:73-96)Path.exists(),Path.stat(),open(),json.load()_save_to_cache(real_video_processor.py:98-115)open(),json.dump()The payloads are full video analyses (metadata + transcript + AI analysis), so
json.load/json.dumpare not trivial — serialization cost scales with transcript length._load_from_cachesits on the hot path of everyprocess_video()call, so the stall is paid on both cache hits and misses._load_from_cacheadditionally splitsexists()→stat()→open()into three separate filesystem calls, leaving a TOCTOU window where the entry can be evicted between the existence check and the read.Reachability evidence
Production entrypoint is
youtube_extension.main:app(Dockerfile:93—CMD python -m uvicorn youtube_extension.main:app ...).RealVideoProcessoris selected byvideo_processor_factory.get_video_processor()in two reachable ways:VIDEO_PROCESSOR_TYPE=real(video_processor_factory.py:44-47). This is a supported deployment knob, wired as a container env var inscripts/archive/service.yaml:61.EnhancedVideoProcessorraises, the factory falls through toRealVideoProcessor(video_processor_factory.py:66-74). This is the degraded-mode path, i.e. exactly when the service is already unhealthy and least able to absorb event-loop stalls.Note:
backend/real_api_endpoints.pyalso calls this processor, but it is not currently mounted bymain.pyand is therefore excluded from this reachability claim.Acceptance criteria
_load_from_cacheand_save_to_cacheperform no blocking filesystem or JSON work on the event loop thread.exists/stat/open/json.loadsequence is performed in a single off-loop hop, closing the TOCTOU window.None; missing file →None; entry aged >= 24h →None; corrupt JSON →None(warning logged, no raise); fresh entry → payload withcached=Trueandcache_age_hours._save_to_cachecontinues to stripcached/cache_age_hoursbefore writing.tests/unit/test_real_processors.pypass without modification.ruff check/ruff formatoutput at parity withmainfor the touched files.Tracking context
youtube_extension.backend.services.real_video_processor.POST /api/v1/process-videopath wheneverRealVideoProcessoris selected — either explicitly viaVIDEO_PROCESSOR_TYPE=real, or as the degraded-mode fallback whenEnhancedVideoProcessorfails to construct.RealVideoProcessoris the configured-or-fallback processor, not the default.test,trivy, and coverage are green onfd5a6b2c5918a5a23ebfb5746c88788babbe4238; CodeRabbit review is still queued.Campaign sequencing
This is item 1 of 10 in a sequenced performance campaign against event-loop-blocking calls in this service. Remaining items target
cloud_aiprovider image reads,intelligent_cacheRedis fan-out,database_optimizerSQLite connects, anddeployment_managersubprocess verification.