DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

Building reactive application with Akka

原文链接

The actor model provides the core functionality of reactive systems, defined in the Reactive Manifesto as responsive, resilient, elastic, and message driven.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static class Counter extends AbstractLoggingActor {
static class Message { }

private int counter = 0;

{
receive(ReceiveBuilder
.match(Message.class, this::onMessage)
.build()
);
}

private void onMessage(Message message) {
counter++;
log().info("Increased counter " + counter);
}
}

send message

1
counter.tell(new Counter.Message(), ActorRef.noSender());

change actor behaviour

1
2
3
4
5
6
7
8
private void onEnable(Enable enable) {
if (password.equals(enable.password)) {
log().info("Alarm enable");
getContext().become(enabled);
} else {
log().info("Someone failed to enable the alarm");
}
}
1
2
3
4
5
6
7
8
9
10
ActorSystem system = ActorSystem.create();
final ActorRef alarm = system.actorOf(Alarm.props("cat"), "alarm");

alarm.tell(new Alarm.Activity(), ActorRef.noSender());
alarm.tell(new Alarm.Enable("dogs"), ActorRef.noSender());
alarm.tell(new Alarm.Enable("cat"), ActorRef.noSender());
alarm.tell(new Alarm.Activity(), ActorRef.noSender());
alarm.tell(new Alarm.Disable("dogs"), ActorRef.noSender());
alarm.tell(new Alarm.Disable("cat"), ActorRef.noSender());
alarm.tell(new Alarm.Activity(), ActorRef.noSender());

Actors may create other actors. When one actor creates another actor, the creator is known as the supervisor and the created actor is known as the worker.

但是这种方式不被推荐?

If one actor does not have the means for dealing with a certain situation, it sends a corresponding failure message to its supervisor, asking for help. The supervisor has four different options for reacting to a failure:

  • Resume the child, keeping its accumulated internal state but ignoring the message that lead to the failure.
  • Restart the child, clearing out its accumulated internal state by starting a new instance.
  • Stop the child permanently and send all future messages for the child to the Dead-Letter Office.
  • Escalate the failure, thereby failing the supervisor itself

针对actor的策略?

1
2
3
4
5
6
7
8
9
10
11
12
public class Supervisor extends AbstractLoggingActor {
{
final ActorRef child = getContext().actorOf(NonTrustWorthyChild.props(), "child");

receive(ReceiveBuilder
.matchAny(command -> child.forward(command, getContext()))
.build()
);

}
//…
}

supervisor是child?

Akka provides two classes of supervision strategies: OneForOneStrategy and AllForOneStrategy.The difference between them is that the former applies the obtained directive only to the failed child, whereas the latter applies it to all siblings as well. Normally, you should use the OneForOneStrategy, which is the default if none is explicitly specified. It is defined by overriding the SupervisorStrategy method.

The output shows, that after four messages the exception gets escalated to the Supervisor and the remaining messages are sent to the deadLetters box. If the SupervisorStrategy would have been defined to restart()instead of stop(), a new instance of the NonTrustWorthyChild actor would have been started.

关于子actor的策略,是restart还是stop