2009-05-25 14:48:43 +02:00
|
|
|
/**
|
|
|
|
|
* Copyright (C) 2009 Scalable Solutions.
|
|
|
|
|
*/
|
|
|
|
|
|
2009-10-08 19:01:04 +02:00
|
|
|
package se.scalablesolutions.akka.dispatch
|
2009-05-25 14:48:43 +02:00
|
|
|
|
2009-07-28 10:45:41 +02:00
|
|
|
import java.util.List
|
2009-10-06 00:07:27 +02:00
|
|
|
|
|
|
|
|
import se.scalablesolutions.akka.util.HashCode
|
|
|
|
|
import se.scalablesolutions.akka.stm.Transaction
|
|
|
|
|
import se.scalablesolutions.akka.actor.Actor
|
|
|
|
|
|
2009-12-13 12:29:18 +01:00
|
|
|
import java.util.concurrent.ConcurrentHashMap
|
2009-07-06 23:45:15 +02:00
|
|
|
|
2009-12-13 12:29:18 +01:00
|
|
|
final class MessageInvocation(val receiver: Actor,
|
|
|
|
|
val message: Any,
|
|
|
|
|
val future: Option[CompletableFutureResult],
|
|
|
|
|
val sender: Option[Actor],
|
|
|
|
|
val tx: Option[Transaction]) {
|
2009-10-06 00:07:27 +02:00
|
|
|
if (receiver == null) throw new IllegalArgumentException("receiver is null")
|
|
|
|
|
if (message == null) throw new IllegalArgumentException("message is null")
|
2009-05-25 14:48:43 +02:00
|
|
|
|
2009-12-11 16:37:44 +01:00
|
|
|
def invoke = receiver.invoke(this)
|
|
|
|
|
|
|
|
|
|
def send = receiver.dispatcher.dispatch(this)
|
|
|
|
|
|
2009-10-06 00:07:27 +02:00
|
|
|
override def hashCode(): Int = synchronized {
|
2009-05-25 15:18:18 +02:00
|
|
|
var result = HashCode.SEED
|
2009-10-06 00:07:27 +02:00
|
|
|
result = HashCode.hash(result, receiver)
|
2009-05-25 15:18:18 +02:00
|
|
|
result = HashCode.hash(result, message)
|
|
|
|
|
result
|
2009-05-25 14:48:43 +02:00
|
|
|
}
|
2009-05-25 15:18:18 +02:00
|
|
|
|
2009-10-06 00:07:27 +02:00
|
|
|
override def equals(that: Any): Boolean = synchronized {
|
2009-05-25 15:18:18 +02:00
|
|
|
that != null &&
|
2009-07-06 23:45:15 +02:00
|
|
|
that.isInstanceOf[MessageInvocation] &&
|
2009-10-06 00:07:27 +02:00
|
|
|
that.asInstanceOf[MessageInvocation].receiver == receiver &&
|
2009-07-28 17:48:11 +02:00
|
|
|
that.asInstanceOf[MessageInvocation].message == message
|
2009-10-06 00:07:27 +02:00
|
|
|
}
|
2009-12-13 12:29:18 +01:00
|
|
|
|
|
|
|
|
override def toString(): String = synchronized {
|
2009-12-08 16:17:22 +01:00
|
|
|
"MessageInvocation[" +
|
|
|
|
|
"\n\tmessage = " + message +
|
|
|
|
|
"\n\treceiver = " + receiver +
|
|
|
|
|
"\n\tsender = " + sender +
|
|
|
|
|
"\n\tfuture = " + future +
|
|
|
|
|
"\n\ttx = " + tx +
|
|
|
|
|
"\n]"
|
2009-10-06 00:07:27 +02:00
|
|
|
}
|
2009-05-25 14:48:43 +02:00
|
|
|
}
|
2009-12-13 12:29:18 +01:00
|
|
|
|
|
|
|
|
trait MessageQueue {
|
|
|
|
|
def append(handle: MessageInvocation)
|
|
|
|
|
def prepend(handle: MessageInvocation)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trait MessageInvoker {
|
|
|
|
|
def invoke(message: MessageInvocation)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trait MessageDispatcher {
|
|
|
|
|
protected val references = new ConcurrentHashMap[String, Actor]
|
|
|
|
|
def dispatch(invocation: MessageInvocation)
|
|
|
|
|
def start
|
|
|
|
|
def shutdown
|
|
|
|
|
def register(actor: Actor) = references.put(actor.uuid, actor)
|
|
|
|
|
def unregister(actor: Actor) = references.remove(actor.uuid)
|
|
|
|
|
def canBeShutDown: Boolean = references.isEmpty
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trait MessageDemultiplexer {
|
|
|
|
|
def select
|
|
|
|
|
def wakeUp
|
|
|
|
|
def acquireSelectedInvocations: List[MessageInvocation]
|
|
|
|
|
def releaseSelectedInvocations
|
|
|
|
|
}
|