I am using Sidekiq in one of my projects. Now I need to clear a queue,
the RetrySet, to be more specific.
Following this page from Sidekiq's Github manual, this should work:
Loading development environment (Rails 4.2.1)
>> Sidekiq::RetrySet.new.clear
NameError: uninitialized constant Sidekiq::RetrySet
But it doesn't. Sidekiq itself seems to be loaded:
>> Sidekiq
=> Sidekiq
What am I doing wrong here?
EDIT:
Using Sidekiq version 3.3.4
Looks like you need to require the api library explicitly.
require 'sidekiq/api'
See this for more info https://github.com/mperham/sidekiq/issues/1732
See https://github.com/mperham/sidekiq/blob/master/lib/sidekiq/api.rb#L612
The inheritance explaination
class SortedSet
...
def clear
...
end
end
class JobSet < SortedSet
...
end
class RetrySet < JobSet
...
end
However, In my rails console it worked without needing me to require the library. It was already required. see
> require 'sidekiq/api'
=> false
I use Sidekiq 4.0.1
> Sidekiq::VERSION
=> "4.0.1"
Related
For a Rails project I'm working on, I'm having an issue with loading Sidekiq and having nested modules in the lib directory.
my lib/scraper/v2.rb looks like this:
require 'scraper/v2/client'
module Scraper
module V2
end
end
my lib/scraper/v2/client.rb looks like this:
module Scraper
module V2
class Client
def initialize
...
end
end
end
end
I then have a Sidekiq job in the jobs directory that looks like this:
class RefreshTokenJob < ApplicationJob
queue_as :default
def perform
client = Scraper::V2::Client.new
...
end
end
If I run bundle exec sidekiq with this configuration, Sidekiq starts, but running Scraper::V2::Client.new form the Rails console returns:
NameError: uninitialized constant Scraper::V2
If I add config.autoload_paths += %W(#{config.root}/lib) to my application.rb file, I can run Scraper::V2::Client.new, but starting Sidekiq gives me and uninitialized constant error from a completely different file (within app/jobs/concerns/).
Any help with this would be much appreciated!
You must follow Rails' conventions for naming files if you want Rails autoloading to work correctly.
For a module named Scraper::V2, it should be in a file named scraper/v2.rb, not scraper_v2.rb.
I have a rake task test that I setup following the only examples I could find online.
It looks like this:
require 'test_helper'
require 'minitest/mock'
require 'rake'
class TestScrapeWelcome < ActiveSupport::TestCase
def setup
Rake.application.init
Rake.application.load_rakefile
#task = Rake::Task['scrape:scrape']
#task.reenable
end
def teardown
Rake::Task.clear
end
test "scraping text and sending to elasticsearch" do
mocked_client = Minitest::Mock.new
get_fixtures.each_with_index do |arg,i|
mocked_client.expect :index, :return_value, [index: "test", type: 'welcome', id: i, body: arg]
end
Elasticsearch::Model.stub :client, mocked_client do
#task.invoke
end
assert mocked_client.verify
end
private
def get_fixtures
(0..11).map { |i|
File.read("test/fixtures/scrape/index_#{i}.json")
}
end
end
But after the task runs once it starts running again without me doing anything (puts prints before and after #task.invoke show that the task is only run the once).
Turns out that rake is already required and initialized when the test runs so all of the following lines need to be removed or the task gets defined twice and runs twice even if you only invoke it once.
require 'minitest/mock'
require 'rake'
...
Rake.application.init
Rake.application.load_rakefile
Updated answer for rails 5.1 (using minitest):
I found I needed the following to load tasks once and only once:
MyAppName::Application.load_tasks if Rake::Task.tasks.empty?
Alternatively add MyAppName::Application.load_tasks to your test_helper, if you don't mind tasks being loaded even when running individual tests that don't need them.
(Replace MyAppName with your application name)
I've tried #iheggie answer but it worked in a way that indeed tests were run once but any other task was breaking with Don't know how to build task '<task_name_like_db_migrate>'.
I'm on Rails 3.2 still. It turned out that there were couple tasks loaded beforehand so the Rake::Task.tasks.empty? was never true and all other useful tasks were not loaded. I've fiddled with it and this version of it works for me right now:
Rake::Task.clear if Rails.env.test?
MyAppName::Application.load_tasks
Hope this helps anyone.
A solution that works for testing the tasks of a Gem that has been made a Railtie so it can add tasks to the Rails app:
Don't define the Railtie in test mode when you're also defining a Rails::Application class in spec_helper.rb (which allows your tests to call Rails.application.load_tasks). Otherwise the Rake file will be loaded once as a Railtie and once as an Engine:
class Railtie < Rails::Railtie
rake_tasks do
load 'tasks/mygem.rake'
end
end unless Rails.env.test? # Without this condition tasks under test are run twice
Another solution would be to put a condition in the Rake file to skip the task definitions if the file has already been loaded.
I have a problem with sidekiq/activejob integration. I have a controller that calls a perform_later method from a MyJob class. This works with the perform method, but when I change to perfom_later, the job is scheduled in my development log. However, when I see the sidekiq dashboard, at the retries section, I can see NameError: uninitialized constant (look below image)
These are my files:
# app/jobs/crime_job.rb
class CrimeJob < ActiveJob::Base
queue_as :default
def perform(crime)
puts "Perform #{crime}"
end
def self.job_name(crime)
"RadarCrime:#{crime.id}"
end
end
Crime Controller
# app/controllers/crime_controller.rb
def show
# [...]
CrimeJob.perform_later(#crime)
end
Sidekiq initializer
# config/initializers/active_job.rb
Rails.application.config.active_job.queue_adapter = :sidekiq
Well, I also open an issue in Sidekiq repository, and the solution is easier than I've think.
Just restart the sidekiq process and it's works fine.
Issue link: https://github.com/mperham/sidekiq/issues/2207
I wanted to preload the configuration (from ".yml" files). In one of my initializer files (config/initializers/facebook.rb) I have following line of code:
FACEBOOK_CONFIG = YAML.load_file("#{Rails.root}/config/facebook.yml")[Rails.env]
So, it works like a charm in the "DEVELOPMENT" mode. Once I switch to the production mode, it keeps telling me, that FACEBOOK_CONFIG is an uninitialized constant for my "facebook.js.coffee.erb" file, located in assets/javascript (If it matters), if I want to o "rake assets:precompile". I've tried doing random stuff, like: RAILS_ENV=production bundle exec rake assets:precompile or
rake assets:precompile:all
, but no luck
I have tried assigning "initialize_on_precompile = true" variable for my production environment (although, it should be true by default), just in case.
Why it doesn't work in production mode (But, I want to emphasise, that it does work(!) in the development environment).
Can someone help with that one ?
I encountered exactly the same problem. This is because your javascript(coffescript) file makes reference to a constant that is defined in an initializer. Because it is precompiled before the initializer the app throws an error.
This is the simple solution I found. You place this code at the bottom of your application.rb file in config:
module AssetsInitializers
class Railtie < Rails::Railtie
initializer "assets_initializers.initialize_rails",
:group => :assets do |app|
require "#{Rails.root}/config/initializers/facebook.rb"
end
end
end
It manually loads up certain files from the initializer folder. It solved my problem.
Hopefully this was the issue for you as well.
module Rails
class << self
def facebook_config
##facebook_config ||= nil
end
def facebook_config=(facebook_config)
##facebook_config = facebook_config
end
end
end
Rails.facebook_config = YAML.load_file("#{Rails.root}/config/facebook.yml")[Rails.env]
# And you can use it like this in anywhere:
puts Rails.facebook_config
I am using resque in my application for delayed jobs, where i cant send emails & sms to bulk number of users asynchronously. And the data is stored in mongodb, mongoid is the ODM connects rails & mongo.
My mongoid model looks like this
class Item
include Mongoid::Document
include Geo::LocationHelper
field :name, :type => String
field :desc, :type => String
#resque queue name
#queue = :item_notification
#resque perform method
def self.perform(item_id)
#item = Item.find(item_id)
end
end
I can able to add jobs to resque, i have verified using resque-web. Whenever i start an resque-worker
QUEUE=item_notification rake resque:work
i got the uninitialized constant Item , since i am using resque as rails gem and starting rake in rails root, i believe my mongoid models should be loaded.
After digging lot, i found that we can explicitly ask rake to load the environment by
QUEUE=item_notification rake environment resque:work
but now also i got the same error uninitialized constant Item
can someone help me out?
and my
Actually, its a problem in dev environment. after adding this line to into resque.rake task file
# load the Rails app all the time
namespace :resque do
puts "Loading Rails environment for Resque"
task :setup => :environment
ActiveRecord::Base.send(:descendants).each { |klass| klass.columns }
end
it works fine
The code taken from GitHub-Resque-Wiki