Sidekiq: NoMethodError: undefined method `perform' - ruby-on-rails

Here is what I am trying to do:
2.1.2 :001 > UpdateStyleRanks.perform_async
Here is the error:
NoMethodError: undefined method `perform' for #<UpdateStyleRanks:0x00000002f5e388>
Here is my worker:
# app/workers/update_style_ranks.rb
class UpdateStyleRanks
include Sidekiq::Worker
def perform
end
end

There is no naming requirement for workers. You can do this:
class Foo
include Sidekiq::Worker
def perform; end
end
I suspect you just need to restart Rails/Spring/Zeus to pick up the new class.

How would one restart a heroku dyno running in background?
heroku run:detached bundle exec sidekiq -e production
Would the following commands force sidekiq to pickup new class?
heroku ps:stop run
heroku run:detached bundle exec sidekiq -e production

In current versions of sidekiq (4 and 5) I believe the solution is to call perform_async and not perform.

You should rename you the file to update_style_rank_worker.rb
and the class name to UpdateStyleRankWorker

Related

Rails 5 gem 'delayed_job_active_record' uninitialized constant Job

I have two jobs to run in Production one is always working fine, but other gets stuck sometimes with error
uninitialized constant AppointmentReminderJob\nDid you mean?
AppointmentLog\n/Path/shared/bundle/ruby/2.5.0/gems/activesupport-
5.2.4.1/lib/active_support/inflector/methods.rb:283:in
Started delayed job on Production via RAILS_ENV=production bin/delayed_job restart
In application.rb set config.active_job.queue_adapter = :delayed_job
File name appointment_reminder_job.rb
class AppointmentReminderJob < ApplicationJob
queue_as :default
def perform(appointment, clinic)
# My code here
end
end
Setting Job
AppointmentReminderJob.set(wait_until: Appointment::TIME_LIMIT).perform_later(#appointment, #clinic)
Note: Am not getting this error always but sometimes.

Error "undefined method `to_datetime'" in sidekiq

Start sidekiq with the command
bundle exec sidekiq -e production -P /path/to/pid/file/tmp/pids/sidekiq.pid -L /path/to/log/file/shared/log/sidekiq.log --daemon
In the log error
2017-06-29T06:59:44.776Z 16181 TID-1jr7pg ERROR: CRON JOB: undefined method `to_datetime' for #<EtOrbi::EoTime:0x0000000a933848>
2017-06-29T06:59:44.776Z 16181 TID-1jr7pg ERROR: CRON JOB: /home/user/.rvm/gems/ruby-2.0.0-p247#script-admin/gems/activesupport-3.2.13/lib/active_support/core_ext/date_time/calculations.rb:141:in `<=>'
error while executing the method /home/user/.rvm/gems/ruby-2.0.0-p247#script-admin/gems/activesupport-3.2.13/lib/active_support/core_ext/date_time/calculations.rb:141:in <=>:
def <=> (other)
super other.kind_of?(Infinity) ? other : other.to_datetime
end
What can be done with the problem?
UPD: Updated version rails to 3.2.22.5 and there is a new error
ERROR: CRON JOB: comparison of Time with EtOrbi::EoTime failed
ERROR: CRON JOB: /home/user/.rvm/gems/ruby-2.0.0-p247#script-admin/gems/sidekiq-cron-0.3.1/lib/sidekiq/cron/job.rb:434:in `<'
in this place
def not_enqueued_after?(time)
#last_enqueue_time.nil? || #last_enqueue_time < last_time(time)
end
Your issue arises not from sidekiq but from Rails 3.2.13. #<=> does not handle undefined method to_datetime. It was fixed in future versions of Rails. For example, in the Rails 3.2.22.5:
def <=>(other)
if other.kind_of?(Infinity)
super
elsif other.respond_to? :to_datetime
super other.to_datetime
else
nil
end
end
Therefore, the simplest way to solve your issue is to update your Rails version. If it is not an options paste your code or rewrite #<=>.
to_datetime is a method from rails' activesupport library and your sidekiq worker is not using this.
try adding require 'active_support/core_ext' to your sidekiq initializer config config/initializers/sidekiq.rb and restart sidekiq

How to run rake db:migrate with sidekiq

I am trying to run the command rake db:migrate using a sidekiq worker but it seems like it just won't work and I am curious if there is a way to do this or not. I am creating a scaffold using sidekiq but cannot migrate it afterwards
This works
class ScaffoldGeneratorWorker
include Sidekiq::Worker
def perform(id)
`rails g scaffold test_#{id} title:string body:text slug:string visible:boolean`
end
end
But I cannot get this to run afterwards and work
class DatabaseMigrationWorker
include Sidekiq::Worker
def perform
`rake db:migrate`
end
end
Is this possible, and, if so, how can I get it to work. Any help is greatly appreciated.
First you should load rake tasks, then invoke:
class DatabaseMigrationWorker
include Sidekiq::Worker
def perform
Name_Of_Your_App::Application.load_tasks
Rake::Task['db:migrate'].invoke
end
end
This code automagically loads the Rake tasks for your Rails application without you even knowing how your application is named (this was the case for me). It also makes the code easier to share between various Rails projects.
class MySidekiqTask
include Sidekiq::Worker
def perform
application_name = Rails.application.class.parent_name
application = Object.const_get(application_name)
application::Application.load_tasks
Rake::Task['db:migrate'].invoke
end
end
If you need to invoke the Rake task with parameters, you can simply pass them in through the invoke method (https://www.rubydoc.info/gems/rake/Rake%2FTask:invoke):
Rake::Task['db:migrate'].invoke(params)
Did you try adding require 'rake' at the top of your file?
a possible duplicate of How do I run rake tasks within my rails application

Is it possible to access Models in schedule.rb (whenever gem)?

I am performing some tests in a Ruby on Rails application using Whenever gem.
Is it possible to access Models from the schedule.rb file ?!
For example:
#Hard Worker
job = Job.find_by(name: 'Hard')
if job.status == 'active'
every 4.minutes do
runner 'HardWorker.perform_async'
end
end
Just checked this and I encountered this error:
config/schedule.rb:2:in `initialize': undefined method `find_by' for Whenever::Job:Class (NoMethodError)
Many thanks !

NameError: uninitialized constant MyJob ActiveJob and Sidekiq

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

Resources