Rails - передать объект в качестве аргумента без сериализации - PullRequest
0 голосов
/ 24 марта 2020

У меня есть контроллер, от которого я должен передать экземпляр объекта в качестве аргумента классу Worker Sidekiq.

Мой контроллер с вызовом WegWorker.synchronize(@service)

class Api::V2::Events::WegSessionsController < Api::V2::Events::ApplicationController
  before_action :load_service

  def synchronize
    @service.keep_cancelled = params[:keep_cancelled].to_b
    if @service.valid_connection?
      WegWorker.perform_async(@service)
      render json: {
        status: :ok,
        message: @service.message
      }, status: :ok
    else
      render json: {
        status: :unprocessable_entity,
        errors: @event.errors.full_messages
      }, status: :ok
    end
  end
    .. some code with service object instantiation
end

My рабочий класс

class WegWorker < ::CarrierWave::Workers::ProcessAsset
  include Sidekiq::Worker 
  sidekiq_options retry: false

  def perform(service)

    service.synchronize
  end
end

Но в настоящее время я получаю сообщение об ошибке:

WARN: NoMethodError: undefined method `synchronize' for "#<WegService:0x0000000013f9abb0>":String

Как передать объект без сериализации его работнику?

Ответы [ 2 ]

2 голосов
/ 24 марта 2020

Задания Sidekiq могут принимать только простые параметры , такие как строка, число и т. Д. c. Чтобы обойти это, рекомендуемый подход состоит в том, чтобы на вашем WegService были определены следующие методы:

class WegService
  def self.from_params(params)
    new(...) #rehydrate your service using params
  end

  def to_params
    [43, 'foo', 'bar'] # pickle your service
  end

  # ...
end

Затем вы бы поставили в очередь вот так:

WegWorker.perform_async(@service.to_params)

И рабочий будет иметь:

def perform(params)
  WebService.from_params(params).synchronize
end
0 голосов
/ 24 марта 2020

Вы ставите в очередь сложный Ruby объект с этим WegWorker.perform_async(@service). Это не будет правильно сериализовано, и вы получите строку, которая выглядит примерно так "#<WegService:0x0000000013f9abb0>". Хотя десериализация Sidekiq не преобразует его в исходный класс, как вы ожидаете.

Вы должны ставить в очередь только простые объекты. Таким образом, вы можете использовать идентификаторы sh для задания asyn c и самостоятельно создать экземпляр службы внутри метода execute.

Кроме того, мой совет будет go в документах Sidekiq. Они довольно маленькие, и вы бы избавили себя от подобных ошибок. Соответствующая ссылка для этого раздела.

...