ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Behavior control (become / unbecome)
    akka & pekko/actors 2023. 7. 17. 17:13

    1. Become() 을 사용하지 않고 구현

    • mutable variable 로 상태 관리
    import akka.actor.{Actor, ActorSystem, Props}
    
    object AkkaTest {
      object Kid {
        def props() = Props(new Kid())
        case object KidAccept
        case object KidReject
    
        val HAPPY = "happy"
        val SAD = "sad"
      }
    
      object Mom {
        def props() = Props(new Mom())
    
        case class Food(food: String)
        case class Ask(message: String)
    
        val VEGETABLE = "vegetable"
        val CHOCOLATE = "chocolate"
      }
    
      class Kid extends Actor {
        import Kid._
        import Mom._
    
        var state: String = HAPPY
    
        override def receive: Receive = {
          case Food(VEGETABLE) => state = SAD
          case Food(CHOCOLATE) => state = HAPPY
          case Ask(_) =>
            if (state == HAPPY) sender() ! KidAccept
            else sender() ! KidReject
        }
      }
    
      class Mom extends Actor {
        import Kid._
    
        override def receive: Receive = {
          case KidAccept => println("My kid is happy")
          case KidReject => println("My kid is sad")
        }
      }
    
      def main(args: Array[String]): Unit = {
        val actorSystem: ActorSystem = ActorSystem(name = "actorCapabilitiesDemo")
    
        val kidActor = actorSystem.actorOf(Kid.props(), "kidActor")
        val momActor = actorSystem.actorOf(Mom.props(), "momActor")
    
        import Mom._
        kidActor.tell(Ask("Do you want to play?"), momActor)
        kidActor.tell(Food(VEGETABLE), momActor)
        kidActor.tell(Ask("Do you want to play?"), momActor)
      }
    }

     

    결과

    My kid is happy
    My kid is sad

     

    2. Become() 을 사용해 구현

    import akka.actor.{Actor, ActorSystem, Props}
    
    object AkkaMain {
      object Kid {
        def props() = Props(new Kid())
        case object KidAccept
        case object KidReject
    
        val HAPPY = "happy"
        val SAD = "sad"
      }
    
      object Mom {
        def props() = Props(new Mom())
    
        case class Food(food: String)
        case class Ask(message: String)
    
        val VEGETABLE = "vegetable"
        val CHOCOLATE = "chocolate"
      }
    
      class Kid extends Actor {
        import Kid._
        import Mom._
    
        var state: String = HAPPY
    
        override def receive: Receive = {
          case Food(VEGETABLE) => state = SAD
          case Food(CHOCOLATE) => state = HAPPY
          case Ask(_) =>
            if (state == HAPPY) sender() ! KidAccept
            else sender() ! KidReject
        }
    
        // state == HAPPY 인 상태에서
        def happyReceive: Receive = {
          case Food(VEGETABLE) => context.become(sadReceive)
          case Food(CHOCOLATE) => // 현재 상태 그대로 유지
          case Ask(_)          => sender() ! KidAccept
        }
    
        // state == SAD 상태에서
        def sadReceive: Receive = {
          case Food(VEGETABLE) => // 현재 상태 그대로 유지
          case Food(CHOCOLATE) => context.become(happyReceive)
          case Ask(_)          => sender() ! KidReject
        }
      }
    
      class Mom extends Actor {
        import Kid._
    
        override def receive: Receive = {
          case KidAccept => println("My kid is happy")
          case KidReject => println("My kid is sad")
        }
      }
    
      def main(args: Array[String]): Unit = {
        val actorSystem: ActorSystem = ActorSystem(name = "actorCapabilitiesDemo")
    
        val kidActor = actorSystem.actorOf(Kid.props(), "kidActor")
        val momActor = actorSystem.actorOf(Mom.props(), "momActor")
    
        import Mom._
        kidActor.tell(Ask("Do you want to play?"), momActor)
        kidActor.tell(Food(VEGETABLE), momActor)
        kidActor.tell(Ask("Do you want to play?"), momActor)
      }
    }

     

    참고

    context.become() 의 두번째 파라미터 discardOld 값이 False 로 지정되면 (default: True) behavior(Receive) 가 stack 된다. 이상태에서 가장 상위의 behavior 하나가 선택되어 동작한다. context.become() 이 호출되면 가장 상위의 behavior 가 제거되고, 바로 아래 있던 behavior 로 동작한다. unbecome() 을 남용하면 코드가 매우 복잡해 질 수 있을 것 같다. become() 은 https://wefree.tistory.com/289 상황 처럼 사용하면 유용할 것 같다.

    'akka & pekko > actors' 카테고리의 다른 글

    Akka Logging  (0) 2023.07.17
    Child Actor  (0) 2023.07.17
    Messages and Behavior  (0) 2023.07.17
    Actor 생성  (0) 2023.07.17
    akka actors 소개  (0) 2023.07.17

    댓글

Designed by Tistory.