What is the best way to re-queue job in Rails with delay?

Viewed 785

I want to re-queue the job automatically after it's done. There will be optional delay for 10 seconds if nothing was processed.

I can see two approaches. The first one is to put the logic inside perform block. The second is to use around_block feature to do that.

What is the more elegant way to do that?

Here is an example of code block with such logic

# Process queue automatically
class ProcessingJob < ApplicationJob
  queue_as :processing_queue

  around_perform do |_job, block|
    if block.call.zero?
      # wait for 10 seconds if 0 items was handled
      self.class.set(wait: 10.seconds).perform_later
    else
      # don't rest, there are many work to do
      self.class.perform_later
    end
  end

  def perform
    # will return number of processed items
    ProcessingService.handle_next_batch
  end
end

Should I put around_block logic into the perform function?

1 Answers
def perform
  # will return number of processed items
  processed_items_count = ProcessingService.handle_next_batch
  delay_for_next_job = processed_items_count.zero? ? 10 : 0
  next_job = self.class.set(wait: delay_for_next_job.seconds)
  next_job.perform_later
end

You can extract delay_for_next_job as private method, etc, apply refactoring as needed.

Why to use around_perform? You don't need job instance here. Depending on your needs, you can also check if any jobs are currently pending using something like https://github.com/mhenrixon/sidekiq-unique-jobs (sorry, I'm not really familiar with ActiveJob API)

Related