Unable to run delayed job at specific time - ruby-on-rails

I have a job file and I am using delayed_job driver for rails.
It works fine for perform later.
My job file:
jobs/test_job_job.rb
class TestJobJob < ActiveJob::Base
queue_as :default
def perform(*args)
puts("test")
end
def test_method
puts('test method')
end
end
In my controller, I did,
TestJobJob.perform_later
It worked fine and gave me right output:
Output:
[Worker(host:hunter pid:8079)] Job ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper (id=18) RUNNING
test
[Worker(host:hunter pid:8079)] Job ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper (id=18) COMPLETED after 0.0397
[Worker(host:hunter pid:8079)] 1 jobs processed at 1.3259 j/s, 0 failed
But when I changed to,
TestJobJob.delay(run_at: 2.minutes.from_now)
Job was not even en-queued, and when I did,
TestJobJob.delay(run_at: 2.minutes.from_now).test_method
It gave me error: undefined method `test_method' for TestJobJob
My config:application.rb
config.active_job.queue_adapter = :delayed_job

Related

Is it possible to reset the timeout of a delayed job in rails?

I have a delayed job that run a few steps. I would like to reset the timeout whenever a step is completed.
Is it possible?
For example
# config/initializers/delayed_job_config.rb
Delayed::Worker.max_run_time = 5.minutes
# app/jobs/my_process_job.rb
class MyProcessJob < ApplicationJob
def perform
`sleep 4m` # step 1
# reset timeout
`sleep 4m` # step 2
puts 'done'
end
end
Looking at how timeouts are implemented in Delayed Job, it's not possible to reset the timeout without modifying Delayed Job. However, you could do the following instead
# config/initializers/delayed_job_config.rb
Delayed::Worker.max_run_time = 10.minutes
# app/jobs/my_process_job.rb
class MyProcessJob < ApplicationJob
def perform
Timeout.timeout(5.minutes.to_i) {
`sleep 4m` # step 1
}
Timeout.timeout(5.minutes.to_i) {
`sleep 4m` # step 2
}
puts 'done'
end
end

Rails delayed job runs twice

I added the delayed_job gem and I created a simple ActiveJob. I am inserting record to the DB after my job run. When I check the table I am seeing 2 records. And I am seeing the following lines in my console.
[Worker(host:k pid:4962)] Job SimpleJob (id=9305) (queue=Default) RUNNING
[Worker(host:k pid:4962)] Job SimpleJob (id=9305) (queue=Default) COMPLETED after 0.7371
[Worker(host:k pid:4962)] Job ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper (id=9306) (queue=Default) RUNNING
[Worker(host:k pid:4962)] Job ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper (id=9306) (queue=Default) COMPLETED after 0.5055
[Worker(host:k pid:4962)] 2 jobs processed at 1.5728 j/s, 0 failed
Why is my job running twice? How can I fix that?
Edit: The following code is my ActiveJob code. I added a SimpleJob.schedule! line in config/initializers/job_initializars.rb for first start.
class SimpleJob < ActiveJob::Base
include Delayed::RecurringJob
run_every 1.minute
queue 'Default'
def perform
begin
Vehicle.where(number_plate: lo."12345" ).update_all(:longitude => "47", :latitude => "33")
rescue => ex
Delayed::Worker.logger.info "---------------->" + ex.message
end
end
end

ActiveJob queue adapter ignored?

user_controller.rb
class UsersController
def create
MyJob.perform_later
User.create(...)
end
end
my_job.rb
class MyJob < ActiveJob::Base
queue_as :default
def perform()
puts "START"
sleep 3
puts "END"
end
end
config/initializer/sucker_punch.rb
require 'sucker_punch/async_syntax'
Rails.application.configure do
config.active_job.queue_adapter = :sucker_punch
end
When I run MyJob.perform_laterin a rails console, everything work fine and the logger display this message Enqueued MyJob (Job ID: 6c857af8-a8ed-4bd0-918b-4296c4315727) to SuckerPunch(default)
However, when I send an http request to my user_controller, I don't receive any response before 3 seconds (which make me think that the job is not executed asynchronously), and the logger display this Enqueued MyJob (Job ID: e3d698eb-00d8-4849-9496-f01c53fc7217) to Inline(default)
It seems to use the inline (default?) adapter in controllers, which is not asynchronous.
ps : I'm using puma as http server, and using sucker_punch without ActiveJob works fine

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

DelayedJob gem behaving different in local and on heroku

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

Resources