1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
# frozen_string_literal: true
module TestProf
module EventProf
# Wrap methods with instrumentation
module Monitor
class BaseTracker
attr_reader :event
def initialize(event)
@event = event
end
def track
TestProf::EventProf.instrumenter.instrument(event) { yield }
end
end
class TopLevelTracker < BaseTracker
attr_reader :id
def initialize(event)
super
@id = :"event_prof_monitor_#{event}"
Thread.current[id] = 0
end
def track
Thread.current[id] += 1
res = nil
begin
res =
if Thread.current[id] == 1
super { yield }
else
yield
end
ensure
Thread.current[id] -= 1
end
res
end
end
class << self
def call(mod, event, *mids, guard: nil, top_level: false)
tracker = top_level ? TopLevelTracker.new(event) : BaseTracker.new(event)
patch = Module.new do
mids.each do |mid|
define_method(mid) do |*args, &block|
next super(*args, &block) unless guard.nil? || instance_exec(*args, &guard)
tracker.track { super(*args, &block) }
end
end
end
mod.prepend(patch)
end
end
end
end
end
|