How to get the time an ActiveJob was enqueued at

Posted on

I recently had a Ruby on Rails ActiveJob task where I needed to know the exact time when the job was originally enqueued at (i.e. when perform_later was called).

Initially I passed an additional argument with the current time to the perform_later method call. That solution proved really messy, as I was needlessly passing the same argument in everywhere. It also wasn't particularly quick to implement onto other projects & jobs.

After a bit of exploration through the documentation, I came across a enqueued_at method which is available out of the box with ActiveJob. However, as I experimented with this method I noticed if a job had to be retried due to an exception, the enqueued_at value would be updated to the time it had been enqueued to be retried again.

Getting the initial time the job was enqueued

I found the cleanest solution to solve this was to add a little attr_writer to my ApplicationJob class, which I pass as an extra value in when a job is serialized & passed onto Sidekiq.

# app/jobs/application_job.rb
class ApplicationJob < ActiveJob::Base
  attr_writer :initially_enqueued_at

  def initially_enqueued_at
    @initially_enqueued_at ||= Time.zone.now
  end

  def serialize
    super.merge('initially_enqueued_at' => initially_enqueued_at)
  end

  def deserialize(job_data)
    super
    self.initially_enqueued_at = Time.parse(job_data['initially_enqueued_at'])
  end
end

Now when whenever I run a job, I have the method initially_enqueued_at available to me which returns the time the initial perform_later is called.

This was written by Mike Rogers, a freelance Ruby on Rails developer based in London.

Share the ♥ by sharing this!

If you want to discuss this post, feel free to tweet me (@MikeRogers0) or drop me an email. Any code samples unless stated otherwise are licensed under the The MIT License (MIT). Spotted a mistake? Send me a pull request :)