Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delayed job: How to reload the payload classes during every call in Development mode

I am running a delayed job worker. When ever I invoke the foo method, worker prints hello.

class User
  def foo
    puts "Hello"
  end
  handle_asynchronously :foo
end

If I make some changes to the foo method, I have to restart the worker for the changes to reflect. In the development mode this can become quite tiresome.

I am trying to find a way to reload the payload class(in this case User class) for every request. I tried monkey patching the DelayedJob library to invoke require_dependency before the payload method invocation.

module Delayed::Backend::Base
  def payload_object_with_reload
    if Rails.env.development? and @payload_object_with_reload.nil?
      require_dependency(File.join(Rails.root, "app", "models", "user.rb"))
    end
    @payload_object_with_reload ||= payload_object_without_reload
  end
  alias_method_chain :payload_object, :reload
end

This approach doesn't work as the classes registered using require_dependency needs to be reloaded before the invocation and I haven't figured out how to do it. I spent some time reading the dispatcher code to figure out how Rails reloads the classes for every request. I wasn't able to locate the reload code.

Has anybody tried this before? How would you advise me to proceed? Or do you have any pointers for locating the Rails class reload code?

like image 697
Harish Shetty Avatar asked Feb 04 '11 21:02

Harish Shetty


2 Answers

I managed to find a solution. I used ActiveSupport::Dependencies.clear method to clear the loaded classes.

Add a file called config/initializers/delayed_job.rb

Delayed::Worker.backend = :active_record
if Rails.env.development?
  module Delayed::Backend::Base
    def payload_object_with_reload
      if @payload_object_with_reload.nil?
        ActiveSupport::Dependencies.clear
      end
      @payload_object_with_reload ||= payload_object_without_reload
    end
    alias_method_chain :payload_object, :reload
  end
end
like image 105
Harish Shetty Avatar answered Nov 16 '22 17:11

Harish Shetty


As of version 4.0.6, DelayedJob reloads automatically if Rails.application.config.cache_classes is set to false:

In development mode, if you are using Rails 3.1+, your application code will automatically reload every 100 jobs or when the queue finishes. You no longer need to restart Delayed Job every time you update your code in development.

like image 1
Phil Avatar answered Nov 16 '22 16:11

Phil