如何在 ActiveJob rails 中正确传递 "request" 参数?

How to properly pass "request" params in ActiveJob rails?

我想传递请求参数,以便我可以在 delayed_job 上执行它,如下所示:

ObserveJob.perform_later(请求)

但错误总是 ActiveJob::SerializationError:不支持的参数类型:ActionDispatch::Request

有没有办法在 rails 中传递这个内置请求参数,以便它可以使用 delayed_job 正确执行?

可以有很多种方式:

Delayed::Job.enqueue(Abc.new(param1, param2, queue: "Update Derive")

延迟的工作将是这样的:

class Abc < Struct.new(:param1, :param2)
  def perform
    sum = param1 + param2
    ...
  end
end

与其传递整个 request 对象(它相当大且复杂),不如仅传递作业实际需要的属性。这有几个优点:

  • 巨大、复杂和嵌套的对象,如您问题中的 request,很难序列化,甚至可能根本不支持序列化。
  • 非常“基本”的简单对象 类,例如数字或字符串,更容易序列化并且在序列化表示中需要更少的内存,最终使您的工作更快。
  • 将复杂的对象传递给只需要某些属性的作业会增加对作业请求的不必要的依赖性。作业需要知道请求对象如何工作以及如何从该对象获取所需的属性。
  • 将简单的对象传递给方法使测试更容易,因为您不需要构建复杂的东西来测试方法。

我会将 perform 方法更改为

def perform(path:, referer:, url: remote_ip:, user_agent:, location:)
  # ...
end

并这样称呼它:

ObserveJob.perform_later(
  path:       request.path,
  referer:    request.referer,
  url:        request.url,
  remote_ip:  request.remote_ip,
  user_agent: request.user_agent,
  location:   request.location
)