Here is my code:
after_commit :notify, on: :create
The notify method, calls to ServiceRequestMailerWorker.perform_async(self.id, email) and here is my that mailer looks like:
class ServiceRequestMailerWorker
include Sidekiq::Worker
def perform(service_request_id, send_to)
#service_request = ServiceRequest.find(service_request_id)
#customer = #service_request.customer
WarrantyMailer.submitted(#service_request, #customer, send_to).deliver
end
end
Error:
2014-07-22T03:05:25.626004+00:00 app[worker.1]: 2014-07-22T03:05:25.625Z 2 TID-os0kqm6sg DEBUG: enqueued retry: {"retry":true,"queue":"default","class":"ServiceRequestMailerWorker","args":[787,"email#email.com"],"jid":"f1d8f416718bafa8c809fa3e","enqueued_at":1405998308.4219391,"error_message":"Couldn't find ServiceRequest with 'id'=787 [WHERE (company_id IS NOT NULL)]","error_class":"ActiveRecord::RecordNotFound","failed_at":1405998308.618538,"retry_count":0}
This ONLY happens in my staging environment on Heroku. I have been trying to debug this for hours. Anyone else run into this issue?
Related
My sidekiq worker use get request to get the speech recognition outcome, the response status will be "SUCCESS" or "FAILED" or "RUNNING". when the status is "RUNNING", I want to retry the sidekiq worker in 10 minutes. How can I retry without sleep or raise a exception. Because sleep will consume too much resource and raise exception will leave newrelic error log which I don't want to record.
class GetAsrTextWorker
include Sidekiq::Worker
sidekiq_options :queue => :default, :retry => 5
sidekiq_retry_in do | count|
600 * (count + 1)
end
def perform(task_id):
# get request to get the outcome
if status == "SUCCESSD"
# save the outcome
elsif status == "FAILED"
raise AsrError
elsif status == "RUNNING"
raise "Asr running"
end
rescue AsrError => e
Sidekiq.logger.error e.message
end
end
This method will retry this worker but will lead to ugly error log in newrelic which I don't want to record.
Use the New Relic Ruby agent option error_collector.ignore_errors to ignore the specific exception you are raising:
Define a custom exception you can raise:
# lib/retry_job.rb
class RetryJob < StandardError; end
Define a worker that raises the exception:
# app/workers/foo_worker.rb
class FooWorker
include Sidekiq::Worker
def perform
raise RetryJob
end
end
Ignore that exception with the New Relic agent:
# config/newrelic.yml
common: &default_settings
error_collector:
ignore_errors: "ActionController::RoutingError,Sinatra::NotFound,RetryJob"
My project use rescue to run background job.
I use actioncable in a job to notify user when the job finish. but it not running when use perform_later, but perform_now => it work ok.
My job:
class FetchExternalDataJob < ApplicationJob
queue_as :default
def perform
# logic here
ActionCable.server.broadcast "some_channel", message: "finish job"
end
end
Call job:
class RoomsController < ApplicationController
def show
FetchExternalDataJob.perform_later
end
Channel javascript:
App.fetch_data = App.cable.subscriptions.create "FetchDataChannel",
received: (data) ->
console.log("job finished")
Have you set up redis as your adapter in cable.yml yet?
ei:
development:
adapter: redis
url: redis://localhost:6379/1
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 am a newbie to delayed job but in local the gem is working flawlessly. In production, the gem logs an entry in delayed_jobs table and then within milli-seconds completes it, deletes it without processing.
A critical difference I found was the handler entry created in the database.
Local
--- !ruby/object:Delayed::PerformableMethod
object: !ruby/ActiveRecord:User
attributes:
id: '1'
email: abc#example.com.au
is_pending: pending
method_name: :job_without_delay
args:
- false
Heroku
--- !ruby/object:Delayed::PerformableMethod
attributes:
id: 1
email: abc#example.com.au
is_pending: pending
What is going on? Can any one please assist?
Controller
def make_pending
#user = current_user
#user.job(false)
redirect_to user_path(current_user)
end
User Model
def job(silence)
Project.job(self.id, silence)
end
handle_asynchronously :job, :run_at => Proc.new { 5.minutes.from_now }
Another difference
Local logs
[Worker(host:__.local pid:5179)] Starting job worker
[Worker(host:__.local pid:5179)] User#job_without_delay completed after 417.0975
[Worker(host:__.local pid:5179)] 1 jobs processed at 0.0024 j/s, 0 failed ...
Heroku logs
013-01-14T12:15:37+00:00 app[worker.1]: [Worker(host:19edbbfb-b8b9-4528-bca6-46ecac4e66bc pid:2)] NilClass# completed after 0.0119
2013-01-14T12:15:37+00:00 app[worker.1]: [Worker(host:19edbbfb-b8b9-4528-bca6-46ecac4e66bc pid:2)] 1 jobs processed at 26.9897 j/s, 0 failed ...
Finally found solution
Added a new model dj.rb
class Dj < Struct.new(:uid, :silence)
def perform
......
end
end
I am just beginning to look into using the delayed_job gem.
To test it, I added "delayed" to the welcome email function and changed that call from
UserMailer.welcome_email(self).deliver
to
UserMailer.delay.welcome_email(self)
This is called inside the User model after_create. I see an entry show up in the delayed_job table after the function executes. Now when I run "rake jobs:work" on command line the task starts but gives errors as below
[Worker(host:Sanjay-PC pid:7008)] Starting job worker
[Worker(host:Sanjay-PC pid:7008)] Class#welcome_email failed with NoMethodError: undefined method `welcome_email' for #<Class:0x4871d60> - 0 failed attempts
[Worker(host:Sanjay-PC pid:7008)] 1 jobs processed at 0.0939 j/s, 1 failed ...
Thinking that if I changed the welcome_email method declaration to a Class method as
def self.welcome_email(user)
(added self. in front) that might help. But then when I run rake jobs:work I get the following error
rake aborted!
undefined method `welcome_email' for class `UserMailer'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/activesupport-3.0.5/lib/active_support/core_ext/module/aliasing.rb:31:in `alias_method'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/activesupport-3.0.5/lib/active_support/core_ext/module/aliasing.rb:31:in `alias_method_chain'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/delayed_job-2.1.4/lib/delayed/message_sending.rb:50:in `handle_asynchronously'
c:/mgn/mgn-r3/app/mailers/user_mailer.rb:10:in `<class:UserMailer>'
c:/mgn/mgn-r3/app/mailers/user_mailer.rb:1:in `<top (required)>'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/activesupport-3.0.5/lib/active_support/dependencies.rb:454:in `load'
<Stack truncated>
It seems to now know the class as UserMailer but it somehow doesn't see the class method welcome_email.
I am on Rails 3.0.5, Ruby 1.9.2p180 and the installed delayed_job gem is 2.1.4 - on Windows
Can't seem to find any related answers anywhere.
Thanks for your thoughts.
-S
Adding UserMailer code per #pjammer's request
class UserMailer < ActionMailer::Base
default :from => "from#example.com"
def welcome_email(user)
#user = user
#url = "http://example.com/login"
mail(:to => user.email,
:subject => "Welcome to My Awesome Site")
end
end
Just use this
UserMailer.delay.welcome_email(self).deliver
instead of
UserMailer.welcome_email(self).delay.deliver
My solution was to redefine function at the handler class (for you it's UserMailer class)
def self.taguri
'tag:ruby.yaml.org,2002:class'
end
It's a hack and I'll try to find a better solution but now it works for me.
(Rails 3.0.9, Ruby 1.9.2-p290, delayed_job 2.1.4)
https://groups.google.com/forum/?fromgroups=#!topic/delayed_job/_gvIcbXrOaE solved my handles_asynchronously error for class methods.
As per Brandon Keeper in the link above, the code is the following:
class ClassName
class << self
def foo
end
handle_asynchronously :foo
end
end
then use ClassName.delay.foo