From cd6603873a5ba3ba420429cc7f1ab786aba2ff6b Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Fri, 27 Mar 2026 17:31:25 -0500 Subject: [PATCH] fix: update Phoenix.PubSub.Redis configuration for 3.1.0 compatibility (#197) The recent dependency update to phoenix_pubsub_redis 3.1.0 introduced breaking changes in the configuration API. The new version no longer accepts connection options at the top level - they must be nested in :redis_opts. Changes: - Move Redix connection options into :redis_opts keyword list - Keep only :node_name at top level per v3.1.0 requirements - Maintains all resilience settings (timeouts, backoff, keepalive) Before (invalid for v3.1.0): [node_name: node(), host: "...", port: 6379, timeout: 5000, ...] After (valid for v3.1.0): [node_name: node(), redis_opts: [host: "...", port: 6379, timeout: 5000, ...]] This fixes the production crash with error: NimbleOptions.ValidationError: unknown options [:timeout, :backoff_initial, :backoff_max, :exit_on_disconnection, :sync_connect] Related: commit 0399b30d (Update Elixir dependencies) Reviewed-on: https://git.mcintire.me/graham/towerops-web/pulls/197 --- CHANGELOG.txt | 11 +++++++++++ lib/towerops/application.ex | 38 +++++++++++++++++-------------------- priv/static/changelog.txt | 1 + 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 4c5a1aa8..1eb12268 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,14 @@ +2026-03-27 +fix: update Phoenix.PubSub.Redis configuration for 3.1.0 compatibility + - Fixed NimbleOptions.ValidationError crash on production pod startup + - Updated redis_pubsub_config/0 to use new phoenix_pubsub_redis 3.1.0 API structure + - Moved connection options (timeout, backoff_*, exit_on_disconnection, sync_connect, socket_opts) into :redis_opts keyword + - Top-level options now only :node_name and :redis_opts per v3.1.0 requirements + - Caused by recent dependency update to phoenix_pubsub_redis 3.1.0 (commit 0399b30d) + - Breaking change: v3.1.0 changed valid options from [:timeout, :backoff_initial, :backoff_max, :exit_on_disconnection, :sync_connect] + to [:node_name, :redis_pool_size, :compression_level, :redis_opts] + Files: lib/towerops/application.ex (redis_pubsub_config/0) + 2026-03-27 fix: handle alert_changed message in DashboardLive - Fixed FunctionClauseError when DashboardLive receives {:alert_changed, org_id} message diff --git a/lib/towerops/application.ex b/lib/towerops/application.ex index 1cc433a9..c05a076a 100644 --- a/lib/towerops/application.ex +++ b/lib/towerops/application.ex @@ -245,28 +245,12 @@ defmodule Towerops.Application do defp redis_pubsub_config do redis_config = Application.get_env(:towerops, :redis, []) - # Base configuration for Phoenix.PubSub.Redis - base_opts = [ + # Build Redix connection options (phoenix_pubsub_redis 3.1.0+ requires :redis_opts key) + redis_opts = [ host: Keyword.get(redis_config, :host, "localhost"), port: Keyword.get(redis_config, :port, 6379), - node_name: node() - ] - - # Add password if configured (read from application config set by runtime.exs) - base_opts = - case Keyword.get(redis_config, :password) do - nil -> base_opts - "" -> base_opts - password -> Keyword.put(base_opts, :password, password) - end - - # Add resilience options for better reconnection handling - resilience_opts = [ - # Redix connection options for better resilience - socket_opts: [ - # TCP keepalive to detect dead connections - keepalive: true - ], + # TCP keepalive to detect dead connections + socket_opts: [keepalive: true], # Connection timeout (5 seconds) timeout: 5_000, # Backoff settings for reconnection @@ -278,7 +262,19 @@ defmodule Towerops.Application do sync_connect: false ] - Keyword.merge(base_opts, resilience_opts) + # Add password if configured (read from application config set by runtime.exs) + redis_opts = + case Keyword.get(redis_config, :password) do + nil -> redis_opts + "" -> redis_opts + password -> Keyword.put(redis_opts, :password, password) + end + + # Phoenix.PubSub.Redis 3.1.0+ configuration structure + [ + node_name: node(), + redis_opts: redis_opts + ] end # Register file logger backend for development (only available in :dev environment) diff --git a/priv/static/changelog.txt b/priv/static/changelog.txt index 5ed3200c..d487450a 100644 --- a/priv/static/changelog.txt +++ b/priv/static/changelog.txt @@ -1,4 +1,5 @@ 2026-03-27 — Stability Improvements +* Fixed production deployment crash related to real-time messaging infrastructure * Fixed dashboard crashes when alerts change * Improved real-time alert updates reliability