AKKA文件(java版)—角色
阿新 • • 發佈:2018-12-23
升級
Akka支援在執行時對角色訊息迴圈 (例如它的的實現)進行實時替換: 在角色中呼叫getContext.become 方法。 熱替換的程式碼被存在一個棧中,可以被pushed(replacing 或 adding 在頂部)和popped。
注意:請注意角色被其監管者重啟後將恢復其最初的行為。
熱替換角色使用getContext().become:
import akka.japi.Procedure;
public class HotSwapActor extends UntypedActor { Procedure<Object> angry = new Procedure<Object>() { @Override public void apply(Object message) { if (message.equals("bar")) { getSender().tell("I am already angry?", getSelf()); } else if (message.equals("foo")) { getContext().become(happy); } } }; Procedure<Object> happy = new Procedure<Object>() { @Override public void apply(Object message) { if (message.equals("bar")) { getSender().tell("I am already happy :-)", getSelf()); } else if (message.equals("foo")) { getContext().become(angry); } } }; public void onReceive(Object message) { if (message.equals("bar")) { getContext().become(angry); } else if (message.equals("foo")) { getContext().become(happy); } else { unhandled(message); } } }
become 方法還有很多其它的用處,一個特別好的例子是用它來實現一個有限狀態機(FSM)。這將代替當前行為(即行為棧頂部),這意味著你不用使用unbecome,而是下一個行為將明確被安裝。
使用become另一個方式:不代替而是新增到行為棧頂部。這種情況是必須要保證在長期執行中“pop”操作(即unbecome)數目匹配“push”數目,否則這個數目將導致記憶體洩露(這就是該行為不是預設原因)。
public class UntypedActorSwapper { public static class Swap { public static Swap SWAP = new Swap(); private Swap() { } } public static class Swapper extends UntypedActor { LoggingAdapter log = Logging.getLogger(getContext().system(), this); public void onReceive(Object message) { if (message == SWAP) { log.info("Hi"); getContext().become(new Procedure<Object>() { @Override public void apply(Object message) { log.info("Ho"); getContext().unbecome(); // resets the latest 'become' } }, false); // this signals stacking of the new behavior } else { unhandled(message); } } } public static void main(String... args) { ActorSystem system = ActorSystem.create("MySystem"); ActorRef swap = system.actorOf(Props.create(Swapper.class)); swap.tell(SWAP, ActorRef.noSender()); // logs Hi swap.tell(SWAP, ActorRef.noSender()); // logs Ho swap.tell(SWAP, ActorRef.noSender()); // logs Hi swap.tell(SWAP, ActorRef.noSender()); // logs Ho swap.tell(SWAP, ActorRef.noSender()); // logs Hi swap.tell(SWAP, ActorRef.noSender()); // logs Ho } }