io.vertx.circuitbreaker.CircuitBreakerState Java Examples

The following examples show how to use io.vertx.circuitbreaker.CircuitBreakerState. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CircuitBreakerImpl.java    From vertx-circuit-breaker with Apache License 2.0 6 votes vote down vote up
/**
 * A version of reset that can force the the state to `close` even if the circuit breaker is open. This is an
 * internal API.
 *
 * @param force whether or not we force the state and allow an illegal transition
 * @return the current circuit breaker.
 */
public synchronized CircuitBreaker reset(boolean force) {
  rollingFailures.reset();

  if (state == CircuitBreakerState.CLOSED) {
    // Do nothing else.
    return this;
  }

  if (!force && state == CircuitBreakerState.OPEN) {
    // Resetting the circuit breaker while we are in the open state is an illegal transition
    return this;
  }

  state = CircuitBreakerState.CLOSED;
  closeHandler.handle(null);
  sendUpdateOnEventBus();
  return this;
}
 
Example #2
Source File: CircuitBreakerWithHTTPTest.java    From vertx-circuit-breaker with Apache License 2.0 6 votes vote down vote up
@Test
public void testOk() {
  breaker = CircuitBreaker.create("test", vertx, new CircuitBreakerOptions());
  assertThat(breaker.state()).isEqualTo(CircuitBreakerState.CLOSED);

  Promise<String> result = Promise.promise();
  breaker.executeAndReport(result, v -> client.get(8080, "localhost", "/",
    ar -> {
      if (ar.succeeded()) {
        HttpClientResponse response = ar.result();
        response.bodyHandler(buffer -> v.complete(buffer.toString()));
      }
    }));

  await().until(() -> result.future().result() != null);
  assertThat(breaker.state()).isEqualTo(CircuitBreakerState.CLOSED);
}
 
Example #3
Source File: PokemonHandler.java    From vertx-in-production with MIT License 6 votes vote down vote up
public PokemonHandler(Vertx vertx) {
    WebClientOptions options = new WebClientOptions().setKeepAlive(true).setSsl(true);
    this.webClient = WebClient.create(vertx, options);

    CircuitBreakerOptions circuitBreakerOptions = new CircuitBreakerOptions()
            .setMaxFailures(3)
            .setTimeout(1000)
            .setFallbackOnFailure(true)
            .setResetTimeout(60000);

    this.circuitBreaker = CircuitBreaker.create("pokeapi", vertx, circuitBreakerOptions);
    this.circuitBreaker.openHandler(v -> logger.info("{} circuit breaker is open", "pokeapi"));
    this.circuitBreaker.closeHandler(v -> logger.info("{} circuit breaker is closed", "pokeapi"));
    this.circuitBreaker.halfOpenHandler(v -> logger.info("{} circuit breaker is half open", "pokeapi"));

    this.healthChecks = HealthChecks.create(vertx);
    healthChecks.register("pokeApiHealthcheck", 1000, future -> {
        if (circuitBreaker.state().equals(CircuitBreakerState.CLOSED)) {
            future.complete(Status.OK());
        } else {
            future.complete(Status.KO());
        }
    });
}
 
Example #4
Source File: CircuitBreakerImpl.java    From vertx-circuit-breaker with Apache License 2.0 5 votes vote down vote up
private synchronized void incrementFailures() {
  rollingFailures.increment();
  if (rollingFailures.count() >= options.getMaxFailures()) {
    if (state != CircuitBreakerState.OPEN) {
      open();
    } else {
      // No need to do it in the previous case, open() do it.
      // If open has been called, no need to send update, it will be done by the `open` method.
      sendUpdateOnEventBus();
    }
  } else {
    // Number of failure has changed, send update.
    sendUpdateOnEventBus();
  }
}
 
Example #5
Source File: APITest.java    From vertx-circuit-breaker with Apache License 2.0 5 votes vote down vote up
/**
 * Reproducer of https://github.com/vert-x3/vertx-circuit-breaker/issues/9
 */
@Test
public void testWhenOptionsAreNull() {
  CircuitBreaker cb = CircuitBreaker.create("name", vertx, null);
  assertThat(cb).isNotNull();
  assertThat(cb.name()).isEqualTo("name");
  assertThat(cb.state()).isEqualTo(CircuitBreakerState.CLOSED);
}
 
