위키백과, 우리 모두의 백과사전.
유한 상태 기계(finite-state machine, FSM) 또는 유한 오토마톤(finite automaton, FA; 복수형: 유한 오토마타 finite automata)는 컴퓨터 프로그램과 전자 논리 회로를 설계하는데에 쓰이는 수학적 모델이다. 간단히 상태 기계라고 부르기도 한다. 유한 상태 기계는 유한한 개수의 상태를 가질 수 있는 오토마타, 즉 추상 기계라고 할 수 있다. 이러한 기계는 한 번에 오로지 하나의 상태만을 가지게 되며, 현재 상태(Current State)란 임의의 주어진 시간의 상태를 칭한다. 이러한 기계는 어떠한 사건(Event)에 의해 한 상태에서 다른 상태로 변화할 수 있으며, 이를 전이(Transition)이라 한다. 특정한 유한 오토마톤은 현재 상태로부터 가능한 전이 상태와, 이러한 전이를 유발하는 조건들의 집합으로서 정의된다.
메시지 처리기도 FSM이 반영된 액터 설계가 가능하며 실제로 이것은
다양한 실시간 메시지를 처리해야하는 액터설계에 중요한 요소로 활용될수 있습니다.
액터와 별개로 OOP에서 이러한 FSM구현을 구조적으로 하기위해
State Degisn Pattern 이 활용되기도 합니다.
AKKA에서 FSM 유틸리티가 직접적으로 지원도되지만(https://doc.akka.io/docs/akka/2.5/fsm.html)
become(전이)/unbecome(전이상태제거) 등을 활용하여 FSM 설계가 가능해집니다.
핫스왑은 작동하는 도중 기능을 바꿀수 있는 기능을 의미하며 , 이것은 유연한 메시지 설계에 도움이 되는 기능중 하나입니다.
|
public class HotSwapActor extends AbstractActor { private AbstractActor.Receive angry; private AbstractActor.Receive happy; public HotSwapActor() { angry = receiveBuilder() .matchEquals("foo", s -> { getSender().tell("I am already angry?", getSelf()); }) .matchEquals("bar", s -> { getContext().become(happy); }) .build(); happy = receiveBuilder() .matchEquals("bar", s -> { getSender().tell("I am already happy :-)", getSelf()); }) .matchEquals("foo", s -> { getContext().become(angry); }) .build(); } @Override public Receive createReceive() { return receiveBuilder() .matchEquals("foo", s -> getContext().become(angry) ) .matchEquals("bar", s -> getContext().become(happy) ) .build(); } } |
Actor API 의 become(상태변화) 기능으로 구현을 한 샘플이며
HowSwapActor와 같이 이미 구현된 객체를 사용하는것이 아닌,
유용한 어떠한 액터설계를 우리가 직접 할수있음을 의미합니다.
Swapper의 경우 전구와 유사한 상태를 가지는 기능이라고 보면된다
위와같이 두가지 상태중 하나만 가지는 모델입니다. |
public class Swapper extends AbstractLoggingActor { @Override public Receive createReceive() { return receiveBuilder() .matchEquals(Swap, s -> { log().info("Hi"); getContext().become(receiveBuilder(). matchEquals(Swap, x -> { log().info("Ho"); getContext().unbecome(); // resets the latest 'become' (just for fun) }).build(), false); // push on top instead of replace }).build(); } } public class SwapperApp { public static void main(String[] args) { ActorSystem system = ActorSystem.create("SwapperSystem"); ActorRef swapper = system.actorOf(Props.create(Swapper.class), "swapper"); swapper.tell(Swap, ActorRef.noSender()); // logs Hi swapper.tell(Swap, ActorRef.noSender()); // logs Ho swapper.tell(Swap, ActorRef.noSender()); // logs Hi swapper.tell(Swap, ActorRef.noSender()); // logs Ho swapper.tell(Swap, ActorRef.noSender()); // logs Hi swapper.tell(Swap, ActorRef.noSender()); // logs Ho system.terminate(); } } |
더복잡한 상태를 가지게될시 AKKA의 FSM 추상화 객체활용이 가능하며
상태의 저장까지 책임지는 영속성 Part에서도 FSM의 기능은 유용합니다.
참고 :