Deprecate actorFor in favor of ActorSelection, see #3074

* Deprecate all actorFor methods
* resolveActorRef in provider
* Identify auto receive message
* Support ActorPath in actorSelection
* Support remote actor selections
* Additional tests of actor selection
* Update tests (keep most actorFor tests)
* Update samples to use actorSelection
* Updates to documentation
* Migration guide, including motivation
This commit is contained in:
Patrik Nordwall 2013-03-26 18:17:50 +01:00
parent 641e499cc4
commit 887af975ae
80 changed files with 1496 additions and 619 deletions

View file

@ -176,12 +176,13 @@ public class TypedActorDocTestBase {
@Test public void proxyAnyActorRef() {
try {
final ActorRef actorRefToRemoteActor = system.deadLetters();
//#typed-actor-remote
Squarer typedActor =
TypedActor.get(system).
typedActorOf(
new TypedProps<Squarer>(Squarer.class),
system.actorFor("akka://SomeSystem@somehost:2552/user/some/foobar")
actorRefToRemoteActor
);
//Use "typedActor" as a FooBar
//#typed-actor-remote

View file

@ -15,6 +15,7 @@ import akka.dispatch.Futures;
import akka.dispatch.Mapper;
import scala.concurrent.Await;
import scala.concurrent.duration.Duration;
import akka.testkit.AkkaSpec;
import akka.util.Timeout;
//#import-future
@ -31,6 +32,12 @@ import akka.japi.Procedure;
import akka.actor.Terminated;
//#import-watch
//#import-identify
import akka.actor.ActorSelection;
import akka.actor.Identify;
import akka.actor.ActorIdentity;
//#import-identify
//#import-gracefulStop
import static akka.pattern.Patterns.gracefulStop;
import scala.concurrent.Future;
@ -58,6 +65,8 @@ import akka.actor.UntypedActor;
import akka.actor.UntypedActorFactory;
import org.junit.Test;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import scala.Option;
import java.lang.Object;
import java.util.Iterator;
@ -65,6 +74,19 @@ import akka.pattern.Patterns;
public class UntypedActorDocTestBase {
private static ActorSystem system;
@BeforeClass
public static void beforeAll() {
system = ActorSystem.create("MySystem", AkkaSpec.testConf());
}
@AfterClass
public static void afterAll() {
system.shutdown();
system = null;
}
@Test
public void createProps() {
//#creating-props-config
@ -96,86 +118,71 @@ public class UntypedActorDocTestBase {
@Test
public void contextActorOf() {
//#context-actorOf
ActorSystem system = ActorSystem.create("MySystem");
ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class), "myactor");
ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class), "myactor2");
//#context-actorOf
myActor.tell("test", null);
system.shutdown();
}
@Test
public void constructorActorOf() {
ActorSystem system = ActorSystem.create("MySystem");
//#creating-constructor
// allows passing in arguments to the MyActor constructor
ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new MyActor("...");
}
}), "myactor");
}), "myactor3");
//#creating-constructor
myActor.tell("test", null);
system.shutdown();
}
@Test
public void propsActorOf() {
ActorSystem system = ActorSystem.create("MySystem");
//#creating-props
ActorRef myActor = system.actorOf(
new Props(MyUntypedActor.class).withDispatcher("my-dispatcher"), "myactor");
new Props(MyUntypedActor.class).withDispatcher("my-dispatcher"), "myactor4");
//#creating-props
myActor.tell("test", null);
system.shutdown();
}
@Test
public void usingAsk() throws Exception {
ActorSystem system = ActorSystem.create("MySystem");
ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new MyAskActor();
}
}), "myactor");
}), "myactor5");
//#using-ask
Future<Object> future = Patterns.ask(myActor, "Hello", 1000);
Object result = Await.result(future, Duration.create(1, TimeUnit.SECONDS));
//#using-ask
system.shutdown();
}
@Test
public void receiveTimeout() {
ActorSystem system = ActorSystem.create("MySystem");
ActorRef myActor = system.actorOf(new Props(MyReceivedTimeoutUntypedActor.class));
myActor.tell("Hello", null);
system.shutdown();
}
@Test
public void usePoisonPill() {
ActorSystem system = ActorSystem.create("MySystem");
ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class));
//#poison-pill
myActor.tell(PoisonPill.getInstance(), null);
//#poison-pill
system.shutdown();
}
@Test
public void useKill() {
ActorSystem system = ActorSystem.create("MySystem");
ActorRef victim = system.actorOf(new Props(MyUntypedActor.class));
//#kill
victim.tell(Kill.getInstance(), null);
//#kill
system.shutdown();
}
@Test
public void useBecome() {
ActorSystem system = ActorSystem.create("MySystem");
ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new HotSwapActor();
@ -184,21 +191,24 @@ public class UntypedActorDocTestBase {
myActor.tell("foo", null);
myActor.tell("bar", null);
myActor.tell("bar", null);
system.shutdown();
}
@Test
public void useWatch() throws Exception {
ActorSystem system = ActorSystem.create("MySystem");
ActorRef myActor = system.actorOf(new Props(WatchActor.class));
Future<Object> future = Patterns.ask(myActor, "kill", 1000);
assert Await.result(future, Duration.create("1 second")).equals("finished");
system.shutdown();
}
@Test
public void useIdentify() throws Exception {
ActorRef a = system.actorOf(new Props(MyUntypedActor.class), "another");
ActorRef b = system.actorOf(new Props(Follower.class));
system.stop(a);
}
@Test
public void usePatternsGracefulStop() throws Exception {
ActorSystem system = ActorSystem.create("MySystem");
ActorRef actorRef = system.actorOf(new Props(MyUntypedActor.class));
//#gracefulStop
try {
@ -210,7 +220,6 @@ public class UntypedActorDocTestBase {
// the actor wasn't stopped within 5 seconds
}
//#gracefulStop
system.shutdown();
}
class Result {
@ -225,7 +234,6 @@ public class UntypedActorDocTestBase {
@Test
public void usePatternsAskPipe() {
ActorSystem system = ActorSystem.create("MySystem");
ActorRef actorA = system.actorOf(new Props(MyUntypedActor.class));
ActorRef actorB = system.actorOf(new Props(MyUntypedActor.class));
ActorRef actorC = system.actorOf(new Props(MyUntypedActor.class));
@ -251,7 +259,6 @@ public class UntypedActorDocTestBase {
pipe(transformed, system.dispatcher()).to(actorC);
//#ask-pipe
system.shutdown();
}
public static class MyActor extends UntypedActor {
@ -399,4 +406,40 @@ public class UntypedActorDocTestBase {
}
//#watch
static
//#identify
public class Follower extends UntypedActor {
String identifyId = "1";
{
ActorSelection selection =
getContext().actorSelection("/user/another");
selection.tell(new Identify(identifyId), getSelf());
}
ActorRef another;
@Override
public void onReceive(Object message) {
if (message instanceof ActorIdentity) {
ActorIdentity identity = (ActorIdentity) message;
if (identity.correlationId().equals(identifyId)) {
ActorRef ref = identity.getRef();
if (ref == null)
getContext().stop(getSelf());
else {
another = ref;
getContext().watch(another);
}
}
} else if (message instanceof Terminated) {
final Terminated t = (Terminated) message;
if (t.getActor().equals(another)) {
getContext().stop(getSelf());
}
} else {
unhandled(message);
}
}
}
//#identify
}

View file

@ -49,10 +49,10 @@ public class SerializationDocTestBase {
//#my-own-serializer
@Test public void serializeActorRefs() {
final ActorSystem theActorSystem =
final ExtendedActorSystem extendedSystem = (ExtendedActorSystem)
ActorSystem.create("whatever");
final ActorRef theActorRef =
theActorSystem.deadLetters(); // Of course this should be you
extendedSystem.deadLetters(); // Of course this should be you
//#actorref-serializer
// Serialize
@ -63,10 +63,10 @@ public class SerializationDocTestBase {
// Deserialize
// (beneath fromBinary)
final ActorRef deserializedActorRef = theActorSystem.actorFor(identifier);
final ActorRef deserializedActorRef = extendedSystem.provider().resolveActorRef(identifier);
// Then just use the ActorRef
//#actorref-serializer
theActorSystem.shutdown();
extendedSystem.shutdown();
}
static
@ -150,7 +150,7 @@ public class SerializationDocTestBase {
return new DefaultAddressExt(system);
}
}
//#external-address-default
public void demonstrateDefaultAddress() {

View file

@ -16,6 +16,7 @@ import akka.actor.ActorKilledException;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Kill;
import akka.actor.PoisonPill;
import akka.actor.Props;
import akka.actor.Terminated;
import akka.actor.UntypedActor;
@ -30,7 +31,7 @@ import akka.testkit.JavaTestKit;
import scala.concurrent.duration.Duration;
public class TestKitDocTest {
//#test-actor-ref
static class MyActor extends UntypedActor {
public void onReceive(Object o) throws Exception {
@ -42,18 +43,18 @@ public class TestKitDocTest {
}
public boolean testMe() { return true; }
}
//#test-actor-ref
private static ActorSystem system;
@BeforeClass
public static void setup() {
final Config config = ConfigFactory.parseString(
"akka.loggers = [akka.testkit.TestEventListener]");
system = ActorSystem.create("demoSystem", config);
}
@AfterClass
public static void cleanup() {
system.shutdown();
@ -68,7 +69,7 @@ public class TestKitDocTest {
assertTrue(actor.testMe());
}
//#test-actor-ref
@Test
public void demonstrateAsk() throws Exception {
//#test-behavior
@ -79,7 +80,7 @@ public class TestKitDocTest {
assertEquals(42, Await.result(future, Duration.Zero()));
//#test-behavior
}
@Test
public void demonstrateExceptions() {
//#test-expecting-exceptions
@ -93,7 +94,7 @@ public class TestKitDocTest {
}
//#test-expecting-exceptions
}
@Test
public void demonstrateWithin() {
//#test-within
@ -108,7 +109,7 @@ public class TestKitDocTest {
}};
//#test-within
}
@Test
public void demonstrateExpectMsg() {
//#test-expectmsg
@ -128,7 +129,7 @@ public class TestKitDocTest {
}};
//#test-expectmsg
}
@Test
public void demonstrateReceiveWhile() {
//#test-receivewhile
@ -136,7 +137,7 @@ public class TestKitDocTest {
getRef().tell(42, null);
getRef().tell(43, null);
getRef().tell("hello", null);
final String[] out =
final String[] out =
new ReceiveWhile<String>(String.class, duration("1 second")) {
// do not put code outside this method, will run afterwards
protected String match(Object in) {
@ -168,7 +169,7 @@ public class TestKitDocTest {
//#test-receivewhile-full
}};
}
@Test
public void demonstrateAwaitCond() {
//#test-awaitCond
@ -205,7 +206,7 @@ public class TestKitDocTest {
}};
//#test-awaitAssert
}
@Test
@SuppressWarnings("unchecked") // due to generic varargs
public void demonstrateExpect() {
@ -236,7 +237,7 @@ public class TestKitDocTest {
assertArrayEquals(new String[] {"hello", "world"}, all);
}};
}
@Test
public void demonstrateIgnoreMsg() {
//#test-ignoreMsg
@ -268,7 +269,7 @@ public class TestKitDocTest {
}};
//#duration-dilation
}
@Test
public void demonstrateProbe() {
//#test-probe
@ -282,11 +283,11 @@ public class TestKitDocTest {
target.forward(msg, getContext());
}
}
new JavaTestKit(system) {{
// create a test probe
final JavaTestKit probe = new JavaTestKit(system);
// create a forwarder, injecting the probes testActor
final Props props = new Props(new UntypedActorFactory() {
private static final long serialVersionUID = 8927158735963950216L;
@ -295,7 +296,7 @@ public class TestKitDocTest {
}
});
final ActorRef forwarder = system.actorOf(props, "forwarder");
// verify correct forwarding
forwarder.tell(42, getRef());
probe.expectMsgEquals(42);
@ -303,7 +304,7 @@ public class TestKitDocTest {
}};
//#test-probe
}
@Test
public void demonstrateSpecialProbe() {
//#test-special-probe
@ -323,20 +324,21 @@ public class TestKitDocTest {
}};
//#test-special-probe
}
@Test
public void demonstrateWatch() {
final ActorRef target = system.actorFor("/buh");
final ActorRef target = system.actorOf(new Props(MyActor.class));
//#test-probe-watch
new JavaTestKit(system) {{
final JavaTestKit probe = new JavaTestKit(system);
probe.watch(target);
target.tell(PoisonPill.getInstance(), null);
final Terminated msg = probe.expectMsgClass(Terminated.class);
assertEquals(msg.getActor(), target);
}};
//#test-probe-watch
}
@Test
public void demonstrateReply() {
//#test-probe-reply
@ -350,7 +352,7 @@ public class TestKitDocTest {
}};
//#test-probe-reply
}
@Test
public void demonstrateForward() {
//#test-probe-forward
@ -364,7 +366,7 @@ public class TestKitDocTest {
}};
//#test-probe-forward
}
@Test
public void demonstrateWithinProbe() {
try {
@ -382,7 +384,7 @@ public class TestKitDocTest {
// expected to fail
}
}
@Test
public void demonstrateAutoPilot() {
//#test-auto-pilot
@ -404,7 +406,7 @@ public class TestKitDocTest {
}};
//#test-auto-pilot
}
// only compilation
public void demonstrateCTD() {
//#calling-thread-dispatcher
@ -413,24 +415,24 @@ public class TestKitDocTest {
.withDispatcher(CallingThreadDispatcher.Id()));
//#calling-thread-dispatcher
}
@Test
public void demonstrateEventFilter() {
//#test-event-filter
new JavaTestKit(system) {{
assertEquals("demoSystem", system.name());
final ActorRef victim = system.actorOf(Props.empty(), "victim");
final int result = new EventFilter<Integer>(ActorKilledException.class) {
protected Integer run() {
victim.tell(Kill.getInstance(), null);
return 42;
}
}.from("akka://demoSystem/user/victim").occurrences(1).exec();
assertEquals(42, result);
}};
//#test-event-filter
}
}