Commit graph

14 commits

Author SHA1 Message Date
SergeantPanda
a90872079b Enhancement: Update session management details and improve stream limit handling in timeshift proxy. Enhance tests for decisive account failover and session probe logic. 2026-07-06 19:49:19 -05:00
SergeantPanda
ca3d0eb9e1 feat(timeshift): Implement session-based media ID handling and improve stream limit checks for timeshift proxy. Enhance session management by allowing distinct client/session identification for timeshift requests, ensuring better resource allocation and user experience. Update tests to validate new session handling logic. 2026-06-26 17:36:23 -05:00
SergeantPanda
9e941c7011 refactor(proxy): Consolidate MPEG-TS sync detection logic into utils.py and streamline comments in timeshift views. Update network access checks for consistency across XC API endpoints. Enhance clarity in timeshift proxy documentation and tests. 2026-06-26 12:53:22 -05:00
Cédric Marcoux
2909c9b339 chore(timeshift): pre-review hardening and dead-code cleanup
- http_streamer.py: restore HTTPStreamReader to its upstream form and keep
  only the find_ts_sync() addition. The response=/extra_headers=/
  strip_ts_preamble= extensions had no remaining callers since the timeshift
  view moved to direct iter_content streaming (delta shrinks from +235/-83
  lines to +28).
- Unify the catchup_days semantics everywhere: a channel's archive depth is
  MAX(catchup_days) over its CATCH-UP streams only. The SQL rollup now uses
  a FILTER (WHERE s.is_catchup) aggregate and the ChannelStream signal uses
  the same MAX aggregation (it previously took the first stream by order,
  and the rollup aggregated over all streams including non-catchup ones).
- Migration backfill: also accept the lowercase 'true' that ->> extraction
  yields for JSON booleans.
- get_channel_catchup_info(): drop the tv_archive_duration key — its only
  caller never used it.
- Document why timeshift termination fails closed when Redis is unavailable
  (denying the new stream is what protects the provider connection limit),
  and update the stale stop-key comment (5 s cadence, not 100 chunks).
2026-06-10 22:05:01 +02:00
Cédric Marcoux
3b8717c4ce fix: timeshift stream management, channel resolution, and streaming throughput
- Channel resolution: resolve by Channel.id first (what the XC API emits
  to clients), fall back to provider stream_id for backward compatibility.
  Fixes 404 on all timeshift requests from XC clients.

- Stream management: timeshift is now a first-class citizen alongside live
  and VOD in the stream-limits system.  get_user_active_connections()
  detects type='timeshift', attempt_stream_termination() sets a Redis
  stop key (same pattern as VOD), and the timeshift view calls
  check_user_stream_limits() before connecting upstream.  The stream
  generator checks the stop key every 100 chunks.  Fixes infinite retry
  loops on max_connections=1 providers for live→timeshift and
  timeshift→timeshift transitions.

- Streaming: replaced HTTPStreamReader thread+pipe with direct
  iter_content+yield (same pattern as VOD proxy).  The pipe approach
  deadlocked under gevent because the reader thread's select() competed
  with the greenlet's pipe read for hub scheduling.  Throughput went
  from ~74 B/s to 13+ MB/s.

- TS preamble: peek now strips pre-sync bytes (PHP warnings, BOM) before
  prepending to the stream, preventing corrupt TS output.

- Credential safety: _redact_url() now truncates to scheme://host/...
  to avoid leaking XC path-based credentials in logs.

- Tests: updated 5 tests that referenced the removed HTTPStreamReader.
  21/21 timeshift tests pass.

- Migration: fixed SyntaxWarning for unescaped regex in 0038.
2026-05-27 23:32:57 +02:00
Jonathan Caicedo
6787e4912f refactor: replace multiple hget calls with hmget where fields are known
- channel_status.py: fold output_format and output_profile_id into the
  existing hmget, reducing per-client Redis calls from 3 to 1
- utils.py: collapse 2x and 3x hget per key in scan_iter loops
  (get_user_active_connections) to single hmget calls
- views.py: replace 3x hget on channel metadata in the worker-join path
  of stream_ts with a single hmget
2026-05-20 22:12:12 -04:00
SergeantPanda
dc649ffd88 Enhancement: Initial fmp4 support and major ts_proxy refactor 2026-05-08 17:46:47 -05:00
SergeantPanda
37922a44ab Enhancement: Update user connection reporting in xc_get_info to reflect active connections and max connections based on user stream limits. (Fixes #990)
Some checks are pending
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-04-30 20:33:30 -05:00
SergeantPanda
7964b2c2cb fix: enhance stream termination logic to handle multiple connections on the same channel 2026-03-26 20:33:03 -05:00
SergeantPanda
46d4063524 fix: change logging level from info to debug in user connection checks 2026-03-26 20:10:03 -05:00
SergeantPanda
aa6fb033d3 fix: update user stream limit checks to include media_id and rename user_limits_settings key 2026-03-26 20:02:54 -05:00
SergeantPanda
58befaa52b fix: correct indentation in check_user_stream_limits function 2026-03-26 19:14:46 -05:00
SergeantPanda
b671a72707 fix: resolve decode_responses migration bugs and user-limit regressions
Fix a wave of bugs introduced by the user-priority branch's migration
from manual .decode('utf-8') calls to decode_responses=True on the
metadata Redis client:

core/utils.py
- Rewrite _init_client: fix SyntaxError at line 138, missing
  redis_password/redis_user params, cls._client corruption when
  decode_responses=False was requested, and dead retry backoff logic

apps/proxy/utils.py
- Fix get_user_limit_settings() → get_user_limits_settings() (2 sites)
- Fix VOD scan key vod_persistent_connections:* → vod_persistent_connection:*
- Fix undefined channel_id in VOD loop (use content_uuid from Redis hash)
- Remove leftover print(active_connections) debug statement
- Refactor manual cursor SCAN while-loops to scan_iter()

apps/channels/tasks.py
- Fix closure bug in _d(): md.get(key) → md.get(bkey) (was reading
  the outer loop variable instead of the local bytes key)

apps/proxy/ts_proxy/server.py
- Replace stale b'init_time', b'total_bytes', b'state' byte-string
  key lookups and .decode() calls with plain string equivalents

apps/proxy/ts_proxy/services/channel_service.py
- Fix ChannelMetadataField.STATE.encode() / .OWNER.encode() →
  .STATE / .OWNER (pre-existing, broke under decoded client)

apps/proxy/ts_proxy/views.py
- Fix ChannelMetadataField.OWNER.encode("utf-8") → .OWNER

apps/proxy/ts_proxy/client_manager.py
- Fix cid.decode('utf-8') in remove_ghost_clients(): smembers()
  already returns str with decode_responses=True
2026-03-26 18:41:42 -05:00
dekzter
a19be96ced fleshed out user limits and termination logic 2026-03-25 17:33:26 -04:00