2017-06-22 1 views
0

Ich habe einen Akteur, der Http Anruf an einen externen Dienst macht. Manchmal reagiert dieser Dienst mit Http 404 und es gibt auch manchmal HTTP-Verbindungsfehler. Beide gehen weg, wenn sie erneut versucht werden.Was ist die korrekte Methode, HTTP-Anrufe von Akka Actors erneut zu versuchen

Was ist der beste Weg, um die Anfrage des Schauspielers erneut zu versuchen.

Was ich denken kann ist

  1. Verwenden Supervisor Strategie und Neustart Schauspieler

  2. Verwenden Sie eine rekursive Methode in dem Schauspieler, der den http Aufruf wiederholt, max-Wiederholungsanzahl mal

Welches ist der richtige Ansatz, 1 oder 2. Ich denke, Ansatz 1 wird ein Overkill für etwas so einfach wie das Wiederholen eines HTTP-Anrufs sein. Bitte teilen Sie Ihre Empfehlungen mit.

Antwort

1

Meiner Meinung nach sind beide Ihrer Ansätze gültig.

Der erste Ansatz ist in meinen Augen der reaktiveren Weg, dies zu umarmen Versagen in Bezug auf tun und zu lassen die Schauspieler nur tun, was es tun sollte (statt es Wiederholungen usw. handhaben)

Es gibt Eine nette Sache, die in Akka Supervision gebaut wurde: BackoffSupervisor

In meinen Augen ist dies eine perfekte Passform für Probleme, bei denen der Schauspieler aufgrund externer Faktoren scheitert und es Sinn machen könnte, einen längeren Zeitraum zu warten (wie in Ihrem Fall) mit http-Rufen).

Aus der Dokumentation:

val supervisor = BackoffSupervisor.props(
    Backoff.onFailure(
    childProps, 
    childName = "myEcho", 
    minBackoff = 3.seconds, 
    maxBackoff = 30.seconds, 
    randomFactor = 0.2 // adds 20% "noise" to vary the intervals slightly 
)) 

Sie können ein Minimum definieren und eine maximale Backoff und der Supervisor wird die Wartezeit verdoppeln, bevor Sie versuchen, den Schauspieler zu starten, bis er das Maximum erreicht. Nur dann wird es aufhören zu versuchen.

Wenn Sie Ihre zweite Option vorziehen, würde ich nicht mit einer rekursiven Methode gehen, aber würde schedule a message den Schauspieler selbst nach einem gewissen Zeit wieder den HTTP-Aufruf, um zu versuchen:

system.scheduler.scheduleOnce(1 seconds, self, TryAgain) 
+0

Danke für den Vorschlag –

0

Id schlagen Sie vor, das "nachher" -Muster zu verwenden. Dadurch können Sie Ihre Anfrage im Falle eines Fehlers wiederholen. Etwas wie das:

def retryRequest(ref: ActorRef, attemptsNumber: Int, step: Int)(
    implicit ac: ActorSystem): Future[HttpResponse] = { 

    implicit val timeout = Timeout(5 seconds) 
    implicit val ec = ac.dispatcher 

    val s1 = after[HttpResponse](5 seconds, ac.scheduler) { 
    Http().singleRequest(HttpRequest(uri = "http://akka.io")) 
    } 
    s1 flatMap { res => 
    res match { 
     case HttpResponse(StatusCodes.NotFound, headers, entity, _) => { 
     if(step < attemptsNumber) 
      retryRequest(ref, attemptsNumber, (step + 1)) 
     else 
      s1 
     } 
     case HttpResponse(StatusCodes.OK, headers, entity, _) => s1 
    } 
    } 
} 
+0

Dies ist auch eine gute Option –

Verwandte Themen