2016-07-25 13 views
1

ich so etwas wie dies tun will -Rückkehr zum „Sender“ von einer Zukunft innerhalb Schauspieler

class MyActor extends Actor { 
.... 
override def receive = { 
    case msg => 
    .... // do something 
    Future { 
     ... // calculate response 
     sender ! response 
    } 
} 
} 

// in some other code - 
val future = myActorRef ? msg 
future.onSuccess { 
    .... 
} 

würde diese Arbeit? Mit anderen Worten, kümmert sich die "ask" Implementierung von Akka darum, ob die Antwort zurückgeschickt wurde, bevor die "receive" Methode beendet wurde oder nicht?

Antwort

5

Ja, es würde funktionieren, und es gibt sogar ein Akka dafür Muster eingebaut - pipe:

import akka.pattern.pipe 

override def receive = { 
    case msg => 
    .... // do something 
    Future { 
     ... // calculate response 
     response 
    } pipeTo sender() 
} 

Es gibt jedoch einige Einschränkungen in Ihrem Code sollten Sie Folgendes beachten:

sender ist Wenn der Code in Ihrem Future{...}-Block ausgeführt wird, verarbeitet der Akteur daher möglicherweise eine Nachricht von einem anderen Absender, sodass Sie dem falschen Absender antworten können. Um dies zu vermeiden, bewerten Sie Ihren Absender außerhalb der Schließung:

val mySender = sender() 
Future { 
    ... // calculate response 
    mySender ! response 
} 

Sie jedoch nicht kümmern müssen, wenn Sie pipe verwenden.


Du eine Zukunft in einen Schauspieler Einwickeln und ruft, dass Schauspieler mit ask, was wiederum gibt Ihnen eine Zukunft. Sie sollten wirklich in Betracht ziehen, die Zukunft direkt und ohne Schauspieler zu nennen. Wenn Sie den Schauspieler wirklich brauchen, z.B. Da Sie einen veränderlichen Zustand oder die Reihenfolge der Nachrichten sind wichtig, sollten Sie sich bewusst sein, dass die Future nicht auf den Thread des Schauspielers passieren, so dass Sie verlieren Ihre Konsistenz Zustand und die Reihenfolge der Nachrichten - ein weiterer Grund, den Schauspieler zu verlieren, und die Zukunft direkt anrufen.

+0

Normalerweise werde ich nicht für eine Zukunft in einem Schauspieler gehen (wo Schauspieler fast nichts). Aber in meinem Fall bin ich auf eine andere Bibliothek angewiesen, die Nachrichten nur an einen Schauspieler senden kann (und das auch als Frage). Daher die Frage :-) – anindyaju99

1

Das Problem ist, dass sender möglicherweise nicht mehr gültig ist, wenn die Zukunft durchgeführt wird. Sie haben ein paar Optionen, hier sind zwei von der Spitze von meinem Kopf:

Sie können Capture die sender vor der Zukunft:

override def receive = { 
    case msg => 
    .... // do something 
    val replyTo = sender 

    Future { 
     ... // calculate response 
     replyTo ! response 
    } 
} 

Oder Sie pipeTo Muster verwenden:

override def receive = { 
    case msg => 
    .... // do something 
    import akka.pattern.pipe 

    Future { 
     ... // calculate response 
    }.pipeTo(sender()) 
}