Adding high-performance MPSC queue based mailbox to Akka

This commit is contained in:
Viktor Klang 2013-03-07 15:58:26 +01:00
parent 3f29adcee5
commit fb2decbcda
3 changed files with 143 additions and 83 deletions

View file

@ -10,10 +10,10 @@ import akka.actor.{ ActorCell, ActorRef, Cell, ActorSystem, InternalActorRef, De
import akka.util.{ Unsafe, BoundedBlockingQueue }
import akka.event.Logging.Error
import scala.concurrent.duration.Duration
import scala.concurrent.duration.FiniteDuration
import scala.annotation.tailrec
import scala.util.control.NonFatal
import com.typesafe.config.Config
import scala.concurrent.duration.FiniteDuration
/**
* INTERNAL API
@ -193,9 +193,6 @@ private[akka] abstract class Mailbox(val messageQueue: MessageQueue)
updateStatus(s, s & ~Scheduled) || setAsIdle()
}
/*
* AtomicReferenceFieldUpdater for system queue.
*/
protected final def systemQueueGet: SystemMessage =
Unsafe.instance.getObjectVolatile(this, AbstractMailbox.systemMessageOffset).asInstanceOf[SystemMessage]
@ -343,6 +340,28 @@ trait MessageQueue {
def cleanUp(owner: ActorRef, deadLetters: MessageQueue): Unit
}
class NodeMessageQueue extends AbstractNodeQueue[Envelope] with MessageQueue {
final def enqueue(receiver: ActorRef, handle: Envelope): Unit = add(handle)
final def dequeue(): Envelope = poll()
final def numberOfMessages: Int = {
@tailrec def count(node: AbstractNodeQueue.Node[Envelope], c: Int): Int = if (node eq null) c else count(node.next(), c + 1)
count(peek(), 0)
}
final def hasMessages: Boolean = peek() ne null
@tailrec final def cleanUp(owner: ActorRef, deadLetters: MessageQueue): Unit = {
val envelope = dequeue()
if (envelope ne null) {
deadLetters.enqueue(owner, envelope)
cleanUp(owner, deadLetters)
}
}
}
/**
* INTERNAL API
*/
@ -518,6 +537,18 @@ case class UnboundedMailbox() extends MailboxType {
}
}
/**
* MPSCUnboundedMailbox is a high-performance unbounded MailboxType,
* the only drawback is that you can't have multiple consumers,
* which rules out using it with BalancingDispatcher for instance.
*/
case class MPSCUnboundedMailbox() extends MailboxType {
def this(settings: ActorSystem.Settings, config: Config) = this()
final override def create(owner: Option[ActorRef], system: Option[ActorSystem]): MessageQueue = new NodeMessageQueue()
}
/**
* BoundedMailbox is the default bounded MailboxType used by Akka Actors.
*/