Rails 6 while running sidekiq database configuration does not specify adapter

Viewed 969

Recently we started migrating our codebase from rails 5 to rails 6. Everything seems to work fine except sidekiq. Whenever we tried to run sidekiq in production mode it always throws an error database configuration does not specify adapter. I am pretty sure that we have mentioned an adapter in database.yml. Can someone please help to resolve this issue?

For reference

Rails 6.0.3.4

Sidekiq 6.1.2

Ruby 2.7.1p83

databsae.yml file

default: &default
  adapter: postgresql
  pool: <%= ENV['DATABASE_POOL'] %>
  timeout: 5000
  database: anajmandi
  
development:
  primary:
    <<: *default
    url: <%= ENV['DATABASE_URL'] %>
    multidb:
      fallback: true
  follower: 
    <<: *default
    url: <%= ENV['DATABASE_SLAVE_URL'] %>
    replica: true
    multidb:
      fallback: true

test:
  <<: *default
  database: db/test.sqlite3

production:
  primary:
    <<: *default
    url: <%= ENV['DATABASE_URL'] %>
    multidb:
      fallback: true
  follower: 
    <<: *default
    url: <%= ENV['DATABASE_SLAVE_URL'] %>
    replica: true
    multidb:
      fallback: true

and sidekiq.rb file

# typed: strict
if Rails.env.production?
  # three unicorns = 3 connections
  Sidekiq.configure_client do |config|
    config.redis = { :size => 1 }
  end

  Sidekiq.configure_server do |config|
    config.redis = { url: ENV['REDIS_URL'], size: 22 }

    Rails.application.config.after_initialize do
      Rails.logger.info("DB Connection Pool size for Sidekiq Server before disconnect is: #{ActiveRecord::Base.connection.pool.instance_variable_get('@size')}")
      ActiveRecord::Base.connection_pool.disconnect!

      ActiveSupport.on_load(:active_record) do
        config = Rails.application.config.database_configuration[Rails.env]
        config['reaping_frequency'] = ENV['DATABASE_REAP_FREQ'] || 10 # seconds
        config['pool'] = ENV['WORKER_DB_POOL_SIZE'] || Sidekiq.options[:concurrency]
        ActiveRecord::Base.establish_connection(config)

        Rails.logger.info("DB Connection Pool size for Sidekiq Server is now: #{ActiveRecord::Base.connection.pool.instance_variable_get('@size')}")
      end
    end
  end

end

and this is the error stack trace on running command bundle exec sidekiq -e production -C config/sidekiq.yml

DB Connection Pool size for Sidekiq Server before disconnect is: 5
database configuration does not specify adapter
/Users/yadusingla/.rvm/gems/ruby-2.7.1/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/connection_specification.rb:161:in `spec'
/Users/yadusingla/.rvm/gems/ruby-2.7.1/gems/activerecord-6.0.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:1052:in `establish_connection'
/Users/yadusingla/.rvm/gems/ruby-2.7.1/gems/activerecord-6.0.3.4/lib/active_record/connection_handling.rb:51:in `establish_connection'
/Users/yadusingla/.rvm/gems/ruby-2.7.1/gems/activerecord-import-1.0.6/lib/activerecord-import/import.rb:250:in `establish_connection'
/Users/yadusingla/spars/procol-backend/config/initializers/sidekiq.rb:19:in `block (3 levels) in <top (required)>'
/Users/yadusingla/.rvm/gems/ruby-2.7.1/gems/activesupport-6.0.3.4/lib/active_support/lazy_load_hooks.rb:71:in `class_eval'
/Users/yadusingla/.rvm/gems/ruby-2.7.1/gems/activesupport-6.0.3.4/lib/active_support/lazy_load_hooks.rb:71:in `block in execute_hook'
/Users/yadusingla/.rvm/gems/ruby-2.7.1/gems/activesupport-6.0.3.4/lib/active_support/lazy_load_hooks.rb:61:in `with_execution_control'
/Users/yadusingla/.rvm/gems/ruby-2.7.1/gems/activesupport-6.0.3.4/lib/active_support/lazy_load_hooks.rb:66:in `execute_hook'
/Users/yadusingla/.rvm/gems/ruby-2.7.1/gems/activesupport-6.0.3.4/lib/active_support/lazy_load_hooks.rb:43:in `block in on_load'
/Users/yadusingla/.rvm/gems/ruby-2.7.1/gems/activesupport-6.0.3.4/lib/active_support/lazy_load_hooks.rb:42:in `each'
/Users/yadusingla/.rvm/gems/ruby-2.7.1/gems/activesupport-6.0.3.4/lib/active_support/lazy_load_hooks.rb:42:in `on_load'
1 Answers

Here I am using a 3-tier configuration, so for 3 tier configuration initializer isn't correctly defined. If we select configurations by environment variable then we'll get two, both primary and follower. Rails don't know which one to access so the app has to select the right one.

Change config = Rails.application.config.database_configuration[Rails.env] to

self.configurations = Rails.application.config.database_configuration

config = configurations.configs_for(env_name: Rails.env, spec_name: "primary").config

Refer to this link https://github.com/rails/rails/issues/40640

Related