deprecate closure-taking Props factories, see #3081

- base Props on Deploy, Class and Seq[Any] (i.e. constructor args)
- remove deprecated Props usage from akka-docs sample code
- rewrite UntypedActorDocTestBase
- rewrite Java/Scala doc section on actor creation
- add migration guide entry
This commit is contained in:
Roland 2013-04-14 22:56:41 +02:00
parent 64f664a706
commit 28aad82b1a
80 changed files with 2268 additions and 1641 deletions

View file

@ -186,7 +186,7 @@ public class FSMDocTestBase {
@org.junit.Test
public void mustBunch() {
final ActorRef buncher = system.actorOf(new Props(MyFSM.class));
final ActorRef buncher = system.actorOf(Props.create(MyFSM.class));
final TestProbe probe = new TestProbe(system);
buncher.tell(new SetTarget(probe.ref()), null);
buncher.tell(new Queue(1), null);

View file

@ -30,7 +30,6 @@ import static java.util.concurrent.TimeUnit.SECONDS;
import static akka.japi.Util.immutableSeq;
import akka.japi.Function;
import scala.Option;
import scala.collection.JavaConverters;
import scala.collection.immutable.Seq;
import org.junit.Test;
@ -171,10 +170,10 @@ public class FaultHandlingTestBase {
system.eventStream().publish(new TestEvent.Mute(ignoreExceptions));
//#create
Props superprops = new Props(Supervisor.class);
Props superprops = Props.create(Supervisor.class);
ActorRef supervisor = system.actorOf(superprops, "supervisor");
ActorRef child = (ActorRef) Await.result(ask(supervisor,
new Props(Child.class), 5000), timeout);
Props.create(Child.class), 5000), timeout);
//#create
//#resume
@ -198,7 +197,7 @@ public class FaultHandlingTestBase {
//#escalate-kill
child = (ActorRef) Await.result(ask(supervisor,
new Props(Child.class), 5000), timeout);
Props.create(Child.class), 5000), timeout);
probe.watch(child);
assert Await.result(ask(child, "get", 5000), timeout).equals(0);
child.tell(new Exception(), null);
@ -206,10 +205,10 @@ public class FaultHandlingTestBase {
//#escalate-kill
//#escalate-restart
superprops = new Props(Supervisor2.class);
superprops = Props.create(Supervisor2.class);
supervisor = system.actorOf(superprops);
child = (ActorRef) Await.result(ask(supervisor,
new Props(Child.class), 5000), timeout);
Props.create(Child.class), 5000), timeout);
child.tell(23, null);
assert Await.result(ask(child, "get", 5000), timeout).equals(23);
child.tell(new Exception(), null);
@ -219,6 +218,7 @@ public class FaultHandlingTestBase {
}
//#testkit
@SuppressWarnings("unchecked")
public <A> Seq<A> seq(A... args) {
return immutableSeq(args);
}

View file

