Remove child event tracking from AS::Subscriber

Previously ActiveSupport::Subscriber would manage its own events, keep
them in a thread-local stack, and track "child" events of the same
subscriber.

I don't think this was particularly useful, since it only considered
notifications delivered to the same subscriber, and I can't find
evidence of this being used in the wild. I think this was intended to
support tracing, but any uch tool would want to do this itself (at
minimum in order to support multiple namespaces).

Additionally, this has caused a few users to OOM in production
environments, notably when queueing many jobs from another job.
This commit is contained in:
John Hawthorn 2022-01-17 10:47:05 -08:00
parent 86fd8d0143
commit 51e28dc322
3 changed files with 7 additions and 29 deletions

View File

@ -107,14 +107,10 @@ module ActiveSupport
LogSubscriber.logger LogSubscriber.logger
end end
def start(name, id, payload) def call(event)
super if logger
end
def finish(name, id, payload)
super if logger super if logger
rescue => e rescue => e
log_exception(name, e) log_exception(event.name, e)
end end
def publish_event(event) def publish_event(event)

View File

@ -126,26 +126,12 @@ module ActiveSupport
attr_reader :patterns # :nodoc: attr_reader :patterns # :nodoc:
def initialize def initialize
@queue_key = [self.class.name, object_id].join "-"
@patterns = {} @patterns = {}
super super
end end
def start(name, id, payload) def call(event)
event = ActiveSupport::Notifications::Event.new(name, nil, nil, id, payload) method = event.name.split(".").first
event.start!
parent = event_stack.last
parent << event if parent
event_stack.push event
end
def finish(name, id, payload)
event = event_stack.pop
event.finish!
event.payload.merge!(payload)
method = name.split(".").first
send(method, event) send(method, event)
end end
@ -153,11 +139,5 @@ module ActiveSupport
method = event.name.split(".").first method = event.name.split(".").first
send(method, event) send(method, event)
end end
private
def event_stack
registry = ActiveSupport::IsolatedExecutionState[:active_support_subscriber_queue_registry] ||= {}
registry[@queue_key] ||= []
end
end end
end end

View File

@ -77,7 +77,9 @@ class SyncLogSubscriberTest < ActiveSupport::TestCase
def test_event_attributes def test_event_attributes
ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber ActiveSupport::LogSubscriber.attach_to :my_log_subscriber, @log_subscriber
instrument "some_event.my_log_subscriber" instrument "some_event.my_log_subscriber" do
[] # Make an allocation
end
wait wait
event = @log_subscriber.event event = @log_subscriber.event
if defined?(JRUBY_VERSION) if defined?(JRUBY_VERSION)