fix: prevent StreamedLog stop() from hanging on a silent stream (#825)
## Summary In `StreamedLog` (`src/apify_client/_streamed_log.py`), `stop()` sets `_stop_logging = True` and then `join()`s the streaming thread. The thread is parked inside `iter_bytes()` on a blocking socket read, so the flag isn't observed until the next chunk arrives or the long-polling server-side timeout (~360s) elapses — `stop()` can block for minutes on a quiet actor. Passing a `_read_timeout` (30s) to `_log_client.stream()` caps how long `iter_bytes()` can block, so `stop()` unblocks within that window. The timeout is exposed as a `ClassVar[timedelta]` so it can be tuned (or shortened in tests) without monkeypatching a module global. The loop is also wrapped in `try/finally` so the buffered tail is flushed even if a read times out. Tradeoff: the sync stream now ends if the actor goes silent for more than 30s (vs. the prior 360s). This is documented on the class attribute and is the intended cost of bounded `stop()`. A regression test covers the bug.
V
Vlada Dusek committed
c15cb1bb2702120dd6fabe154a4b3d879248aafa
Parent: e794411
Committed by GitHub <noreply@github.com>
on 5/26/2026, 6:41:59 AM