pekko/akka-core/src/main/scala/dispatch/ThreadBasedDispatcher.scala

61 lines
2 KiB
Scala
Raw Normal View History

/**
2009-12-27 16:01:53 +01:00
* Copyright (C) 2009-2010 Scalable Solutions AB <http://scalablesolutions.se>
*/
package se.scalablesolutions.akka.dispatch
import java.util.concurrent.LinkedBlockingQueue
import java.util.Queue
2010-06-01 09:23:45 +02:00
import se.scalablesolutions.akka.actor.{Actor, ActorRef}
/**
* Dedicates a unique thread for each actor passed in as reference. Served through its messageQueue.
2010-05-21 20:08:49 +02:00
*
* @author <a href="http://jonasboner.com">Jonas Bon&#233;r</a>
*/
2010-06-01 09:23:45 +02:00
class ThreadBasedDispatcher(private val actor: ActorRef) extends MessageDispatcher {
private val name = actor.getClass.getName + ":" + actor.uuid
private val threadName = "akka:thread-based:dispatcher:" + name
private val queue = new BlockingMessageQueue(name)
private var selectorThread: Thread = _
@volatile private var active: Boolean = false
2010-05-21 20:08:49 +02:00
def dispatch(invocation: MessageInvocation) = queue.append(invocation)
2009-12-11 06:44:59 +01:00
def start = if (!active) {
log.debug("Starting up %s", toString)
active = true
selectorThread = new Thread(threadName) {
override def run = {
while (active) {
try {
2010-06-01 09:23:45 +02:00
actor.invoke(queue.take)
} catch { case e: InterruptedException => active = false }
}
}
}
selectorThread.start
}
2010-05-21 20:08:49 +02:00
def isShutdown = !active
def shutdown = if (active) {
log.debug("Shutting down %s", toString)
active = false
selectorThread.interrupt
references.clear
}
override def toString = "ThreadBasedDispatcher[" + threadName + "]"
}
class BlockingMessageQueue(name: String) extends MessageQueue {
// FIXME: configure the LinkedBlockingQueue in BlockingMessageQueue, use a Builder like in the ReactorBasedThreadPoolEventDrivenDispatcher
private val queue = new LinkedBlockingQueue[MessageInvocation]
2009-12-11 06:44:59 +01:00
def append(invocation: MessageInvocation) = queue.put(invocation)
def take: MessageInvocation = queue.take
def read(destination: Queue[MessageInvocation]) = throw new UnsupportedOperationException
def interrupt = throw new UnsupportedOperationException
}