diff --git a/lib/sidekiq.rb b/lib/sidekiq.rb index 0761c2984b..76113a66d4 100644 --- a/lib/sidekiq.rb +++ b/lib/sidekiq.rb @@ -103,6 +103,7 @@ def self.redis # to disconnect and reopen the socket to get back to the primary. # 4495 Use the same logic if we have a "Not enough replicas" error from the primary # 4985 Use the same logic when a blocking command is force-unblocked + # The same retry logic is also used in client.rb if retryable && ex.message =~ /READONLY|NOREPLICAS|UNBLOCKED/ conn.disconnect! retryable = false diff --git a/lib/sidekiq/client.rb b/lib/sidekiq/client.rb index 9a79ba22f4..1b8a75eb9d 100644 --- a/lib/sidekiq/client.rb +++ b/lib/sidekiq/client.rb @@ -189,8 +189,23 @@ def enqueue_in(interval, klass, *args) def raw_push(payloads) @redis_pool.with do |conn| - conn.pipelined do |pipeline| - atomic_push(pipeline, payloads) + retryable = true + begin + conn.pipelined do + atomic_push(conn, payloads) + end + rescue Redis::BaseError => ex + # 2550 Failover can cause the server to become a replica, need + # to disconnect and reopen the socket to get back to the primary. + # 4495 Use the same logic if we have a "Not enough replicas" error from the primary + # 4985 Use the same logic when a blocking command is force-unblocked + # The retry logic is copied from sidekiq.rb + if retryable && ex.message =~ /READONLY|NOREPLICAS|UNBLOCKED/ + conn.disconnect! + retryable = false + retry + end + raise end end true