mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-05 05:31:31 +02:00
#2705 fixed simultaneous captures colliding on the built-in camera path, keyed by printer IP through capture_camera_frame_bytes(). External cameras reach the same collision through a different function - external_camera.capture_frame() - that #2705 didn't touch, and a V4L2 USB device allows exactly one open handle just like Bambu's own RTSP limit. Nothing coalesced two one-shot capturers here either: Obico polling, the in-print frame bank, the finish-photo moment, plate detection and the notification snapshot could each open their own connection to the same USB camera and collide - is_stream_active() only stops a capturer from competing with an attached viewer, not with another capturer (that's what #2707 fixed). capture_frame() is now a single-flight coalescing wrapper (actual dispatch moved to _capture_frame_uncoalesced), keyed by (url, camera_type, snapshot_url) - snapshot_url is part of the key since #1177's override routes to a completely different endpoint. Mirrors #2705's shape: coalesces, doesn't cache (a call after the previous one finishes always captures fresh); each caller keeps its own timeout via wait_for(shield(...)) rather than inheriting the leader's; a follower whose leader fails takes its own turn instead of inheriting a failure it never had a chance to avoid, bounded at two rounds; cancellation is disambiguated via leader.cancelled() so a follower's own cancellation still propagates while a cancelled leader is treated as a failed one. 12 tests mirroring test_camera_capture_coalescing.py's structure.