Example #6
Source File: CircuitBreakerWithHTTPTest.java    From vertx-circuit-breaker with Apache License 2.0 5 votes vote down vote up
@Test
public void testTimeout() {
  CircuitBreakerOptions options = new CircuitBreakerOptions().setTimeout(100).setMaxFailures(2);
  breaker = CircuitBreaker.create("test", vertx, options);
  assertThat(breaker.state()).isEqualTo(CircuitBreakerState.CLOSED);

  AtomicInteger count = new AtomicInteger();

  for (int i = 0; i < options.getMaxFailures(); i++) {
    breaker.execute(future ->
        client.get(8080, "localhost", "/long", response -> {
          count.incrementAndGet();
          future.complete();
        }));
  }

  await().untilAtomic(count, is(options.getMaxFailures()));
  assertThat(breaker.state()).isEqualTo(CircuitBreakerState.OPEN);

  Promise<String> result = Promise.promise();
  breaker.executeAndReportWithFallback(result, future ->
    client.get(8080, "localhost", "/long", response -> {
      System.out.println("Got response");
      future.complete();
    }), v -> "fallback");

  await().until(() -> result.future().result().equals("fallback"));
  assertThat(breaker.state()).isEqualTo(CircuitBreakerState.OPEN);
}
 
Example #7
Source File: CircuitBreakerMetricsTest.java    From vertx-circuit-breaker with Apache License 2.0 5 votes vote down vote up
@Test
@Repeat(10)
public void testLatencyComputation(TestContext tc) {
  breaker = CircuitBreaker.create("some-circuit-breaker", vertx);
  Async async = tc.async();


  int count = 1000;

  // Future chain
  Future<Void> fut = breaker.execute(commandThatWorks());
  for (int i = 1; i < count; i++) {
    Future<Void> newFut = breaker.execute(commandThatWorks());
    fut = fut.compose(v -> newFut); // Chain futures
  }

  fut
    .onComplete(ar -> {
      assertThat(ar).succeeded();
      assertThat(metrics())
        .contains("name", "some-circuit-breaker")
        .contains("state", CircuitBreakerState.CLOSED.name())
        .contains("failures", 0)
        .contains("totalErrorCount", 0)
        .contains("totalSuccessCount", count)
        .contains("totalTimeoutCount", 0)
        .contains("totalExceptionCount", 0)
        .contains("totalFailureCount", 0)
        .contains("totalOperationCount", count)
        .contains("totalSuccessPercentage", 100)
        .contains("totalErrorPercentage", 0);
      assertThat(metrics().getInteger("totalLatencyMean")).isNotZero();
      async.complete();
    });
}
 
Example #8
Source File: CircuitBreakerMetricsTest.java    From vertx-circuit-breaker with Apache License 2.0 5 votes vote down vote up
@Test
@Repeat(10)
public void testWithTimeoutCommands(TestContext tc) {
  breaker = CircuitBreaker.create("some-circuit-breaker", vertx, new CircuitBreakerOptions().setTimeout(100));
  Async async = tc.async();

  Future<Void> command1 = breaker.execute(commandThatFails());
  Future<Void> command2 = breaker.execute(commandThatWorks());
  Future<Void> command3 = breaker.execute(commandThatWorks());
  Future<Void> command4 = breaker.execute(commandThatFails());
  Future<Void> command5 = breaker.execute(commandThatTimeout(100));

  CompositeFuture.join(command1, command2, command3, command4, command5)
    .onComplete(ar -> {
      assertThat(metrics())
        .contains("name", "some-circuit-breaker")
        .contains("state", CircuitBreakerState.CLOSED.name())
        .contains("totalErrorCount", 3) // Failure + Timeout + Exception
        .contains("totalSuccessCount", 2)
        .contains("totalTimeoutCount", 1)
        .contains("totalExceptionCount", 0)
        .contains("totalFailureCount", 2)
        .contains("totalOperationCount", 5)
        .contains("totalSuccessPercentage", (2.0 / 5 * 100))
        .contains("totalErrorPercentage", (3.0 / 5 * 100));
      async.complete();
    });
}
 
