All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twitter.finagle.util.Updater.scala Maven / Gradle / Ivy

The newest version!
package com.twitter.finagle.util

import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.ConcurrentLinkedQueue

/**
 * Assigns an integral priority to `T`-typed values. Smaller
 * priorities are higher.
 */
private[finagle] trait Prioritized[T] extends (T => Int)

/**
 * Process updates of type `T` with the function `f`. When an update
 * arrives while another is being processed, it is queued, to be
 * delivered after the current update completes. When multiple
 * updates have been enqueued, we deliver only the one with the
 * lowest priority (according to the
 * [[com.twitter.finagle.util.Prioritized Prioritized]] instance);
 * when multiple items have the same priority, the one which was
 * enqueued last is chosen.
 */
private class Updater[T: Prioritized](f: T => Unit) extends (T => Unit) {
  private[this] val n = new AtomicInteger(0)
  private[this] val q = new ConcurrentLinkedQueue[T]
  private[this] val pri = implicitly[Prioritized[T]]

  def apply(t: T) {
    q.offer(t)
    if (n.getAndIncrement() > 0)
      return

    do {
      var el = q.peek()
      while (n.get > 1) {
        n.decrementAndGet()
        val el1 = q.poll()
        if (pri(el1) <= pri(el))
          el = el1
      }

      val el1 = q.poll()
      val min = if (pri(el1) <= pri(el)) el1 else el
      f(min)
    } while (n.decrementAndGet() > 0)
  }
}

private[finagle] object Updater {
  def apply[T: Prioritized](f: T => Unit): (T => Unit) = new Updater(f)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy