List of scheduled Active Job in rails - ruby-on-rails

How i can see the list scheduled or pending active job in rails 5.2.
I have Scheduled a job after 10min to send a email but user resend it again and again so i need to see that is job scheduled is executed or not.
My Job look like this
class GenerateTemplatePreviewJob < ApplicationJob
queue_as :default
def perform(*args)
# Do something later
end
end
I Have Called The job from Model
after_save ->{
GenerateTemplatePreviewJob.set(wait_until:
10.second.after).perform_later(self.template.id.to_s)
}

Related

sidekiq perform_in perform_at is not working

I am using Sidekiq
on my gemfile I have:
#gemfile
gem 'sidekiq', '~> 6.0.7'
Now my model looks like
class Special < ActiveRecord::Base
def set_queue
if send_at.present? # send at is a data time
SpecialQueueClientsJob.perform_at(self.send_at, self)
end
end
end
This is the code to my job and this works perfect when I just call it normally SpecialQueueClientsJob.perform_later(special: self)
class SpecialQueueClientsJob < ApplicationJob
queue_as :default
def perform(special)
...
end
end
https://github.com/mperham/sidekiq
I am getting an error undefined method perform_at' for SpecialQueueClientsJob `
I am looking at https://github.com/mperham/sidekiq/wiki/Scheduled-Jobs
Sidekiq allows you to schedule the time when a job will be executed.
You use perform_in(interval_in_seconds, *args) or
perform_at(timestamp, *args) rather than the standard
perform_async(*args):
MyWorker.perform_in(3.hours, 'mike', 1)
MyWorker.perform_at(3.hours.from_now, 'mike', 1) This is useful for
example if you want to send the user an email 3 hours after they sign
up. Jobs which are scheduled in the past are enqueued for immediate
execution.

ActiveJob not enqueuing job

I've implemented Ahoy for tracking events inside my application and I want to move the processing into a background job.
My setup works fine when I call perform_now (the job gets processed), but changing to perform_later doesn't work. From the logs, it seems the job doesn't even get enqueued.
config/initializers/ahoy.rb
class Ahoy::Store < Ahoy::BaseStore
def track_visit(data)
AhoyTrackVisitJob.perform_later(#options, data)
end
def track_event(data)
AhoyTrackEventJob.perform_later(#options, data)
end
end
app/jobs/ahoy_track_event_job.rb
class AhoyTrackEventJob < ApplicationJob
queue_as :default
def perform(options, data)
Ahoy::DatabaseStore.new(options).track_event(data)
end
end
I've tried with both Sidekiq and SuckerPunch:
development.rb
config.active_job.queue_adapter = :sidekiq

How can I prevent ActiveJob from performing if the object it should perform on is deleted?

I have a background job that does some work on uploaded images, but sometimes the image is deleted by the user before the background job is performed, and it creates an ActiveJob::DeserializationError
Is there something I can do in the model in before_destroy to cancel the job? Or something in the job class I can do in before_perform to not execute the job if the record has been deleted in the database?
Thanks!
Active job instances include ActiveSupport::Rescuable which means you can use rescue_from in a job in the same way you can in a controller.
You can then recover from any deserialization error:
class MyJob < ApplicationJob
rescue_from(ActiveJob::DeserializationError) do |e|
true
end
end
If you want to use this pattern in a lot of jobs you could extract it to a module:
module DeserializationErrorIsOkay
extend ActiveSupport::Concern
included do
rescue_from(ActiveJob::DeserializationError) do |e|
# This error is okay and doesn't indicate a failed job
true
end
end
end
which you can just include in your jobs:
class MyJob < ApplicationJob
include DeserializationErrorIsOkay
end
NB: this recovers from any of the objects being serialized in the job failing to be deserialized
This might be a more up-to-date answer:
discard_on ActiveJob::DeserializationError
See: https://edgeguides.rubyonrails.org/active_job_basics.html#retrying-or-discarding-failed-jobs
Example:
class RemoteServiceJob < ApplicationJob
retry_on CustomAppException # defaults to 3s wait, 5 attempts
discard_on ActiveJob::DeserializationError
def perform(*args)
# Might raise CustomAppException or ActiveJob::DeserializationError
end
end
Handle the record deleted or not in job class
begin
record.reload
# if no exception continue executing job
rescue ActiveRecord::RecordNotFound => e
# If deleted exception is raised and skip executing the job
end

How to perform a background job now?

I want to execute this on background
Product.all.map { |product| product.save }
When I save the product will call a callback to create a new record in a table with the costs of products
I create a job for this, but if I execute perform_now it is not executed on background and perform_later executes long after.
I want to execute this right now but in background. I'm not sure if I can just execute this in a thread too.
I am using Delayed Job, here is the job
class UpdateProductCostsJob < ApplicationJob
queue_as :default
def perform
Product.all.map { |product| product.save }
end
end
And I want to execute every time this model is saved
class CostComposition < ApplicationRecord
before_save :update_product_costs
private
def update_product_costs
UpdateProductCostsJob.perform_now
end
end
Assuming that you are using rails 5, you can create a high priority queue and create the job under that queue. If you have only one queue, you can add the job to the queue as well as specify the time when you want to process that job.
UpdateProductCostJob.set(wait_until: Time.now + 5.minutes).perform_later
refer http://edgeguides.rubyonrails.org/active_job_basics.html#enqueue-the-job

ActiveJob: start a job automatically when starting server

For example I have a job that I want recurrence every 1 hour. Here is my code:
class NewsletterJob < ApplicationJob
queue_as :default
after_perform do |job|
NewsletterJob.set(wait: 1.hour).perform_later user
end
def perform(*args)
puts "I am busy mailing newsletter."
end
end
My question is: How can I call above code that is satisfied 2 conditions:
run automatically when server is started.
run only once. For example, I use sidekiq for message queue. So I want the next time restart server, only one instance of job is available.
There are a list of cron projects here https://github.com/mperham/sidekiq/wiki/Related-Projects#recurring-jobs

Resources