+doc #15537 add Typed router pattern

Conflicts:
	akka-docs/rst/scala/code/docs/persistence/PersistenceDocSpec.scala
This commit is contained in:
Konrad 'ktoso' Malawski 2014-07-14 14:51:09 +02:00
parent 76bc8afe8c
commit ba2411833a
5 changed files with 205 additions and 24 deletions

View file

@ -9,16 +9,22 @@ import akka.actor.TypedActor;
import akka.actor.*;
import akka.japi.*;
import akka.dispatch.Futures;
import scala.concurrent.Await;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
import java.util.concurrent.TimeUnit;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import akka.routing.RoundRobinGroup;
//#imports
import java.lang.Exception;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
//#imports
public class TypedActorDocTest {
Object someReference = null;
ActorSystem system = null;
@ -190,4 +196,58 @@ public class TypedActorDocTest {
//dun care
}
}
//#typed-router-types-1
interface HasName {
String name();
}
class Named implements HasName {
private int id = new Random().nextInt(1024);
@Override public String name() { return "name-" + id; }
}
//#typed-router-types
@Test public void typedRouterPattern() {
try {
//#typed-router
// prepare routees
TypedActorExtension typed = TypedActor.get(system);
Named named1 =
typed.typedActorOf(new TypedProps<Named>(Named.class));
Named named2 =
typed.typedActorOf(new TypedProps<Named>(Named.class));
List<Named> routees = new ArrayList<Named>();
routees.add(named1);
routees.add(named2);
List<String> routeePaths = new ArrayList<String>();
routeePaths.add(typed.getActorRefFor(named1).path().toStringWithoutAddress());
routeePaths.add(typed.getActorRefFor(named2).path().toStringWithoutAddress());
// prepare untyped router
ActorRef router = system.actorOf(new RoundRobinGroup(routeePaths).props(), "router");
// prepare typed proxy, forwarding MethodCall messages to `router`
Named typedRouter = typed.typedActorOf(new TypedProps<Named>(Named.class), router);
System.out.println("actor was: " + typedRouter.name()); // name-243
System.out.println("actor was: " + typedRouter.name()); // name-614
System.out.println("actor was: " + typedRouter.name()); // name-243
System.out.println("actor was: " + typedRouter.name()); // name-614
//#typed-router
typed.poisonPill(named1);
typed.poisonPill(named2);
typed.poisonPill(typedRouter);
} catch (Exception e) {
//dun care
}
}
}

View file

@ -221,3 +221,21 @@ Lookup & Remoting
Since ``TypedActors`` are backed by ``Akka Actors``, you can use ``typedActorOf`` to proxy ``ActorRefs`` potentially residing on remote nodes.
.. includecode:: code/docs/actor/TypedActorDocTest.java#typed-actor-remote
Typed Router pattern
--------------------
Sometimes you want to spread messages between multiple actors. The easiest way to achieve this in Akka is to use a :ref:`Router <routing-java>`,
which can implement a specific routing logic, such as ``smallest-mailbox`` or ``consistent-hashing`` etc.
Routers are not provided directly for typed actors, but it is really easy to leverage an untyped router and use a typed proxy in front of it.
To showcase this let's create typed actors that assign themselves some random ``id``, so we know that in fact, the router has sent the message to different actors:
.. includecode:: code/docs/actor/TypedActorDocTest.java#typed-router-types
In order to round robin among a few instances of such actors, you can simply create a plain untyped router,
and then facade it with a ``TypedActor`` like shown in the example below. This works because typed actors of course
communicate using the same mechanisms as normal actors, and methods calls on them get transformed into message sends of ``MethodCall`` messages.
.. includecode:: code/docs/actor/TypedActorDocTest.java#typed-router