Add typed actor/agent-combination as alternative messaging solution
From the discussion I started on the mailing list:
I have been thinking about type-parameterizing actors for quite a while now, because I don't like the fact that the type of the messages and answers is Any. Unfortunately it is not possible to have ask-answer-aware actors (or such that know their sender) which have type parameters for the messages and answers.
Therefore I have come up with a solution which is a combination of actors (that don't know their sender) and agents: Instead of (implicitly) passing the sender along with a message, an "answer handler" function is used. This would look like that:
The Future would be "based" on the answerHandler, e.g. like this:
From Jonas' answer:
I like the idea. One could create a GenericActor:
This would function as the current Actor.
Please commit the changes in a branch. If we add GenericActor then they don't need to be that intrusive. Wonder if there is anything we have missed or if all will play out nicely.
I have been thinking about type-parameterizing actors for quite a while now, because I don't like the fact that the type of the messages and answers is Any. Unfortunately it is not possible to have ask-answer-aware actors (or such that know their sender) which have type parameters for the messages and answers.
Therefore I have come up with a solution which is a combination of actors (that don't know their sender) and agents: Instead of (implicitly) passing the sender along with a message, an "answer handler" function is used. This would look like that:
trait Actor[M, A] { def !(message: M): Unit def !![T](message: M)(implicit answerHandler: A => T): Option[T] def !!![T](message: M)(implicit answerHandler: A => T): Future[T] def receive: PartialFunction[M, A] }
The Future would be "based" on the answerHandler, e.g. like this:
trait Future[T] { def get: T } private[typesafe] class AnswerHandlerFuture[A, T](answerHandler: A => T) extends Future[T] { def get = value getOrElse { throw new IllegalStateException } private[typesafe] def fulfill(answer: A) { value = Some(answerHandler(answer)) } private var value: Option[T] = None } // Just to show the answer handler concept: Concurrency handling not implemented! trait TrialActorImpl[M, A] extends Actor[M, A] { def !(message: M) { mailbox + (message -> None) } def !!![T](message: M)(implicit answerHandler: A => T) = { val future = new AnswerHandlerFuture(answerHandler) mailbox + (message -> Some(future)) future } def work() { val (message, futureOption) = mailbox.head futureOption match { case Some(future) => future fulfill receive(message) case None => receive(message) } } import scala.collection.mutable.Map private val mailbox: Map[M, Option[AnswerHandlerFuture[A, _]]] = Map.empty }
From Jonas' answer:
I like the idea. One could create a GenericActor:
trait GenericActor extends Actor[Any, Any] { override def !![Any](message: Any)(implicit answerHandler: Any => Any = (a: Any) => a): Option[Any] override def !!![Any](message: Any)(implicit answerHandler: Any => Any = (a: Any) => a): Future[Any] }
This would function as the current Actor.
Please commit the changes in a branch. If we add GenericActor then they don't need to be that intrusive. Wonder if there is anything we have missed or if all will play out nicely.
Leave a comment
on 2010-07-13 10:52 *
By Heiko Seeberger
Milestone changed from 0.10 to 0.11
Summary changed from Make actors typed to Add typed actor/agent-combination as alternative messaging solution
on 2010-09-02 07:20 *
By Jonas Bonér
Heiko,
What is the status on this one?
Do you want to do it or should we close it?
What is the status on this one?
Do you want to do it or should we close it?
on 2011-01-13 00:53 *
By Heiko Seeberger
Assigned to changed from Heiko Seeberger to -none-
Status changed from Accepted to New
Sorry, but no time for that.
This ticket starved to death.