Search code examples
ruby-on-railsrubynginxunicorn

RuntimeError: The connection cannot be reused in the forked process (ruby-oci8 gem)


I am getting

RuntimeError: The connection cannot be reused in the forked process

from

ruby-oci8 (2.1.3) lib/oci8/cursor.rb:28:in `__initialize'

I am using oracle db for rails application, recently I started deploying rails application with unicorn and nginx and from their onward I am getting this error please help.

I am using ruby 1.9.3 with rails 3.1 and this is my unicorn.rb file

rails_env = ENV['RAILS_ENV'] || 'production'

worker_processes 6

preload_app true

timeout 75

app_dir     = File.expand_path("../../..", __FILE__)
shared_path = "#{app_dir}/shared"
working_directory "#{app_dir}/current"

# Set up socket location
listen "#{shared_path}/sockets/unicorn.sock", :backlog => 64

# Set master PID location
pid "#{shared_path}/pids/unicorn.pid"

stderr_path "#{shared_path}/log/unicorn.log"
stdout_path "#{shared_path}/log/unicorn.log"

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  # reset the connection since the pre-forked connection will be stale
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  if defined?(ActiveRecord::Base)
    config = ActiveRecord::Base.configurations[Rails.env] ||
            Rails.application.config.database_configuration[Rails.env]
    config['pool'] = ENV['DB_POOL'] || 5
    ActiveRecord::Base.establish_connection(config)
  end
end

Solution

  • I got the solution. Basically my model contains the establish_connection definition like this

    class User < ActiveRecord::Base
      establish_connection "user_#{Rails.env}"
    end
    

    and my unicorn.rb file before_fork block contains the following code.

    defined?(ActiveRecord::Base) and
      ActiveRecord::Base.connection.disconnect!
    

    I found that above code doesn't work when you explicitly write establish_connection in your model. To resolve the issue I had to change the above code to the below one

    defined?(ActiveRecord::Base) &&
      ActiveRecord::Base.remove_connection(User) &&
      ActiveRecord::Base.connection.disconnect!
    

    and it worked like a charm. :-)