3
votes

I am using Redis with my Rails app. I have sidekiq gem installed too. My redis server runs in the same machine in default port.

I created a initializer which initalizes a redis lient.

config/initializers/redis.rb

$redis = Redis.new(:host => 'localhost', :port => 6379)

I have another initalizer that sets the number of accounts currently active in the system.

config/initializers/z_account_list.rb

$redis.set('accounts',Account.count);

In one of my views i am using this piece of code.

<div class="more-text">and <%= "#{$redis.get('accounts')}" %> more...</div>

When i set the value for accounts manually in redis without using the initializer, everything works fine. But when i add the initializer, i get

ActionView::Template::Error (Tried to use a connection from a child process without reconnecting. You need to reconnect to Redis after forking.):

I searched for the error. But most solutions are for resque and has something to do with after_fork. Since i am new to Rails and Redis and since i am not using Resque i am getting a little confused. Please help me out on this.

1
What ruby web server are you using? Unicorn or other web servers that fork child processes of a master process will need to be configured to reconnect Redis, and likely any other database/socket/etc connection your app uses after forking. The unicorn docs, or whatever server you are using, will have info on how to configure what is done before/after fork. Should be as simple as reconnecting in the config's after_fork block.Carl Zulauf
I am using pushion passenger web server.Anirudhan J

1 Answers

9
votes

In forked environments like pushion passenger, we have to reconnect to redis whenever a worker is forked. My biggest confusion was where to put the reconnection statements. In many blogs it was suggested to put it in config/environments.rb. But it didn't work for me.

I added

if defined?(PhusionPassenger)
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
    if forked
      $redis.client.disconnect
      $redis = Redis.new(:host => 'localhost', :port => 6379)
      Rails.logger.info "Reconnecting to redis"
    else
      # We're in conservative spawning mode. We don't need to do anything.
    end
  end
end

to config/initializers/redis.rb and everything started working fine.