backend/Scala_Play_Akka

[Akka] Akka Document - Actor Architecture (2) - actor lifecycle

버리야 2018. 4. 22. 17:58
반응형

이 글은 원문 : https://doc.akka.io/docs/akka/current/guide/tutorial_1.html 글을 읽고 간략하게 정리한 내용입니다. (생략된 내용도 있습니다.)



Akka Version 2.5.12


The actor lifecycle


actor가 만들어지면 존재하게되고 나중에 사용자 요청에 따라 멈추게 된다. actor가 멈추면 모든 자식도 재귀적으로 멈춘다. 

이 동작은 리소스 정리를 크게 단순화하고 열린 소켓 및 파일로 인해 발생하는 리소스 유출을 방지하는 데 도움이 된다. 

사실 저수준 멀티 스레드 코드를 처리 할 때 일반적으로 간과되는 어려움은 다양한 동시 자원의 라이프 사이클 관리하는 것이다.



actor를 정지 시키려면, actor 내에서 getContext().stop(getSelf())를 호출하는걸 추천한다. 
기술적으로 다른 actor를 정지시키는 것은 getContext().stop(actorRef)를 호출하는 것으로 가능 하지만, 
이 방법으로 임의의 actor를 정지시키는 것은 나쁜 습관이다 : PoisonPill이나 custom stop 메시지를 보내는 방법을..

Akka actor API는 actor 구현에서 재정의 할 수있는 많은 라이프 사이클 hook를 제공한다. 
가장 일반적으로 사용되는 것은 preStart () 및 postStop () 이다.

preStart ()는 actor가 시작된 후 첫 번째 메시지를 처리하기 전에 호출된다.
postStop ()은 actor가 정지하기 직전에 호출된다. 이 시점 이후에는 메시지가 처리되지 않는다.

preStart() and postStop() lifecycle hook를 이용한 예제를 보자.
class StartStopActor1 extends Actor {
  override def preStart(): Unit = {
    println("first started")
    context.actorOf(Props[StartStopActor2], "second")
  }
  override def postStop(): Unit = println("first stopped")

  override def receive: Receive = {
    case "stop" ⇒ context.stop(self)
  }
}

class StartStopActor2 extends Actor {
  override def preStart(): Unit = println("second started")
  override def postStop(): Unit = println("second stopped")

  // Actor.emptyBehavior is a useful placeholder when we don't
  // want to handle any messages in the actor.
  override def receive: Receive = Actor.emptyBehavior
}

위와 같이 'main' 클래스를 만들어 actor를 시작한 다음 'stop' 메시지를 보낸다.

val first = system.actorOf(Props[StartStopActor1], "first")
first ! "stop"


출력은 다음과 같다.

first started
second started
second stopped
first stopped

우리가 actor를 먼저 멈추었을 때, 멈추기 전에 자식 actor를 멈추게 했다. 이 순서는 엄격하다. 
부모의 postStop () hook이 호출되기 전에 자식의 모든 postStop () hook이 호출된다.



반응형