ちょっとハマったのでメモ…
akka.pattern.ask で待ってくれるActorは別人であった…
#askのお試し
例えで、一定時間ごとに挨拶してくれるActorを作ってみた。
import akka.actor.{ ActorRef, ActorLogging, Actor}
import akka.util.Timeout
import scala.concurrent.Await
import scala.concurrent.duration._
import akka.pattern.ask
import scala.collection.mutable.ListBuffer
class HelloActor extends Actor with ActorLogging{
val connectionList = ListBuffer[ActorRef]()
val system = context.system
implicit val executionContext = system.dispatcher
system.scheduler.schedule(1 seconds, 2 seconds, self, Update )
override def receive = {
case Connect =>{
connectionList += sender
sender ! OK
}
case Update => {
connectionList.foreach( _ ! Hello )
}
}
}
class ConnectActor extends Actor with ActorLogging{
val duration = 5 second
var server :ActorRef = _
implicit val timeout = Timeout(3 seconds)
override def receive = {
case SetRef(server) => {
this.server = server
Await.result(server ? Connect , duration) match { // ask here!
case OK => log.info("init OK!")
}
}
case Hello =>{
log.info("Hello")
}
}
}
case object Connect
case object Hello
case object OK
case object Update
case class SetRef(ref:ActorRef)
object Main {
def main(args: Array[String]): Unit = {
val system = ActorSystem.create("test-system")
val server = system.actorOf(Props[HelloActor])
val actor1 = system.actorOf(Props[ConnectActor],name = "actor1")
actor1 ! SetRef(server)
val actor2 = system.actorOf(Props[ConnectActor],name = "actor2")
actor2 ! SetRef(server)
}
}
実行結果はこちら↓
[INFO] [10/08/2015 16:24:27.805] [test-system-akka.actor.default-dispatcher-2] [akka://test-system/user/actor2] init OK!
[INFO] [10/08/2015 16:24:27.805] [test-system-akka.actor.default-dispatcher-4] [akka://test-system/user/actor1] init OK!
[INFO] [10/08/2015 16:24:28.814] [test-system-akka.actor.default-dispatcher-4] [akka://test-system/deadLetters] Message [chat2.Hello$] from Actor[akka://test-system/user/$a#1304157529] to Actor[akka://test-system/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [10/08/2015 16:24:28.814] [test-system-akka.actor.default-dispatcher-4] [akka://test-system/deadLetters] Message [chat2.Hello$] from Actor[akka://test-system/user/$a#1304157529] to Actor[akka://test-system/deadLetters] was not delivered. [2] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
違うActorに送っているみたいだ…なぜ?
実はserver ? Connect
で待ってるActorは違う人だったのだ…
#tellのお試し
試しに**!(tell)**に変えてみた
import akka.actor.{ ActorRef, ActorLogging, Actor}
import akka.util.Timeout
import scala.concurrent.duration._
import scala.collection.mutable.ListBuffer
class HelloActor extends Actor with ActorLogging{
val connectionList = ListBuffer[ActorRef]()
val system = context.system
implicit val executionContext = system.dispatcher
system.scheduler.schedule(1 seconds, 2 seconds, self, Update )
override def receive = {
case Connect =>{
connectionList += sender
sender ! OK
}
case Update => {
connectionList.foreach( _ ! Hello )
}
}
}
class ConnectActor extends Actor with ActorLogging{
val duration = 5 second
var server :ActorRef = _
implicit val timeout = Timeout(3 seconds)
override def receive = {
case SetRef(server) => {
this.server = server
server ! Connect // tell here!
}
case Hello =>{
log.info("Hello")
}
case OK =>{
log.info("init OK!")
}
}
}
case object Connect
case object Hello
case object OK
case object Update
case class SetRef(ref:ActorRef)
実行結果はこちら↓
[INFO] [10/08/2015 23:25:37.830] [test-system-akka.actor.default-dispatcher-3] [akka://test-system/user/actor2] init OK!
[INFO] [10/08/2015 23:25:37.830] [test-system-akka.actor.default-dispatcher-5] [akka://test-system/user/actor1] init OK!
[INFO] [10/08/2015 23:25:38.847] [test-system-akka.actor.default-dispatcher-5] [akka://test-system/user/actor1] Hello
[INFO] [10/08/2015 23:25:38.847] [test-system-akka.actor.default-dispatcher-6] [akka://test-system/user/actor2] Hello
[INFO] [10/08/2015 23:25:40.834] [test-system-akka.actor.default-dispatcher-3] [akka://test-system/user/actor1] Hello
[INFO] [10/08/2015 23:25:40.834] [test-system-akka.actor.default-dispatcher-5] [akka://test-system/user/actor2] Hello
どうやら挨拶されているようだ。
#まとめ
- Askを使うとsenderがakka://test-system/user/$a#1304157529に変わっていた(見た感じ適当な変数)…
- Tellではsenderは正しかった
- Askで送信元伝えたい時どうしたらいいんやろ?
以上、いつも引っかかるのでメモりました。
間違いあればご指摘お願いしますm(_ _)m