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

참고 :


  • No labels