0

I'm working on a Rails app that is using Juggernaut to push data to clients at regular intervals. I use a controller action to get the pushing started; but since the pushing is often a long process (10 minutes or more), I am using spawn to fork the task. For example:

def start_pushing
  spawn_block(:argv => "juggernaut-pushing") do
    for x in y
      Juggernaut.publish(stuff in here)
      sleep(30) # delay before publishing next item
    end
  end
end

The problem is that I find this error in the log file when I hit the start_pushing action:

spawn> Exception in child[27898] - Redis::InheritedError: Tried to use a connection from a child process without reconnecting. You need to reconnect to Redis after forking.

So I added the following right inside the spawn_block, hoping it would fix the problem:

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

It didn't seem to fix it, though the action has been working intermittently even before I added this to reset $redis. I'm thinking that perhaps resetting $redis isn't doing anything; Juggernaut is still accessing an old connection. Does that seem likely? How would I make sure that Juggernaut uses a new Redis connection?

Please let me know of any questions about what I'm describing. I appreciate the help, because I'm stuck right now.

Alex Watt
  • 927
  • 5
  • 14

1 Answers1

0

The problem is using a global (variable that begins with $) and using Passenger. All globals are shared accross ALL passenger processes. Redis has some kind of check to make sure the process ID of the redis call is the same one as the one that connected. So if redis was connected using the passenger worker 1 but then worker 2 uses it, it will give this error.

See the method connect and ensure_connected of the Redis::Client class for more information.

The solution is explained in this issue. Basically, they suggest that you do like memcache as explained here.

In short, in your config/environement.rb, add the following:

if defined?(PhusionPassenger)
    PhusionPassenger.on_event(:starting_worker_process) do |forked|
        if forked
            # We're in smart spawning mode.
            $redis.reconnect
        else
            # We're in conservative spawning mode. We don't need to do anything.
        end
    end
end
roychri
  • 2,866
  • 1
  • 21
  • 29