ActiveJob с Sidekiq, передавая сложный объект в качестве параметра - PullRequest
0 голосов
/ 25 сентября 2019

Параметр работника Sidekiq должен быть простым типом данных согласно этой вики автора (https://github.com/mperham/sidekiq/wiki/Best-Practices)

Параметр ActiveJob может быть сложным объектом, благодаря глобальному идентификатору (https://edgeguides.rubyonrails.org/active_job_basics.html#globalid)

ActiveJobbackend может быть настроен для использования Sidekiq.

Так что же происходит за кулисами, когда я передаю сложный объект работнику ActiveJob с внутренним интерфейсом Sidekiq? Я не думаю, что Sidekiq не сможет обработать его из-за того, что «не выживет»на этот раз корректно выполняется выгрузка / выгрузка.

1 Ответ

1 голос
/ 25 сентября 2019

Глобальный идентификатор модели можно найти с помощью #to_global_id:

gid = MyModel.first.to_global_id

gid.uri # => #<URI ...

gid.to_s # => "gid://..."

GlobalID::Locator.locate(gid) # => #<MyModel

Код для GlobalID здесь .

СоздаетURI из имени приложения, класса модели, идентификатора модели и необязательных параметров.Это делается в GlobalID :: URI :: GID .

Вы можете создать свой собственный GID следующим образом:

URI::GID.create('myapp', MyModel.first, database: 'my_app_development')
# => #<URI::GID gid://myapp/MyModel/1?database=my_app_development>

Переданная модель должна быть жалобой ActiveRecord,поэтому передача PORO (Plain Old Ruby Object) не будет работать:

class MyModel
end

URI::GID.create('myapp', MyModel.new)
# => NoMethodError (undefined method `id'

Давайте добавим атрибут id:

MyModel = Struct.new(:id)

gid = URI::GID.create('myapp', MyModel.new(1))
# => #<URI::GID gid://myapp/MyModel/1>

GlobalID::Locator.locate(gid)
# => NoMethodError (undefined method `find' for MyModel:Class)

И метод класса #find:

MyModel = Struct.new(:id) do
  def self.find(id)
    new(id)
  end
end

gid = URI::GID.create('myapp', MyModel.new(1))

GlobalID::Locator.locate(gid)
# => #<struct MyModel id="1">
...