我试图在Akka 2.4.0中使用UnboundedControlAwareMailbox。
我创建了一个实现RequiresMessageQueue<UnboundedControlAwareMessageQueueSemantics>
的演员:
public class ControlActor extends AbstractLoggingActor
implements RequiresMessageQueue<UnboundedControlAwareMailbox> {
public ControlActor(ActorRef testActor) {
this.testActor = testActor;
receive(ReceiveBuilder.
match(HiPriority.class,
msg -> testActor.tell(msg, self())).
match(LoPriority.class,
msg -> testActor.tell(msg, self())).
build());
}
private void forward(Object msg) {
try {
Thread.currentThread().sleep(50);
testActor.tell(msg, self());
} catch (Exception exc) {
log().error(exc, "Failed to wait or forward");
fail(exc.getMessage());
}
}
private final ActorRef testActor;
}
使用这些消息:
public class HiPriority implements ControlMessage {
String id;
}
public class LoPriority {
String id;
}
The mailbox documentation建议我可以通过
创建演员system.actorOf(Props.create(ControlActor.class,
getRef()).
withDispatcher("akka.actor.mailbox.unbounded-control-aware-queue-based").
"control");
但即便
system.actorOf(Props.create(ControlActor.class,
getRef()).
withDispatcher("akka.actor.mailbox.unbounded-control-aware-queue-based").
withMailbox("akka.actor.mailbox.unbounded-control-aware-queue-based"),
"control");
失败
akka.ConfigurationException: configuration problem while creating [akka://ControlActorTest/user/control] with dispatcher [akka.actor.mailbox.unbounded-control-aware-queue-based] and mailbox [akka.actor.mailbox.unbounded-control-aware-queue-based]
at akka.actor.LocalActorRefProvider.actorOf(ActorRefProvider.scala:766) ~[akka-actor_2.11-2.4.0.jar:na]
at akka.actor.dungeon.Children$class.makeChild(Children.scala:220) ~[akka-actor_2.11-2.4.0.jar:na]
at akka.actor.dungeon.Children$class.attachChild(Children.scala:42) ~[akka-actor_2.11-2.4.0.jar:na]
at akka.actor.ActorCell.attachChild(ActorCell.scala:373) ~[akka-actor_2.11-2.4.0.jar:na]
at akka.actor.ActorSystemImpl.actorOf(ActorSystem.scala:586) ~[akka-actor_2.11-2.4.0.jar:na]
...
Caused by: java.lang.IllegalArgumentException: produced message queue type [class akka.dispatch.UnboundedControlAwareMailbox$MessageQueue] does not fulfill requirement for actor class [class com.str.rspace.ControlActorTest$ControlActor]
at akka.dispatch.Mailboxes.verifyRequirements$1(Mailboxes.scala:141) ~[akka-actor_2.11-2.4.0.jar:na]
at akka.dispatch.Mailboxes.getMailboxType(Mailboxes.scala:147) ~[akka-actor_2.11-2.4.0.jar:na]
at akka.actor.LocalActorRefProvider.actorOf(ActorRefProvider.scala:761) ~[akka-actor_2.11-2.4.0.jar:na]
... 34 common frames omitted
示例使用UntypedActor。使用AbstractActor类有不同的方法吗?
如果没有,我如何配置我的actor使用这个队列语义?
使用案例
当我写这篇文章时,我只是想让一个接收两种类型消息的actor,并且会处理在处理任何第二种类型之前收到的所有第一种类型。基本上,控制消息(第一类型)配置当前环境和请求解决当前环境中的问题的第二类消息。解决之后,需要更新环境以反映解决方案,因此如果收到两个求解消息,则在处理完第一个求解后,我需要接收并处理控制消息以反映该解决方案,然后再处理第二个求解消息。 / p>
这似乎是ControlAware语义/邮箱/调度程序的直接使用,但我无法使用该选项启动我的actor。
为了确保在第一次解决之后和处理第二次求解之前我能够收到控制消息,该actor是一个FSM actor。当actor没有处于正确的状态时,它会隐藏消息,这允许第二个actor在第一次求解后发送控制消息。所以在这一点上,我需要存储和控制消息。存储需要deque语义。高优先级消息需要控制感知语义。我找到了各自单独使用的调度员,但我找不到同时使用两者的调度员。
我最终实现了一个使用两个DequeBasedMessageQueue的自定义邮箱,以获得我需要的所有功能。
我会尽快升级到Akka 2.5,但我们目前正在进行集成测试,我不希望在结束之前做出这样的改变。