@ -10,7 +10,7 @@ import akka.actor.UntypedActor;
//#context-actorOf
public class FirstUntypedActor extends UntypedActor {
ActorRef myActor = getContext().actorOf(new Props(MyActor.class), "myactor");
ActorRef myActor = getContext().actorOf(Props.create(MyActor.class), "myactor");
//#context-actorOf

View file

@ -78,7 +78,7 @@ public class InitializationDocSpecJava {
public void testIt() {
new JavaTestKit(system) {{
ActorRef testactor = system.actorOf(new Props(MessageInitExample.class), "testactor");
ActorRef testactor = system.actorOf(Props.create(MessageInitExample.class), "testactor");
String probe = "U OK?";
testactor.tell(probe, getRef());

View file

@ -4,13 +4,16 @@
package docs.actor;
//#receive-timeout
import akka.actor.ActorRef;
import akka.actor.ReceiveTimeout;
import akka.actor.UntypedActor;
import scala.concurrent.duration.Duration;
public class MyReceivedTimeoutUntypedActor extends UntypedActor {
public class MyReceiveTimeoutUntypedActor extends UntypedActor {
ActorRef target = getContext().system().deadLetters();
public MyReceivedTimeoutUntypedActor() {
public MyReceiveTimeoutUntypedActor() {
// To set an initial delay
getContext().setReceiveTimeout(Duration.create("30 seconds"));
}
@ -18,12 +21,13 @@ public class MyReceivedTimeoutUntypedActor extends UntypedActor {
public void onReceive(Object message) {
if (message.equals("Hello")) {
// To set in a response to a message
getContext().setReceiveTimeout(Duration.create("10 seconds"));
getSender().tell("Hello world", getSelf());
} else if (message == ReceiveTimeout.getInstance()) {
getContext().setReceiveTimeout(Duration.create("1 second"));
target = getSender();
target.tell("Hello world", getSelf());
} else if (message instanceof ReceiveTimeout) {
// To turn it off
getContext().setReceiveTimeout(Duration.Undefined());
throw new RuntimeException("received timeout");
target.tell("timeout", getSelf());
} else {
unhandled(message);
}

View file

@ -12,9 +12,10 @@ public class MyUntypedActor extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
public void onReceive(Object message) throws Exception {
if (message instanceof String)
if (message instanceof String) {
log.info("Received String message: {}", message);
else
getSender().tell(message, getSelf());
} else
unhandled(message);
}
}

View file

@ -10,9 +10,7 @@ import java.util.concurrent.TimeUnit;
//#imports1
//#imports2
import akka.actor.Actor;
import akka.actor.UntypedActor;
import akka.actor.UntypedActorFactory;
import akka.actor.Cancellable;
//#imports2
@ -32,7 +30,7 @@ public class SchedulerDocTestBase {
@Before
public void setUp() {
system = ActorSystem.create("MySystem", AkkaSpec.testConf());
testActor = system.actorOf(new Props(MyUntypedActor.class));
testActor = system.actorOf(Props.create(MyUntypedActor.class));
}
@After
@ -61,20 +59,18 @@ public class SchedulerDocTestBase {
@Test
public void scheduleRecurringTask() {
//#schedule-recurring
ActorRef tickActor = system.actorOf(new Props().withCreator(
new UntypedActorFactory() {
public UntypedActor create() {
return new UntypedActor() {
public void onReceive(Object message) {
if (message.equals("Tick")) {
// Do someting
} else {
unhandled(message);
}
}
};
class Ticker extends UntypedActor {
@Override
public void onReceive(Object message) {
if (message.equals("Tick")) {
// Do someting
} else {
unhandled(message);
}
}));
}
}
ActorRef tickActor = system.actorOf(Props.create(Ticker.class, this));
//This will schedule to send the Tick-message
//to the tickActor after 0ms repeating every 50ms

View file

@ -3,74 +3,82 @@
*/
package docs.actor;
//#imports
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
//#imports
//#import-future
import scala.concurrent.Future;
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
//#import-actors
import akka.actor.PoisonPill;
import akka.actor.Kill;
//#import-actors
//#import-procedure
import akka.japi.Procedure;
//#import-procedure
//#import-watch
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;
import scala.concurrent.Await;
import scala.concurrent.duration.Duration;
import akka.pattern.AskTimeoutException;
//#import-gracefulStop
//#import-askPipe
//#import-ask
import static akka.pattern.Patterns.ask;
import static akka.pattern.Patterns.pipe;
import scala.concurrent.Future;
import akka.dispatch.Futures;
import scala.concurrent.duration.Duration;
import akka.util.Timeout;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
//#import-askPipe
//#import-ask
//#import-gracefulStop
import static akka.pattern.Patterns.gracefulStop;
//#import-gracefulStop
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
//#import-gracefulStop
import scala.concurrent.Await;
//#import-ask
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
//#import-ask
//#import-gracefulStop
//#import-indirect
import akka.actor.Actor;
//#import-indirect
//#import-identify
import akka.actor.ActorIdentity;
//#import-identify
import akka.actor.ActorKilledException;
//#import-identify
import akka.actor.ActorSelection;
//#import-identify
//#import-actorRef
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
//#import-actorRef
//#import-identify
import akka.actor.Identify;
//#import-identify
//#import-indirect
import akka.actor.IndirectActorProducer;
//#import-indirect
import akka.actor.OneForOneStrategy;
//#import-props
import akka.actor.Props;
//#import-props
import akka.actor.SupervisorStrategy;
import akka.actor.SupervisorStrategy.Directive;
//#import-terminated
import akka.actor.Terminated;
//#import-terminated
//#import-untypedActor
import akka.actor.UntypedActor;
import akka.actor.UntypedActorFactory;
//#import-untypedActor
//#import-stash
import akka.actor.UntypedActorWithStash;
//#import-stash
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;
//#import-ask
import akka.dispatch.Futures;
import akka.dispatch.Mapper;
//#import-ask
import akka.japi.Function;
//#import-procedure
import akka.japi.Procedure;
//#import-procedure
//#import-gracefulStop
import akka.pattern.AskTimeoutException;
//#import-gracefulStop
import akka.pattern.Patterns;
import akka.testkit.AkkaSpec;
import akka.testkit.JavaTestKit;
//#import-ask
import akka.util.Timeout;
//#import-ask
public class UntypedActorDocTestBase {
@ -87,71 +95,148 @@ public class UntypedActorDocTestBase {
system = null;
}
@SuppressWarnings("unused")
@Test
public void createProps() {
//#creating-props-config
Props props1 = new Props();
Props props2 = new Props(MyUntypedActor.class);
Props props3 = new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new MyUntypedActor();
}
});
Props props4 = props1.withCreator(new UntypedActorFactory() {
public UntypedActor create() {
return new MyUntypedActor();
}
});
Props props1 = Props.create(MyUntypedActor.class);
Props props2 = Props.create(MyActor.class, "...");
//#creating-props-config
}
@SuppressWarnings("deprecation")
@Test
public void createPropsDeprecated() {
//#creating-props-deprecated
// DEPRECATED: encourages to close over enclosing class
final Props props1 = new Props(new UntypedActorFactory() {
private static final long serialVersionUID = 1L;
@Override
public UntypedActor create() throws Exception {
return new MyUntypedActor();
}
});
// DEPRECATED: encourages to close over enclosing class
final Props props2 = new Props().withCreator(new UntypedActorFactory() {
private static final long serialVersionUID = 1L;
@Override
public UntypedActor create() throws Exception {
return new MyUntypedActor();
}
});
// these are DEPRECATED due to duplicate functionality with Props.create()
final Props props3 = new Props(MyUntypedActor.class);
final Props props4 = new Props().withCreator(MyUntypedActor.class);
//#creating-props-deprecated
new JavaTestKit(system) {
{
for (Props props : new Props[] { props1, props2, props3, props4 }) {
final ActorRef a = system.actorOf(props);
a.tell("hello", getRef());
expectMsgEquals("hello");
}
}
};
}
@Test
public void systemActorOf() {
//#system-actorOf
ActorSystem system = ActorSystem.create("MySystem");
ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class), "myactor");
// ActorSystem is a heavy object: create only one per application
final ActorSystem system = ActorSystem.create("MySystem");
final ActorRef myActor = system.actorOf(Props.create(MyUntypedActor.class), "myactor");
//#system-actorOf
myActor.tell("test", null);
system.shutdown();
try {
new JavaTestKit(system) {
{
myActor.tell("hello", getRef());
expectMsgEquals("hello");
}
};
} finally {
system.shutdown();
}
}
@Test
public void contextActorOf() {
//#context-actorOf
ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class), "myactor2");
//#context-actorOf
myActor.tell("test", null);
}
@Test
public void constructorActorOf() {
//#creating-constructor
// allows passing in arguments to the MyActor constructor
ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new MyActor("...");
new JavaTestKit(system) {
{
//#context-actorOf
class A extends UntypedActor {
final ActorRef child =
getContext().actorOf(Props.create(MyUntypedActor.class), "myChild");
//#plus-some-behavior
@Override
public void onReceive(Object msg) {
getSender().tell(child, getSelf());
}
//#plus-some-behavior
}
//#context-actorOf
final ActorRef top = system.actorOf(Props.create(A.class, this));
top.tell("hello", getRef());
final ActorRef child = expectMsgClass(ActorRef.class);
child.tell("hello", getRef());
expectMsgEquals("hello");
}
}), "myactor3");
//#creating-constructor
myActor.tell("test", null);
};
}
// this is just to make the test below a tiny fraction nicer
private ActorSystem getContext() {
return system;
}
static
//#creating-indirectly
class DependencyInjector implements IndirectActorProducer {
final Object applicationContext;
final String beanName;
public DependencyInjector(Object applicationContext, String beanName) {
this.applicationContext = applicationContext;
this.beanName = beanName;
}
@Override
public Class<? extends Actor> actorClass() {
return MyActor.class;
}
@Override
public MyActor produce() {
MyActor result;
//#obtain-fresh-Actor-instance-from-DI-framework
result = new MyActor((String) applicationContext);
//#obtain-fresh-Actor-instance-from-DI-framework
return result;
}
}
//#creating-indirectly
@Test
public void propsActorOf() {
//#creating-props
ActorRef myActor = system.actorOf(
new Props(MyUntypedActor.class).withDispatcher("my-dispatcher"), "myactor4");
//#creating-props
myActor.tell("test", null);
public void indirectActorOf() {
final String applicationContext = "...";
//#creating-indirectly
final ActorRef myActor = getContext().actorOf(
Props.create(DependencyInjector.class, applicationContext, "MyActor"), "myactor3");
//#creating-indirectly
new JavaTestKit(system) {
{
myActor.tell("hello", getRef());
expectMsgEquals("...");
}
};
}
@SuppressWarnings("unused")
@Test
public void usingAsk() throws Exception {
ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new MyAskActor();
}
}), "myactor5");
ActorRef myActor = system.actorOf(Props.create(MyAskActor.class, this), "myactor5");
//#using-ask
Future<Object> future = Patterns.ask(myActor, "Hello", 1000);
@ -161,55 +246,181 @@ public class UntypedActorDocTestBase {
@Test
public void receiveTimeout() {
ActorRef myActor = system.actorOf(new Props(MyReceivedTimeoutUntypedActor.class));
myActor.tell("Hello", null);
final ActorRef myActor = system.actorOf(Props.create(MyReceiveTimeoutUntypedActor.class));
new JavaTestKit(system) {
{
new Within(Duration.create(1, TimeUnit.SECONDS), Duration.create(1500,
TimeUnit.MILLISECONDS)) {
@Override
protected void run() {
myActor.tell("Hello", getRef());
expectMsgEquals("Hello world");
expectMsgEquals("timeout");
}
};
}
};
}
@Test
public void usePoisonPill() {
ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class));
//#poison-pill
myActor.tell(PoisonPill.getInstance(), null);
//#poison-pill
final ActorRef myActor = system.actorOf(Props.create(MyUntypedActor.class));
new JavaTestKit(system) {
{
final ActorRef sender = getRef();
//#poison-pill
myActor.tell(akka.actor.PoisonPill.getInstance(), sender);
//#poison-pill
watch(myActor);
expectTerminated(myActor);
}
};
}
@Test
public void useKill() {
ActorRef victim = system.actorOf(new Props(MyUntypedActor.class));
//#kill
victim.tell(Kill.getInstance(), null);
//#kill
new JavaTestKit(system) {
{
class Master extends UntypedActor {
private SupervisorStrategy strategy = new OneForOneStrategy(-1,
Duration.Undefined(), new Function<Throwable, Directive>() {
@Override
public Directive apply(Throwable thr) {
if (thr instanceof ActorKilledException) {
target.tell("killed", getSelf());
getContext().stop(getSelf());
return SupervisorStrategy.stop();
}
return SupervisorStrategy.escalate();
}
});
final ActorRef target;
ActorRef child;
//#preStart
@Override
public void preStart() {
child = getContext().actorOf(Props.empty());
}
//#preStart
@SuppressWarnings("unused")
public Master(ActorRef target) {
this.target = target;
/*
* Only compilation of `forward` is verified here.
*/
final Object result = "";
//#forward
target.forward(result, getContext());
//#forward
}
@Override
public SupervisorStrategy supervisorStrategy() {
return strategy;
}
//#reply
@Override
public void onReceive(Object msg) {
Object result =
//#calculate-result
child;
//#calculate-result
// do not forget the second argument!
getSender().tell(result, getSelf());
}
//#reply
//#postStop
@Override
public void postStop() {
//#clean-up-resources-here
final String message = "stopped";
//#tell
// dont forget to think about who is the sender (2nd argument)
target.tell(message, getSelf());
//#tell
//#clean-up-resources-here
}
//#postStop
}
final ActorRef master = system.actorOf(Props.create(Master.class, this, getRef()));
expectMsgEquals("");
master.tell("", getRef());
final ActorRef victim = expectMsgClass(ActorRef.class);
//#kill
victim.tell(akka.actor.Kill.getInstance(), null);
//#kill
expectMsgEquals("killed");
expectMsgEquals("stopped");
assert getLastSender().equals(master);
}
};
}
@Test
public void useBecome() {
ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new HotSwapActor();
new JavaTestKit(system) {
{
ActorRef myActor = system.actorOf(Props.create(HotSwapActor.class));
myActor.tell("foo", getRef());
myActor.tell("bar", getRef());
expectMsgEquals("I am already happy :-)");
myActor.tell("bar", getRef());
expectMsgEquals("I am already happy :-)");
}
}));
myActor.tell("foo", null);
myActor.tell("bar", null);
myActor.tell("bar", null);
};
}
@Test
public void useWatch() throws Exception {
ActorRef myActor = system.actorOf(new Props(WatchActor.class));
ActorRef myActor = system.actorOf(Props.create(WatchActor.class));
Future<Object> future = Patterns.ask(myActor, "kill", 1000);
assert Await.result(future, Duration.create("1 second")).equals("finished");
}
// compilation test only
public void compileSelections() {
//#selection-local
// will look up this absolute path
getContext().actorSelection("/user/serviceA/actor");
// will look up sibling beneath same supervisor
getContext().actorSelection("../joe");
//#selection-local
//#selection-wildcard
// will look all children to serviceB with names starting with worker
getContext().actorSelection("/user/serviceB/worker*");
// will look up all siblings beneath same supervisor
getContext().actorSelection("../*");
//#selection-wildcard
//#selection-remote
getContext().actorSelection("akka.tcp://app@otherhost:1234/user/serviceB");
//#selection-remote
}
@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);
new JavaTestKit(system) {
{
ActorRef a = system.actorOf(Props.create(MyUntypedActor.class), "another");
ActorRef b = system.actorOf(Props.create(Follower.class, getRef()));
expectMsgEquals(a);
system.stop(a);
watch(b);
expectTerminated(b);
}
};
}
@Test
public void usePatternsGracefulStop() throws Exception {
ActorRef actorRef = system.actorOf(new Props(MyUntypedActor.class));
ActorRef actorRef = system.actorOf(Props.create(MyUntypedActor.class));
//#gracefulStop
try {
Future<Boolean> stopped =
@ -223,68 +434,143 @@ public class UntypedActorDocTestBase {
}
class Result {
final int x;
final String x;
final String s;
public Result(int x, String s) {
public Result(String x, String s) {
this.x = x;
this.s = s;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((s == null) ? 0 : s.hashCode());
result = prime * result + ((x == null) ? 0 : x.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Result other = (Result) obj;
if (s == null) {
if (other.s != null)
return false;
} else if (!s.equals(other.s))
return false;
if (x == null) {
if (other.x != null)
return false;
} else if (!x.equals(other.x))
return false;
return true;
}
}
@Test
public void usePatternsAskPipe() {
ActorRef actorA = system.actorOf(new Props(MyUntypedActor.class));
ActorRef actorB = system.actorOf(new Props(MyUntypedActor.class));
ActorRef actorC = system.actorOf(new Props(MyUntypedActor.class));
//#ask-pipe
final Timeout t = new Timeout(Duration.create(5, TimeUnit.SECONDS));
new JavaTestKit(system) {
{
ActorRef actorA = system.actorOf(Props.create(MyUntypedActor.class));
ActorRef actorB = system.actorOf(Props.create(MyUntypedActor.class));
ActorRef actorC = getRef();
final ArrayList<Future<Object>> futures = new ArrayList<Future<Object>>();
futures.add(ask(actorA, "request", 1000)); // using 1000ms timeout
futures.add(ask(actorB, "another request", t)); // using timeout from above
//#ask-pipe
final Timeout t = new Timeout(Duration.create(5, TimeUnit.SECONDS));
final Future<Iterable<Object>> aggregate =
Futures.sequence(futures, system.dispatcher());
final ArrayList<Future<Object>> futures = new ArrayList<Future<Object>>();
futures.add(ask(actorA, "request", 1000)); // using 1000ms timeout
futures.add(ask(actorB, "another request", t)); // using timeout from
// above
final Future<Result> transformed = aggregate.map(
new Mapper<Iterable<Object>, Result>() {
public Result apply(Iterable<Object> coll) {
final Iterator<Object> it = coll.iterator();
final String s = (String) it.next();
final int x = (Integer) it.next();
return new Result(x, s);
}
}, system.dispatcher());
final Future<Iterable<Object>> aggregate = Futures.sequence(futures,
system.dispatcher());
pipe(transformed, system.dispatcher()).to(actorC);
//#ask-pipe
final Future<Result> transformed = aggregate.map(
new Mapper<Iterable<Object>, Result>() {
public Result apply(Iterable<Object> coll) {
final Iterator<Object> it = coll.iterator();
final String x = (String) it.next();
final String s = (String) it.next();
return new Result(x, s);
}
}, system.dispatcher());
pipe(transformed, system.dispatcher()).to(actorC);
//#ask-pipe
expectMsgEquals(new Result("request", "another request"));
}
};
}
//#props-factory
public static class DemoActor extends UntypedActor {
/**
* Create Props for an actor of this type.
* @param name The name to be passed to this actors constructor.
* @return a Props for creating this actor, which can then be further configured
* (e.g. calling `.withDispatcher()` on it)
*/
public static Props mkProps(String name) {
return Props.create(DemoActor.class, name);
}
final String name;
public DemoActor(String name) {
this.name = name;
}
@Override
public void onReceive(Object msg) {
// some behavior here
}
}
//#props-factory
{
if (system != null)
//#props-factory
system.actorOf(DemoActor.mkProps("hello"));
//#props-factory
}
public static class MyActor extends UntypedActor {
final String s;
public MyActor(String s) {
this.s = s;
}
public void onReceive(Object message) throws Exception {
try {
operation();
} catch (Exception e) {
getSender().tell(new akka.actor.Status.Failure(e), getSelf());
throw e;
}
}
private void operation() {
public void onReceive(Object message) {
getSender().tell(s, getSelf());
}
/*
* This section must be kept in sync with the actual Actor trait.
*
* BOYSCOUT RULE: whenever you read this, verify that!
*/
//#lifecycle-callbacks
public void preStart() {
}
public void preRestart(Throwable reason, Option<Object> message) {
for (ActorRef each : getContext().getChildren())
public void preRestart(Throwable reason, scala.Option<Object> message) {
for (ActorRef each : getContext().getChildren()) {
getContext().unwatch(each);
getContext().stop(each);
}
postStop();
}
@ -297,7 +583,7 @@ public class UntypedActorDocTestBase {
//#lifecycle-callbacks
}
public static class MyAskActor extends UntypedActor {
public class MyAskActor extends UntypedActor {
public void onReceive(Object message) throws Exception {
//#reply-exception
@ -409,13 +695,20 @@ public class UntypedActorDocTestBase {
static
//#identify
public class Follower extends UntypedActor {
String identifyId = "1";
final String identifyId = "1";
{
ActorSelection selection =
getContext().actorSelection("/user/another");
selection.tell(new Identify(identifyId), getSelf());
}
ActorRef another;
//#test-omitted
final ActorRef probe;
public Follower(ActorRef probe) {
this.probe = probe;
}
//#test-omitted
@Override
public void onReceive(Object message) {
@ -428,6 +721,9 @@ public class UntypedActorDocTestBase {
else {
another = ref;
getContext().watch(another);
//#test-omitted
probe.tell(ref, getSelf());
//#test-omitted
}
}
} else if (message instanceof Terminated) {

View file

@ -43,7 +43,7 @@ public class UntypedActorSwapper {
public static void main(String... args) {
ActorSystem system = ActorSystem.create("MySystem");
ActorRef swap = system.actorOf(new Props(Swapper.class));
ActorRef swap = system.actorOf(Props.create(Swapper.class));
swap.tell(SWAP, null); // logs Hi
swap.tell(SWAP, null); // logs Ho
swap.tell(SWAP, null); // logs Hi

View file

@ -47,8 +47,8 @@ public class FaultHandlingDocSample {
"akka.actor.debug.lifecycle = on");
ActorSystem system = ActorSystem.create("FaultToleranceSample", config);
ActorRef worker = system.actorOf(new Props(Worker.class), "worker");
ActorRef listener = system.actorOf(new Props(Listener.class), "listener");
ActorRef worker = system.actorOf(Props.create(Worker.class), "worker");
ActorRef listener = system.actorOf(Props.create(Listener.class), "listener");
// start the work and listen on progress
// note that the listener is used as sender of the tell,
// i.e. it will receive replies from the worker
@ -121,7 +121,7 @@ public class FaultHandlingDocSample {
// about progress
ActorRef progressListener;
final ActorRef counterService = getContext().actorOf(
new Props(CounterService.class), "counter");
Props.create(CounterService.class), "counter");
final int totalCount = 51;
// Stop the CounterService child if it throws ServiceUnavailable
@ -202,6 +202,7 @@ public class FaultHandlingDocSample {
}
public static class ServiceUnavailable extends RuntimeException {
private static final long serialVersionUID = 1L;
public ServiceUnavailable(String msg) {
super(msg);
}
@ -271,7 +272,7 @@ public class FaultHandlingDocSample {
*/
void initStorage() {
storage = getContext().watch(getContext().actorOf(
new Props(Storage.class), "storage"));
Props.create(Storage.class), "storage"));
// Tell the counter, if any, to use the new storage
if (counter != null)
counter.tell(new UseStorage(storage), getSelf());
@ -286,12 +287,7 @@ public class FaultHandlingDocSample {
counter == null) {
// Reply from Storage of the initial value, now we can create the Counter
final long value = ((Entry) msg).value;
counter = getContext().actorOf(new Props().withCreator(
new UntypedActorFactory() {
public Actor create() {
return new Counter(key, value);
}
}));
counter = getContext().actorOf(Props.create(Counter.class, key, value));
// Tell the counter to use current storage
counter.tell(new UseStorage(storage), getSelf());
// and send the buffered backlog to the counter
@ -435,6 +431,7 @@ public class FaultHandlingDocSample {
}
public static class StorageException extends RuntimeException {
private static final long serialVersionUID = 1L;
public StorageException(String msg) {
super(msg);
}

View file

@ -36,7 +36,7 @@ public class DurableMailboxDocTestBase {
@Test
public void configDefinedDispatcher() {
//#dispatcher-config-use
ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class).
ActorRef myActor = system.actorOf(Props.create(MyUntypedActor.class).
withDispatcher("my-dispatcher"), "myactor");
//#dispatcher-config-use
myActor.tell("test", null);

View file

@ -9,7 +9,6 @@ package docs.camel;
import akka.util.Timeout;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
import scala.concurrent.duration.FiniteDuration;
import static java.util.concurrent.TimeUnit.SECONDS;
//#CamelActivation
@ -17,13 +16,14 @@ import org.junit.Test;
public class ActivationTestBase {
@SuppressWarnings("unused")
@Test
public void testActivation() {
//#CamelActivation
// ..
ActorSystem system = ActorSystem.create("some-system");
Props props = new Props(MyConsumer.class);
Props props = Props.create(MyConsumer.class);
ActorRef producer = system.actorOf(props,"myproducer");
Camel camel = CamelExtension.get(system);
// get a future reference to the activation of the endpoint of the Consumer Actor

View file

@ -11,7 +11,7 @@ public class CustomRouteTestBase {
//#CustomRoute
ActorSystem system = ActorSystem.create("some-system");
Camel camel = CamelExtension.get(system);
ActorRef responder = system.actorOf(new Props(Responder.class), "TestResponder");
ActorRef responder = system.actorOf(Props.create(Responder.class), "TestResponder");
camel.context().addRoutes(new CustomRouteBuilder(responder));
//#CustomRoute
system.stop(responder);

View file

@ -7,14 +7,10 @@ public class OnRouteResponseTestBase {
public void onRouteResponse(){
//#RouteResponse
ActorSystem system = ActorSystem.create("some-system");
Props receiverProps = new Props(ResponseReceiver.class);
Props receiverProps = Props.create(ResponseReceiver.class);
final ActorRef receiver = system.actorOf(receiverProps,"responseReceiver");
UntypedActorFactory factory = new UntypedActorFactory() {
public Actor create() {
return new Forwarder("http://localhost:8080/news/akka", receiver);
}
};
ActorRef forwardResponse = system.actorOf(new Props(factory));
ActorRef forwardResponse = system.actorOf(Props.create(
Forwarder.class, "http://localhost:8080/news/akka", receiver));
// the Forwarder sends out a request to the web page and forwards the response to
// the ResponseReceiver
forwardResponse.tell("some request", null);

View file

@ -14,17 +14,18 @@ public class ProducerTestBase {
public void tellJmsProducer() {
//#TellProducer
ActorSystem system = ActorSystem.create("some-system");
Props props = new Props(Orders.class);
Props props = Props.create(Orders.class);
ActorRef producer = system.actorOf(props, "jmsproducer");
producer.tell("<order amount=\"100\" currency=\"PLN\" itemId=\"12345\"/>", null);
//#TellProducer
system.shutdown();
}
@SuppressWarnings("unused")
public void askProducer() {
//#AskProducer
ActorSystem system = ActorSystem.create("some-system");
Props props = new Props(FirstProducer.class);
Props props = Props.create(FirstProducer.class);
ActorRef producer = system.actorOf(props,"myproducer");
Future<Object> future = Patterns.ask(producer, "some request", 1000);
//#AskProducer
@ -35,7 +36,7 @@ public class ProducerTestBase {
public void correlate(){
//#Correlate
ActorSystem system = ActorSystem.create("some-system");
Props props = new Props(Orders.class);
Props props = Props.create(Orders.class);
ActorRef producer = system.actorOf(props,"jmsproducer");
Map<String,Object> headers = new HashMap<String, Object>();
headers.put(CamelMessage.MessageExchangeId(),"123");

View file

@ -9,19 +9,15 @@ public class HttpSample {
// run the example in the MicroKernel. Just add the three lines below
// to your boot class.
ActorSystem system = ActorSystem.create("some-system");
final ActorRef httpTransformer = system.actorOf(new Props(HttpTransformer.class));
final ActorRef httpTransformer = system.actorOf(
Props.create(HttpTransformer.class));
final ActorRef httpProducer = system.actorOf(new Props(new UntypedActorFactory(){
public Actor create() {
return new HttpProducer(httpTransformer);
}
}));
ActorRef httpConsumer = system.actorOf(new Props(new UntypedActorFactory(){
public Actor create() {
return new HttpConsumer(httpProducer);
}
}));
final ActorRef httpProducer = system.actorOf(
Props.create(HttpProducer.class, httpTransformer));
final ActorRef httpConsumer = system.actorOf(
Props.create(HttpConsumer.class, httpProducer));
//#HttpExample
}
}

View file

@ -6,7 +6,7 @@ import akka.actor.Props;
public class QuartzSample {
public static void main(String[] args) {
ActorSystem system = ActorSystem.create("my-quartz-system");
system.actorOf(new Props(MyQuartzActor.class));
system.actorOf(Props.create(MyQuartzActor.class));
}
}
//#QuartzExample

View file

@ -4,25 +4,16 @@ import akka.actor.*;
import akka.camel.CamelExtension;
public class CustomRouteSample {
@SuppressWarnings("unused")
public static void main(String[] args) {
try {
//#CustomRouteExample
// the below lines can be added to a Boot class, so that you can run the
// example from a MicroKernel
ActorSystem system = ActorSystem.create("some-system");
final ActorRef producer = system.actorOf(new Props(Producer1.class));
final ActorRef mediator = system.actorOf(new Props(new UntypedActorFactory() {
public Actor create() {
return new Transformer(producer);
}
}));
ActorRef consumer = system.actorOf(new Props(new UntypedActorFactory() {
public Actor create() {
return new Consumer3(mediator);
}
}));
final ActorRef producer = system.actorOf(Props.create(Producer1.class));
final ActorRef mediator = system.actorOf(Props.create(Transformer.class, producer));
final ActorRef consumer = system.actorOf(Props.create(Consumer3.class, mediator));
CamelExtension.get(system).context().addRoutes(new CustomRouteBuilder());
//#CustomRouteExample
} catch (Exception e) {

View file

@ -58,32 +58,36 @@ public class DispatcherDocTestBase {
system = null;
}
@SuppressWarnings("unused")
@Test
public void defineDispatcherInConfig() {
//#defining-dispatcher-in-config
ActorRef myActor =
system.actorOf(new Props(MyUntypedActor.class),
system.actorOf(Props.create(MyUntypedActor.class),
"myactor");
//#defining-dispatcher-in-config
}
@SuppressWarnings("unused")
@Test
public void defineDispatcherInCode() {
//#defining-dispatcher-in-code
ActorRef myActor =
system.actorOf(new Props(MyUntypedActor.class).withDispatcher("my-dispatcher"),
system.actorOf(Props.create(MyUntypedActor.class).withDispatcher("my-dispatcher"),
"myactor3");
//#defining-dispatcher-in-code
}
@SuppressWarnings("unused")
@Test
public void definePinnedDispatcher() {
//#defining-pinned-dispatcher
ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class)
ActorRef myActor = system.actorOf(Props.create(MyUntypedActor.class)
.withDispatcher("my-pinned-dispatcher"));
//#defining-pinned-dispatcher
}
@SuppressWarnings("unused")
public void compileLookup() {
//#lookup
// this is scala.concurrent.ExecutionContext
@ -97,33 +101,24 @@ public class DispatcherDocTestBase {
JavaTestKit probe = new JavaTestKit(system);
//#prio-dispatcher
// We create a new Actor that just prints out what it processes
ActorRef myActor = system.actorOf(
new Props().withCreator(new UntypedActorFactory() {
public UntypedActor create() {
return new UntypedActor() {
LoggingAdapter log =
Logging.getLogger(getContext().system(), this);
{
for(Object msg : new Object[] {
"lowpriority",
"lowpriority",
"highpriority",
"pigdog",
"pigdog2",
"pigdog3",
"highpriority",
PoisonPill.getInstance() }) {
getSelf().tell(msg, getSelf());
}
}
class Demo extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
{
for (Object msg : new Object[] { "lowpriority", "lowpriority",
"highpriority", "pigdog", "pigdog2", "pigdog3", "highpriority",
PoisonPill.getInstance() }) {
getSelf().tell(msg, getSelf());
}
}
public void onReceive(Object message) {
log.info(message.toString());
}
};
}
}).withDispatcher("prio-dispatcher"));
public void onReceive(Object message) {
log.info(message.toString());
}
}
// We create a new Actor that just prints out what it processes
ActorRef myActor = system.actorOf(Props.create(Demo.class, this)
.withDispatcher("prio-dispatcher"));
/*
Logs:

View file

@ -22,7 +22,6 @@ import org.junit.Test;
import scala.Option;
import akka.actor.UntypedActorFactory;
//#imports-deadletter
import akka.actor.Props;
import akka.actor.ActorRef;
@ -36,11 +35,7 @@ public class LoggingDocTestBase {
@Test
public void useLoggingActor() {
ActorSystem system = ActorSystem.create("MySystem");
ActorRef myActor = system.actorOf(new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new MyActor();
}
}));
ActorRef myActor = system.actorOf(Props.create(MyActor.class, this));
myActor.tell("test", null);
system.shutdown();
}
@ -49,7 +44,7 @@ public class LoggingDocTestBase {
public void subscribeToDeadLetters() {
//#deadletters
final ActorSystem system = ActorSystem.create("DeadLetters");
final ActorRef actor = system.actorOf(new Props(DeadLetterActor.class));
final ActorRef actor = system.actorOf(Props.create(DeadLetterActor.class));
system.eventStream().subscribe(actor, DeadLetter.class);
//#deadletters
system.shutdown();

View file

@ -110,7 +110,7 @@ public class FutureDocTestBase {
@Test
public void useBlockingFromActor() throws Exception {
ActorRef actor = system.actorOf(new Props(MyActor.class));
ActorRef actor = system.actorOf(Props.create(MyActor.class));
String msg = "hello";
//#ask-blocking
Timeout timeout = new Timeout(Duration.create(5, "seconds"));

View file

@ -13,12 +13,10 @@ import org.junit.Test;
import scala.concurrent.duration.Duration;
import akka.actor.Actor;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.PoisonPill;
import akka.actor.Props;
import akka.actor.UntypedActorFactory;
import akka.io.AbstractPipelineContext;
import akka.io.PipelineFactory;
import akka.io.PipelineInjector;
@ -117,25 +115,23 @@ public class PipelineTest {
public void testTick() {
new JavaTestKit(system) {
{
final ActorRef proc = system.actorOf(new Props(
new UntypedActorFactory() {
private static final long serialVersionUID = 1L;
class P extends Processor {
public P(ActorRef cmds, ActorRef evts) throws Exception {
super(cmds, evts);
}
@Override
public Actor create() throws Exception {
return new Processor(getRef(), getRef()) {
@Override
public void onReceive(Object obj) throws Exception {
if (obj.equals("fail!")) {
throw new RuntimeException("FAIL!");
}
super.onReceive(obj);
}
};
}
}), "processor");
@Override
public void onReceive(Object obj) throws Exception {
if (obj.equals("fail!")) {
throw new RuntimeException("FAIL!");
}
super.onReceive(obj);
}
}
final ActorRef proc = system.actorOf(Props.create(
P.class, this, getRef(), getRef()), "processor");
expectMsgClass(TickGenerator.Tick.class);
proc.tell(msg, null);
final ByteString encoded = expectMsgClass(ByteString.class);

View file

@ -66,6 +66,7 @@ public class ConsistentHashingRouterDocTestBase {
static
//#cache-actor
public final class Evict implements Serializable {
private static final long serialVersionUID = 1L;
public final String key;
public Evict(String key) {
this.key = key;
@ -76,6 +77,7 @@ public class ConsistentHashingRouterDocTestBase {
static
//#cache-actor
public final class Get implements Serializable, ConsistentHashable {
private static final long serialVersionUID = 1L;
public final String key;
public Get(String key) {
this.key = key;
@ -89,6 +91,7 @@ public class ConsistentHashingRouterDocTestBase {
static
//#cache-actor
public final class Entry implements Serializable {
private static final long serialVersionUID = 1L;
public final String key;
public final String value;
public Entry(String key, String value) {
@ -122,7 +125,7 @@ public class ConsistentHashingRouterDocTestBase {
}
};
ActorRef cache = system.actorOf(new Props(Cache.class).withRouter(
ActorRef cache = system.actorOf(Props.create(Cache.class).withRouter(
new ConsistentHashingRouter(10).withHashMapper(hashMapper)),
"cache");

View file

@ -57,7 +57,7 @@ public class CustomRouterDocTestBase {
@Test
public void demonstrateDispatchers() {
//#dispatchers
final ActorRef router = system.actorOf(new Props(MyActor.class)
final ActorRef router = system.actorOf(Props.create(MyActor.class)
// head router will run on "head" dispatcher
.withRouter(new RoundRobinRouter(5).withDispatcher("head"))
// MyActor workers will run on "workers" dispatcher
@ -71,7 +71,7 @@ public class CustomRouterDocTestBase {
final SupervisorStrategy strategy =
new OneForOneStrategy(5, Duration.create("1 minute"),
Collections.<Class<? extends Throwable>>singletonList(Exception.class));
final ActorRef router = system.actorOf(new Props(MyActor.class)
final ActorRef router = system.actorOf(Props.create(MyActor.class)
.withRouter(new RoundRobinRouter(5).withSupervisorStrategy(strategy)));
//#supervision
}
@ -80,7 +80,7 @@ public class CustomRouterDocTestBase {
@Test
public void countVotesAsIntendedNotAsInFlorida() throws Exception {
ActorRef routedActor = system.actorOf(
new Props().withRouter(new VoteCountRouter()));
Props.empty().withRouter(new VoteCountRouter()));
routedActor.tell(DemocratVote, null);
routedActor.tell(DemocratVote, null);
routedActor.tell(RepublicanVote, null);
@ -167,9 +167,9 @@ public class CustomRouterDocTestBase {
@Override
public CustomRoute createCustomRoute(RouteeProvider routeeProvider) {
final ActorRef democratActor =
routeeProvider.context().actorOf(new Props(DemocratActor.class), "d");
routeeProvider.context().actorOf(Props.create(DemocratActor.class), "d");
final ActorRef republicanActor =
routeeProvider.context().actorOf(new Props(RepublicanActor.class), "r");
routeeProvider.context().actorOf(Props.create(RepublicanActor.class), "r");
List<ActorRef> routees =
Arrays.asList(new ActorRef[] { democratActor, republicanActor });

View file

@ -22,7 +22,7 @@ public class ParentActor extends UntypedActor {
if (msg.equals("rrr")) {
//#roundRobinRouter
ActorRef roundRobinRouter = getContext().actorOf(
new Props(PrintlnActor.class).withRouter(new RoundRobinRouter(5)),
Props.create(PrintlnActor.class).withRouter(new RoundRobinRouter(5)),
"router");
for (int i = 1; i <= 10; i++) {
roundRobinRouter.tell(i, getSelf());
@ -31,7 +31,7 @@ public class ParentActor extends UntypedActor {
} else if (msg.equals("rr")) {
//#randomRouter
ActorRef randomRouter = getContext().actorOf(
new Props(PrintlnActor.class).withRouter(new RandomRouter(5)),
Props.create(PrintlnActor.class).withRouter(new RandomRouter(5)),
"router");
for (int i = 1; i <= 10; i++) {
randomRouter.tell(i, getSelf());
@ -40,7 +40,7 @@ public class ParentActor extends UntypedActor {
} else if (msg.equals("smr")) {
//#smallestMailboxRouter
ActorRef smallestMailboxRouter = getContext().actorOf(
new Props(PrintlnActor.class).withRouter(new SmallestMailboxRouter(5)),
Props.create(PrintlnActor.class).withRouter(new SmallestMailboxRouter(5)),
"router");
for (int i = 1; i <= 10; i++) {
smallestMailboxRouter.tell(i, getSelf());
@ -49,13 +49,13 @@ public class ParentActor extends UntypedActor {
} else if (msg.equals("br")) {
//#broadcastRouter
ActorRef broadcastRouter = getContext().actorOf(
new Props(PrintlnActor.class).withRouter(new BroadcastRouter(5)), "router");
Props.create(PrintlnActor.class).withRouter(new BroadcastRouter(5)), "router");
broadcastRouter.tell("this is a broadcast message", getSelf());
//#broadcastRouter
} else if (msg.equals("sgfcr")) {
//#scatterGatherFirstCompletedRouter
ActorRef scatterGatherFirstCompletedRouter = getContext().actorOf(
new Props(FibonacciActor.class).withRouter(
Props.create(FibonacciActor.class).withRouter(
new ScatterGatherFirstCompletedRouter(5, Duration.create(2, "seconds"))),
"router");
Timeout timeout = new Timeout(Duration.create(5, "seconds"));

View file

@ -44,7 +44,7 @@ public class RouterViaConfigExample {
ActorSystem system = ActorSystem.create("Example", config);
//#configurableRouting
ActorRef router = system.actorOf(
new Props(ExampleActor.class).withRouter(new FromConfig()), "myrouter1");
Props.create(ExampleActor.class).withRouter(new FromConfig()), "myrouter1");
//#configurableRouting
for (int i = 1; i <= 10; i++) {
router.tell(new ExampleActor.Message(i), null);
@ -52,7 +52,7 @@ public class RouterViaConfigExample {
//#configurableRoutingWithResizer
ActorRef router2 = system.actorOf(
new Props(ExampleActor.class).withRouter(new FromConfig()), "myrouter2");
Props.create(ExampleActor.class).withRouter(new FromConfig()), "myrouter2");
//#configurableRoutingWithResizer
for (int i = 1; i <= 10; i++) {
router2.tell(new ExampleActor.Message(i), null);

View file

@ -3,21 +3,23 @@
*/
package docs.jrouting;
import akka.actor.*;
import akka.remote.routing.RemoteRouterConfig;
import java.util.Arrays;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
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.routing.Broadcast;
import akka.routing.RoundRobinRouter;
import akka.testkit.JavaTestKit;
import docs.jrouting.RouterViaProgramExample.ExampleActor;
import docs.routing.RouterViaProgramDocSpec.Echo;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class RouterViaProgramDocTestBase {
@ -45,17 +47,18 @@ public class RouterViaProgramDocTestBase {
}
}
@SuppressWarnings("unused")
@Test
public void demonstrateRouteesFromPaths() {
new JavaTestKit(system) {{
//#programmaticRoutingRouteePaths
ActorRef actor1 = system.actorOf(new Props(ExampleActor.class), "actor1");
ActorRef actor2 = system.actorOf(new Props(ExampleActor.class), "actor2");
ActorRef actor3 = system.actorOf(new Props(ExampleActor.class), "actor3");
ActorRef actor1 = system.actorOf(Props.create(ExampleActor.class), "actor1");
ActorRef actor2 = system.actorOf(Props.create(ExampleActor.class), "actor2");
ActorRef actor3 = system.actorOf(Props.create(ExampleActor.class), "actor3");
Iterable<String> routees = Arrays.asList(
new String[] { "/user/actor1", "/user/actor2", "/user/actor3" });
ActorRef router = system.actorOf(
new Props().withRouter(new RoundRobinRouter(routees)));
Props.empty().withRouter(new RoundRobinRouter(routees)));
//#programmaticRoutingRouteePaths
for (int i = 1; i <= 6; i++) {
router.tell(new ExampleActor.Message(i), null);
@ -66,7 +69,7 @@ public class RouterViaProgramDocTestBase {
@Test
public void demonstrateBroadcast() {
new JavaTestKitWithSelf(system) {{
ActorRef router = system.actorOf(new Props(Echo.class).withRouter(new RoundRobinRouter(5)));
ActorRef router = system.actorOf(Props.create(Echo.class).withRouter(new RoundRobinRouter(5)));
//#broadcastDavyJonesWarning
router.tell(new Broadcast("Watch out for Davy Jones' locker"), getSelf());
//#broadcastDavyJonesWarning
@ -77,7 +80,7 @@ public class RouterViaProgramDocTestBase {
@Test
public void demonstratePoisonPill() {
new JavaTestKitWithSelf(system) {{
ActorRef router = system.actorOf(new Props(Echo.class).withRouter(new RoundRobinRouter(5)));
ActorRef router = system.actorOf(Props.create(Echo.class).withRouter(new RoundRobinRouter(5)));
watch(router);
//#poisonPill
router.tell(PoisonPill.getInstance(), getSelf());
@ -89,7 +92,7 @@ public class RouterViaProgramDocTestBase {
@Test
public void demonstrateBroadcastOfPoisonPill() {
new JavaTestKitWithSelf(system) {{
ActorRef router = system.actorOf(new Props(Echo.class).withRouter(new RoundRobinRouter(5)));
ActorRef router = system.actorOf(Props.create(Echo.class).withRouter(new RoundRobinRouter(5)));
watch(router);
//#broadcastPoisonPill
router.tell(new Broadcast(PoisonPill.getInstance()), getSelf());
@ -101,7 +104,7 @@ public class RouterViaProgramDocTestBase {
@Test
public void demonstrateKill() {
new JavaTestKitWithSelf(system) {{
ActorRef router = system.actorOf(new Props(Echo.class).withRouter(new RoundRobinRouter(5)));
ActorRef router = system.actorOf(Props.create(Echo.class).withRouter(new RoundRobinRouter(5)));
watch(router);
//#kill
router.tell(Kill.getInstance(), getSelf());
@ -113,7 +116,7 @@ public class RouterViaProgramDocTestBase {
@Test
public void demonstrateBroadcastOfKill() {
new JavaTestKitWithSelf(system) {{
ActorRef router = system.actorOf(new Props(Echo.class).withRouter(new RoundRobinRouter(5)));
ActorRef router = system.actorOf(Props.create(Echo.class).withRouter(new RoundRobinRouter(5)));
watch(router);
//#broadcastKill
router.tell(new Broadcast(Kill.getInstance()), getSelf());

View file

@ -41,25 +41,26 @@ public class RouterViaProgramExample {
}
}
@SuppressWarnings("unused")
public static void main(String... args) {
ActorSystem system = ActorSystem.create("RPE");
//#programmaticRoutingNrOfInstances
int nrOfInstances = 5;
ActorRef router1 = system.actorOf(
new Props(ExampleActor.class).withRouter(new RoundRobinRouter(nrOfInstances)));
Props.create(ExampleActor.class).withRouter(new RoundRobinRouter(nrOfInstances)));
//#programmaticRoutingNrOfInstances
for (int i = 1; i <= 6; i++) {
router1.tell(new ExampleActor.Message(i), null);
}
//#programmaticRoutingRoutees
ActorRef actor1 = system.actorOf(new Props(ExampleActor.class));
ActorRef actor2 = system.actorOf(new Props(ExampleActor.class));
ActorRef actor3 = system.actorOf(new Props(ExampleActor.class));
ActorRef actor1 = system.actorOf(Props.create(ExampleActor.class));
ActorRef actor2 = system.actorOf(Props.create(ExampleActor.class));
ActorRef actor3 = system.actorOf(Props.create(ExampleActor.class));
Iterable<ActorRef> routees = Arrays.asList(
new ActorRef[] { actor1, actor2, actor3 });
ActorRef router2 = system.actorOf(
new Props().withRouter(RoundRobinRouter.create(routees)));
Props.empty().withRouter(RoundRobinRouter.create(routees)));
//#programmaticRoutingRoutees
for (int i = 1; i <= 6; i++) {
router2.tell(new ExampleActor.Message(i), null);
@ -70,7 +71,7 @@ public class RouterViaProgramExample {
int upperBound = 15;
DefaultResizer resizer = new DefaultResizer(lowerBound, upperBound);
ActorRef router3 = system.actorOf(
new Props(ExampleActor.class).withRouter(new RoundRobinRouter(resizer)));
Props.create(ExampleActor.class).withRouter(new RoundRobinRouter(resizer)));
//#programmaticRoutingWithResizer
for (int i = 1; i <= 6; i++) {
router3.tell(new ExampleActor.Message(i), null);
@ -80,11 +81,12 @@ public class RouterViaProgramExample {
Address addr1 = new Address("akka", "remotesys", "otherhost", 1234);
Address addr2 = AddressFromURIString.parse("akka://othersys@anotherhost:1234");
Address[] addresses = new Address[] { addr1, addr2 };
ActorRef routerRemote = system.actorOf(new Props(ExampleActor.class)
ActorRef routerRemote = system.actorOf(Props.create(ExampleActor.class)
.withRouter(new RemoteRouterConfig(new RoundRobinRouter(5), addresses)));
//#remoteRoutees
}
@SuppressWarnings("unused")
private class CompileCheckJavaDocsForRouting extends UntypedActor {
@Override

View file

@ -121,13 +121,7 @@ public class SchedulerPatternTest {
public void scheduleInConstructor() {
new TestSchedule(system) {{
final JavaTestKit probe = new JavaTestKit(system);
final Props props = new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new ScheduleInConstructor(probe.getRef());
}
});
final Props props = Props.create(ScheduleInConstructor.class, probe.getRef());
testSchedule(probe, props, duration("3000 millis"), duration("2000 millis"));
}};
}
@ -135,16 +129,9 @@ public class SchedulerPatternTest {
@Test
@Ignore // no way to tag this as timing sensitive
public void scheduleInReceive() {
new TestSchedule(system) {{
final JavaTestKit probe = new JavaTestKit(system);
final Props props = new Props(new UntypedActorFactory() {
public UntypedActor create() {
return new ScheduleInReceive(probe.getRef());
}
});
final Props props = Props.create(ScheduleInReceive.class, probe.getRef());
testSchedule(probe, props, duration("3000 millis"), duration("2500 millis"));
}};
}

View file

@ -45,7 +45,7 @@ public class SupervisedAsk {
public void onReceive(Object message) throws Exception {
if (message instanceof AskParam) {
ActorRef supervisor = getContext().actorOf(
Props.apply(AskSupervisor.class));
Props.create(AskSupervisor.class));
supervisor.forward(message, getContext());
} else {
unhandled(message);
@ -104,6 +104,6 @@ public class SupervisedAsk {
synchronized public static ActorRef createSupervisorCreator(
ActorRefFactory factory) {
return factory.actorOf(Props.apply(AskSupervisorCreator.class));
return factory.actorOf(Props.create(AskSupervisorCreator.class));
}
}

View file

@ -18,7 +18,7 @@ public class SupervisedAskSpec {
ActorRef supervisorCreator = SupervisedAsk
.createSupervisorCreator(actorSystem);
Future<Object> finished = SupervisedAsk.askOf(supervisorCreator,
Props.apply(someActor), message, timeout);
Props.create(someActor), message, timeout);
return Await.result(finished, timeout.duration());
} catch (Exception e) {
// exception propagated by supervision

View file

@ -48,7 +48,7 @@ public class RemoteDeploymentDocTestBase {
addr = AddressFromURIString.parse("akka.tcp://sys@host:1234"); // the same
//#make-address
//#deploy
ActorRef ref = system.actorOf(new Props(SampleActor.class).withDeploy(
ActorRef ref = system.actorOf(Props.create(SampleActor.class).withDeploy(
new Deploy(new RemoteScope(addr))));
//#deploy
assert ref.path().address().equals(addr);
@ -58,7 +58,7 @@ public class RemoteDeploymentDocTestBase {
public void demonstrateSampleActor() {
//#sample-actor
ActorRef actor = system.actorOf(new Props(SampleActor.class), "sampleActor");
ActorRef actor = system.actorOf(Props.create(SampleActor.class), "sampleActor");
actor.tell("Pretty slick", null);
//#sample-actor
}

View file

@ -20,7 +20,6 @@ import akka.actor.PoisonPill;
import akka.actor.Props;
import akka.actor.Terminated;
import akka.actor.UntypedActor;
import akka.actor.UntypedActorFactory;
import scala.concurrent.Await;
import scala.concurrent.Future;
import akka.testkit.CallingThreadDispatcher;
@ -63,7 +62,7 @@ public class TestKitDocTest {
//#test-actor-ref
@Test
public void demonstrateTestActorRef() {
final Props props = new Props(MyActor.class);
final Props props = Props.create(MyActor.class);
final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "testA");
final MyActor actor = ref.underlyingActor();
assertTrue(actor.testMe());
@ -73,7 +72,7 @@ public class TestKitDocTest {
@Test
public void demonstrateAsk() throws Exception {
//#test-behavior
final Props props = new Props(MyActor.class);
final Props props = Props.create(MyActor.class);
final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "testB");
final Future<Object> future = akka.pattern.Patterns.ask(ref, "say42", 3000);
assertTrue(future.isCompleted());
@ -84,7 +83,7 @@ public class TestKitDocTest {
@Test
public void demonstrateExceptions() {
//#test-expecting-exceptions
final Props props = new Props(MyActor.class);
final Props props = Props.create(MyActor.class);
final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "myActor");
try {
ref.receive(new Exception("expected"));
@ -208,7 +207,7 @@ public class TestKitDocTest {
}
@Test
@SuppressWarnings("unchecked") // due to generic varargs
@SuppressWarnings({ "unchecked", "unused" }) // due to generic varargs
public void demonstrateExpect() {
new JavaTestKit(system) {{
getRef().tell("hello", null);
@ -273,28 +272,24 @@ public class TestKitDocTest {
@Test
public void demonstrateProbe() {
//#test-probe
// simple actor which just forwards messages
class Forwarder extends UntypedActor {
final ActorRef target;
public Forwarder(ActorRef target) {
this.target = target;
}
public void onReceive(Object msg) {
target.forward(msg, getContext());
}
}
new JavaTestKit(system) {{
// simple actor which just forwards messages
class Forwarder extends UntypedActor {
final ActorRef target;
@SuppressWarnings("unused")
public Forwarder(ActorRef target) {
this.target = target;
}
public void onReceive(Object msg) {
target.forward(msg, getContext());
}
}
// 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;
public UntypedActor create() {
return new Forwarder(probe.getRef());
}
});
final Props props = Props.create(Forwarder.class, this, probe.getRef());
final ActorRef forwarder = system.actorOf(props, "forwarder");
// verify correct forwarding
@ -327,7 +322,7 @@ public class TestKitDocTest {
@Test
public void demonstrateWatch() {
final ActorRef target = system.actorOf(new Props(MyActor.class));
final ActorRef target = system.actorOf(Props.create(MyActor.class));
//#test-probe-watch
new JavaTestKit(system) {{
final JavaTestKit probe = new JavaTestKit(system);
@ -411,7 +406,7 @@ public class TestKitDocTest {
public void demonstrateCTD() {
//#calling-thread-dispatcher
system.actorOf(
new Props(MyActor.class)
Props.create(MyActor.class)
.withDispatcher(CallingThreadDispatcher.Id()));
//#calling-thread-dispatcher
}

View file

@ -53,7 +53,7 @@ public class TestKitSampleTest {
* if you want to receive actor replies or use Within(), etc.
*/
new JavaTestKit(system) {{
final Props props = new Props(SomeActor.class);
final Props props = Props.create(SomeActor.class);
final ActorRef subject = system.actorOf(props);
// can also use JavaTestKit from the outside

View file

@ -23,8 +23,8 @@ public class TransactorDocTest {
//#coordinated-example
ActorSystem system = ActorSystem.create("CoordinatedExample");
ActorRef counter1 = system.actorOf(new Props(CoordinatedCounter.class));
ActorRef counter2 = system.actorOf(new Props(CoordinatedCounter.class));
ActorRef counter1 = system.actorOf(Props.create(CoordinatedCounter.class));
ActorRef counter2 = system.actorOf(Props.create(CoordinatedCounter.class));
Timeout timeout = new Timeout(5, SECONDS);
@ -47,7 +47,7 @@ public class TransactorDocTest {
//#create-coordinated
ActorSystem system = ActorSystem.create("CoordinatedApi");
ActorRef actor = system.actorOf(new Props(Coordinator.class));
ActorRef actor = system.actorOf(Props.create(Coordinator.class));
//#send-coordinated
actor.tell(new Coordinated(new Message(), timeout), null);
@ -65,7 +65,7 @@ public class TransactorDocTest {
@Test
public void counterTransactor() throws Exception {
ActorSystem system = ActorSystem.create("CounterTransactor");
ActorRef counter = system.actorOf(new Props(Counter.class));
ActorRef counter = system.actorOf(Props.create(Counter.class));
Timeout timeout = new Timeout(5, SECONDS);
Coordinated coordinated = new Coordinated(timeout);
@ -81,8 +81,8 @@ public class TransactorDocTest {
@Test
public void friendlyCounterTransactor() throws Exception {
ActorSystem system = ActorSystem.create("FriendlyCounterTransactor");
ActorRef friend = system.actorOf(new Props(Counter.class));
ActorRef friendlyCounter = system.actorOf(new Props(FriendlyCounter.class));
ActorRef friend = system.actorOf(Props.create(Counter.class));
ActorRef friendlyCounter = system.actorOf(Props.create(FriendlyCounter.class));
Timeout timeout = new Timeout(5, SECONDS);
Coordinated coordinated = new Coordinated(timeout);

View file

@ -68,6 +68,7 @@ public class ZeromqDocTestBase {
system.shutdown();
}
@SuppressWarnings("unused")
@Test
public void demonstrateCreateSocket() {
Assume.assumeTrue(checkZeroMQInstallation());
@ -78,7 +79,7 @@ public class ZeromqDocTestBase {
//#pub-socket
//#sub-socket
ActorRef listener = system.actorOf(new Props(ListenerActor.class));
ActorRef listener = system.actorOf(Props.create(ListenerActor.class));
ActorRef subSocket = ZeroMQExtension.get(system).newSubSocket(
new Connect("tcp://127.0.0.1:1233"),
new Listener(listener), Subscribe.all());
@ -115,17 +116,17 @@ public class ZeromqDocTestBase {
//#health2
system.actorOf(new Props(HealthProbe.class), "health");
system.actorOf(Props.create(HealthProbe.class), "health");
//#health2
//#logger2
system.actorOf(new Props(Logger.class), "logger");
system.actorOf(Props.create(Logger.class), "logger");
//#logger2
//#alerter2
system.actorOf(new Props(HeapAlerter.class), "alerter");
system.actorOf(Props.create(HeapAlerter.class), "alerter");
//#alerter2
// Let it run for a while to see some output.
@ -159,6 +160,7 @@ public class ZeromqDocTestBase {
static
//#health
public class Heap implements Serializable {
private static final long serialVersionUID = 1L;
public final long timestamp;
public final long used;
public final long max;
@ -174,6 +176,7 @@ public class ZeromqDocTestBase {
static
//#health
public class Load implements Serializable {
private static final long serialVersionUID = 1L;
public final long timestamp;
public final double loadAverage;

View file

@ -32,7 +32,7 @@ Creating Actors
Defining an Actor class
-----------------------
Actor in Java are implemented by extending the ``UntypedActor`` class and implementing the
Actors in Java are implemented by extending the ``UntypedActor`` class and implementing the
:meth:`onReceive` method. This method takes the message as a parameter.
Here is an example:
@ -42,84 +42,132 @@ Here is an example:
Props
-----
``Props`` is a configuration class to specify options for the creation
of actors. Here are some examples on how to create a ``Props`` instance.
:class:`Props` is a configuration class to specify options for the creation
of actors, think of it as an immutable and thus freely shareable recipe for
creating an actor including associated deployment information (e.g. which
dispatcher to use, see more below). Here are some examples of how to create a
:class:`Props` instance.
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#import-props
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#creating-props-config
The last line shows how to pass constructor arguments to the :class:`Actor`
being created. The presence of a matching constructor is verified during
construction of the :class:`Props` object, resulting in an
:class:`IllegalArgumentEception` if no or multiple matching constructors are
found.
Deprecated Variants
^^^^^^^^^^^^^^^^^^^
Up to Akka 2.1 there were also the following possibilities (which are retained
for a migration period):
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#import-untypedActor
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#creating-props-deprecated
The last two are deprecated because their functionality is available in full
through :meth:`Props.create()`.
The first two are deprecated because the resulting :class:`UntypedActorFactory`
is typically a local class which means that it implicitly carries a reference
to the enclosing class. This can easily make the resulting :class:`Props`
non-serializable, e.g. when the enclosing class is an :class:`Actor`. Akka
advocates location transparency, meaning that an application written with
actors should just work when it is deployed over multiple network nodes, and
non-serializable actor factories would break this principle. In case indirect
actor creation is needed—for example when using dependency injection—there is
the possibility to use an :class:`IndirectActorProducer` as described below.
There were two use-cases for these methods: passing constructor arguments to
the actor—which is solved by the newly introduced :meth:`Props.create()` method
above—and creating actors “on the spot” as anonymous classes. The latter should
be solved by making these actors named inner classes instead (if they are not
``static`` then the enclosing instances ``this`` reference needs to be passed
as the first argument).
.. warning::
Declaring one actor within another is very dangerous and breaks actor
encapsulation unless the nested actor is a static inner class. Never pass an
actors ``this`` reference into :class:`Props`!
Recommended Practices
^^^^^^^^^^^^^^^^^^^^^
It is a good idea to provide static factory methods on the
:class:`UntypedActor` which help keeping the creation of suitable
:class:`Props` as close to the actor definition as possible, thus containing
the gap in type-safety introduced by reflective instantiation within a single
class instead of spreading it out across a whole code-base. This helps
especially when refactoring the actors constructor signature at a later point,
where compiler checks will allow this modification to be done with greater
confidence than without.
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#props-factory
Creating Actors with Props
--------------------------
Actors are created by passing in a ``Props`` instance into the ``actorOf`` factory method.
Actors are created by passing a :class:`Props` instance into the
:meth:`actorOf` factory method which is available on :class:`ActorSystem` and
:class:`ActorContext`.
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#creating-props
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#import-actorRef
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#system-actorOf
Using the :class:`ActorSystem` will create top-level actors, supervised by the
actor systems provided guardian actor, while using an actors context will
create a child actor.
Creating Actors with default constructor
----------------------------------------
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#context-actorOf
:exclude: plus-some-behavior
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
:include: imports
It is recommended to create a hierarchy of children, grand-children and so on
such that it fits the logical failure-handling structure of the application,
see :ref:`actor-systems`.
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
:include: system-actorOf
The call to :meth:`actorOf` returns an instance of :class:`ActorRef`. This is a
handle to the actor instance and the only way to interact with it. The
:class:`ActorRef` is immutable and has a one to one relationship with the Actor
it represents. The :class:`ActorRef` is also serializable and network-aware.
This means that you can serialize it, send it over the wire and use it on a
remote host and it will still be representing the same Actor on the original
node, across the network.
The call to :meth:`actorOf` returns an instance of ``ActorRef``. This is a handle to
the ``UntypedActor`` instance which you can use to interact with the ``UntypedActor``. The
``ActorRef`` is immutable and has a one to one relationship with the Actor it
represents. The ``ActorRef`` is also serializable and network-aware. This means
that you can serialize it, send it over the wire and use it on a remote host and
it will still be representing the same Actor on the original node, across the
network.
In the above example the actor was created from the system. It is also possible
to create actors from other actors with the actor ``context``. The difference is
how the supervisor hierarchy is arranged. When using the context the current actor
will be supervisor of the created child actor. When using the system it will be
a top level actor, that is supervised by the system (internal guardian actor).
.. includecode:: code/docs/actor/FirstUntypedActor.java#context-actorOf
The name parameter is optional, but you should preferably name your actors, since
that is used in log messages and for identifying actors. The name must not be empty
or start with ``$``, but it may contain URL encoded characters (eg. ``%20`` for a blank space).
If the given name is already in use by another child to the
same parent actor an `InvalidActorNameException` is thrown.
The name parameter is optional, but you should preferably name your actors,
since that is used in log messages and for identifying actors. The name must
not be empty or start with ``$``, but it may contain URL encoded characters
(eg. ``%20`` for a blank space). If the given name is already in use by
another child to the same parent an `InvalidActorNameException` is thrown.
Actors are automatically started asynchronously when created.
When you create the ``UntypedActor`` then it will automatically call the ``preStart``
callback method on the ``UntypedActor`` class. This is an excellent place to
add initialization code for the actor.
.. code-block:: java
.. _actor-create-factory:
@Override
public void preStart() {
... // initialization code
}
Creating Actors with Factory Methods
------------------------------------
Creating Actors with non-default constructor
--------------------------------------------
If your UntypedActor has a constructor that takes parameters then those need to
be part of the :class:`Props` as well, as described `above <Props>`_. But there
are cases when a factory method must be used, for example when the actual
constructor arguments are determined by a dependency injection framework.
If your UntypedActor has a constructor that takes parameters then you can't create it using
'actorOf(new Props(clazz))'. Then you can instead pass in 'new Props(new UntypedActorFactory() {..})'
in which you can create the Actor in any way you like.
Here is an example:
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#creating-constructor
This way of creating the Actor is also great for integrating with Dependency Injection
(DI) frameworks like Guice or Spring.
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#import-indirect
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
:include: creating-indirectly
:exclude: obtain-fresh-Actor-instance-from-DI-framework
.. warning::
You might be tempted at times to offer an ``UntypedActor`` factory which
always returns the same instance, e.g. by using a static field. This is not
supported, as it goes against the meaning of an actor restart, which is
You might be tempted at times to offer an :class:`IndirectActorProducer`
which always returns the same instance, e.g. by using a static field. This is
not supported, as it goes against the meaning of an actor restart, which is
described here: :ref:`supervision-restart`.
When using a dependency injection framework, actor beans *MUST NOT* have
singleton scope.
UntypedActor API
================
@ -180,6 +228,7 @@ termination (see `Stopping Actors`_). This service is provided by the
Registering a monitor is easy (see fourth line, the rest is for demonstrating
the whole functionality):
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#import-terminated
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#watch
It should be noted that the :class:`Terminated` message is generated
@ -205,14 +254,15 @@ Start Hook
Right after starting the actor, its :meth:`preStart` method is invoked.
::
@Override
public void preStart() {
// registering with other actors
someService.tell(Register(getSelf());
}
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#preStart
This method is called when the actor is first created. During restarts it is
called by the default implementation of :meth:`postRestart`, which means that
by overriding that method you can choose whether the initialization code in
this method is called only exactly once for this actor or for every restart.
Initialization code which is part of the actors constructor will always be
called when an instance of the actor class is created, which happens at every
restart.
Restart Hooks
-------------
@ -279,12 +329,9 @@ are used by the system to look up actors, e.g. when a remote message is
received and the recipient is searched, but they are also useful more directly:
actors may look up other actors by specifying absolute or relative
paths—logical or physical—and receive back an :class:`ActorSelection` with the
result::
result:
// will look up this absolute path
getContext().actorSelection("/user/serviceA/actor");
// will look up sibling beneath same supervisor
getContext().actorSelection("../joe");
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#selection-local
The supplied path is parsed as a :class:`java.net.URI`, which basically means
that it is split on ``/`` into path elements. If the path starts with ``/``, it
@ -296,12 +343,9 @@ It should be noted that the ``..`` in actor paths here always means the logical
structure, i.e. the supervisor.
The path elements of an actor selection may contain wildcard patterns allowing for
broadcasting of messages to that section::
broadcasting of messages to that section:
// will look all children to serviceB with names starting with worker
getContext().actorSelection("/user/serviceB/worker*");
// will look up all siblings beneath same supervisor
getContext().actorSelection("../*");
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#selection-wildcard
Messages can be sent via the :class:`ActorSelection` and the path of the
:class:`ActorSelection` is looked up when delivering each message. If the selection
@ -314,11 +358,11 @@ and automatically reply to with a ``ActorIdentity`` message containing the
:class:`ActorRef`.
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
:include: identify-imports,identify
:include: import-identify,identify
Remote actor addresses may also be looked up, if :ref:`remoting <remoting-java>` is enabled::
Remote actor addresses may also be looked up, if :ref:`remoting <remoting-java>` is enabled:
getContext().actorSelection("akka.tcp://app@otherhost:1234/user/serviceB");
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#selection-remote
An example demonstrating remote actor look-up is given in :ref:`remote-lookup-sample-java`.
@ -368,28 +412,24 @@ In all these methods you have the option of passing along your own ``ActorRef``.
Make it a practice of doing so because it will allow the receiver actors to be able to respond
to your message, since the sender reference is sent along with the message.
.. _actors-tell-sender-java:
Tell: Fire-forget
-----------------
This is the preferred way of sending messages. No blocking waiting for a
message. This gives the best concurrency and scalability characteristics.
.. code-block:: java
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#tell
actor.tell("Hello");
.. _actors-tell-sender-java:
Or with the sender reference passed along with the message and available to the receiving Actor
in its ``getSender: ActorRef`` member field. The target actor can use this
to reply to the original sender, by using ``getSender().tell(replyMsg)``.
.. code-block:: java
actor.tell("Hello", getSelf());
If invoked without the sender parameter the sender will be
:obj:`deadLetters` actor reference in the target actor.
The sender reference is passed along with the message and available within the
receiving actor via its :meth:`getSender()` method while processing this
message. Inside of an actor it is usually :meth:`getSelf` who shall be the
sender, but there can be cases where replies shall be routed to some other
actor—e.g. the parent—in which the second argument to :meth:`tell` would be a
different one. Outside of an actor and if no reply is needed the second
argument can be ``null``; if a reply is needed outside of an actor you can use
the ask-pattern described next..
Ask: Send-And-Receive-Future
----------------------------
@ -397,8 +437,7 @@ Ask: Send-And-Receive-Future
The ``ask`` pattern involves actors as well as futures, hence it is offered as
a use pattern rather than a method on :class:`ActorRef`:
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#import-askPipe
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#import-ask
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#ask-pipe
This example demonstrates ``ask`` together with the ``pipe`` pattern on
@ -453,9 +492,7 @@ through a 'mediator'. This can be useful when writing actors that work as
routers, load-balancers, replicators etc.
You need to pass along your context variable as well.
.. code-block:: java
myActor.forward(message, getContext());
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#forward
Receive messages
================
@ -483,12 +520,8 @@ for replying later, or passing on to other actors. If there is no sender (a
message was sent without an actor or future context) then the sender
defaults to a 'dead-letter' actor ref.
.. code-block:: java
public void onReceive(Object request) {
String result = process(request);
getSender().tell(result); // will have dead-letter actor as default
}
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#reply
:exclude: calculate-result
Receive timeout
===============
@ -505,7 +538,7 @@ timeout there must have been an idle period beforehand as configured via this me
Once set, the receive timeout stays in effect (i.e. continues firing repeatedly after inactivity
periods). Pass in `Duration.Undefined` to switch off this feature.
.. includecode:: code/docs/actor/MyReceivedTimeoutUntypedActor.java#receive-timeout
.. includecode:: code/docs/actor/MyReceiveTimeoutUntypedActor.java#receive-timeout
.. _stopping-actors-java:
@ -542,12 +575,8 @@ whole system.
The :meth:`postStop()` hook is invoked after an actor is fully stopped. This
enables cleaning up of resources:
.. code-block:: java
@Override
public void postStop() {
// close some file or database connection
}
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#postStop
:exclude: clean-up-resources-here
.. note::
@ -569,9 +598,6 @@ in the mailbox.
Use it like this:
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
:include: import-actors
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
:include: poison-pill
@ -658,6 +684,7 @@ order as they have been received originally.
Here is an example of the ``UntypedActorWithStash`` class in action:
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#import-stash
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java#stash
Invoking ``stash()`` adds the current message (the message that the
@ -701,9 +728,6 @@ See :ref:`supervision-directives` for more information.
Use ``Kill`` like this:
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
:include: import-actors
.. includecode:: code/docs/actor/UntypedActorDocTestBase.java
:include: kill