Example #9
Source File: CircuitBreakerMetricsTest.java    From vertx-circuit-breaker with Apache License 2.0 5 votes vote down vote up
@Test
@Repeat(10)
public void testWithCrashingCommands(TestContext tc) {
  breaker = CircuitBreaker.create("some-circuit-breaker", vertx);
  Async async = tc.async();

  Future<Void> command1 = breaker.execute(commandThatFails());
  Future<Void> command2 = breaker.execute(commandThatWorks());
  Future<Void> command3 = breaker.execute(commandThatWorks());
  Future<Void> command4 = breaker.execute(commandThatFails());
  Future<Void> command5 = breaker.execute(commandThatCrashes());

  CompositeFuture.join(command1, command2, command3, command4, command5)
    .onComplete(ar -> {
      assertThat(metrics())
        .contains("name", "some-circuit-breaker")
        .contains("state", CircuitBreakerState.CLOSED.name())
        .contains("totalErrorCount", 3) // Failure + Timeout + Exception
        .contains("totalSuccessCount", 2)
        .contains("totalTimeoutCount", 0)
        .contains("totalExceptionCount", 1)
        .contains("totalFailureCount", 2)
        .contains("totalOperationCount", 5)
        .contains("totalSuccessPercentage", (2.0 / 5 * 100))
        .contains("totalErrorPercentage", (3.0 / 5 * 100));
      async.complete();
    });
}
 
Example #10
Source File: CircuitBreakerMetricsTest.java    From vertx-circuit-breaker with Apache License 2.0 5 votes vote down vote up
@Test
@Repeat(10)
public void testWithFailedCommands(TestContext tc) {
  breaker = CircuitBreaker.create("some-circuit-breaker", vertx);
  Async async = tc.async();

  Future<Void> command1 = breaker.execute(commandThatFails());
  Future<Void> command2 = breaker.execute(commandThatWorks());
  Future<Void> command3 = breaker.execute(commandThatWorks());
  Future<Void> command4 = breaker.execute(commandThatFails());

  CompositeFuture.join(command1, command2, command3, command4)
    .onComplete(ar -> {
      assertThat(metrics())
        .contains("name", "some-circuit-breaker")
        .contains("state", CircuitBreakerState.CLOSED.name())
        .contains("totalErrorCount", 2) // Failure + Timeout + Exception
        .contains("totalSuccessCount", 2)
        .contains("totalTimeoutCount", 0)
        .contains("totalExceptionCount", 0)
        .contains("totalFailureCount", 2)
        .contains("totalOperationCount", 4)
        .contains("totalSuccessPercentage", 50)
        .contains("totalErrorPercentage", 50);
      async.complete();
    });
}
 
Example #11
Source File: CircuitBreakerMetricsTest.java    From vertx-circuit-breaker with Apache License 2.0 5 votes vote down vote up
@Test
@Repeat(10)
public void testWithSuccessfulCommands(TestContext tc) {
  breaker = CircuitBreaker.create("some-circuit-breaker", vertx);
  Async async = tc.async();


  Future<Void> command1 = breaker.execute(commandThatWorks());
  Future<Void> command2 = breaker.execute(commandThatWorks());
  Future<Void> command3 = breaker.execute(commandThatWorks());

  CompositeFuture.all(command1, command2, command3)
    .onComplete(ar -> {
      assertThat(ar).succeeded();
      assertThat(metrics())
        .contains("name", "some-circuit-breaker")
        .contains("state", CircuitBreakerState.CLOSED.name())
        .contains("failures", 0)
        .contains("totalErrorCount", 0)
        .contains("totalSuccessCount", 3)
        .contains("totalTimeoutCount", 0)
        .contains("totalExceptionCount", 0)
        .contains("totalFailureCount", 0)
        .contains("totalOperationCount", 3)
        .contains("totalSuccessPercentage", 100)
        .contains("totalErrorPercentage", 0);

      async.complete();
    });
}
 
Example #12
Source File: CircuitBreakerImpl.java    From vertx-circuit-breaker with Apache License 2.0 5 votes vote down vote up
private <T> Promise<T> retryFuture(Context context, int retryCount, Handler<Promise<T>> command, Promise<T>
  operationResult, CircuitBreakerMetrics.Operation call) {
  Promise<T> retry = Promise.promise();

  retry.future().onComplete(event -> {
    if (event.succeeded()) {
      reset();
      context.runOnContext(v -> {
        operationResult.complete(event.result());
      });
      return;
    }

    CircuitBreakerState currentState;
    synchronized (this) {
      currentState = state;
    }

    if (currentState == CircuitBreakerState.CLOSED) {
      if (retryCount < options.getMaxRetries() - 1) {
        executeRetryWithTimeout(retryCount, l -> {
          context.runOnContext(v -> {
            // Don't report timeout or error in the retry attempt, only the last one.
            executeOperation(context, command, retryFuture(context, retryCount + 1, command, operationResult, null),
              call);
          });
        });
      } else {
        executeRetryWithTimeout(retryCount, (l) -> {
          context.runOnContext(v -> {
            executeOperation(context, command, operationResult, call);
          });
        });
      }
    } else {
      context.runOnContext(v -> operationResult.fail(OpenCircuitException.INSTANCE));
    }
  });
  return retry;
}
 
