diff --git a/akka-actor/src/main/scala/akka/routing/Routing.scala b/akka-actor/src/main/scala/akka/routing/Routing.scala index b285d6783a..15ec9653a9 100644 --- a/akka-actor/src/main/scala/akka/routing/Routing.scala +++ b/akka-actor/src/main/scala/akka/routing/Routing.scala @@ -4,7 +4,9 @@ package akka.routing -import akka.actor.{ UntypedActor, Actor, ActorRef } +//TODO: This will package is going to be removed. + +import akka.actor.{ UntypedActor, Actor} import akka.actor.Actor._ import akka.actor.ActorRef @@ -203,7 +205,9 @@ case class CyclicIterator[T](val items: Seq[T]) extends InfiniteIterator[T] { * useful for work-stealing. */ case class SmallestMailboxFirstIterator(val items: Seq[ActorRef]) extends InfiniteIterator[ActorRef] { + def this(items: java.util.List[ActorRef]) = this(items.toList) + def hasNext = items != Nil def next = items.reduceLeft((a1, a2) ⇒ if (a1.dispatcher.mailboxSize(a1) < a2.dispatcher.mailboxSize(a2)) a1 else a2) diff --git a/akka-cluster/src/main/scala/akka/cluster/Routing.scala b/akka-cluster/src/main/scala/akka/cluster/Routing.scala index c9db1e7208..36a2393be6 100644 --- a/akka-cluster/src/main/scala/akka/cluster/Routing.scala +++ b/akka-cluster/src/main/scala/akka/cluster/Routing.scala @@ -20,6 +20,7 @@ import java.util.concurrent.atomic.AtomicReference * @author Jonas Bonér */ object Router { + def newRouter( routerType: RouterType, inetSocketAddresses: Array[Tuple2[UUID, InetSocketAddress]], @@ -36,16 +37,35 @@ object Router { } /** + * The Router is responsible for sending a message to one (or more) of its connections. + * * @author Jonas Bonér */ trait Router { + /** + * Returns a Map containing all ActorRefs this Router uses send messages to. + */ def connections: Map[InetSocketAddress, ActorRef] + /** + * A callback this Router uses to indicate that some actorRef was not usable. + * + * Implementations should make sure that this method can be called without the actorRef being part of the + * current set of connections. The most logical way to deal with this situation, is just to ignore it. + * + * @param ref the dead + */ def signalDeadActor(ref: ActorRef): Unit + /** + * + */ def route(message: Any)(implicit sender: Option[ActorRef]): Unit + /** + * + */ def route[T](message: Any, timeout: Long)(implicit sender: Option[ActorRef]): Future[T] } @@ -94,6 +114,11 @@ object Router { } /** + * A Router that is used when a durable actor is used. All requests are send to the node containing the actor. + * As soon as that instance fails, a different instance is created and since the mailbox is durable, the internal + * state can be restored using event sourcing, and once this instance is up and running, all request will be send + * to this instance. + * * @author Jonas Bonér */ trait Direct extends BasicRouter { @@ -106,9 +131,12 @@ object Router { } /** + * A Router that randomly selects one of the target connections to send a message to. + * * @author Jonas Bonér */ trait Random extends BasicRouter { + private val random = new java.util.Random(System.currentTimeMillis) def next: Option[ActorRef] = @@ -121,6 +149,8 @@ object Router { } /** + * A Router that uses round-robin to select a connection. + * * @author Jonas Bonér */ trait RoundRobin extends BasicRouter {