6

Tôi đang sử dụng DelayedJob và tôi muốn cập nhật ứng dụng Rails 4.2 của mình để sử dụng ActiveJob. Vấn đề là tôi có một loạt các công việc tùy chỉnh mà trông như thế này:Tôi làm cách nào để sử dụng các công việc tùy chỉnh bị chậm trễ với ActiveJob?

AssetDeleteJob = Struct.new(:user_id, :params) do 
    def perform 
    # code 
    end 
    # more methods n' stuff 
end 

Sau đó, trong một bộ điều khiển ở đâu đó công việc được enqueued với cú pháp này:

@asset_delete_job = AssetDeleteJob.new(current_admin_user.id, params) 
Delayed::Job.enqueue @asset_delete_job 

Tôi muốn tìm ra tương đương với ActiveJob. Ở trên cơ bản là thẳng từ các tài liệu DJ. Sử dụng nó để enqueue một cuộc gọi duy nhất là đơn giản như gọi phương thức thực hiện công việc, giống như với DJ. Nhưng tôi phức tạp hơn và yêu cầu cú pháp của cấu trúc DJ và các đối số được truyền cho nó.

Đây là những gì tôi đã cố gắng cho đến nay:

class AssetDeleteJob < ActiveJob::Base 
    queue_as :default 

    def initialize(user_id, params) 
    @user_id = user_id 
    @params = params 
    end 

    def perform 
    #code 
    end 

    # more methods n' stuff 

end 

job = AssetDeleteJob.new(1, {ids: [1,2,3]}) 

Thật không may, đối tượng cụ thể không có phương pháp #perform_later như tôi mong đợi. Nó có #enqueue, nhưng tôi nhận được một lỗi lẻ:

Could not log "enqueue.active_job" event. NoMethodError: undefined method `any?' for nil:NilClass

... theo sau là một vết đống trong một mảng, kết thúc bằng

NoMethodError: undefined method `map' for nil:NilClass

Một cặp vợ chồng kỳ lạ của lỗi, nhưng biết đâu tôi sẽ không được cho là truy cập trực tiếp #enqueue. Ở trên có vẻ như nó là khá trên mũi như xa như những gì ActiveJob đang tìm kiếm. Tôi đang thiếu gì?

Trả lời

5

Tôi có thể thấy hai vấn đề. Trước tiên, bạn đã xác định phương thức initialize trong lớp công việc tùy chỉnh của mình, do đó ghi đè phương thức initialize trong lớp ActiveJob. Đây là những gì gây ra ngoại lệ để được ném. Tôi không chắc chắn nếu bạn có thể fiddle về với instantiation của công việc đang hoạt động. Thứ hai, bạn đang cố gắng gọi phương thức lớp perform_later trên một thể hiện của lớp đó, mà ruby ​​sẽ không cho phép.

Nó đơn giản để sửa chữa, chỉ cần thêm các đối số cho phương thức perform trong lớp tùy chỉnh của bạn thay vì:

class AssetDeleteJob < ActiveJob::Base 
    #code 

    def perform(user_id, params) 
    #do a thing 
    end 

    #more code 
end 

và sau đó hàng đợi công việc bằng cách gọi một cái gì đó như:

AssetDeleteJob.perform_later(1, {ids: [1,2,3]}) 
0
# in jobs/asset_delete_job.rb 
class AssetDeleteJob < ActiveJob::Base 
    queue_as :default 
    def perform(user_id, params) 
    AssetService.new(user_id, params).delete # for example 
    end 
end 

# somewhere in your controllers/assets_controller.rb 
    AssetDeleteJob.perform_later(1, {ids: [1,2,3]}) 
Các vấn đề liên quan