document RemoteRouterConfig, see #1846
- fix Java API - change to pass in Addresses so that validation happens earlier
This commit is contained in:
parent
2d765718cf
commit
ef0af0b47f
7 changed files with 56 additions and 11 deletions
|
|
@ -5,10 +5,13 @@ package akka.docs.jrouting;
|
||||||
|
|
||||||
import akka.routing.RoundRobinRouter;
|
import akka.routing.RoundRobinRouter;
|
||||||
import akka.routing.DefaultResizer;
|
import akka.routing.DefaultResizer;
|
||||||
|
import akka.routing.RemoteRouterConfig;
|
||||||
import akka.actor.ActorRef;
|
import akka.actor.ActorRef;
|
||||||
import akka.actor.Props;
|
import akka.actor.Props;
|
||||||
import akka.actor.UntypedActor;
|
import akka.actor.UntypedActor;
|
||||||
import akka.actor.ActorSystem;
|
import akka.actor.ActorSystem;
|
||||||
|
import akka.actor.Address;
|
||||||
|
import akka.actor.AddressExtractor;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class RouterViaProgramExample {
|
public class RouterViaProgramExample {
|
||||||
|
|
@ -67,6 +70,14 @@ public class RouterViaProgramExample {
|
||||||
for (int i = 1; i <= 6; i++) {
|
for (int i = 1; i <= 6; i++) {
|
||||||
router3.tell(new ExampleActor.Message(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 {
|
private class CompileCheckJavaDocsForRouting extends UntypedActor {
|
||||||
|
|
|
||||||
|
|
@ -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.
|
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
|
How Routing is Designed within Akka
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package akka.docs.routing
|
||||||
import akka.routing.RoundRobinRouter
|
import akka.routing.RoundRobinRouter
|
||||||
import akka.actor.{ ActorRef, Props, Actor, ActorSystem }
|
import akka.actor.{ ActorRef, Props, Actor, ActorSystem }
|
||||||
import akka.routing.DefaultResizer
|
import akka.routing.DefaultResizer
|
||||||
|
import akka.routing.RemoteRouterConfig
|
||||||
|
|
||||||
case class Message1(nbr: Int)
|
case class Message1(nbr: Int)
|
||||||
|
|
||||||
|
|
@ -40,4 +41,13 @@ object RoutingProgrammaticallyExample extends App {
|
||||||
//#programmaticRoutingWithResizer
|
//#programmaticRoutingWithResizer
|
||||||
1 to 6 foreach { i ⇒ router3 ! Message1(i) }
|
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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -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.
|
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
|
How Routing is Designed within Akka
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class RemoteDeployer(_settings: ActorSystem.Settings, _pm: DynamicAccess) extend
|
||||||
case AddressExtractor(r) ⇒ Some(deploy.copy(scope = RemoteScope(r)))
|
case AddressExtractor(r) ⇒ Some(deploy.copy(scope = RemoteScope(r)))
|
||||||
case str ⇒
|
case str ⇒
|
||||||
if (!str.isEmpty) throw new ConfigurationException("unparseable remote node name " + 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
|
if (nodes.isEmpty || deploy.routerConfig == NoRouter) d
|
||||||
else Some(deploy.copy(routerConfig = RemoteRouterConfig(deploy.routerConfig, nodes)))
|
else Some(deploy.copy(routerConfig = RemoteRouterConfig(deploy.routerConfig, nodes)))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ import akka.config.ConfigurationException
|
||||||
import akka.remote.RemoteScope
|
import akka.remote.RemoteScope
|
||||||
import akka.actor.AddressExtractor
|
import akka.actor.AddressExtractor
|
||||||
import akka.actor.SupervisorStrategy
|
import akka.actor.SupervisorStrategy
|
||||||
|
import akka.actor.Address
|
||||||
|
|
||||||
|
import scala.collection.JavaConverters._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [[akka.routing.RouterConfig]] implementation for remote deployment on defined
|
* [[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
|
* which makes it possible to mix this with the built-in routers such as
|
||||||
* [[akka.routing.RoundRobinRouter]] or custom routers.
|
* [[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)
|
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.
|
* 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) {
|
extends RouteeProvider(_context, _resizer) {
|
||||||
|
|
||||||
// need this iterator as instance variable since Resizer may call createRoutees several times
|
// need this iterator as instance variable since Resizer may call createRoutees several times
|
||||||
private val nodeAddressIter = {
|
private val nodeAddressIter = Stream.continually(nodes).flatten.iterator
|
||||||
val nodeAddresses = nodes map {
|
|
||||||
case AddressExtractor(a) ⇒ a
|
|
||||||
case x ⇒ throw new ConfigurationException("unparseable remote node " + x)
|
|
||||||
}
|
|
||||||
Stream.continually(nodeAddresses).flatten.iterator
|
|
||||||
}
|
|
||||||
|
|
||||||
override def createRoutees(props: Props, nrOfInstances: Int, routees: Iterable[String]): IndexedSeq[ActorRef] =
|
override def createRoutees(props: Props, nrOfInstances: Int, routees: Iterable[String]): IndexedSeq[ActorRef] =
|
||||||
(nrOfInstances, routees, nodes) match {
|
(nrOfInstances, routees, nodes) match {
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ akka.actor.deployment {
|
||||||
|
|
||||||
"deploy its children on remote host driven by programatic definition" in {
|
"deploy its children on remote host driven by programatic definition" in {
|
||||||
val router = system.actorOf(Props[Echo].withRouter(new RemoteRouterConfig(RoundRobinRouter(2),
|
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 {
|
val replies = for (i ← 1 to 5) yield {
|
||||||
router ! ""
|
router ! ""
|
||||||
expectMsgType[ActorRef].path
|
expectMsgType[ActorRef].path
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue