Search in sources :

Example 11 with TimeoutException

use of io.strimzi.operator.common.operator.resource.TimeoutException in project strimzi-kafka-operator by strimzi.

the class Util method waitFor.

/**
 * Invoke the given {@code completed} supplier on a pooled thread approximately every {@code pollIntervalMs}
 * milliseconds until it returns true or {@code timeoutMs} milliseconds have elapsed.
 * @param reconciliation The reconciliation
 * @param vertx The vertx instance.
 * @param logContext A string used for context in logging.
 * @param logState The state we are waiting for use in log messages
 * @param pollIntervalMs The poll interval in milliseconds.
 * @param timeoutMs The timeout, in milliseconds.
 * @param completed Determines when the wait is complete by returning true.
 * @param failOnError Determine whether a given error thrown by {@code completed},
 *                    should result in the immediate completion of the returned Future.
 * @return A future that completes when the given {@code completed} indicates readiness.
 */
public static Future<Void> waitFor(Reconciliation reconciliation, Vertx vertx, String logContext, String logState, long pollIntervalMs, long timeoutMs, BooleanSupplier completed, Predicate<Throwable> failOnError) {
    Promise<Void> promise = Promise.promise();
    LOGGER.debugCr(reconciliation, "Waiting for {} to get {}", logContext, logState);
    long deadline = System.currentTimeMillis() + timeoutMs;
    Handler<Long> handler = new Handler<Long>() {

        @Override
        public void handle(Long timerId) {
            vertx.createSharedWorkerExecutor("kubernetes-ops-pool").executeBlocking(future -> {
                try {
                    if (completed.getAsBoolean()) {
                        future.complete();
                    } else {
                        LOGGER.traceCr(reconciliation, "{} is not {}", logContext, logState);
                        future.fail("Not " + logState + " yet");
                    }
                } catch (Throwable e) {
                    LOGGER.warnCr(reconciliation, "Caught exception while waiting for {} to get {}", logContext, logState, e);
                    future.fail(e);
                }
            }, true, res -> {
                if (res.succeeded()) {
                    LOGGER.debugCr(reconciliation, "{} is {}", logContext, logState);
                    promise.complete();
                } else {
                    if (failOnError.test(res.cause())) {
                        promise.fail(res.cause());
                    } else {
                        long timeLeft = deadline - System.currentTimeMillis();
                        if (timeLeft <= 0) {
                            String exceptionMessage = String.format("Exceeded timeout of %dms while waiting for %s to be %s", timeoutMs, logContext, logState);
                            LOGGER.errorCr(reconciliation, exceptionMessage);
                            promise.fail(new TimeoutException(exceptionMessage));
                        } else {
                            // Schedule ourselves to run again
                            vertx.setTimer(Math.min(pollIntervalMs, timeLeft), this);
                        }
                    }
                }
            });
        }
    };
    // Call the handler ourselves the first time
    handler.handle(null);
    return promise.future();
}
Also used : Handler(io.vertx.core.Handler) TimeoutException(io.strimzi.operator.common.operator.resource.TimeoutException)

Example 12 with TimeoutException

use of io.strimzi.operator.common.operator.resource.TimeoutException in project strimzi-kafka-operator by strimzi.

the class KafkaRollerTest method pod3NotReadyAfterRolling.

@Test
public void pod3NotReadyAfterRolling(VertxTestContext testContext) throws InterruptedException {
    PodOperator podOps = mockPodOps(podId -> podId == 3 ? failedFuture(new TimeoutException("Timeout")) : succeededFuture());
    StatefulSet sts = buildStatefulSet();
    TestingKafkaRoller kafkaRoller = rollerWithControllers(sts, podOps, 2);
    // On the first reconciliation we expect it to abort when it gets to pod 3 (but not 2, which is controller)
    doFailingRollingRestart(testContext, kafkaRoller, asList(0, 1, 2, 3, 4), KafkaRoller.FatalProblem.class, "Error while waiting for restarted pod c-kafka-3 to become ready", asList(3));
    // On the next reconciliation only pods 2 (controller) and 4 would need rolling, and we expect it to fail in the same way
    kafkaRoller = rollerWithControllers(sts, podOps, 2);
    clearRestarted();
    doFailingRollingRestart(testContext, kafkaRoller, asList(0, 1, 2, 4), KafkaRoller.FatalProblem.class, "Error while waiting for non-restarted pod c-kafka-3 to become ready", emptyList());
}
Also used : PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) TimeoutException(io.strimzi.operator.common.operator.resource.TimeoutException) Test(org.junit.jupiter.api.Test)

Aggregations

TimeoutException (io.strimzi.operator.common.operator.resource.TimeoutException)12 PodOperator (io.strimzi.operator.common.operator.resource.PodOperator)10 StatefulSet (io.fabric8.kubernetes.api.model.apps.StatefulSet)8 Test (org.junit.jupiter.api.Test)8 PodBuilder (io.fabric8.kubernetes.api.model.PodBuilder)2 Handler (io.vertx.core.Handler)2 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)2