ActorContext.getParent for Java API #22413
This commit is contained in:
parent
5ff44194a3
commit
2eb226ed32
213 changed files with 1319 additions and 1523 deletions
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2017 Lightbend Inc. <http://www.lightbend.com>
|
||||
*/
|
||||
package jdocs.pattern;
|
||||
|
||||
import akka.actor.*;
|
||||
import akka.pattern.Backoff;
|
||||
import akka.pattern.BackoffSupervisor;
|
||||
import akka.testkit.TestActors.EchoActor;
|
||||
//#backoff-imports
|
||||
import scala.concurrent.duration.Duration;
|
||||
//#backoff-imports
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BackoffSupervisorDocTest {
|
||||
|
||||
void exampleStop (ActorSystem system) {
|
||||
//#backoff-stop
|
||||
final Props childProps = Props.create(EchoActor.class);
|
||||
|
||||
final Props supervisorProps = BackoffSupervisor.props(
|
||||
Backoff.onStop(
|
||||
childProps,
|
||||
"myEcho",
|
||||
Duration.create(3, TimeUnit.SECONDS),
|
||||
Duration.create(30, TimeUnit.SECONDS),
|
||||
0.2)); // adds 20% "noise" to vary the intervals slightly
|
||||
|
||||
system.actorOf(supervisorProps, "echoSupervisor");
|
||||
//#backoff-stop
|
||||
}
|
||||
|
||||
void exampleFailure (ActorSystem system) {
|
||||
//#backoff-fail
|
||||
final Props childProps = Props.create(EchoActor.class);
|
||||
|
||||
final Props supervisorProps = BackoffSupervisor.props(
|
||||
Backoff.onFailure(
|
||||
childProps,
|
||||
"myEcho",
|
||||
Duration.create(3, TimeUnit.SECONDS),
|
||||
Duration.create(30, TimeUnit.SECONDS),
|
||||
0.2)); // adds 20% "noise" to vary the intervals slightly
|
||||
|
||||
system.actorOf(supervisorProps, "echoSupervisor");
|
||||
//#backoff-fail
|
||||
}
|
||||
}
|
||||
172
akka-docs/rst/java/code/jdocs/pattern/SchedulerPatternTest.java
Normal file
172
akka-docs/rst/java/code/jdocs/pattern/SchedulerPatternTest.java
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2017 Lightbend Inc. <http://www.lightbend.com>
|
||||
*/
|
||||
|
||||
package jdocs.pattern;
|
||||
|
||||
import akka.actor.*;
|
||||
import akka.testkit.*;
|
||||
import akka.testkit.TestEvent.Mute;
|
||||
import akka.testkit.TestEvent.UnMute;
|
||||
import jdocs.AbstractJavaTest;
|
||||
import org.junit.*;
|
||||
import scala.concurrent.duration.Duration;
|
||||
import scala.concurrent.duration.FiniteDuration;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SchedulerPatternTest extends AbstractJavaTest {
|
||||
|
||||
@ClassRule
|
||||
public static AkkaJUnitActorSystemResource actorSystemResource =
|
||||
new AkkaJUnitActorSystemResource("SchedulerPatternTest", AkkaSpec.testConf());
|
||||
|
||||
private final ActorSystem system = actorSystemResource.getSystem();
|
||||
|
||||
static
|
||||
//#schedule-constructor
|
||||
public class ScheduleInConstructor extends AbstractActor {
|
||||
|
||||
private final Cancellable tick = getContext().getSystem().scheduler().schedule(
|
||||
Duration.create(500, TimeUnit.MILLISECONDS),
|
||||
Duration.create(1, TimeUnit.SECONDS),
|
||||
getSelf(), "tick", getContext().dispatcher(), null);
|
||||
//#schedule-constructor
|
||||
// this variable and constructor is declared here to not show up in the docs
|
||||
final ActorRef target;
|
||||
public ScheduleInConstructor(ActorRef target) {
|
||||
this.target = target;
|
||||
}
|
||||
//#schedule-constructor
|
||||
|
||||
@Override
|
||||
public void postStop() {
|
||||
tick.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder()
|
||||
.matchEquals("tick", message -> {
|
||||
// do something useful here
|
||||
//#schedule-constructor
|
||||
target.tell(message, getSelf());
|
||||
//#schedule-constructor
|
||||
})
|
||||
.matchEquals("restart", message -> {
|
||||
throw new ArithmeticException();
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
//#schedule-constructor
|
||||
|
||||
static
|
||||
//#schedule-receive
|
||||
public class ScheduleInReceive extends AbstractActor {
|
||||
//#schedule-receive
|
||||
// this variable and constructor is declared here to not show up in the docs
|
||||
final ActorRef target;
|
||||
public ScheduleInReceive(ActorRef target) {
|
||||
this.target = target;
|
||||
}
|
||||
//#schedule-receive
|
||||
|
||||
@Override
|
||||
public void preStart() {
|
||||
getContext().getSystem().scheduler().scheduleOnce(
|
||||
Duration.create(500, TimeUnit.MILLISECONDS),
|
||||
getSelf(), "tick", getContext().dispatcher(), null);
|
||||
}
|
||||
|
||||
// override postRestart so we don't call preStart and schedule a new message
|
||||
@Override
|
||||
public void postRestart(Throwable reason) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder()
|
||||
.matchEquals("tick", message -> {
|
||||
// send another periodic tick after the specified delay
|
||||
getContext().getSystem().scheduler().scheduleOnce(
|
||||
Duration.create(1, TimeUnit.SECONDS),
|
||||
getSelf(), "tick", getContext().dispatcher(), null);
|
||||
// do something useful here
|
||||
//#schedule-receive
|
||||
target.tell(message, getSelf());
|
||||
//#schedule-receive
|
||||
})
|
||||
.matchEquals("restart", message -> {
|
||||
throw new ArithmeticException();
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
//#schedule-receive
|
||||
|
||||
@Test
|
||||
@Ignore // no way to tag this as timing sensitive
|
||||
public void scheduleInConstructor() {
|
||||
new TestSchedule(system) {{
|
||||
final JavaTestKit probe = new JavaTestKit(system);
|
||||
final Props props = Props.create(ScheduleInConstructor.class, probe.getRef());
|
||||
testSchedule(probe, props, duration("3000 millis"), duration("2000 millis"));
|
||||
}};
|
||||
}
|
||||
|
||||
@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 = Props.create(ScheduleInReceive.class, probe.getRef());
|
||||
testSchedule(probe, props, duration("3000 millis"), duration("2500 millis"));
|
||||
}};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doNothing() {
|
||||
// actorSystemResource.after is not called when all tests are ignored
|
||||
}
|
||||
|
||||
public static class TestSchedule extends JavaTestKit {
|
||||
private ActorSystem system;
|
||||
|
||||
public TestSchedule(ActorSystem system) {
|
||||
super(system);
|
||||
this.system = system;
|
||||
}
|
||||
|
||||
public void testSchedule(final JavaTestKit probe, Props props,
|
||||
FiniteDuration startDuration,
|
||||
FiniteDuration afterRestartDuration) {
|
||||
Iterable<akka.testkit.EventFilter> filter =
|
||||
Arrays.asList(new akka.testkit.EventFilter[]{
|
||||
(akka.testkit.EventFilter) new ErrorFilter(ArithmeticException.class)});
|
||||
try {
|
||||
system.eventStream().publish(new Mute(filter));
|
||||
|
||||
final ActorRef actor = system.actorOf(props);
|
||||
new Within(startDuration) {
|
||||
protected void run() {
|
||||
probe.expectMsgEquals("tick");
|
||||
probe.expectMsgEquals("tick");
|
||||
probe.expectMsgEquals("tick");
|
||||
}
|
||||
};
|
||||
actor.tell("restart", getRef());
|
||||
new Within(afterRestartDuration) {
|
||||
protected void run() {
|
||||
probe.expectMsgEquals("tick");
|
||||
probe.expectMsgEquals("tick");
|
||||
}
|
||||
};
|
||||
system.stop(actor);
|
||||
}
|
||||
finally {
|
||||
system.eventStream().publish(new UnMute(filter));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
106
akka-docs/rst/java/code/jdocs/pattern/SupervisedAsk.java
Normal file
106
akka-docs/rst/java/code/jdocs/pattern/SupervisedAsk.java
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
package jdocs.pattern;
|
||||
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import scala.concurrent.duration.Duration;
|
||||
|
||||
import akka.actor.ActorKilledException;
|
||||
import akka.actor.ActorRef;
|
||||
import akka.actor.ActorRefFactory;
|
||||
import akka.actor.Cancellable;
|
||||
import akka.actor.OneForOneStrategy;
|
||||
import akka.actor.Props;
|
||||
import akka.actor.Scheduler;
|
||||
import akka.actor.Status;
|
||||
import akka.actor.SupervisorStrategy;
|
||||
import akka.actor.Terminated;
|
||||
import akka.actor.AbstractActor;
|
||||
import akka.pattern.PatternsCS;
|
||||
import akka.util.Timeout;
|
||||
|
||||
public class SupervisedAsk {
|
||||
|
||||
private static class AskParam {
|
||||
Props props;
|
||||
Object message;
|
||||
Timeout timeout;
|
||||
|
||||
AskParam(Props props, Object message, Timeout timeout) {
|
||||
this.props = props;
|
||||
this.message = message;
|
||||
this.timeout = timeout;
|
||||
}
|
||||
}
|
||||
|
||||
private static class AskTimeout {
|
||||
}
|
||||
|
||||
public static class AskSupervisorCreator extends AbstractActor {
|
||||
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder()
|
||||
.match(AskParam.class, message -> {
|
||||
ActorRef supervisor = getContext().actorOf(
|
||||
Props.create(AskSupervisor.class));
|
||||
supervisor.forward(message, getContext());
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class AskSupervisor extends AbstractActor {
|
||||
private ActorRef targetActor;
|
||||
private ActorRef caller;
|
||||
private AskParam askParam;
|
||||
private Cancellable timeoutMessage;
|
||||
|
||||
@Override
|
||||
public SupervisorStrategy supervisorStrategy() {
|
||||
return new OneForOneStrategy(0, Duration.Zero(), cause -> {
|
||||
caller.tell(new Status.Failure(cause), getSelf());
|
||||
return SupervisorStrategy.stop();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return receiveBuilder()
|
||||
.match(AskParam.class, message -> {
|
||||
askParam = message;
|
||||
caller = getSender();
|
||||
targetActor = getContext().actorOf(askParam.props);
|
||||
getContext().watch(targetActor);
|
||||
targetActor.forward(askParam.message, getContext());
|
||||
Scheduler scheduler = getContext().getSystem().scheduler();
|
||||
timeoutMessage = scheduler.scheduleOnce(askParam.timeout.duration(),
|
||||
getSelf(), new AskTimeout(), getContext().dispatcher(), null);
|
||||
})
|
||||
.match(Terminated.class, message -> {
|
||||
Throwable ex = new ActorKilledException("Target actor terminated.");
|
||||
caller.tell(new Status.Failure(ex), getSelf());
|
||||
timeoutMessage.cancel();
|
||||
getContext().stop(getSelf());
|
||||
})
|
||||
.match(AskTimeout.class, message -> {
|
||||
Throwable ex = new TimeoutException("Target actor timed out after "
|
||||
+ askParam.timeout.toString());
|
||||
caller.tell(new Status.Failure(ex), getSelf());
|
||||
getContext().stop(getSelf());
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
public static CompletionStage<Object> askOf(ActorRef supervisorCreator, Props props,
|
||||
Object message, Timeout timeout) {
|
||||
AskParam param = new AskParam(props, message, timeout);
|
||||
return PatternsCS.ask(supervisorCreator, param, timeout);
|
||||
}
|
||||
|
||||
synchronized public static ActorRef createSupervisorCreator(
|
||||
ActorRefFactory factory) {
|
||||
return factory.actorOf(Props.create(AskSupervisorCreator.class));
|
||||
}
|
||||
}
|
||||
30
akka-docs/rst/java/code/jdocs/pattern/SupervisedAskSpec.java
Normal file
30
akka-docs/rst/java/code/jdocs/pattern/SupervisedAskSpec.java
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
package jdocs.pattern;
|
||||
|
||||
import akka.actor.ActorRef;
|
||||
import akka.actor.ActorRefFactory;
|
||||
import akka.actor.Props;
|
||||
import akka.actor.AbstractActor;
|
||||
import akka.util.Timeout;
|
||||
import scala.concurrent.duration.FiniteDuration;
|
||||
|
||||
import java.util.concurrent.CompletionStage;
|
||||
|
||||
public class SupervisedAskSpec {
|
||||
|
||||
public Object execute(Class<? extends AbstractActor> someActor,
|
||||
Object message, Timeout timeout, ActorRefFactory actorSystem)
|
||||
throws Exception {
|
||||
// example usage
|
||||
try {
|
||||
ActorRef supervisorCreator = SupervisedAsk
|
||||
.createSupervisorCreator(actorSystem);
|
||||
CompletionStage<Object> finished = SupervisedAsk.askOf(supervisorCreator,
|
||||
Props.create(someActor), message, timeout);
|
||||
FiniteDuration d = timeout.duration();
|
||||
return finished.toCompletableFuture().get(d.length(), d.unit());
|
||||
} catch (Exception e) {
|
||||
// exception propagated by supervision
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue