提问人:user3587051 提问时间:4/15/2022 更新时间:4/16/2022 访问量:592
使用 ActiveSupport Around-Callbacks 在调用我的服务时执行代码(跟踪/日志记录)?
Use ActiveSupport Around-Callbacks to execute code (tracing/logging) around when my services are invoked?
问:
在我的 app/services 目录中,我有一堆服务,每个服务都有一个 initialize 方法和一个不带参数的公共方法。perform
显示结构的简单示例服务可能如下所示:
module Users
class CreateService
def initialize(name)
@name = name
end
def perform
# code to create the user
end
end
我的目标是将跟踪添加到我的应用程序,以便我可以跟踪何时调用我的每个服务,而无需对每个服务的代码进行重大修改。最后,我希望这样做,以便当我的任何服务调用其方法时,都会自动生成跟踪。perform()
我相信这应该可以使用ActiveSupport::Callbacks来实现,类似于ActiveJob让我们定义around_perform工作回调的方式。我试图创建一个关注点,我可以将其包含在我的服务中,这将检测所需的行为
module Traceable
extend ActiveSupport::Concern
include ActiveSupport::Callbacks
included do
include ActiveSupport::Callbacks
define_callbacks :perform
set_callback :perform, :around, lambda { |r, block|
puts "start the trace"
result = block.call
puts "end the trace"
}
end
end
但是,在包含此问题之后,我想定义的回调(所有服务的统一)仍然没有被调用。我怎样才能做到这一点?谢谢!
参考资料:https://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html https://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html https://edgeapi.rubyonrails.org/classes/ActiveJob/Callbacks/ClassMethods.html#method-i-around_perform(查看类方法的源代码)around_perform
答:
最干净的方法是使用预置。
它看起来像这样:
module Traceable
extend ActiveSupport::Concern
prepended do
include ActiveSupport::Callbacks
define_callbacks :trace
set_callback :trace, :around do |_r, block|
puts "start the trace"
block.call
puts "end the trace"
end
end
def perform
run_callbacks :trace do
super
end
end
end
module Users
class CreateService
prepend Traceable
attr_accessor :name
def initialize(name)
@name = name
end
def perform
# code to create the user
puts "perform"
end
end
end
该链接有更多详细信息。在服务中意味着将首先在模块中查找其定义。这允许在回调中包装。prepend
Users::CreateService.perform
Traceable
Traceable
perform
由于我们使用的是 而不是在服务中,因此我们需要在 的块内调用 和 。prepend
include
define_callbacks
set_callback
ActiveSupport::Concern
prepended
如果你的服务中有模块,你真的不需要或根本不需要。该模块可以是这样的,并且具有相同的结果:prepend
Traceable
callbacks
concerns
Traceable
module Traceable
def perform
puts "before"
super
puts "after"
end
end
module Users
class CreateService
prepend Traceable
...
end
end
评论