2016-10-30 1 views
0

Ich benutze Play! 2.5 (Java) und Akka. Hier ist mein Problem: Ich versuche mit WSClient einen externen Dienst anzurufen und möchte, dass er hinter einem Akka Leistungsschalter steht. Der Code, den ich unten gezeigt habe, scheint nicht wie erwartet zu funktionieren.Wie benutze ich Akka Java Leistungsschalter mit CompletableFutures?

Ich würde erwarten, dass der Leistungsschalter öffnet, wenn der externe Dienst nicht erreichbar ist, aber es nicht tut. Ich nehme an, das Problem ist in einem Java 8 Lambda-Ausdruck umhüllt eine completableFuture innerhalb einer akaa.dispatch.Future.future.

Hat der Code ich richtig aussehen? Wenn etwas nicht stimmt, wie kann ich es reparieren?

@Inject 
    public ServiceActor(WSClient ws) { 

     this.ws = ws; 

     circuitBreaker = new CircuitBreaker(getContext().dispatcher(), 
       getContext().system().scheduler(), 
       MAX_FAILURES, 
       CALL_TIMEOUT, 
       RESET_TIMEOUT 
     ) 
.onOpen(this::onOpen) 
.onClose(this::onClose) 
.onHalfOpen(this::onHalfOpen); 

     receive(ReceiveBuilder 
       .match(String.class, x -> { 
          circuitBreaker.callWithCircuitBreaker(() -> future(() -> callService(),getContext().dispatcher())); 
       }) 
       .matchAny(o -> log.info("Unknown message")) 
       .build() 
     ); 
    } 

private CompletableFuture<JsonNode> callService() { 
     return ws.url(SOME_URL).get() 
       .thenApply(WSResponse::asJson) 
       .toCompletableFuture(); 
} 

Wenn ich einfach einen Laufzeit Ausdruck in werfen ohne callservice wie etwas zu tun:

private CompletableFuture<JsonNode> callService() { 
      throw new RuntimeException() 
    } 

Nun öffnet sich der Leistungsschalter.

Antwort

2

Ich habe herausgefunden, wie man es zur Arbeit bringt. Die Verwendung von callWithCircuitBreakerCS gibt eine Java 8-Abschlussstufe zurück, die ich verwenden möchte, wobei das behobene Problem und die Ausnahmen dazu führen, dass der Leistungsschalter in einen offenen Zustand versetzt wird.