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();
}
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());
}
Aggregations