Как решить Future [Any] в akka-http - PullRequest
0 голосов
/ 29 декабря 2018

Я создал маршрут:

post {
        path("validate" / Segment / Segment / Segment) { (userId, listId, prefix) =>
            parameters('filter.?) { filter =>
                def result = (
                    phoneValidationActor ? ValidateUserList(userId.toInt, listId.toInt, prefix.toUpperCase, filter)
                )
                complete(result)
            }
        }
    }

И актер

class PhoneNumberActor extends Actor with ActorLogging {

    import PhoneNumberActor._

    def receive: Receive = {
        case ValidateUserList(userId, listId, prefix, filter) =>
            sender() ! validateUserList(userId, listId, prefix, filter)
    }
}

И функция получения для актера

def validateUserList(user_id: Int, list_id: Int, prefix: String, filter: Option[String]): Future[Seq[PhoneNumber]] = {
    val prefixTrim = prefix.trim
    val listContact = new ListContactRepository
    listContact.getAllContacts(user_id, list_id).map { lines =>
        lines.map { line =>
            validateNumber(line.phone, prefixTrim)
        }
    }
}

В маршруте результатанализируется как Future[Any] вместо Future[Seq[PhoneNumber]] Нужна помощь для решения этой проблемы

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

Точно так же, как сказал @Ivan Stanislavciuc, вам нужно добавить метод mapTo для безопасного приведения Future к ожидаемому типу, который в данном случае равен [Seq[PhoneNumber]].для вашего маршрута я бы обновил его примерно так:

post {
    path("validate" / Segment / Segment / Segment) { (userId, listId, prefix) =>
        parameters('filter.?) { filter =>
            val result = 
                (phoneValidationActor ? ValidateUserList(userId.toInt, listId.toInt, prefix.toUpperCase, filter)).mapTo[Seq[PhoneNumber]]
            onSuccess(result) { maybeResult =>
              complete(maybeResult)
           }
        }
    }
}

И если вы хотите обработать успех и неудачу, вы можете использовать onComplete вместо onSuccess и иметь что-то вроде:

                onComplete(result) {
                  case scala.util.Success(res) => complete(res)
                  case scala.util.Failure(ex) => complete(StatusCodes.BadRequest, ex)}
0 голосов
/ 29 декабря 2018

Вам нужно позвонить mapTo по результатам вызова Ask.

(phoneValidationActor ? ValidateUserList(userId.toInt, listId.toInt, prefix.toUpperCase, filter))).mapTo[Seq[PhoneNumber]]

и обработать будущее внутри актера, чтобы избежать ClassCastException

class PhoneNumberActor extends Actor with ActorLogging {

    import PhoneNumberActor._

    def receive: Receive = {
        case ValidateUserList(userId, listId, prefix, filter) =>
          val theSender = sender() //do not call this method in callback function onSuccess as it breaks actor principles and can send message to a wrong sender 
          validateUserList(userId, listId, prefix, filter).onSuccess { phoneNumbers => 
            theSender ! phoneNumbers
          }
    }
}
...