Scala - повторить HTTP-запрос с тайм-аутом

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

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

Я просматриваю документацию по Akka HTTP и WSClient от Play, но не могу найти нигде упоминания.

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

2 ответа

Вы также можете использовать повтор из паттернов 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"

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

меры

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

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

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

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

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

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

Другие вопросы по тегам