유한상태기계(Finite State Machine)
위키백과, 우리 모두의 백과사전.
유한 상태 기계(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 설계가 가능해집니다.
HotSwapActor
핫스왑은 작동하는 도중 기능을 바꿀수 있는 기능을 의미하며 , 이것은 유연한 메시지 설계에
도움이 되는 기능중 하나입니다.
- 현재 감정 상태에따라 다른 반응을 한다.
- foo 를 받으면 화를 내는 상태가 된다.
- bar를 받으면 행복한 상태가된다.
- 감정의 변화가 일어나는 조건을 전이라고 한다.
- 이미 화난상태이거나 행복한 상태일때 다른 메시지 처리를 한다.
구현샘플
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와 같이 이미 구현된 객체를 사용하는것이 아닌,
유용한 어떠한 액터설계를 우리가 직접 할수있음을 의미합니다.
SwapperActor
Swapper의 경우 전구와 유사한 상태를 가지는 기능이라고 보면된다
- 전구는 ON / OFF 두가지 상태를 갖는다.
- 전구는 반드시 둘중 하나의 상태만 취한다.
- 각 상태는 특정 조건 (스위치 올림 / 내림 ) 에 따라 변한다
- 전구를 다음과 같이 정의할 수 있다.
- ON : 스위치가 올라가면 OFF로 전이
- OFF : 스위치가 내려가면 ON으로 전이
위와같이 두가지 상태중 하나만 가지는 모델입니다.
구현샘플
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의 기능은 유용합니다.
참고 :