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
Related
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
def process_order
OrderProcess.delay(run_at:1.minutes.from_now).processing_order(params[:id])
redirect_to '/'
end
when process_order is executed
it will execute delayed job
class OrderProcess
def self.processing_order(order_id)
system("rails generate controller welcome index")
end
end
when we remove delay(run_at:1.minutes.from_now) and process_order then rails commands in system command are getting executed but when we run through delayed job rails commands are not getting executed
thanks in advance
What is the best way to test something that requires background jobs with Cucumber? I need to run DelayedJob and Sneakers workers in background while tests are running.
You can run any application in the background:
#pid = Process.spawn "C:/Apps/whatever.exe"
Process.detach(#pid)
And even kill it after tests are done:
Process.kill('KILL', #pid) unless #pid.nil?
You can create your own step definition in features/step_definitions/whatever_steps.rb (hopefully with a better name)
When /^I wait for background jobs to complete$/ do
Delayed::Worker.new.work_off
end
That can be extended for any other scripts you'd like to run with that step. Then in the test, it goes something like:
Then I should see the text "..."
When I wait for background jobs to complete
And I refresh the page
Then I should see the text "..."
If anyone has similar problem I ended up writing this (thanks to Square blog post):
require "timeout"
class CucumberExternalWorker
attr_accessor :worker_pid, :start_command
def initialize(start_command)
raise ArgumentError, "start_command was expected" if start_command.nil?
self.start_command = start_command
end
def start
puts "Trying to start #{start_command}..."
self.worker_pid = fork do
start_child
end
at_exit do
stop_child
end
end
private
def start_child
exec({ "RAILS_ENV" => Rails.env }, start_command)
end
def stop_child
puts "Trying to stop #{start_command}, pid: #{worker_pid}"
# send TERM and wait for exit
Process.kill("TERM", worker_pid)
begin
Timeout.timeout(10) do
Process.waitpid(worker_pid)
puts "Process #{start_command} stopped successfully"
end
rescue Timeout::Error
# Kill process if could not exit in 10 seconds
puts "Sending KILL signal to #{start_command}, pid: #{worker_pid}"
Process.kill("KILL", worker_pid)
end
end
end
This can be called as following (added it to env.rb for cucumber):
# start delayed job
$delayed_job_worker = CucumberExternalWorker.new("rake jobs:work")
$delayed_job_worker.start
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 using resque, and resque-scheduler in my rails application. I am facing strange problem in using resque-scheduler. One of my job is not getting removed from queue, once it finishes with the 'perform' method. I need to kill it explicitly to get out of the queue, then other jobs in the queue starts executing.
Job class is simple, like:
class FooJob
#queue = :high_volume
def self.perform
puts "FooJob#perform:"
# some method call
end
end
And resque_schedule.yml contains:
add_jobs_from_foo:
cron: "15 * * * *"
class: FooJob
description: "enqueue jobs from Foo"
Can it be problem with gem versions? or any other?
Did you actually verify by looking at redis directly? The job gets removed from the queue before perform even starts execution.
lets try this gem "resque-status"
get job status-
status = Resque::Plugins::Status::Hash.get(job_id)
Resque::Plugins::Status::Hash.get(job_id) object gonna returns:
status.pct_complete #=> 0
status.status #=> 'queued'
status.queued? #=> true
status.working? #=> false
status.time #=> Time object
status.message #=> "Created at ..."
get this gem and for details: https://github.com/quirkey/resque-status