Se avete veramente bisogno di aspettare il futuro per completare prima di elaborare il messaggio successivo, si può provare qualcosa di simile:
object SimpleMessageHandler{
case class SimpleMessage()
case class FinishSimpleMessage(i:Int)
}
class SimpleMessageHandler extends Actor with Stash{
import SimpleMessageHandler._
import context._
import akka.pattern.pipe
def receive = waitingForMessage
def waitingForMessage: Receive = {
case SimpleMessage() =>
val futData:Future[Int] = ...
futData.map(FinishSimpleMessage(_)) pipeTo self
context.become(waitingToFinish(sender))
}
def waitingToFinish(originalSender:ActorRef):Receive = {
case SimpleMessage() => stash()
case FinishSimpleMessage(i) =>
//Do whatever you need to do to finish here
...
unstashAll()
context.become(waitingForMessage)
case Status.Failure(ex) =>
//log error here
unstashAll()
context.become(waitingForMessage)
}
}
In questo approccio, elaboriamo un SimpleMessage
e quindi passare la gestione logica per riporre tutti i successivi SimpleMessage
s ricevuti fino a quando non si ottiene un risultato dal futuro. Quando otteniamo un risultato, un fallimento o meno, togliamo tutti gli altri SimpleMessage
s che abbiamo ricevuto mentre aspettiamo il futuro e andiamo sulla nostra strada allegra.
Questo attore attiva e disattiva alternativamente due stati e ciò consente di elaborare completamente uno solo SimpleMessage
alla volta senza dover bloccare il futuro.
Che cosa stai cercando di fare con i dati provenienti dal futuro? – cmbaxter
Questi sono dati dal mio db (mongo), e voglio filtrarli e solo una parte di essi può essere salvata in un'altra raccolta. Ma fondamentalmente si tratta di dati DB, non posso farlo in background, e devo aspettare per finire questa azione prima del prossimo * SimpleMessage *. –
Si sta inviando un messaggio al 'mittente' o no? –