R
R
Roman Gafiyatullin2016-03-23 15:10:37
Scala
Roman Gafiyatullin, 2016-03-23 15:10:37

How to apply value from Future[T] to actor state?

So: Akka, the actor's receive function.
We get a request. We turn to a third-party service for some kind of result .
The next value of the actor's state depends on some result .
We do not have a result , there is only the Future of this result.
You cannot process the following requests without knowing the result value .
Googled, found only suggestions to do Await.result(…) , but you can’t block in an actor.
Toy examples on
*scala: https://gist.github.com/RGafiyatullin/26ac0fa7b9c8...
*erlang: https://gist.github.com/RGafiyatullin/95ed4830a044....
Question: is it possible to do without Await?
Thanks in advance!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
R
Roman Gafiyatullin, 2016-05-05
@RomkoGoofique

After reading the documentation more closely, I found the following: doc.akka.io/docs/akka/current/scala/actors.html#Stash
This is it :)

A
Artem, 2016-03-23
@mrRontgen

Well, something like that, I guess.

class BlockingInsideOfActor extends Actor {
  var state = State() // next time I'll use become(newState)...
  def timeout: Timeout = ...
  
  val queue = Queue[(Request, ActorRef)].empty
  
  def pending: Receive = {
     case req: Request =>
      queue.push((req, sender()))
      //log message here 
  }

  def normalContext = {
   //popping queue in order of incoming message
  }
  
  def receive = {
    case req: Request =>
      val futRespData: Future[ResponseData] = processRequest(req) // resp is under a Future.
      val sndr = sender()
      context.become(pending)// catch all messagee whil pending request 
      
      futRespData.onComplete{ tryResutl => 
        tryResutl match {
          
          case Success(...) =>  
              val nextState =if (respData.success) state.incSuccessCount 
              else state.incFailureCount
              
           // response is a function of 'resp'
          sndr ! Response(
                    data = respData, 
                    successCount = nextState.successCount
                    failureCount = failureCount.failureCount)    
                    
   //       state = nextState     
         context.become(normalContext)  
        }
      }
      
  }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question