0

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

问题是从未运行过失败订阅,而且我不知道我是否无法理解某些内容,但这似乎是根据克莱门特游乐场的有效用例:

https://gist.github.com/cescoffier/e9abce907a1c3d05d70bea3dae6dc3d5

任何人都可以对此有所了解吗?

提前非常感谢。

4

1 回答 1

0

用例完全有效,但您的测试没有正确编写。这种重试是异步的。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");
}
于 2021-11-10T07:15:25.650 回答