diff --git a/apps/proxy/live_proxy/server.py b/apps/proxy/live_proxy/server.py index 08a029e3..ecc6bb75 100644 --- a/apps/proxy/live_proxy/server.py +++ b/apps/proxy/live_proxy/server.py @@ -184,6 +184,7 @@ class ProxyServer: redis_db = int(os.environ.get("REDIS_DB", getattr(settings, 'REDIS_DB', 0))) redis_password = os.environ.get("REDIS_PASSWORD", getattr(settings, 'REDIS_PASSWORD', '')) redis_user = os.environ.get("REDIS_USER", getattr(settings, 'REDIS_USER', '')) + redis_url = getattr(settings, "REDIS_URL", "") ssl_params = getattr(settings, 'REDIS_SSL_PARAMS', {}) pubsub_client = redis.Redis( @@ -198,6 +199,14 @@ class ProxyServer: health_check_interval=30, decode_responses=True, **ssl_params + ) if not redis_url else redis.Redis.from_url( + redis_url, + socket_timeout=60, + socket_connect_timeout=10, + socket_keepalive=True, + health_check_interval=30, + decode_responses=True, + **ssl_params ) logger.info("Created fallback Redis PubSub client for event listener") diff --git a/apps/proxy/vod_proxy/views.py b/apps/proxy/vod_proxy/views.py index 6e570e81..783370a7 100644 --- a/apps/proxy/vod_proxy/views.py +++ b/apps/proxy/vod_proxy/views.py @@ -802,6 +802,7 @@ def head_vod(request, content_type, content_id, session_id=None, profile_id=None redis_db = int(getattr(settings, 'REDIS_DB', 0)) redis_password = getattr(settings, 'REDIS_PASSWORD', '') redis_user = getattr(settings, 'REDIS_USER', '') + redis_url = getattr(settings, "REDIS_URL", "") ssl_params = getattr(settings, 'REDIS_SSL_PARAMS', {}) r = redis.StrictRedis( host=redis_host, @@ -811,6 +812,10 @@ def head_vod(request, content_type, content_id, session_id=None, profile_id=None username=redis_user if redis_user else None, decode_responses=True, **ssl_params + ) if not redis_url else redis.StrictRedis.from_url( + redis_url, + decode_responses=True, + **ssl_params ) content_length_key = f"vod_content_length:{session_id}" r.set(content_length_key, total_size, ex=1800) # Store for 30 minutes diff --git a/core/utils.py b/core/utils.py index c167e6b9..ea6bd20f 100644 --- a/core/utils.py +++ b/core/utils.py @@ -127,6 +127,7 @@ class RedisClient: redis_db = int(os.environ.get("REDIS_DB", getattr(settings, 'REDIS_DB', 0))) redis_password = os.environ.get("REDIS_PASSWORD", getattr(settings, 'REDIS_PASSWORD', '')) redis_user = os.environ.get("REDIS_USER", getattr(settings, 'REDIS_USER', '')) + redis_url = getattr(settings, "REDIS_URL", "") # Use standardized settings socket_timeout = getattr(settings, 'REDIS_SOCKET_TIMEOUT', 5) @@ -152,6 +153,15 @@ class RedisClient: retry_on_timeout=retry_on_timeout, decode_responses=decode_responses, **ssl_params + ) if not redis_url else redis.Redis.from_url( + redis_url, + socket_timeout=socket_timeout, + socket_connect_timeout=socket_connect_timeout, + socket_keepalive=socket_keepalive, + health_check_interval=health_check_interval, + retry_on_timeout=retry_on_timeout, + decode_responses=decode_responses, + **ssl_params ) # Validate connection with ping @@ -236,6 +246,7 @@ class RedisClient: redis_db = int(os.environ.get("REDIS_DB", getattr(settings, 'REDIS_DB', 0))) redis_password = os.environ.get("REDIS_PASSWORD", getattr(settings, 'REDIS_PASSWORD', '')) redis_user = os.environ.get("REDIS_USER", getattr(settings, 'REDIS_USER', '')) + redis_url = getattr(settings, "REDIS_URL", "") # Use standardized settings but without socket timeouts for PubSub # Important: socket_timeout is None for PubSub operations @@ -260,6 +271,15 @@ class RedisClient: retry_on_timeout=retry_on_timeout, decode_responses=True, **ssl_params + ) if not redis_url else redis.Redis.from_url( + redis_url, + socket_timeout=None, # Critical: No timeout for PubSub operations + socket_connect_timeout=socket_connect_timeout, + socket_keepalive=socket_keepalive, + health_check_interval=health_check_interval, + retry_on_timeout=retry_on_timeout, + decode_responses=True, + **ssl_params ) # Validate connection with ping diff --git a/core/views.py b/core/views.py index aafd0f69..24a2338f 100644 --- a/core/views.py +++ b/core/views.py @@ -42,6 +42,7 @@ def stream_view(request, channel_uuid): redis_db = int(getattr(settings, "REDIS_DB", "0")) redis_password = getattr(settings, "REDIS_PASSWORD", "") redis_user = getattr(settings, "REDIS_USER", "") + redis_url = getattr(settings, "REDIS_URL", "") ssl_params = getattr(settings, "REDIS_SSL_PARAMS", {}) redis_client = redis.Redis( host=redis_host, @@ -50,6 +51,9 @@ def stream_view(request, channel_uuid): password=redis_password if redis_password else None, username=redis_user if redis_user else None, **ssl_params + ) if not redis_url else redis.Redis.from_url( + redis_url, + **ssl_params ) # Retrieve the channel by the provided stream_id. diff --git a/dispatcharr/persistent_lock.py b/dispatcharr/persistent_lock.py index 45625857..8bdc2daf 100644 --- a/dispatcharr/persistent_lock.py +++ b/dispatcharr/persistent_lock.py @@ -81,6 +81,8 @@ if __name__ == "__main__": redis_db = int(os.environ.get("REDIS_DB", 0)) redis_password = os.environ.get("REDIS_PASSWORD", "") redis_user = os.environ.get("REDIS_USER", "") + redis_url = os.environ.get("REDIS_URL", "") + ssl_kwargs = {} if os.environ.get("REDIS_SSL", "false").lower() == "true": import ssl as _ssl @@ -108,6 +110,9 @@ if __name__ == "__main__": password=redis_password if redis_password else None, username=redis_user if redis_user else None, **ssl_kwargs + ) if not redis_url else redis.Redis.from_url( + redis_url, + **ssl_kwargs ) lock = PersistentLock(client, "lock:example_account", lock_timeout=120) diff --git a/dispatcharr/settings.py b/dispatcharr/settings.py index 5b8de973..2afc25dd 100644 --- a/dispatcharr/settings.py +++ b/dispatcharr/settings.py @@ -175,7 +175,7 @@ if REDIS_PASSWORD: else: _redis_auth = "" -_channels_redis_url = f"{_redis_scheme}://{_redis_auth}{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}" +_channels_redis_url = os.environ.get("REDIS_URL", f"{_redis_scheme}://{_redis_auth}{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}") # channels_redis accepts either a URL string or a dict with "address" + kwargs. # When TLS is enabled, pass SSL params alongside the URL so the connection pool # uses the correct CA cert and verification settings. @@ -335,7 +335,7 @@ STATICFILES_DIRS = [ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" AUTH_USER_MODEL = "accounts.User" -_default_redis_url = f"{_redis_scheme}://{_redis_auth}{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}" +_default_redis_url = os.environ.get("REDIS_URL", f"{_redis_scheme}://{_redis_auth}{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}") # Celery/Kombu require SSL parameters in the URL query string because # internal URL parsing can overwrite the CELERY_BROKER_USE_SSL dict. if REDIS_SSL: