diff --git a/akka-actor/src/main/scala/akka/event/EventBus.scala b/akka-actor/src/main/scala/akka/event/EventBus.scala index 66b0aa0c29..cb83fbe806 100644 --- a/akka-actor/src/main/scala/akka/event/EventBus.scala +++ b/akka-actor/src/main/scala/akka/event/EventBus.scala @@ -143,7 +143,9 @@ trait SubchannelClassification { this: EventBus ⇒ def unsubscribe(subscriber: Subscriber, from: Classifier): Boolean = subscriptions.synchronized { val diff = subscriptions.removeValue(from, subscriber) - cache ++= diff // FIXME What is the reason this isn't calling removeFromCache? + // removeValue(K, V) does not return the diff to remove from or add to the cache + // but instead the whole set of keys and values that should be updated in the cache + cache ++= diff diff.nonEmpty } @@ -165,7 +167,6 @@ trait SubchannelClassification { this: EventBus ⇒ recv foreach (publish(event, _)) } - // we can only let keys that already exist in the cache get updated private def removeFromCache(changes: Seq[(Classifier, Set[Subscriber])]): Unit = cache = (cache /: changes) { case (m, (c, cs)) ⇒ m.updated(c, m.getOrElse(c, Set.empty[Subscriber]) -- cs) diff --git a/akka-actor/src/main/scala/akka/util/SubclassifiedIndex.scala b/akka-actor/src/main/scala/akka/util/SubclassifiedIndex.scala index bff7a0ffee..ae82da6407 100644 --- a/akka-actor/src/main/scala/akka/util/SubclassifiedIndex.scala +++ b/akka-actor/src/main/scala/akka/util/SubclassifiedIndex.scala @@ -132,11 +132,14 @@ private[akka] class SubclassifiedIndex[K, V] private (private var values: Set[V] /** * Remove value from all keys which are subclasses of the given key. * - * @return the complete changes that should be inserted in the cache + * @return the complete changes that should be updated in the cache */ def removeValue(key: K, value: V): Changes = + // the reason for not using the values in the returned diff is that we need to + // go through the whole tree to find all values for the "changed" keys in other + // parts of the tree as well, since new nodes might have been created mergeChangesByKey(innerRemoveValue(key, value)) map { - case (k, v) ⇒ (k, findValues(k)) + case (k, _) ⇒ (k, findValues(k)) } // this will return the keys and values to be removed from the cache