Example #13
Source File: CircuitBreakerImpl.java    From vertx-circuit-breaker with Apache License 2.0 5 votes vote down vote up
private synchronized CircuitBreaker attemptReset() {
  if (state == CircuitBreakerState.OPEN) {
    passed.set(0);
    state = CircuitBreakerState.HALF_OPEN;
    halfOpenHandler.handle(null);
    sendUpdateOnEventBus();
  }
  return this;
}
 
Example #14
Source File: CircuitBreakerImpl.java    From vertx-circuit-breaker with Apache License 2.0 5 votes vote down vote up
@Override
public synchronized CircuitBreaker open() {
  state = CircuitBreakerState.OPEN;
  openHandler.handle(null);
  sendUpdateOnEventBus();

  // Set up the attempt reset timer
  long period = options.getResetTimeout();
  if (period != -1) {
    vertx.setTimer(period, l -> attemptReset());
  }

  return this;
}
 
Example #15
Source File: CircuitBreaker.java    From prebid-server-java with Apache License 2.0 5 votes vote down vote up
/**
 * Resets failure counter to adjust open-circuit time frame.
 * <p>
 * Note: the operations {@link io.vertx.circuitbreaker.CircuitBreaker#state()}
 * and {@link io.vertx.circuitbreaker.CircuitBreaker#reset()} can take a while,
 * so it is better to perform them on a worker thread.
 */
private <T> void ensureState(Promise<T> executeBlockingPromise) {
    final long currentTime = clock.millis();
    if (breaker.state() == CircuitBreakerState.CLOSED && lastFailureTime > 0
            && currentTime - lastFailureTime > openingIntervalMs) {
        breaker.reset();
    }

    lastFailureTime = currentTime;
    executeBlockingPromise.complete();
}
 
Example #16
Source File: CircuitBreakerImpl.java    From vertx-circuit-breaker with Apache License 2.0 4 votes vote down vote up
@Override
public <T> CircuitBreaker executeAndReportWithFallback(
  Promise<T> userFuture,
  Handler<Promise<T>> command,
  Function<Throwable, T> fallback) {

  Context context = vertx.getOrCreateContext();

  CircuitBreakerState currentState;
  synchronized (this) {
    currentState = state;
  }

  CircuitBreakerMetrics.Operation call = metrics.enqueue();

  // this future object tracks the completion of the operation
  // This future is marked as failed on operation failures and timeout.
  Promise<T> operationResult = Promise.promise();

  if (currentState == CircuitBreakerState.CLOSED) {
    operationResult.future().onComplete(event -> {
      context.runOnContext(v -> {
        if (event.failed()) {
          incrementFailures();
          call.failed();
          if (options.isFallbackOnFailure()) {
            invokeFallback(event.cause(), userFuture, fallback, call);
          } else {
            userFuture.fail(event.cause());
          }
        } else {
          call.complete();
          reset();
          userFuture.complete(event.result());
        }
        // Else the operation has been canceled because of a time out.
      });
    });

    if (options.getMaxRetries() > 0) {
      executeOperation(context, command, retryFuture(context, 0, command, operationResult, call), call);
    } else {
      executeOperation(context, command, operationResult, call);
    }
  } else if (currentState == CircuitBreakerState.OPEN) {
    // Fallback immediately
    call.shortCircuited();
    invokeFallback(OpenCircuitException.INSTANCE, userFuture, fallback, call);
  } else if (currentState == CircuitBreakerState.HALF_OPEN) {
    if (passed.incrementAndGet() == 1) {
      operationResult.future().onComplete(event -> {
        context.runOnContext(v -> {
          if (event.failed()) {
            open();
            call.failed();
            if (options.isFallbackOnFailure()) {
              invokeFallback(event.cause(), userFuture, fallback, call);
            } else {
              userFuture.fail(event.cause());
            }
          } else {
            call.complete();
            reset();
            userFuture.complete(event.result());
          }
        });
      });
      // Execute the operation
      executeOperation(context, command, operationResult, call);
    } else {
      // Not selected, fallback.
      call.shortCircuited();
      invokeFallback(OpenCircuitException.INSTANCE, userFuture, fallback, call);
    }
  }
  return this;
}
 
