[Akka] Classic supervision

smlee·2023년 8월 24일
0

Akka

목록 보기
7/50
post-thumbnail

Supervision이란

supervision이란 액터들 사이의 의존 관계를 뜻한다. supervision은 task들을 하위 액터에 위임을 한다. 그러므로 supervision은 반드시 실패에 응답을 해야한다. 만약 task를 위임 받고 실행시키다가 실패를 탐지하면(예를 들어 예외를 throw), 그는 자기 자신을 중지시키고 task들을 위임 받은 모든 하위 액터와 supervisior들(의존 관계에 있는 모든 액터들)에게 실패했다는 메시지를 보낸다.

이렇게 실패에 대한 연락을 받은 supervisior들은 다음과 같은 4가지 선택을 할 수 있다.

  1. 하위 액터들을 재개하고, 누적된 내부 상태들을 유지한다.
  2. 하위 액터들을 재시작하고, 누적된 내부 상태들을 지운다.
  3. 하위 액터들을 영원히 멈춘다.
  4. failure를 확대시켜 그 자체를 실패시킨다.

위와 같은 전략들은 supervision 계층의 일부로써 액터를 보는 것이 매우 중요하다.


각각의 supervisor들은 위쪽에 제시된 4가지 선택지 중 하나로 가능한 모든 실패를 다루는 함수로 볼 수 있다. 특히, 이러한 함수는 올바르지 않은 액터의 아이덴티티를 input으로 받지 않는다.

Akka는 parental supervision이라는 특정한 폼을 implement한다. 액터들은 다른 액터에 의해서면 생성된다. 그리고, 생성된 액터들은 부모 액터에 의해 감독된다. 이러현 제약은 액터 supervision 계층을 만들고, 무탈한 디자인 결정을 내릴 수 있게한다.

이때 주의해야 할 점은, supervision-related 커뮤니케이션은 유저 메시지와 분리되어 해당 커뮤니케이션만을 다루는 mailbox가 있는 특별한 시스템 메시지로 다룬다. 이러한 특징은 이벤트와 관련된 supervision들은 기존의 메시지와 결정적이지 않다. 보통은 사용자들은 기본 메시지들과 실패 알림의 순서에 영향을 끼치지 못한다.

Top level supervisors


액터 시스템들은 최소한 3개의 액터로 시작한다. 그 예시는 위와 같다. 즉, root guardian, system guardian, guardian actor 3개가 있는 것이다.

(1) / : the root guardian

루트 가디언은 가장 최상위에 있는 액터이다. 이 액터는 special actor들을 SupervisorStrategy.stoppingStrategy를 사용하여 모두 감독할 수 있다. 이 액터의 목적은 어떠한 타입의 예외가 발생하더라도 자손 액터들을 종료시킬 수 있다는 것이다. 모든 throwable 예외들은 확대시킬 수 있는다. 이때, root guardian은 real actor가 아니다. 그 이유는 모든 Real actor는 supervisor가 존재하는데, 루트 가디언은 최상위 액터이므로 supervisor가 존재하지 않는다. 따라서 supervisor는 real actor가 아니다.

(2) /user : the guardian actor

모든 유저가 생성한 액터의 부모 액터이자 가장 많이 소통하는 액터 중 하나이다. 이 가디언의 이름은 "/user"이다. system.actorOf()를 통해 생성된 액터들은 이 가디언 액터의 자손이다. 이 뜻은 가디언 액터가 종료되면 시스템에 존재하는 모든 일반 액터들이 종료된다는 뜻이다. 또한 이것은 가디언의 supervisor 정책이 어떻게 일반 액터들이 감독되는지를 결정한다는 뜻이다.

(3) /system : the system guardian

이 스페셜 가디언은 로깅이 활성화 되어있는 상태에서 모든 일반 액터가 종료될 때 순서대로 종료하는 것을 이루기 위해 도입된 가디언이다.

one-for-one strategy vs all-for-one strategy

두 정책은 모두 supervision 정책이다. 두 정책의 차이는 one-for-one은 실패한 자손 액터에게 직접적으로 적용되는 것이며, 후자는 모든 자손에 적용되는 것이다. 보통은 OneForOneStrategy을 사용하는 것이 일반적이다. 그리고, OneForOneStrategy가 기본 정책이다.

AllForOneStrategy를 사용하는 경우도 존재하는데, 자손들의 어셈블들이 그들 사이에 단단한 의존이 존재한다면, 한 자손의 실패는 다른 자손들에게까지 영향을 미친다. restart가 메일박스를 비워내지 않으므로 자손들을 모두 종료시키고 재생성하는 것이 유용하다. 따라서 이런 경우 AllForOneStrategy가 유용하게 사용된다.

📚 Reference

0개의 댓글