使用重试策略时 Uni 订阅不是 运行
Uni subscription not running when using retry policy
我在 Quarkus 中使用 Mutiny 时遇到了一些奇怪的行为。
我的问题是我正在尝试将现有方法包装到 Uni 中,我希望此方法重试一定次数,如果它们都失败了,我希望调用我的失败订阅,但是没有。
为了更好的理解这一点,我为它写了一个测试:
@Test
void mutinySubscriptionNotCalledAfterRetry() {
final AtomicBoolean executed = new AtomicBoolean(false);
Uni.createFrom().item(this::error)
.onFailure()
.retry()
.withBackOff(Duration.ofSeconds(1)).withJitter(0.2)
.atMost(5)
.subscribe()
.with(success -> fail(),
failure -> executed.set(true));
assertTrue(executed.get()); // Failing statement
}
private boolean error() {
throw new RuntimeException();
}
问题是失败订阅永远不会 运行,我不知道我是否没有理解某些东西,但根据 Clement 的游乐场,这似乎是一个有效的用例:
https://gist.github.com/cescoffier/e9abce907a1c3d05d70bea3dae6dc3d5
任何人都可以阐明这一点吗?
非常感谢。
用例完全有效,但您的测试编写不正确。这种重试是异步的。因此,执行断言时尚未调用失败回调 (failure -> execute(set(true));
)。你需要等到它被调用。在您的情况下,大约需要 35 秒。
要等待,您可以使用 Awaitility 并执行如下操作:await().until(() -> executed.get());
。您也可以使用 io.smallrye.mutiny.helpers.test.UniAssertSubscriber
:
@Test
void mutinySubscriptionNotCalledAfterRetry() {
UniAssertSubscriber<Boolean> subscriber =
Uni.createFrom().item(this::error)
.onFailure().retry()
.withBackOff(Duration.ofSeconds(1)).withJitter(0.2)
.atMost(5)
.subscribe().withSubscriber(new UniAssertSubscriber<>());
subscriber.awaitFailure(Duration.ofSeconds(35));
}
private boolean error() {
throw new RuntimeException("boom");
}
我在 Quarkus 中使用 Mutiny 时遇到了一些奇怪的行为。
我的问题是我正在尝试将现有方法包装到 Uni 中,我希望此方法重试一定次数,如果它们都失败了,我希望调用我的失败订阅,但是没有。
为了更好的理解这一点,我为它写了一个测试:
@Test
void mutinySubscriptionNotCalledAfterRetry() {
final AtomicBoolean executed = new AtomicBoolean(false);
Uni.createFrom().item(this::error)
.onFailure()
.retry()
.withBackOff(Duration.ofSeconds(1)).withJitter(0.2)
.atMost(5)
.subscribe()
.with(success -> fail(),
failure -> executed.set(true));
assertTrue(executed.get()); // Failing statement
}
private boolean error() {
throw new RuntimeException();
}
问题是失败订阅永远不会 运行,我不知道我是否没有理解某些东西,但根据 Clement 的游乐场,这似乎是一个有效的用例:
https://gist.github.com/cescoffier/e9abce907a1c3d05d70bea3dae6dc3d5
任何人都可以阐明这一点吗?
非常感谢。
用例完全有效,但您的测试编写不正确。这种重试是异步的。因此,执行断言时尚未调用失败回调 (failure -> execute(set(true));
)。你需要等到它被调用。在您的情况下,大约需要 35 秒。
要等待,您可以使用 Awaitility 并执行如下操作:await().until(() -> executed.get());
。您也可以使用 io.smallrye.mutiny.helpers.test.UniAssertSubscriber
:
@Test
void mutinySubscriptionNotCalledAfterRetry() {
UniAssertSubscriber<Boolean> subscriber =
Uni.createFrom().item(this::error)
.onFailure().retry()
.withBackOff(Duration.ofSeconds(1)).withJitter(0.2)
.atMost(5)
.subscribe().withSubscriber(new UniAssertSubscriber<>());
subscriber.awaitFailure(Duration.ofSeconds(35));
}
private boolean error() {
throw new RuntimeException("boom");
}