Add sentinel support to ActionCable Redis subscription adapter

I’ve been trying to deploy a small, sample Rails 5 app that uses ActionCable to send some real-time updates via WebSockets to the front-end Javascript. It works fine when running locally, or on single node test environments running single-node Redis as well.

When I tried to deploy it on to Kubernetes, however, I ran into a small stumbling block because to deploy Redis on to Kubernetes in a highly available manner it seems the recommended way is through use of Redis Sentinels:

redis-rails already supports sentinels, so use of Redis with sentinels for cache, sessions, etc. is not a problem: https://github.com/redis-store/redis-rails#usage-with-redis-sentinel

However, the ActionCable Redis subscription adapter is configured independently, and when I dived into the code it became apparent that the configuration did not currently support specifying Redis sentinel configuration (even though the underlying redis gem powering both ActionCable and redis-rails already does).

It looks like it should only take a couple of lines of additional code at https://github.com/rails/rails/blob/master/actioncable/lib/action_cable/subscription_adapter/redis.rb#L13 to support an additional sentinels: [...] configuration parameter (if present).

I realize that I could simply supply my own custom lambda to ActionCable::SubscriptionAdapter::Redis.redis_connector in an initializer to support sentinels there, but am wondering if this is something the rest of the community might appreciate. If so, I’ll gladly raise a PR.

Cheers!

  • alistair

Hi Alistair,
This is something that I need, care to share any pointers about how you solved this?

Thanks,

  • Blaed

require ‘action_cable/subscription_adapter/redis’

ActionCable::SubscriptionAdapter::Redis.redis_connector = lambda do |config|
redis_opts = { url: config[:url] }
redis_opts[:sentinels] = config[:sentinels] if config.key?(:sentinels)
::Redis.new(redis_opts)
end

``

Basically, check if an optional “sentinels” key was placed in config/cable.yml, and use that to configure the Redis connector accordingly. For example:

production:
adapter: redis
url: redis://mymaster
sentinels:

  • host: redis-sentinel
    port: 26379

``

Hope this helps!

Hey Alistair,
No problem at all! That was nearly the exact solution I ended up using, so hopefully this is helpful to any other googlers

This is fantastic, thank you both!