1. 程式人生 > >AKKA文件(java版)—角色

AKKA文件(java版)—角色

升級

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
  }

}