Google の Cloud Memorystore で Action Cable 6.0 を動かす。

株式会社ジラフ
3 min readOct 15, 2019

--

Cable Action
Photo by Garry Neesam on Unsplash

エンジニアの桂です。

ヒカカク!では Action Cable を運用しているのですが、 Rails 6 へのアップデートの際に例外が発生する事案がありました。その原因と回避策について紹介します。

現象

GCP の Cloud Memorystore を Action Cable の Redis サーバーに設定した状態で ActionCable.server.broadcastすると以下のような例外が発生した。

Redis::CommandErrorERR unknown command 'client'

発生箇所はこちら

原因

Action Cable が Redis.new するとき、自動的に id を設定する。Redis::Clientid が設定されると Redis サーバーに client 命令を発行してその id を設定するが、 Cloud Memorystore は client 命令に対応していない

回避策

エラー発生箇所のコードから、 Redis.new の際、 idnil 渡してやると client 命令を発行せずに済むことが分かります。

Action Cable 曰く、

Overwrite this factory method for Redis connections if you want to use a different Redis library than the redis gem.

ということなので、ちょっと目的は違いますが、この値をパッチしてやります。

# config/initializers/action_cable.rbrequire 'action_cable/subscription_adapter/redis'ActionCable::SubscriptionAdapter::Redis.redis_connector = ->(config) do
config[:id] = "ActionCable-PID-#{$$}" unless config.has_key?(:id)
::Redis.new(config.except(:adapter, :channel_prefix))
end

これで config/cable.yml から id: null を渡してやることができるようになり、 client 命令を回避することができました。

# config/cable.ymlproduction:
adapter: redis
url: <%= "redis://#{ENV['REDIS_HOST']}:6379/0" %>
id: null

コントリビューションはじめました

id を明示的に null に指定しても強制的に上書きされるのは一先ずよくない挙動だということで、 Rails に PR を出しておきました

仲間募集してます

--

--