ruby-on-railsgoogle-cloud-platformsidekiqactioncablegoogle-cloud-memorystore

Ruby on Rails Action Cable + Sidekiq with GCP Memorystore Redis client command not supported


I have set up a rails application in docker using cloud sql in GCP. Im now adding a Memorystore Redis along with Action Cable and also Sidekiq.

GCP Memorystore redis does not support the client command and causes a hard error:

RedisClient::CommandError: ERR unknown command `CLIENT`, with args beginning with: `SETNAME`, `ActionCable-PID-18`

Running things locally in docker compose works without any issues.

It is well documented by Google that Memorystore redis at GCP does not support the client command.

As far as configuration goes the serverless VPC is setup and the image is build using:

vpc-connector=VPC_id 
update-env-vars REDIS_URL=redis://ip:port

Booting the docker image it creates the cloud sql db and starts to seed.

During seeding the error occurs as emails are being send during user creation using action cable/sidekiq.

According to sidekiq git: https://github.com/sidekiq/sidekiq/issues/3518 There is a know work around for this. In my redis initializer i have added:

  Sidekiq.configure_server do |config|
    config.redis = { url: ENV["REDIS_URL"], id: nil }
  end

  Sidekiq.configure_client do |config|
    config.redis = { url: ENV["REDIS_URL"], id: nil  }
  end 

No change in behavior.

Also i don't really think that this is a sidekiq issue as: https://github.com/sidekiq/sidekiq/wiki/Using-Redis clear states that:

If your Redis server supports it, you may instruct Sidekiq to use CLIENT SETNAME when establishing connections. This will make it easier to identify Sidekiq clients when debugging with CLIENT LIST.

config.redis = { id: "Sidekiq-server-PID-#{::Process.pid}" }
This is disabled by default because many SaaS Redis hosts do not support it.

Zooming in on action cable i have found another older SO thread about this issue: Google App Engine + Ruby on rails + Redis + actioncable

I have tried this and this causes the rails application to fail silently in GCP just after bundle is completed.

My cable.yml contains for the environment:

  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
  channel_prefix: my_project
  driver: :ruby
  ssl_params:
    verify_mode: <%= OpenSSL::SSL::VERIFY_NONE %>

Im looking for any input that might help me resolve this issue. Not being able to find a working GCP Memorystore redis + rails guide any where, makes me wonder if this is so obvious that i don't see it or it is a dead end and I should just stop now :)


Solution

  • Faced with the same issue. Added initializer config/initializers/actioncable.rb for solve this:

    # frozen_string_literal: true
    
    require 'action_cable/subscription_adapter/redis'
    
    ActionCable::SubscriptionAdapter::Redis.redis_connector = lambda do |config|
      config[:id] = nil if ENV['REDIS_DISABLE_CLIENT_COMMAND'].present?
      Redis.new(config.except(:adapter, :channel_prefix))
    end
    

    And then use REDIS_DISABLE_CLIENT_COMMAND if need.

    Path to find this solution was:

    1. https://gitlab.com/gitlab-org/gitlab/-/issues/346421
    2. https://github.com/rails/rails/issues/38244
    3. https://github.com/chatwoot/chatwoot/pull/4422/files

    I hope it helps you.