aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/notifications
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@github.com>2019-02-11 17:42:17 -0800
committerGitHub <noreply@github.com>2019-02-11 17:42:17 -0800
commit87a5b5d023cf785d89cf0abd3e78e3084b6af02d (patch)
tree2e01b11de9ba371280d370e0eca6436bde74982f /activesupport/lib/active_support/notifications
parent819b06f494d2b934b3124808526debe0aa81b57a (diff)
parent94f8e8c8f73b7034a9cc3e7f6bf040350aa9701f (diff)
downloadrails-87a5b5d023cf785d89cf0abd3e78e3084b6af02d.tar.gz
rails-87a5b5d023cf785d89cf0abd3e78e3084b6af02d.tar.bz2
rails-87a5b5d023cf785d89cf0abd3e78e3084b6af02d.zip
Merge pull request #32861 from zvkemp/asn-unsubscribe-proxy
use ProxyPattern to match for ActiveSupport::Notifications fanout/unsubscribe
Diffstat (limited to 'activesupport/lib/active_support/notifications')
-rw-r--r--activesupport/lib/active_support/notifications/fanout.rb38
1 files changed, 35 insertions, 3 deletions
diff --git a/activesupport/lib/active_support/notifications/fanout.rb b/activesupport/lib/active_support/notifications/fanout.rb
index 11721db103..f06504cf2c 100644
--- a/activesupport/lib/active_support/notifications/fanout.rb
+++ b/activesupport/lib/active_support/notifications/fanout.rb
@@ -2,6 +2,7 @@
require "mutex_m"
require "concurrent/map"
+require "set"
module ActiveSupport
module Notifications
@@ -39,6 +40,7 @@ module ActiveSupport
when String
@string_subscribers[subscriber_or_name].clear
@listeners_for.delete(subscriber_or_name)
+ @other_subscribers.each { |sub| sub.unsubscribe!(subscriber_or_name) }
else
pattern = subscriber_or_name.try(:pattern)
if String === pattern
@@ -113,11 +115,33 @@ module ActiveSupport
end
end
+ class Matcher #:nodoc:
+ attr_reader :pattern, :exclusions
+
+ def self.wrap(pattern)
+ return pattern if String === pattern
+ new(pattern)
+ end
+
+ def initialize(pattern)
+ @pattern = pattern
+ @exclusions = Set.new
+ end
+
+ def unsubscribe!(name)
+ exclusions << -name if pattern === name
+ end
+
+ def ===(name)
+ pattern === name && !exclusions.include?(name)
+ end
+ end
+
class Evented #:nodoc:
attr_reader :pattern
def initialize(pattern, delegate)
- @pattern = pattern
+ @pattern = Matcher.wrap(pattern)
@delegate = delegate
@can_publish = delegate.respond_to?(:publish)
end
@@ -137,11 +161,15 @@ module ActiveSupport
end
def subscribed_to?(name)
- @pattern === name
+ pattern === name
end
def matches?(name)
- @pattern && @pattern === name
+ pattern && pattern === name
+ end
+
+ def unsubscribe!(name)
+ pattern.unsubscribe!(name)
end
end
@@ -204,6 +232,10 @@ module ActiveSupport
true
end
+ def unsubscribe!(*)
+ false
+ end
+
alias :matches? :===
end
end