6

Я использую DelayedJob, и я хочу обновить приложение Rails 4.2 для использования ActiveJob. Проблема заключается в том, что у меня есть куча пользовательских рабочих мест, которые выглядят следующим образом:Как использовать пользовательские задания delayed_job с ActiveJob?

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

Тогда в контроллере где-то задание помещается в очередь с этим синтаксисом:

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

я хотел бы найти эквивалент для ActiveJob. Вышеуказанное в основном прямо из диджейских документов. Использование его для включения одного вызова так же просто, как вызов метода выполнения задания, как и у DJ. Но мои более сложны и требуют синтаксиса синтаксиса DJ и аргументы, переданные ему.

Вот что я пытался до сих пор:

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]}) 

К сожалению, созданный объект не имеет метод #perform_later, как я бы ожидать. У него есть #enqueue, но я получаю странное сообщение об ошибке:

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

... а затем трассировки стека в массиве, заканчивающийся в

NoMethodError: undefined method `map' for nil:NilClass

нечетного пару ошибок, но я мог бы не должно быть доступ к #enqueue напрямую. Вышеприведенное выглядит так, как будто на носу довольно хорошо, что и ищет ActiveJob. Что мне не хватает?

ответ

5

Я вижу две проблемы. Во-первых, вы определили метод initialize в своем классе специальных заданий, тем самым перезаписав метод initialize в классе ActiveJob. Это то, что вызывает исключение исключения. Я не уверен, что вы можете играть с созданием активных рабочих мест. Во-вторых, вы пытаетесь вызвать метод класса perform_later на экземпляр этого класса, который Ruby не позволит.

Это легко исправить, просто добавьте аргументы метода perform в пользовательский класс вместо:

class AssetDeleteJob < ActiveJob::Base 
    #code 

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

    #more code 
end 

, а затем в очереди на работу по телефону что-то вроде:

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]}) 
Смежные вопросы