Answer the question
In order to leave comments, you need to log in
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
After reading the documentation more closely, I found the following: doc.akka.io/docs/akka/current/scala/actors.html#Stash
This is it :)
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 questionAsk a Question
731 491 924 answers to any question