From c88360ef3651702ca8f7f600e15774f51c84698b Mon Sep 17 00:00:00 2001
From: Carlhuda <carlhuda@engineyard.com>
Date: Mon, 1 Mar 2010 16:01:08 -0800
Subject: You can unsubscribe a subscriber

---
 activesupport/lib/active_support/notifications.rb        |  4 ++++
 activesupport/lib/active_support/notifications/fanout.rb | 11 ++++++++---
 activesupport/test/notifications_test.rb                 | 14 +++++++++++++-
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb
index 06d57765bc..fca2efd969 100644
--- a/activesupport/lib/active_support/notifications.rb
+++ b/activesupport/lib/active_support/notifications.rb
@@ -69,6 +69,10 @@ module ActiveSupport
         @queue.bind(pattern).subscribe(&block)
       end
 
+      def unsubscribe(subscriber)
+        @queue.unsubscribe(subscriber)
+      end
+
       def wait
         @queue.wait
       end
diff --git a/activesupport/lib/active_support/notifications/fanout.rb b/activesupport/lib/active_support/notifications/fanout.rb
index 090eb1eac6..e08011e23f 100644
--- a/activesupport/lib/active_support/notifications/fanout.rb
+++ b/activesupport/lib/active_support/notifications/fanout.rb
@@ -4,7 +4,7 @@ module ActiveSupport
     # just pushes events to all registered log subscribers.
     class Fanout
       def initialize
-        @log_subscribers = []
+        @subscribers = []
       end
 
       def bind(pattern)
@@ -12,11 +12,16 @@ module ActiveSupport
       end
 
       def subscribe(pattern = nil, &block)
-        @log_subscribers << Subscriber.new(pattern, &block)
+        @subscribers << Subscriber.new(pattern, &block)
+        @subscribers.last
+      end
+
+      def unsubscribe(subscriber)
+        @subscribers.delete(subscriber)
       end
 
       def publish(*args)
-        @log_subscribers.each { |s| s.publish(*args) }
+        @subscribers.each { |s| s.publish(*args) }
       end
 
       # This is a sync queue, so there is not waiting.
diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb
index 779771553c..baee779b8a 100644
--- a/activesupport/test/notifications_test.rb
+++ b/activesupport/test/notifications_test.rb
@@ -6,7 +6,7 @@ module Notifications
       ActiveSupport::Notifications.notifier = nil
       @notifier = ActiveSupport::Notifications.notifier
       @events = []
-      @notifier.subscribe { |*args| @events << event(*args) }
+      @subscription = @notifier.subscribe { |*args| @events << event(*args) }
     end
 
     private
@@ -19,6 +19,18 @@ module Notifications
       end
   end
 
+  class UnsubscribeTest < TestCase
+    def unsubscribing_removes_a_subscription
+      @notifier.publish :foo
+      @notifier.wait
+      assert_equal [[:foo]], @events
+      @notifier.unsubscribe(@subscription)
+      @notifier.publish :bar
+      @notifier.wait
+      assert_equal [[:foo]], @events
+    end
+  end
+
   class SyncPubSubTest < TestCase
     def test_events_are_published_to_a_listener
       @notifier.publish :foo
-- 
cgit v1.2.3