Added reply methods to Actor trait + fixed race-condition in Actor.spawn

This commit is contained in:
Jonas Bonér 2010-06-07 09:06:42 +02:00
parent 7afe411f8b
commit 22fe2ac8a7
2 changed files with 25 additions and 5 deletions

View file

@ -228,12 +228,11 @@ object Actor extends Logging {
def spawn(body: => Unit): Unit = {
case object Spawn
actorOf(new Actor() {
self.start
self ! Spawn
def receive = {
case Spawn => body; self.stop
}
})
}).start ! Spawn
}
}
@ -413,6 +412,22 @@ trait Actor extends Logging {
*/
def initTransactionalState {}
/**
* Use <code>reply(..)</code> to reply with a message to the original sender of the message currently
* being processed.
* <p/>
* Throws an IllegalStateException if unable to determine what to reply to.
*/
def reply(message: Any) = self.reply(message)
/**
* Use <code>reply_?(..)</code> to reply with a message to the original sender of the message currently
* being processed.
* <p/>
* Returns true if reply was sent, and false if unable to determine what to reply to.
*/
def reply_?(message: Any): Boolean = self.reply_?(message)
// =========================================
// ==== INTERNAL IMPLEMENTATION DETAILS ====
// =========================================

View file

@ -7,7 +7,7 @@ package se.scalablesolutions.akka.dispatch
import java.util.List
import se.scalablesolutions.akka.util.{HashCode, Logging}
import se.scalablesolutions.akka.actor.{Actor, ActorRef}
import se.scalablesolutions.akka.actor.{Actor, ActorRef, ActorInitializationException}
import java.util.concurrent.ConcurrentHashMap
@ -23,7 +23,12 @@ final class MessageInvocation(val receiver: ActorRef,
val transactionSet: Option[CountDownCommitBarrier]) {
if (receiver eq null) throw new IllegalArgumentException("receiver is null")
def invoke = receiver.invoke(this)
def invoke = try {
receiver.invoke(this)
} catch {
case e: NullPointerException => throw new ActorInitializationException(
"Don't call 'self ! message' in the Actor's constructor (e.g. body of the class).")
}
def send = receiver.dispatcher.dispatch(this)