Задать вопрос
RomkoGoofique
@RomkoGoofique

Как применить значение из Future[T] к стейту актора?

Итак: Akka, receive-функция актора.
К нам приходит запрос. Мы обращаемся к стороннему сервису за каким-то результатом.
Следующее значение состояния актора зависит от некоего результата.
Результата у нас нет, есть только Future этого результата.
Нельзя обрабатывать следующие запросы, не узнав, значения результата.

Гуглил, нашёл только предложения делать Await.result(…) , но ведь в акторе нельзя блокироваться.

Игрушечные примеры на
* scala: https://gist.github.com/RGafiyatullin/26ac0fa7b9c8...
* erlang: https://gist.github.com/RGafiyatullin/95ed4830a044... .

Вопрос: нельзя ли обойтись без Await'а?

Заранее, спасибо!
  • Вопрос задан
  • 269 просмотров
Подписаться 1 Оценить Комментировать
Решения вопроса 1
RomkoGoofique
@RomkoGoofique Автор вопроса
Почитав документацию повнимательнее обнаружил следующее: doc.akka.io/docs/akka/current/scala/actors.html#Stash

Это оно :)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
mrRontgen
@mrRontgen
Scala lover.
Ну типа того наверное,

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)  
        }
      }
      
  }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы