我正在尝试将以下用例作为我的akka学习的一部分来实现
我想计算所有州所有城市的街道总数。我有一个包含所需细节的数据库。这是我到目前为止所拥有的
配置
import UIKit
class ThirdViewController: UIViewController {
var orderTextController = SecondViewController().orderType
override func viewDidLoad() {
super.viewDidLoad()
order1Label.text = orderTextController
}
override func viewWillAppear(animated: Bool) {
order1Label.text = orderTextController
}
@IBOutlet var order1Label: UILabel!
}
主要
akka.actor.deployment {
/CityActor{
router = random-pool
nr-of-instances = 10
}
/StateActor {
router = random-pool
nr-of-instances = 1
}}
MasterActor
public static void main(String[] args) {
try {
Config conf = ConfigFactory
.parseReader(
new FileReader(ClassLoader.getSystemResource("config/forum.conf").getFile()))
.withFallback(ConfigFactory.load());
System.out.println(conf);
final ActorSystem system = ActorSystem.create("AkkaApp", conf);
final ActorRef masterActor = system.actorOf(Props.create(MasterActor.class), "Migrate");
masterActor.tell("", ActorRef.noSender());
} catch (Exception e) {
e.printStackTrace();
}
}
StateActor
public class MasterActor extends UntypedActor {
private final ActorRef randomRouter = getContext().system()
.actorOf(Props.create(StateActor.class).withRouter(new akka.routing.FromConfig()), "StateActor");
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
getContext().watch(randomRouter);
for (String aState : getStates()) {
randomRouter.tell(aState, getSelf());
}
randomRouter.tell(new Broadcast(PoisonPill.getInstance()), getSelf());
} else if (message instanceof Terminated) {
Terminated ater = (Terminated) message;
if (ater.getActor().equals(randomRouter)) {
getContext().system().terminate();
}
}
}
public List<String> getStates() {
return new ArrayList<String>(Arrays.asList("CA", "MA", "TA", "NJ", "NY"));
};}
CityActor
public class StateActor extends UntypedActor {
private final ActorRef randomRouter = getContext().system()
.actorOf(Props.create(CityActor.class).withRouter(new akka.routing.FromConfig()), "CityActor");
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
System.out.println("Processing state " + message);
for (String aCity : getCitiesForState((String) message)) {
randomRouter.tell(aCity, getSelf());
}
Thread.sleep(1000);
}
}
public List<String> getCitiesForState(String stateName) {
return new ArrayList<String>(Arrays.asList("Springfield-" + stateName, "Salem-" + stateName,
"Franklin-" + stateName, "Clinton-" + stateName, "Georgetown-" + stateName));
};}
我是否正确实施了这个用例?
我无法正确终止代码,我收到了死信。我知道为什么我会得到它们,但不知道如何正确实现它。
非常感谢任何帮助。 感谢
答案 0 :(得分:0)
我使用Akka 2.4.17
测试并运行了您的用例。它正常工作和终止,没有记录任何死信。
以下是一些有助于提高您对Akka工具包的理解的评论/建议:
不要在演员中使用Thread.sleep()
。基本上,它永远不是一个好的做法,因为同一个线程可以为许多actor执行许多任务(这是共享线程池的默认行为)。相反,您可以使用Akka调度程序或将单个线程分配给特定的Actor(有关详细信息,请参阅this post)。另请参阅有关该主题的Akka documentation。
有一些死信并不总是一个问题。通常在系统停止其邮箱中包含某些邮件的Actor时出现。在这种情况下,剩余的未处理消息将发送到deadLetters
的{{1}}。我建议您检查您提供的用于记录死信的配置。如果您提供的文件ActorSystem
是Akka的完整配置文件,您可能需要自定义一些其他设置。请参阅Akka网站上的页面Logging of Dead Letters和Stopping actors。例如,你可以有一个这样的部分:
forum.conf
不是使用akka {
# instead of System.out.println(conf);
log-config-on-start = on
# Max number of dead letters to log
log-dead-letters = 10
log-dead-letters-during-shutdown = on
}
进行日志/调试,而是为每个Actor设置专用记录器更方便,它为您提供调度程序,演员姓名等附加信息。如果您有兴趣,请查看Logging页面。
使用一些自定义immutable message objects而不是系统字符串。首先,必须声明新的附加类似乎很痛苦,但最终它有助于更好地设计复杂的行为,并且它更具可读性。例如,演员A可以使用System.out.println()
或自定义RequestMsg
来回答来自演员B的AnswerMsg
。然后,对于你的演员B,你将得到以下ErrorMsg
方法:
onReceive()
我希望这些资源对您有用。
快乐的Akka节目! ;)