-
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