document RemoteRouterConfig, see #1846

- fix Java API
- change to pass in Addresses so that validation happens earlier
This commit is contained in:
Roland 2012-02-21 15:37:51 +01:00
parent 2d765718cf
commit ef0af0b47f
7 changed files with 56 additions and 11 deletions

View file

@ -5,10 +5,13 @@ package akka.docs.jrouting;
import akka.routing.RoundRobinRouter;
import akka.routing.DefaultResizer;
import akka.routing.RemoteRouterConfig;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.actor.ActorSystem;
import akka.actor.Address;
import akka.actor.AddressExtractor;
import java.util.Arrays;
public class RouterViaProgramExample {
@ -67,6 +70,14 @@ public class RouterViaProgramExample {
for (int i = 1; i <= 6; i++) {
router3.tell(new ExampleActor.Message(i));
}
//#remoteRoutees
Address addr1 = new Address("akka", "remotesys", "otherhost", 1234);
Address addr2 = AddressExtractor.parse("akka://othersys@anotherhost:1234");
Address[] addresses = new Address[] { addr1, addr2 };
ActorRef routerRemote = system.actorOf(new Props(ExampleActor.class)
.withRouter(new RemoteRouterConfig(new RoundRobinRouter(5), addresses)));
//#remoteRoutees
}
private class CompileCheckJavaDocsForRouting extends UntypedActor {

View file

@ -54,6 +54,18 @@ Once you have the router actor it is just to send messages to it as you would to
The router will apply its behavior to the message it receives and forward it to the routees.
Remotely Deploying Routees
**************************
In addition to being able to supply looked-up remote actors as routees, you can
make the router deploy its created children on a set of remote hosts; this will
be done in round-robin fashion. In order to do that, wrap the router
configuration in a :class:`RemoteRouterConfig`, attaching the remote addresses of
the nodes to deploy to. Naturally, this requires your to include the
``akka-remote`` module on your classpath:
.. includecode:: code/akka/docs/jrouting/RouterViaProgramExample.java#remoteRoutees
How Routing is Designed within Akka
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -6,6 +6,7 @@ package akka.docs.routing
import akka.routing.RoundRobinRouter
import akka.actor.{ ActorRef, Props, Actor, ActorSystem }
import akka.routing.DefaultResizer
import akka.routing.RemoteRouterConfig
case class Message1(nbr: Int)
@ -40,4 +41,13 @@ object RoutingProgrammaticallyExample extends App {
//#programmaticRoutingWithResizer
1 to 6 foreach { i router3 ! Message1(i) }
//#remoteRoutees
import akka.actor.{ Address, AddressExtractor }
val addresses = Seq(
Address("akka", "remotesys", "otherhost", 1234),
AddressExtractor("akka://othersys@anotherhost:1234"))
val routerRemote = system.actorOf(Props[ExampleActor1].withRouter(
RemoteRouterConfig(RoundRobinRouter(5), addresses)))
//#remoteRoutees
}

View file

@ -54,6 +54,18 @@ Once you have the router actor it is just to send messages to it as you would to
The router will apply its behavior to the message it receives and forward it to the routees.
Remotely Deploying Routees
**************************
In addition to being able to supply looked-up remote actors as routees, you can
make the router deploy its created children on a set of remote hosts; this will
be done in round-robin fashion. In order to do that, wrap the router
configuration in a :class:`RemoteRouterConfig`, attaching the remote addresses of
the nodes to deploy to. Naturally, this requires your to include the
``akka-remote`` module on your classpath:
.. includecode:: code/akka/docs/routing/RouterViaProgramExample.scala#remoteRoutees
How Routing is Designed within Akka
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -23,7 +23,7 @@ class RemoteDeployer(_settings: ActorSystem.Settings, _pm: DynamicAccess) extend
case AddressExtractor(r) Some(deploy.copy(scope = RemoteScope(r)))
case str
if (!str.isEmpty) throw new ConfigurationException("unparseable remote node name " + str)
val nodes = deploy.config.getStringList("target.nodes").asScala
val nodes = deploy.config.getStringList("target.nodes").asScala map (AddressExtractor(_))
if (nodes.isEmpty || deploy.routerConfig == NoRouter) d
else Some(deploy.copy(routerConfig = RemoteRouterConfig(deploy.routerConfig, nodes)))
}

View file

@ -14,6 +14,9 @@ import akka.config.ConfigurationException
import akka.remote.RemoteScope
import akka.actor.AddressExtractor
import akka.actor.SupervisorStrategy
import akka.actor.Address
import scala.collection.JavaConverters._
/**
* [[akka.routing.RouterConfig]] implementation for remote deployment on defined
@ -21,7 +24,10 @@ import akka.actor.SupervisorStrategy
* which makes it possible to mix this with the built-in routers such as
* [[akka.routing.RoundRobinRouter]] or custom routers.
*/
case class RemoteRouterConfig(local: RouterConfig, nodes: Iterable[String]) extends RouterConfig {
case class RemoteRouterConfig(local: RouterConfig, nodes: Iterable[Address]) extends RouterConfig {
def this(local: RouterConfig, nodes: java.lang.Iterable[Address]) = this(local, nodes.asScala)
def this(local: RouterConfig, nodes: Array[Address]) = this(local, nodes: Iterable[Address])
override def createRouteeProvider(context: ActorContext) = new RemoteRouteeProvider(nodes, context, resizer)
@ -49,17 +55,11 @@ case class RemoteRouterConfig(local: RouterConfig, nodes: Iterable[String]) exte
*
* Routee paths may not be combined with remote target nodes.
*/
class RemoteRouteeProvider(nodes: Iterable[String], _context: ActorContext, _resizer: Option[Resizer])
class RemoteRouteeProvider(nodes: Iterable[Address], _context: ActorContext, _resizer: Option[Resizer])
extends RouteeProvider(_context, _resizer) {
// need this iterator as instance variable since Resizer may call createRoutees several times
private val nodeAddressIter = {
val nodeAddresses = nodes map {
case AddressExtractor(a) a
case x throw new ConfigurationException("unparseable remote node " + x)
}
Stream.continually(nodeAddresses).flatten.iterator
}
private val nodeAddressIter = Stream.continually(nodes).flatten.iterator
override def createRoutees(props: Props, nrOfInstances: Int, routees: Iterable[String]): IndexedSeq[ActorRef] =
(nrOfInstances, routees, nodes) match {

View file

@ -90,7 +90,7 @@ akka.actor.deployment {
"deploy its children on remote host driven by programatic definition" in {
val router = system.actorOf(Props[Echo].withRouter(new RemoteRouterConfig(RoundRobinRouter(2),
Seq("akka://remote_sys@localhost:12347"))), "blub2")
Seq(Address("akka", "remote_sys", "localhost", 12347)))), "blub2")
val replies = for (i 1 to 5) yield {
router ! ""
expectMsgType[ActorRef].path