Stream.get_stream() was never called in the preview path of
generate_stream_url(), so the channel_stream and stream_profile
Redis keys were never written. This caused the stream_id to be
missing from channel metadata, which silently broke two things:
- Stats page showed no stream name or logo
- stream_stats were never saved to the database
Fix: replace the manual profile-selection loop in the preview path
with a direct call to Stream.get_stream(), matching the channel path
exactly. This also fixes a pre-existing non-atomic slot reservation
(read-then-check vs INCR-first) that could over-allocate connections
on concurrent previews.
Regression introduced in 49b7b9e2.
All 12 call sites for Channel.release_stream() and Stream.release_stream() now check the boolean return value and log warnings when release fails.
Files updated:
- server.py: 4 call sites (zombie cleanup + _clean_redis_keys)
- channel_service.py: 2 call sites (stop_channel)
- stream_generator.py: 1 call site (last client disconnect)
- views.py: 4 call sites (failed init, redirect, init failure, exception)
- url_utils.py: 1 call site (URL generation error)
Also fixed bare except clause in _clean_redis_keys and uncaught
Stream.DoesNotExist in channel_service.stop_channel.
Based on PR #838 by patchy8736
Fixed four leak paths in the TS proxy streaming initialization:
1. url_utils.py - generate_stream_url(): Wrapped post-get_stream() code in try/except that calls release_stream() on any failure
2. views.py - stream_ts() retry loop: Added release_stream() before returning 503 to clean up the error-checking get_stream() call at line 181 which could INCR without a matching release when the retry loop times out
3. views.py - stream_ts() init failure: Added guarded release_stream() when initialize_channel() returns False, using a connection_allocated flag to prevent incorrect decrements when joining an existing channel
4. views.py - stream_ts() outer except: Added guarded release_stream() as a safety net for unexpected exceptions, only releasing when the flag confirms the slot was allocated and the channel hasn't been initialized yet
The connection_allocated flag prevents double-decrements by tracking whether request flow actually INCR'd the counter (fresh initialization) vs
returned cached results (joining an existing channel on another worker)
- Updated `get_stream` method to return error reasons for better debugging.
- Improved `generate_stream_url` to handle errors and log specific issues.
- Implemented retry mechanism in `stream_ts` view for obtaining streams with exponential backoff.
- Added new configuration options for connection timeout and retry intervals.