유한상태기계(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의 기능은 유용합니다.
참고 :

