Skip to content

Commit

Permalink
Unsubscribe all built-in subscribers
Browse files Browse the repository at this point in the history
Fixes roidrage#385

Assumes that a built-in subscriber is nested under the component
namespace, so under ActionView or ActionController.
  • Loading branch information
owst committed Jan 24, 2024
1 parent 2839d2c commit 409072e
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
9 changes: 8 additions & 1 deletion lib/lograge.rb
Expand Up @@ -121,11 +121,18 @@ def unsubscribe(component, subscriber)
events = subscriber.public_methods(false).reject { |method| method.to_s == 'call' }
events.each do |event|
Lograge.notification_listeners_for("#{event}.#{component}").each do |listener|
ActiveSupport::Notifications.unsubscribe listener if listener.instance_variable_get('@delegate') == subscriber
ActiveSupport::Notifications.unsubscribe listener if built_in_rails_listener?(listener, component)
end
end
end

def built_in_rails_listener?(listener, component)
delegate = listener.instance_variable_get('@delegate')

# Assume that anything nested under the component namespace is built in to Rails
delegate.class.name.start_with?("#{component.to_s.classify}::")
end

def setup(app)
self.application = app
disable_rack_cache_verbose_output
Expand Down
28 changes: 20 additions & 8 deletions spec/lograge_spec.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require 'support/custom_listener'

require 'active_support'
require 'active_support/notifications'
require 'active_support/core_ext/string'
Expand All @@ -21,24 +23,34 @@
Lograge.remove_existing_log_subscriptions
end.to change {
Lograge.notification_listeners_for('process_action.action_controller')
}
}.to([])
end

it 'removes subscribers for all events' do
expect do
Lograge.remove_existing_log_subscriptions
end.to change {
Lograge.notification_listeners_for('render_template.action_view')
}
}.to([])
end

it "does not remove subscribers that aren't from Rails" do
blk = -> {}
ActiveSupport::Notifications.subscribe('process_action.action_controller', &blk)
Lograge.remove_existing_log_subscriptions
listeners = Lograge.notification_listeners_for('process_action.action_controller')
expect(listeners.size).to eq(1)
shared_examples 'preserving non-Rails subscribers' do |event_name|
context "with event_name #{event_name}" do
it "does not remove subscribers that aren't from Rails" do
proc_subscriber = ActiveSupport::Notifications.subscribe(event_name, proc {})
custom_subscriber =
ActiveSupport::Notifications.subscribe(event_name, CustomListener.new)

Lograge.remove_existing_log_subscriptions

listeners = Lograge.notification_listeners_for(event_name)
expect(listeners).to contain_exactly(proc_subscriber, custom_subscriber)
end
end
end

include_examples 'preserving non-Rails subscribers', 'render_template.action_view'
include_examples 'preserving non-Rails subscribers', 'process_action.action_controller'
end

describe 'keep_original_rails_log option' do
Expand Down
11 changes: 11 additions & 0 deletions spec/support/custom_listener.rb
@@ -0,0 +1,11 @@
class CustomListener
attr_reader :events

def initialize
@events = []
end

def call(*args)
@events << args
end
end

0 comments on commit 409072e

Please sign in to comment.