15
votes

I have the following code inside an Actor

def receive = {
    case All() => {
        val collection: BSONCollection = db("ping")
        val future:Future[List[Ping]] = collection.find(BSONDocument()).cursor[Ping].toList()
        val zender = sender
        future onComplete {
            case Success(list) => zender ! list
            case Failure(throwable) => zender ! List()
        }
    }
}

I don't like how I have to use the onComplete function to send the result back to the sender actor. I'd like to know if it is possible to convert it into something like this:

def receive = {
    case All() => {
        val collection: BSONCollection = db("ping")
        val future:Future[List[Ping]] = collection.find(BSONDocument()).cursor[Ping].toList()
        "sender ! future" // one option
        "future.map( list => sender ! list)" //Another option. I know it's not map, but maybe another function        
    }
}

I feel that this flows better with future chaining.

2
doesn't your first approach work?Incerteza
@Alex Yes, but the pipe is much more elegant.Luciano
Alright. But you're saying I don't like how I have to use the onComplete function to send the result back to the sender actor. and your code does exactly that - you're sending the result back to the sender actor.Incerteza

2 Answers

33
votes

You can use the pipe pattern for that. Just import akka.pattern.pipe and then you'll be able to pipe messages from futures to actors with future pipeTo actor.

11
votes

If you want to have an empty list when failure happens, you probably want to have chained calls of "recover" and "pipeTo".