Oversight Strategy
The Akka framework gives us enough control. Within the Akka framework, parent Acotr can monitor child Actors to see if they behave differently. Oversight strategies can be divided into two types: one is oversight of the OneForOneStrategy strategy (which handles only the problematic sub-Actors) and the other is oversight of the AllForOneStrategy strategy (which handles both the problematic sub-Acotr and all its siblings, suitable for scenarios where the individual Actors are closely connected).
Customized supervisor strategy
Define the supervision of a OneForOneStrategy policy. In this surveillance strategy, after running an Actor encounters an error, it retries three times in a minute, and if it exceeds this frequency, it kills the Actor directly. When you encounter an ArithmeticException exception (such as a divide by 0 error), continue to specify the Actor without handling it; restart when you encounter a null pointer. Stop Acotr directly if you encounter Illegan ArgumentException
public class Supervisor extends UntypedAbstractActor { private static SupervisorStrategy strategy= new OneForOneStrategy(3, Duration.create(1, TimeUnit.MINUTES), //Try again three times a minute new Function<Throwable, SupervisorStrategy.Directive>() { @Override public SupervisorStrategy.Directive apply(Throwable param) throws Exception { if(param instanceof ArithmeticException){ System.out.println("meet ArithmeticException,just resume"); return SupervisorStrategy.resume(); }else if(param instanceof NullPointerException){ System.out.println("meet NullPointerException,restart"); return SupervisorStrategy.restart(); }else if(param instanceof IllegalArgumentException){ return SupervisorStrategy.stop(); }else { return SupervisorStrategy.escalate(); } } }); public static SupervisorStrategy getStrategy() { return strategy; } @Override public void onReceive(Object message) throws Throwable { if(message instanceof Props){ getContext().actorOf((Props) message,"restartActor"); }else { unhandled(message); } } }
public class RestartActor extends UntypedAbstractActor { public enum Msg{ DONE,RESTART; } @Override public void preStart() throws Exception { System.out.println("preStart hashcode:"+this.hashCode()); } @Override public void postStop() throws Exception { System.out.println("postStop hashcode:"+this.hashCode()); } @Override public void postRestart(Throwable reason) throws Exception { super.postRestart(reason); System.out.println("postRestart hashcode:"+this.hashCode()); } @Override public void preRestart(Throwable reason, Optional<Object> message) throws Exception { System.out.println("preSRestart hashcode:"+this.hashCode()); } @Override public void onReceive(Object message) throws Throwable { if(message==Msg.DONE){ getContext().stop(getSelf()); }else if(message==Msg.RESTART){ System.out.println("--------"); double a=0/0;//resume } unhandled(message); } public static void main(String[] args) { ActorSystem system = ActorSystem.create("lifeStyle"); ActorRef a=system.actorOf(Props.create(Supervisor.class),"supervisor"); a.tell(Props.create(RestartActor.class),ActorRef.noSender()); ActorSelection sel=system.actorSelection("akka://lifeStyle/user/supervisor/restartActor"); for (int i = 0; i < 100; i++) { sel.tell(Msg.RESTART,ActorRef.noSender()); } } }
You can see that preStart indicates that RestartActor is initializing, and its hashcode is 126294244. When a null pointer exception is encountered, it is restarted according to a custom policy. The preRestart method is called before the restart, and hashcode is 1276294244. After a new instance is generated, the hashcode of preStart becomes 99731995. The hashcode returned to the postRestart method was also 99731995, and the original instance was waved because it was restarted. This means that the same Actor may not always maintain the same instance while working on the system.
Select Actor
In an Actor System, there may be a large number of Actors. How can you effectively manage and communicate a large number of Actors in batch? Akka provides us with an ActorSelection class for bulk messaging.
for(int i=0;i<WORDER_COUNT;i++){ workers.add(system.actorOf(Props.create(MyWorker.class,i),"worker_"+i)); } ActorSelection selection=getContext().actorSelection("/user/worker_*"); selection.tell(5,getSelf());
The code above generates a large number of Actors in batch, and we want to send messages to these worker s to get ActorSelections that represent all the conditions that are met using the selection wildcards provided by the actorSelection() method.