mdesantis
mdesantis

Reputation: 8517

Check whether I am in a delayed_job process or not

I have a Rails app in which I use delayed_job. I want to detect whether I am in a delayed_job process or not; something like

if in_delayed_job?
  # do something only if it is a delayed_job process...
else
  # do something only if it is not a delayed_job process...
end

But I can't figure out how. This is what I'm using now:

IN_DELAYED_JOB = begin
  basename        = File.basename $0
  arguments       = $*
  rake_args_regex = /\Ajobs:/

  ( basename == 'delayed_job' ) ||
  ( basename == 'rake' && arguments.find{ |v| v =~ rake_args_regex } )
end

Another solution is, as @MrDanA said:

$ DELAYED_JOB=true script/delayed_job start
# And in the app:
IN_DELAYED_JOB = ENV['DELAYED_JOB'].present?

but they are IMHO weak solutions. Can anyone suggest a better solution?

Upvotes: 7

Views: 2177

Answers (5)

Felix Livni
Felix Livni

Reputation: 1244

You can create a plugin for delayed job, e.g. create the file is_dj_job_plugin.rb in the config/initializers directory.

class IsDjJobPlugin < Delayed::Plugin

  callbacks do |lifecycle|
    lifecycle.around(:invoke_job) do |job, *args, &block|
      begin
        old_is_dj_job = Thread.current[:is_dj_job]
        Thread.current[:is_dj_job] = true
        block.call(job, *args) # Forward the call to the next callback in the callback chain
        Thread.current[:is_dj_job] = old_is_dj_job
      end
    end
  end

  def self.is_dj_job?
    Thread.current[:is_dj_job] == true
  end
end

Delayed::Worker.plugins << IsDjJobPlugin

You can then test in the following way:

class PrintDelayedStatus
  def run
    puts IsDjJobPlugin.is_dj_job? ? 'delayed' : 'not delayed'
  end
end

PrintDelayedStatus.new.run
PrintDelayedStatus.new.delay.run

Upvotes: 0

frankleonrose
frankleonrose

Reputation: 365

This works for me:

def delayed_job_worker?
  (ENV["_"].include? "delayed_job")
end

Unix will set the "_" environment variable to the current command.

It'll be wrong if you have a bin script called "not_a_delayed_job", but don't do that.

Upvotes: 1

baash05
baash05

Reputation: 4516

How about ENV['PROC_TYPE']
Speaking only of heroku... but when you're a worker dyno, this is set to 'worker' I use it as my "I'm in a DJ"

Upvotes: 0

John Naegle
John Naegle

Reputation: 8247

Maybe something like this. Add a field to your class and set it when your invoke the method that does all your work from delayed job:

class User < ActiveRecord::Base
  attr_accessor :in_delayed_job

   def queue_calculation_request
     Delayed::Job.enqueue(CalculationRequest.new(self.id))
   end

   def do_the_work
     if (in_delayed_job)
       puts "Im in delayed job"
     else
       puts "I was called directly"
     end
   end

   class CalculationRequest < Struct.new(:id)
     def perform
       user = User.find(id)
       user.in_delayed_job = true
       user.do_the_work
     end

     def display_name
       "Perform the needeful user Calculations"
     end
   end
end

Here is how it looks:

From Delayed Job:

Worker(host:Johns-MacBook-Pro.local pid:67020)] Starting job worker
Im in delayed job
[Worker(host:Johns-MacBook-Pro.local pid:67020)] Perform the needeful user Calculations completed after 0.2787
[Worker(host:Johns-MacBook-Pro.local pid:67020)] 1 jobs processed at 1.5578 j/s, 0 failed ...

From the console

user = User.first.do_the_work
  User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 101]]
I was called directly

Upvotes: 1

kobaltz
kobaltz

Reputation: 7070

The way that I handle these is through a Paranoid worker. I use delayed_job for video transcoding that was uploaded to my site. Within the model of the video, I have a field called video_processing which is set to 0/null by default. Whenever the video is being transcoded by the delayed_job (whether on create or update of the video file), it will use the hooks from delayed_job and will update the video_processing whenever the job starts. Once the job is completed, the completed hook will update the field to 0.

In my view/controller I can do video.video_processing? ? "Video Transcoding in Progress" : "Video Fished Transcoding"

Upvotes: 1

Related Questions