Github user JoshRosen commented on a diff in the pull request:

    https://github.com/apache/spark/pull/18083#discussion_r120999648
  
    --- Diff: core/src/main/scala/org/apache/spark/util/ListenerBus.scala ---
    @@ -23,29 +23,41 @@ import scala.collection.JavaConverters._
     import scala.reflect.ClassTag
     import scala.util.control.NonFatal
     
    +import com.codahale.metrics.Timer
    +
     import org.apache.spark.internal.Logging
     
     /**
      * An event bus which posts events to its listeners.
      */
     private[spark] trait ListenerBus[L <: AnyRef, E] extends Logging {
     
    +  private[this] val listenersPlusTimers = new CopyOnWriteArrayList[(L, 
Timer)]
    +
       // Marked `private[spark]` for access in tests.
    -  private[spark] val listeners = new CopyOnWriteArrayList[L]
    +  private[spark] def listeners = 
listenersPlusTimers.asScala.map(_._1).asJava
    +
    +  /**
    +   * Returns a CodaHale metrics Timer for measuring the listener's event 
processing time.
    +   * This method is intended to be overridden by subclasses.
    +   */
    +  protected def getTimer(listener: L): Option[Timer] = None
     
       /**
        * Add a listener to listen events. This method is thread-safe and can 
be called in any thread.
        */
       final def addListener(listener: L): Unit = {
    -    listeners.add(listener)
    +    listenersPlusTimers.add((listener, getTimer(listener).orNull))
       }
     
       /**
        * Remove a listener and it won't receive any events. This method is 
thread-safe and can be called
        * in any thread.
        */
       final def removeListener(listener: L): Unit = {
    -    listeners.remove(listener)
    +    listenersPlusTimers.asScala.find(_._1 eq listener).foreach { 
listenerAndTimer =>
    +      listenersPlusTimers.remove(listenerAndTimer)
    --- End diff --
    
    I think the only reason that `CopyOnWriteArrayList` was used was for 
thread-safety and fast performance for readers interleaved with very rare 
mutations / writes. If we were to replace the array list then we'd need to add 
a `synchronized` to guard the `listenersPlusTimers` field itself.
    
    Given the workload and access patterns here, I'm not sure that it's worth 
it to attempt to optimize this `removeListener()` method any further.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to