Example #17
Source File: CircuitBreakerImpl.java    From vertx-circuit-breaker with Apache License 2.0 4 votes vote down vote up
@Override
public synchronized CircuitBreakerState state() {
  return state;
}
 
Example #18
Source File: HystrixMetricEventStream.java    From vertx-circuit-breaker with Apache License 2.0 4 votes vote down vote up
private JsonObject build(JsonObject body) {
  String state = body.getString("state");
  JsonObject json = new JsonObject();
  json.put("type", "HystrixCommand");
  json.put("name", body.getString("name"));
  json.put("group", body.getString("node"));
  json.put("currentTime", System.currentTimeMillis());
  json.put("isCircuitBreakerOpen", state.equalsIgnoreCase(CircuitBreakerState.OPEN.toString()));
  json.put("errorPercentage", body.getInteger("rollingErrorPercentage", 0));
  json.put("errorCount", body.getInteger("rollingErrorCount", 0));
  json.put("requestCount", body.getInteger("rollingOperationCount", 0));
  json.put("rollingCountCollapsedRequests", 0);
  json.put("rollingCountExceptionsThrown", body.getInteger("rollingExceptionCount", 0));
  json.put("rollingCountFailure", body.getInteger("rollingFailureCount", 0));
  json.put("rollingCountTimeout", body.getInteger("rollingTimeoutCount", 0));
  json.put("rollingCountFallbackFailure", body.getInteger("rollingFallbackFailureCount", 0));
  json.put("rollingCountFallbackRejection", body.getInteger("fallbackRejection", 0));
  json.put("rollingCountFallbackSuccess", body.getInteger("rollingFallbackSuccessCount", 0));
  json.put("rollingCountResponsesFromCache", 0);
  json.put("rollingCountSemaphoreRejected", 0);
  json.put("rollingCountShortCircuited", body.getInteger("rollingShortCircuitedCount", 0));
  json.put("rollingCountSuccess", body.getInteger("rollingSuccessCount", 0));
  json.put("rollingCountThreadPoolRejected", 0);
  json.put("rollingCountTimeout", body.getInteger("rollingTimeoutCount", 0));
  json.put("rollingCountBadRequests", 0);
  json.put("rollingCountEmit", 0);
  json.put("rollingCountFallbackEmit", 0);
  json.put("rollingCountFallbackMissing", 0);
  json.put("rollingMaxConcurrentExecutionCount", 0);
  json.put("currentConcurrentExecutionCount", 0);
  json.put("latencyExecute_mean", body.getInteger("rollingLatencyMean", 0));
  json.put("latencyExecute", body.getJsonObject("rollingLatency", new JsonObject()));
  json.put("latencyTotal_mean", body.getInteger("totalLatencyMean", 0));
  json.put("latencyTotal", body.getJsonObject("totalLatency", new JsonObject()));

  json.put("propertyValue_circuitBreakerRequestVolumeThreshold", 0);
  json.put("propertyValue_circuitBreakerSleepWindowInMilliseconds", body.getLong("resetTimeout", 0L));
  json.put("propertyValue_circuitBreakerErrorThresholdPercentage", 0);
  json.put("propertyValue_circuitBreakerForceOpen", false);
  json.put("propertyValue_circuitBreakerForceClosed", false);
  json.put("propertyValue_circuitBreakerEnabled", true);
  json.put("propertyValue_executionIsolationStrategy", "THREAD");
  json.put("propertyValue_executionIsolationThreadTimeoutInMilliseconds", body.getLong("timeout", 0L));
  json.put("propertyValue_executionIsolationThreadInterruptOnTimeout", true);
  json.put("propertyValue_executionIsolationThreadPoolKeyOverride", "");
  json.put("propertyValue_executionIsolationSemaphoreMaxConcurrentRequests", 0);
  json.put("propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests", 0);
  json.put("propertyValue_metricsRollingStatisticalWindowInMilliseconds", body.getLong("metricRollingWindow", 0L));
  json.put("propertyValue_requestCacheEnabled", false);
  json.put("propertyValue_requestLogEnabled", false);
  json.put("reportingHosts", 1);
  return json;
}