Akka 2.4.1 Java API 。我现在没有足够的带宽来学习Scala,所以我想这里的代码示例也使用Java API。
我有一个现有的ActorSystem
,它充满了异步演员,而且效果很好。我现在需要在同步上下文中重用这个actor系统,如下所示:
// Groovy pseudo-code; NOT inside the actor system here!
ComputationRequest request = new ComputationRequest(1, 7, true)
MasterActor master = actorSystem.get(...)
ComputationResult result = actorSystem.tell(master, request)
在Akka的文档中没有任何地方我看到一个明确的例子,即将动画发送到演员系统(从外部),然后检索结果。我可以在这里使用Futures
吗?在Akka(代码示例)中处理这种模式的标准方法是什么?
答案 0 :(得分:11)
ask模式可以满足您的需求。它希望目标参与者通过tell
将回复“返回”getSender()
。你会得到一个Future
的响应,可以使用它(阻止,如果必须的话)。
import akka.dispatch.*;
import scala.concurrent.ExecutionContext;
import scala.concurrent.Future;
import scala.concurrent.Await;
import scala.concurrent.Promise;
import akka.util.Timeout;
ComputationRequest request = new ComputationRequest(1, 7, true);
MasterActor master = actorSystem.get(...);
Timeout timeout = new Timeout(Duration.create(5, "seconds"));
Future<Object> future = Patterns.ask(master, request, timeout);
ComputationResult result = (ComputationResult) Await.result(future, timeout.duration());
答案 1 :(得分:0)
您可以将包含在演员中的回调注入akka系统,并将其用作&#34;发件人&#34;告诉力学。完整的例子:
import akka.actor.*;
import akka.dispatch.Await;
import akka.dispatch.Future;
import akka.pattern.Patterns;
import akka.util.Timeout;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) throws Exception {
// init your akka system
final ActorSystem system = ActorSystem.create("Cambria");
final ActorRef worker = system.actorOf(new Props(Worker.class), "worker");
worker.tell(new Work(10));
// make callback
final Consumer<Object> callback = a -> System.out.println("from the other side: " + a);
// wrap call back into sub-actor
class TheSpy extends UntypedActor {
@Override
public void onReceive(final Object message) throws Exception {
callback.accept(message);
}
}
// inject callback into the system
final ActorRef theSpy = system.actorOf(new Props(TheSpy::new), "spy");
// find actor you want to hack
final ActorSelection found = system.actorSelection("/user/worker");
// send it a message and observe using callback)
found.tell(new Work(20), theSpy);
final Timeout timeout = new Timeout(5, TimeUnit.SECONDS);
final Future<Object> future = Patterns.ask(worker, new Work(30), timeout);
final Work result = (Work) Await.result(future, timeout.duration());
System.out.println(result);
system.shutdown();
system.awaitTermination();
}
}
public class Worker extends UntypedActor {
public void onReceive(Object message) {
if (message instanceof Work) {
Work work = (Work) message;
System.out.println("work = " + work);
getSender().tell(new Work(work.getStart() + 1));
} else {
unhandled(message);
}
}
}
public class Work {
private final int start;
public Work(int start) {
this.start = start;
}
public int getStart() {
return start;
}
@Override
public String toString() {
return "Work{" +
"start=" + start +
'}';
}
}