Akka in Scala, Ausrufezeichen und Fragezeichen


74

Was ist der Unterschied zwischen Ausrufezeichen ( !) und Fragezeichen ( ?) beim Senden von Nachrichten an Schauspieler?

myActor ! Hello(value1)
myActor ? Hello(value1)

Antworten:


124

Schamlos kopiertes [fantastisches] offizielles Dokument (weitere Informationen finden Sie im Abschnitt Nachrichten senden ):

Nachrichten werden über eine der folgenden Methoden an einen Akteur gesendet.

!bedeutet "Feuer und Vergessen", z. B. asynchron eine Nachricht senden und sofort zurückkehren. Auch bekannt als tell.

?sendet eine Nachricht asynchron und gibt Futureeine mögliche Antwort zurück. Auch bekannt als ask.


2
Für alle, die daran interessiert sind, wie dies erreicht wurde - siehe Operator Overloading in Scala: dzone.com/articles/operator-overloading-scala
Janac Meena

! bedeutet "Feuer und Vergessen" Es könnte nicht aussagekräftiger sein!
Adelin

24

Aus Sicht des Empfängers werden die Nachrichten auf dieselbe Weise angezeigt tellund askgesendet. Allerdings , wenn ein Empfang telldes Wertes senderwird der Schauspieler sein die Referenz, die die Nachricht gesendet, während für eine ask, die senderderart eingerichtet ist, dass jede Antwort auf die geht Futurein den Schauspieler geschaffen , die den geforderten tat.

Es hat den Vorteil ask, dass leicht zu erkennen ist, dass die Antwort, die Sie erhalten, definitiv auf die von Ihnen angeforderte Nachricht zurückzuführen ist, während Sie bei Tell möglicherweise eindeutige IDs verwenden müssen, um ein ähnliches Ergebnis zu erzielen. Jedoch mit askbenötigen Sie einen einstellen , timeoutnach der das Futurefehl , wenn keine Antwort empfangen wird.

Im folgenden Code wird der gleiche Effekt mit einem tellund und erzielt 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!"
  }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.