Код: Выделить всё
package org.acme;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.unchecked.Unchecked;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.jboss.logging.Logger;
import java.util.Random;
@Path("/api/bake")
@ApplicationScoped
public class CakeResource {
private static final Logger logger = Logger.getLogger(CakeResource.class);
private final Random r = new Random();
@GET
@Produces(MediaType.TEXT_PLAIN)
public Uni bakeCake() {
final double randomDouble = r.nextDouble();
logger.info("****** Backing Cake Starts with random value : ******** : " + randomDouble);
return Uni.createFrom().deferred(Unchecked.supplier(() -> {
try {
if (randomDouble < 0.5) {
logger.info(" No items left sorry .... ");
return Uni.createFrom().item(0L);
}
if (randomDouble < 0.999) {
logger.info(" oops Cake burned... ");
return Uni.createFrom().item(0L);
}
logger.info(" Cake prepared ");
return Uni.createFrom().item(1L);
} catch (Exception e) {
throw new RuntimeException("Error checking the random value");
}
}))
.onItem()
.transformToUni(count -> {
if (count < 1L) {
return Uni.createFrom().item(-1L);
}
return Uni.createFrom().item(count);
})
.onItem()
.transformToUni(count -> {
if (count == -1L) {
return Uni.createFrom().failure(new RuntimeException("Count is less than 1 sorry unable to prepare cake"));
}
return Uni.createFrom().item(count);
})
.onFailure()
.retry()
.atMost(4)
.onFailure()
.recoverWithUni(failure -> Uni.createFrom().item(0L));
}
}
Вместо использования логики повтора внутри метода я хочу использовать аннотации SmallRye Fault Tolerance, такие как @Retry, поэтому я изменил свой код и добавил @Retry вот так:
Код: Выделить всё
@GET
@Produces(MediaType.TEXT_PLAIN)
@Retry(maxRetries = 5)
public Uni bakeCake() {
final double randomDouble = r.nextDouble();
logger.info("****** Backing Cake Starts with random value : ******** : " + randomDouble);
return Uni.createFrom().deferred(Unchecked.supplier(() -> {
try {
if (randomDouble < 0.5) {
logger.info(" No items left sorry .... ");
return Uni.createFrom().item(0L);
}
if (randomDouble < 0.999) {
logger.info(" oops Cake burned... ");
return Uni.createFrom().item(0L);
}
logger.info(" Cake prepared ");
return Uni.createFrom().item(1L);
} catch (Exception e) {
throw new RuntimeException("Error checking the random value");
}
}))
.onItem()
.transformToUni(count -> {
if (count < 1L) {
return Uni.createFrom().item(-1L);
}
return Uni.createFrom().item(count);
})
.onItem()
.transformToUni(count -> {
if (count == -1L) {
throw new RuntimeException("Error checking the random value");
}
return Uni.createFrom().item(count);
})
.onFailure()
.recoverWithUni(failure -> Uni.createFrom().item(0L));
}
В первом сценарии, когда я не работал с @Retry< /code> во время отладки я мог видеть, что выполнение возвращает Uni.createFrom().item(0L); несколько раз во время сбоя.
С помощью @Retry , этого не происходит. Выполнение происходит только один раз, и во время сбоя @Retry не срабатывает, и я выхожу из метода без каких-либо повторных попыток.
На основе SmallRye Fault Tolerance документации. Я пробовал следующее:
- Класс помечен @ApplicationScoped.
- Метод public.
- Аннотированный метод с @Retry.
Какие изменения мне нужно внести, чтобы это работало и выполнялась ли повторная попытка во время провала?
Подробнее здесь: https://stackoverflow.com/questions/791 ... rye-mutiny