일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 스칼라
- 안드로이드 웹뷰
- Adapter 패턴
- 하이퍼레저 패브릭
- hyperledger fabric
- play2 강좌
- 스칼라 동시성
- 하이브리드앱
- 블록체인
- 스칼라 강좌
- 파이썬 데이터분석
- Play2 로 웹 개발
- Akka
- akka 강좌
- Hyperledger fabric gossip protocol
- Golang
- Actor
- 파이썬 강좌
- play 강좌
- 파이썬
- 엔터프라이즈 블록체인
- 그라파나
- 파이썬 머신러닝
- 스위프트
- 이더리움
- 플레이프레임워크
- 주키퍼
- 파이썬 동시성
- CORDA
- Play2
- Today
- Total
HAMA 블로그
예제로 보는 아카(akka) - 12. 액터 찾기 & 참조하기 & 액터 패스 본문
- Scala 2.11.8 기반
- Akka 2.4.11 기반
- Java 8 (akka 2.4 부터는 java 8 요구함. scala 2.11 은 java 7도 괜찮지만~)
- Akka 공식 문서 : http://doc.akka.io/docs/akka/snapshot/general/addressing.html
액터 찾기 & 참조하기
액터시스템에 여러개의 액터가 활동 할 때 , A 액터는 메세지에 따라서 B,C,D 액터에게 메세지를 따로 보내야 할때가 있다. 이때 A 액터는 B,C,D 액터에 대한 참조를 어떻게 알 수 있을까? 일단 보통 객체 코딩 했었을 때 를 생각하면서 A 액터에 setActor 같은 메소드를 만들어서 B,C,D 액터의 참조를 주입시키는 방법으로 손가락이 먼저 반응 했는데 다른 방법이 있다.
val ruleEngine = context.actorSelection("/user/RuleEngine")
이렇게 actorSelection 을 통해서 멤버로 가지고 있으면 된다. 이때 주의 할점은 /user 앞에 슬래쉬(/) 잊지말길.. 저거 때문에 한참 해맸다 ㅜㅜ
그리고 액터의 라이프 사이클을 관리하는 차원에서 actor path 보다는 actor ref 를 이용하자.
아래 내용에 나오겠지만 Identify() 를 이용하여 획득 할 수 있다.
액터 식별 정리
@ 최상위의 사용자 액터들은 /user/ 아래에 위치한다.
@ /user/* 하면 최상위의 모든 액터로 가는 패스를 리턴 한다.
@ ../* 는 현재 액터와 모든 형제들을 의미한다.
@ actorSelection 은 ActorRef 대신 ActorSelection 객체를 반환한다. 0~여러개의 개수일 수 있으니..
@ 역터 시스템에 있는 임의의 액터들과 통신하기 위해서는 actorSelection 을 이용한다.
@ actorSelection 은 실제 액터 참조를 알려 주진 않는다. 실제 액터 참조를 얻기 위해서는 Identify 메세지를 이용한다.
액터 식별 예제
import akka.actor.{Actor, ActorSystem, Props}
import akka.event.Logging
class CheckActor extends Actor {
import akka.actor.{Identify, ActorIdentity}
val log = Logging(context.system, this)
def receive = {
case path: String =>
log.info(s"checking path => $path")
context.actorSelection(path) ! Identify(path)
case ActorIdentity(path, Some(ref)) =>
log.info(s"found actor $ref on $path")
case ActorIdentity(path, None) =>
log.info(s"could not find an actor on $path")
}
}
object ActorsIdentify extends App {
val ourSystem = ActorSystem("mysystem")
val checker = ourSystem.actorOf(Props[CheckActor], "checker")
checker ! "../*"
Thread.sleep(1000)
checker ! "../../*"
Thread.sleep(1000)
checker ! "/system/*"
Thread.sleep(1000)
checker ! "/user/checker2"
Thread.sleep(1000)
checker ! "akka://OurExampleSystem/system"
Thread.sleep(1000)
ourSystem.stop(checker)
Thread.sleep(1000)
ourSystem.terminate()
}
- 파일 시스템의 파일 경로와 매우 비슷하다.
- ../* 현재 액터와 모든 형제들을 의미한다.
- 액터 경로만을 사용해 특정 액터에 메세지를 보낼 수 없다.(액터 참조와 다름)
- 액터 경로에 있는 액터 참조를 얻으려면 context 객체에 대해 actorSelection 메소드를 호출.
- 어떤 아카 액터가 Identify 메세지를 받으면, 자동으로 자신의 ActorRef가 들어 있는 ActorIdentify 메세지로응답한다.
- 액터 선택이 가르키는 액터가 없다면, 아무 ActorRef 객체가 없는 ActorIdentify 메세지를 송신한 액터에 돌려준다. 송신한 액터는 case ActorIdentify(path,None) 으로 받게된다.
Actor Path 형식
- "akka://my-sys/user/service-a/worker1" // 지역 액터 패스
- "akka.tcp://my-sys@host.example.com:5678/user/service-b" // 원격 액터 패스
Actor Path 와 Actor Ref 와 차이점
- 액터 참조는 액터가 실제 있어야 만들어진다. 반면 패스는 실제 액터가 없어도 만들 수 있다.
- A 액터를 만들고 종료시키고 B 액터를 만들었을때 , 동일한 액터패스를 가질 수 있다. 그냥 이름이니깐
하지만 액터 참조는 그대로 사용 할 수 없다. 액터 참조는 대응되는 액터의 라이프 사이클과 함께 한다.
원격 Actor 의 Path
- 로컬의 액터의 자식 액터를 만드는데 위치를 원격에 둘 수 있다.
- 이때 로컬에서 보기에 자식패스로 볼 수 있지만 실제는 원격에 위치해있다. 바인딩된다.
언제 ActorSelection 를 써야 하나요?
참고:https://petabridge.com/blog/when-should-I-use-actor-selection/
1. 액터의 위치를 와일드 카드를 이용 하여 처리하는 방법이 필요 할때
2. 원격액터시스템의 액터와 커뮤니케이션 하고 싶을때, 그 액터에 대한 참조를 아직 가지고 있지 않았고
유의 사항
* 가능하면 항상 ActorRef 를 사용하라. (액터가 죽었더라도 액터 패스는 메세지를 보낸다)
또한 ActorRef 를 사용하면 참조하는 액터들의 라이프 사이클을 알 수 있으니..
* 개별 액터코드내에 액터패스를 하드 코딩하지 말고 한곳에 모아둬라. (읽기전용 스태틱으로~)
참고 : 아래 같은 방법으로 액터를 관리한다.
'Akka' 카테고리의 다른 글
예제로 보는 아카(akka) - 14. Slick 으로 PostgreSQL 사용하기 (0) | 2016.10.21 |
---|---|
예제로 보는 아카(akka) - 13. TCP 와 데이터의 끝? (0) | 2016.10.19 |
왜 우리는 Vert.x 보다 아카(akka) 를 우리의 클라우드 시스템을 위해 선택했나? (번역) (0) | 2016.10.13 |
예제로 보는 아카(akka) - 11. 클러스터 (분산컴퓨팅) (0) | 2016.10.11 |
예제로 보는 아카(akka) - 10. Inbox (0) | 2016.10.10 |