Returning a future message from the actor

I have an existing APIone that returns Future. Now we present Actorfor one of the use cases and try to continue to use the same service with it API. Below you can see the MyService.saveValuesreturn of the future.

object MyActor {
   implicit val ec = scala.concurrent.ExecutionContext.Implicits.global
   implicit val timeout = Timeout(1 second)
   case class SampleMessage(list: List[String])
   val actorSystem =  //get actorSystem that was created at the startup


  def saveMessage(list: List[String])  ={
    val res = (actorSystem.actorOf(Props[MyActor]) ? SaveMyMessage(list) ).mapTo[Future[\/[Throwable,String]]
 //res map{ r=>

 //}

 }
}
class MyActor extends Actor {
import MyActor._

def receive = {
  case SaveMyMessage(list) =>

   val originalSender = sender

   val res : Future[\/[Throwable,String] ] = MyService.saveValues(list)


   originalSender ! res
  }
}

As you can see in def saveMessage, I use askto wait for a result from an actor. However, it askalso creates its own future, so the result ( val res) in saveMessagebecomes Future[Future[T]]that looks annoying. What is the best way to handle this scenario?

+4
source share
1 answer

pipeTo ActorRef.

import akka.pattern.pipe


val originalSender = sender
val res : Future[\/[Throwable,String] ] = MyService.saveValues(list)
res pipeTo originalSender

saveValues , -, .

- Future[Future[A]], Future[A] sequencing/traversing - , "flatMap ".

import ExecutionContext.Implicits.global
val foo: Future[Future[Int]] = ???
val bar: Future[Int] = foo.flatMap(identity)

scalaz ( scalaz.contrib if on scalaz 7.0.x), join, .

import scalaz.syntax.monad._
import scalaz.contrib.std.scalaFuture._
val bar2: Future[Int] = foo.join
+7

Source: https://habr.com/ru/post/1547481/


All Articles