Scala - повторить HTTP-запрос с тайм-аутом - PullRequest
0 голосов
/ 25 января 2019

Я хочу создать сервис, в котором он отправляет HTTP-запрос на определенный URL-адрес, и если он не дает результата в течение 1 секунды, этот запрос истекает, а затем повторяется с другим запросом, максимум 3повторяет попытку.

Как реализовать это в Scala?

Я просматриваю документацию по Akka HTTP и WSClient от Play, но не могу найти, чтобы это упоминалось где-либо.

Примечание: в случае, если запрос имеет побочные эффекты на сервере, я хочу, чтобы неудачный запрос не вызывал побочных эффектов.Как можно добиться такого поведения?Это вообще возможно?

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Вы также можете использовать retry из шаблонов akka:

import akka.pattern.{ask, pipe, retry}
import akka.actor.{Actor, ActorSystem, Props, Scheduler}
import akka.util.Timeout
import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext, Future}

class ClientActor extends Actor { //actor which times out 2 times and succeeds 3rd time

    var attempts = 0

    def receive = {
      case "request" =>
        this.attempts = attempts + 1
        if (attempts < 3) {
          Thread.sleep(2000)
          Future.failed(new Exception("timed out")) pipeTo sender
        } else {
          Thread.sleep(500)
          Future.successful(s"Successful in $attempts attempt") pipeTo sender
        }
        println(s"Attempt: $attempts")
    }
}


val system = ActorSystem("system") //actor system and needed implicits
implicit val ec: ExecutionContext = system.dispatcher 
implicit val timeout: Timeout = Timeout(1 seconds)
implicit val scheduler: Scheduler = system.scheduler


val client = system.actorOf(Props[ClientActor], "client-actor")

val future = retry(() => client ? "request", 3, 1 second) //create future which would retry 3 times

println(Await.result(future, 10 seconds)) //Would write "Successful in 3 attempt"
0 голосов
/ 25 января 2019

Как я понимаю ваш вопрос, что вам нужно сделать, это:

шаги

  • Конечная точка для доступа к некоторому API через HTTP-вызов.
  • Если ответ не приходит в течение 1 секунды, вам нужно получить исключение.
  • В случае возникновения исключения вам необходимо перезапустить сервис и снова отправить запрос.

Вы можете сделать это в сотрудничестве с Akka Http и Akka Actors.

С помощью актеров Akka вы можете сообщить своему сервису, что нужно делать, когда вы получаете TimeoutException. Вы можете сделать свой вызов API через шаблон запроса Akka. Если вы увидите документацию Акки, задайте шаблон здесь . это берет тайм-аут запроса Akka, который вы можете установить на любое значение, которое вы хотите. В случае, если вы не получаете ответ обратно в тайм-аут, вы получите AkkaAskTimeOutException, который будет перехвачен вашим дочерним актором, а затем будет передан актеру супервизора , В то время как субъект-супервизор ловит исключение, мы можем использовать стратегию супервизора и указать, что нужно сделать, например (перезагрузка, завершение работы, возобновление и т. Д.).

Стратегия супервизора: Вы можете прочитать об этом здесь . Ниже приведена базовая структура приложения, основанного на актере akka.

Актер супервизора (мы пишем стратегию супервизора в супервизоре), и у него есть дочерние актеры.

child1 (бизнес-логика) child2 (бизнес-логика)

...