Moved example code, fixed indentation in SupervisedAsk
This commit is contained in:
parent
b965506f10
commit
1d4d65d449
3 changed files with 100 additions and 79 deletions
|
|
@ -1,90 +1,87 @@
|
|||
package docs.pattern;
|
||||
|
||||
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 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 UntypedActor {
|
||||
private static class AskTimeout {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Object message) throws Exception {
|
||||
if (message instanceof AskParam) {
|
||||
ActorRef supervisor = getContext().actorOf(
|
||||
Props.apply(AskSupervisor.class));
|
||||
supervisor.forward(message, getContext());
|
||||
} else {
|
||||
unhandled(message);
|
||||
public static class AskSupervisorCreator extends UntypedActor {
|
||||
|
||||
@Override
|
||||
public void onReceive(Object message) throws Exception {
|
||||
if (message instanceof AskParam) {
|
||||
ActorRef supervisor = getContext().actorOf(
|
||||
Props.apply(AskSupervisor.class));
|
||||
supervisor.forward(message, getContext());
|
||||
} else {
|
||||
unhandled(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class AskSupervisor extends UntypedActor {
|
||||
private ActorRef targetActor;
|
||||
private ActorRef caller;
|
||||
private AskParam askParam;
|
||||
private Cancellable timeoutMessage;
|
||||
|
||||
@Override
|
||||
public SupervisorStrategy supervisorStrategy() {
|
||||
return new OneForOneStrategy(0, Duration.Zero(),
|
||||
new Function<Throwable, Directive>() {
|
||||
public Directive apply(Throwable cause) {
|
||||
caller.tell(new Status.Failure(cause));
|
||||
return SupervisorStrategy.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static class AskSupervisor extends UntypedActor {
|
||||
private ActorRef targetActor;
|
||||
private ActorRef caller;
|
||||
private AskParam askParam;
|
||||
private Cancellable timeoutMessage;
|
||||
|
||||
@Override
|
||||
public SupervisorStrategy supervisorStrategy() {
|
||||
return new OneForOneStrategy(0, Duration.Zero(),
|
||||
new Function<Throwable, Directive>() {
|
||||
public Directive apply(Throwable cause) {
|
||||
caller.tell(new Status.Failure(cause));
|
||||
return SupervisorStrategy.stop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Object message) throws Exception {
|
||||
if (message instanceof AskParam) {
|
||||
askParam = (AskParam) message;
|
||||
caller = getSender();
|
||||
targetActor = getContext().actorOf(askParam.props);
|
||||
getContext().watch(targetActor);
|
||||
targetActor.forward(askParam.message, getContext());
|
||||
Scheduler scheduler = getContext().system().scheduler();
|
||||
timeoutMessage = scheduler.scheduleOnce(askParam.timeout.duration(), self(), new AskTimeout());
|
||||
} else if (message instanceof Terminated) {
|
||||
Throwable ex = new ActorKilledException("Target actor terminated.");
|
||||
caller.tell(new Status.Failure(ex));
|
||||
timeoutMessage.cancel();
|
||||
getContext().stop(self());
|
||||
} else if (message instanceof AskTimeout) {
|
||||
Throwable ex = new TimeoutException("Target actor timed out after " + askParam.timeout.toString());
|
||||
caller.tell(new Status.Failure(ex));
|
||||
getContext().stop(self());
|
||||
} else
|
||||
unhandled(message);
|
||||
}
|
||||
@Override
|
||||
public void onReceive(Object message) throws Exception {
|
||||
if (message instanceof AskParam) {
|
||||
askParam = (AskParam) message;
|
||||
caller = getSender();
|
||||
targetActor = getContext().actorOf(askParam.props);
|
||||
getContext().watch(targetActor);
|
||||
targetActor.forward(askParam.message, getContext());
|
||||
Scheduler scheduler = getContext().system().scheduler();
|
||||
timeoutMessage = scheduler.scheduleOnce(askParam.timeout.duration(),
|
||||
self(), new AskTimeout());
|
||||
} else if (message instanceof Terminated) {
|
||||
Throwable ex = new ActorKilledException("Target actor terminated.");
|
||||
caller.tell(new Status.Failure(ex));
|
||||
timeoutMessage.cancel();
|
||||
getContext().stop(self());
|
||||
} else if (message instanceof AskTimeout) {
|
||||
Throwable ex = new TimeoutException("Target actor timed out after "
|
||||
+ askParam.timeout.toString());
|
||||
caller.tell(new Status.Failure(ex));
|
||||
getContext().stop(self());
|
||||
} else
|
||||
unhandled(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static Future<Object> askOf(ActorRef supervisorCreator,
|
||||
Props props, Object message, Timeout timeout) {
|
||||
AskParam param = new AskParam(props, message, timeout);
|
||||
return Patterns.ask(supervisorCreator, param, timeout);
|
||||
}
|
||||
public static Future<Object> askOf(ActorRef supervisorCreator, Props props,
|
||||
Object message, Timeout timeout) {
|
||||
AskParam param = new AskParam(props, message, timeout);
|
||||
return Patterns.ask(supervisorCreator, param, timeout);
|
||||
}
|
||||
|
||||
synchronized public static ActorRef createSupervisorCreator(ActorRefFactory factory) {
|
||||
return factory.actorOf(Props.apply(AskSupervisorCreator.class));
|
||||
}
|
||||
}
|
||||
|
||||
// example usage
|
||||
try {
|
||||
ActorRef supervisorCreator = SupervisedAsk.createSupervisorCreator(actorSystem);
|
||||
Future<Object> finished = SupervisedAsk.askOf(supervisorCreator,
|
||||
Props.apply(SomeActor.class), message, timeout);
|
||||
SomeResult result = (SomeResult) Await.result(finished, timeout.duration());
|
||||
} catch (Exception e) {
|
||||
// exception propagated by supervision
|
||||
synchronized public static ActorRef createSupervisorCreator(
|
||||
ActorRefFactory factory) {
|
||||
return factory.actorOf(Props.apply(AskSupervisorCreator.class));
|
||||
}
|
||||
}
|
||||
23
akka-docs/rst/java/code/docs/pattern/SupervisedAskSpec.java
Normal file
23
akka-docs/rst/java/code/docs/pattern/SupervisedAskSpec.java
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
package docs.pattern;
|
||||
|
||||
import docs.testkit.TestKitSampleTest.SomeActor;
|
||||
import scala.actors.Future;
|
||||
import actor.ActorRef;
|
||||
import actor.Props;
|
||||
|
||||
public class SupervisedAskSpec {
|
||||
|
||||
public void execute() {
|
||||
// example usage
|
||||
try {
|
||||
ActorRef supervisorCreator = SupervisedAsk
|
||||
.createSupervisorCreator(actorSystem);
|
||||
Future<Object> finished = SupervisedAsk.askOf(supervisorCreator,
|
||||
Props.apply(SomeActor.class), message, timeout);
|
||||
Object result = Await.result(finished,
|
||||
timeout.duration());
|
||||
} catch (Exception e) {
|
||||
// exception propagated by supervision
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ Single-Use Actor Trees with High-Level Error Reporting
|
|||
A nice way to enter the actor world from java is the use of Patterns.ask().
|
||||
This method starts a temporary actor to forward the message and collect the result from the actor to be "asked".
|
||||
In case of errors within the asked actor the default supervision handling will take over.
|
||||
The caller of Patterns.ask() will not be notified.
|
||||
The caller of Patterns.ask() will *not* be notified.
|
||||
|
||||
If that caller is interested in such an exception, he must make sure that the asked actor replies with Status.Failure(Throwable).
|
||||
Behind the asked actor a complex actor hierarchy might be spawned to accomplish asynchronous work.
|
||||
|
|
@ -51,6 +51,7 @@ Afterwards the actor hierarchy is stopped.
|
|||
|
||||
Finally we are able to execute an actor and receive the results or exceptions.
|
||||
|
||||
.. includecode:: code/docs/pattern/SupervisedAskSpec.java
|
||||
|
||||
Template Pattern
|
||||
================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue