Search code examples
ruby-on-railscapistranosidekiq

Load ActiveRecord's data to Capistrano's deploy.rb


I'am using Capistrano for deployment and Sidekiq for queues. I need to load user ids to set :sidekiq_queues variable in deploy.rb file to perform sidekiq queues. Now I use following code

set :sidekiq_queues, ::User.all.map {|u| "-q parsing_user_#{u.id}"}.join(" ") + " -q parsing_user_0"

but it throws following error

./config/deploy.rb:29:in `load': uninitialized constant User (NameError)

I tried to require 'rubygems' and 'active_record' into deploy.rb, but it didn't help. In result I should have sidekiq_queues == "-q parsing_user_1 -q parsing_user_2 -q parsing_user_3 -q parsing_user_4 -q parsing_user_5 -q parsing_user_0". Hardcoding queue names isn't a solution.


Solution

  • Capistrano executes deploy.rb locally, and it doesn't load your Rails environment in deploy.rb.

    It might be more trouble than it is worth. Especially if you want to execute this on your remote server, you might consider doing a Rake task instead. The => :environment in the rake task ensures that your Rails environment is loaded.

    # in deploy.rb
    namespace :sidekiq do
      desc "Do something with queues"
      task :queues, :roles => :web  do
        run "cd #{current_path} ; RAILS_ENV=#{rails_env} bundle exec rake sidekiq:queues"
      end
    end
    
    # you'll need to decide when to execute this in your deployment process, 
    # something like this:
    
    after "deploy:update_code", "sidekiq:queues"
    
    
    
    # in lib/tasks/sidekiq.rake
    namespace :sidekiq do
      desc "Do something with queues"
      task :queues => :environment do
        queues = (User.scoped.pluck(:id) + [0]).map{|id| "-q parsing_user_#{id}"}.join(" ")
        # do what you need to do
      end
    end