2011-02-04 9 views
13

Tôi đang chạy công nhân bị trì hoãn. Khi tôi gọi phương thức foo, nhân viên in hello.Công việc bị trì hoãn: Cách tải lại các lớp tải trọng trong mọi cuộc gọi ở Chế độ phát triển

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

Nếu tôi thực hiện một số thay đổi đối với phương pháp foo, tôi phải khởi động lại nhân viên để thay đổi phản ánh. Trong chế độ phát triển, điều này có thể trở nên khá mệt mỏi.

Tôi đang cố gắng tìm cách tải lại lớp tải trọng (trong trường hợp này là Lớp người dùng) cho mọi yêu cầu. Tôi đã thử khỉ vá thư viện DelayedJob để gọi require_dependency trước khi gọi phương thức tải trọng.

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 

Cách tiếp cận này không hoạt động như các lớp học đã đăng ký sử dụng require_dependency cần phải được nạp lại trước khi gọi và tôi đã không tìm ra cách để làm điều đó. Tôi đã dành một chút thời gian đọc mã điều phối để tìm ra cách Rails tải lại các lớp cho mọi yêu cầu. Tôi không thể định vị mã tải lại.

Có ai đã thử điều này trước đây không? Bạn khuyên tôi nên tiếp tục như thế nào? Hay bạn có bất kỳ con trỏ nào để định vị mã nạp lại lớp Rails?

Trả lời

19

Tôi đã tìm được giải pháp. Tôi đã sử dụng phương pháp ActiveSupport::Dependencies.clear để xóa các lớp đã tải.

Thêm một tập tin gọi 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 
+1

cảm ơn bạn! điều này làm việc tuyệt vời, ngay cả với mongoid như phụ trợ. tôi chỉ phải loại bỏ dòng đầu tiên để nó hoạt động :) –

+0

Rất tuyệt! đã làm điều tương tự nhưng dưới dạng [tập lệnh riêng biệt] (http://stackoverflow.com/questions/1609586/rails-delayed-job-want-to-load-newest-version-of-job-class/7861250#7861250) và sử dụng nó cùng với [foreman] (http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) –

+0

Tôi không thực sự hiểu * tại sao * nhưng điều này khiến bộ nhớ Rails của tôi bị nổ tung trong mọi môi trường (bao gồm cả sản xuất) và các phiên bản không phải DJ. –

1

Tính đến phiên bản 4.0.6, DelayedJob tự động tải lại nếu Rails.application.config.cache_classes là đặt thành false:

Trong chế độ phát triển, nếu bạn đang sử dụng Rails 3.1+, mã ứng dụng của bạn sẽ tự động tải lại mỗi 100 công việc hoặc khi hàng đợi kết thúc. Bạn không còn cần phải khởi động lại công việc bị trì hoãn mỗi khi bạn cập nhật mã của bạn trong phát triển.