包装 Sidekiq 的 perform 方法以添加时区感知

Nic*_*eys 3 ruby ruby-on-rails sidekiq

我有一个动态配置的时区的 rails 应用程序。它存储在包含其他选项的数据库表中,并且 rails 应用程序本身配置为 UTC(默认)。

我已经通过一个简单的around过滤器使用Time.use_zone(..., &block).

我想为我的 Sidekiq 员工做类似的事情。其中一些处理与时区相关的数据,因此他们需要它。我在 Sidekiq 本身没有看到任何可用的过滤选项,没有回调,在我可以挂钩的类型之前/之后。我目前的解决方案是prepend一个模块,如下所示:

module TimeZoneAwareWorker

  def perform(*args)
    Time.use_zone(Options.time_zone) do
      super
    end
  end

end
Run Code Online (Sandbox Code Playgroud)

并混入:

class MyWorker

  include Sidekiq::Worker

  prepend TimeZoneAwareWorker

  ...

end
Run Code Online (Sandbox Code Playgroud)

这适用于简单的工人,但如果prependinclude Sidekiq::Worker. 如果工作程序是子类化的,则层次结构不适用于perform包装实现的前置任务。

有没有更好的办法? 最终,我真正想要的是一种万无一失的方法,用另一种方法包装单个方法,并产生包装的实现。

我知道我的另一个选择是在 Sidekiq 的实现中对前/后/周围类型回调进行猴子修补,但我只想在被迫时去那里。

Uri*_*ssi 5

Sidekiq 有自己的中间件解决方案:

Sidekiq 有一个与 Rack 类似的中间件概念:这些是可以实现功能的一小段代码。Sidekiq 将中间件分为客户端和服务器端。

  • 客户端中间件在将作业推送到 Redis 之前运行,并允许您在推送之前修改/停止作业。客户端中间件可以接收类参数作为类对象或包含类名称的字符串。
  • 服务器端中间件“围绕”作业处理运行。Sidekiq 的重试功能是作为一个简单的中间件实现的。

您可以轻松创建自己的中间件代理来添加时区感知代码。