I am using sidekiq to run a background job. Sidekiq uses Redis to store all of its job and operational data. Recently I faced an issue with multiple sidekiq daemons when we run more than one sidekiq daemon on the same machine.
Start Sidekiq
To start sidekiq process, goto your project root and run the following command on your terminal.
bundle exec sidekiq -d -L log/sidekiq.log -C config/sidekiq.yml -e production
# -d option to make the sidekiq to start as daemon i,e it will be running even after the terminal is being closed, -L option to set the log file path, -C option to set the sidekiq configuration file path, -e option to set the environment.
What will happen when we host two rails application on the same ubuntu machine and then start sidekiq using the above command.
Sidekiq will start where you can check the running instance of sidekiq by using the below command,
To Check Sidekiq Process
ps -ef | grep sidekiq
Well! the Sidekiq have started on both the projects and started running on different ports. But what will happen when any one of the sidekiq worker process stopped (due to low memory issue or it may be an exception). It is obvious that, the multiple sidekiq daemon conflicting with each other and background processing start breaking.
we may see(http://WEB_URL/sidekiq) the following an exceptions which may be unrelated to our rails mailer class or method name.
1. NoMethodError: undefined method ‘xxxx’ for XxxMailer:Class
2. ArgumentError: wrong number of arguments(given 3, expected 2)
3. ArgumentError: undefined class/module XxxxMailer
Then, I came to know about the namespace used in redis database.
To fix the sidekiq conflict issue
We need to configure sidekiq to use the same redis server available locally, but make them to use different database and also separate them with namespace.
Create a new file in rails application
# config/initializers/sidekiq.rb
require 'sidekiq'
Sidekiq.configure_server do |config|
config.redis = { :namespace => 'project1', :url => 'redis://localhost:6379/1' }
end
Sidekiq.configure_client do |config|
config.redis = { :namespace => 'project1', :url => 'redis://localhost:6379/1' }
end
So the project1 will use database 1 of the redis server at redis://localhost:6379.
Create a similar sidekiq.rb file in the other project and then restart the sidekiq on both the projects and you can see that everything works fine 🙂
Happy Coding 🙂