web-dev-qa-db-ja.com

ScalaのAkka、感嘆符、疑問符

感嘆符(!)および疑問符(?)アクターにメッセージを送信するとき?

myActor ! Hello(value1)
myActor ? Hello(value1)
63
ticofab

恥知らずにコピーされた[awesome]公式ドキュメント (lookSend messagesセクションもっと):

メッセージは、次のいずれかの方法でアクターに送信されます。

!は「火と忘れ」を意味します。非同期でメッセージを送信し、すぐに戻ります。 tellとも呼ばれます。

?はメッセージを非同期的に送信し、可能な応答を表すFutureを返します。 askとも呼ばれます。

111
om-nom-nom

受信者の観点から見ると、tellaskのメッセージは同じように見えます。ただし、tellを受信すると、senderの値はメッセージを送信したアクターの参照になりますが、askの場合、senderは設定されます応答は、質問を行ったアクターで作成されたFutureに送られます。

askには利点があります。受け取った応答は間違いなくあなたが尋ねたメッセージの結果であったことを簡単に知ることができますが、Tellでは、同様のことを達成するために一意のID結果。ただし、askでは、timeoutを設定する必要があります。その後、応答が受信されない場合、Futureは失敗します。

以下のコードでは、tellおよびaskを使用しても同じ効果が得られます。

import akka.actor.{Props, Actor}
import scala.concurrent.duration._
import akka.pattern.ask

class TellActor extends Actor {

  val recipient = context.actorOf(Props[ReceiveActor])

  def receive = {
    case "Start" =>
      recipient ! "Hello" // equivalent to recipient.tell("hello", self)

    case reply => println(reply)
  }
} 

class AskActor extends Actor {

  val recipient = context.actorOf(Props[ReceiveActor])

  def receive = {
    case "Start" =>
      implicit val timeout = 3 seconds
      val replyF = recipient ? "Hello" // equivalent to recipient.ask("Hello")
      replyF.onSuccess{
        case reply => println(reply)
      }
  }
}

class ReceiveActor extends Actor {

  def receive = {
    case "Hello" => sender ! "And Hello to you!"
  }
}
20
mattinbits