如果在截止日期之前没有生成任何项目,则使用占位符项目完成 Uni,而不取消处理管道
Complete Uni with placeholder item, without cancelling the processing pipeline, if no item has been produced before deadline
我有一个异步操作管道需要很长时间才能完成,我想
如果管道在截止日期之前没有生成项目,让 Uni 继续使用占位符项目,如下所示:
Uni<Item> u = processingPipeline();
return u.ifNoItem().after(Duration.of(10, SECONDS)).recoverWith(placeholderItem);
但是当使用这种方法时,处理管道被取消并且操作链被中断。
是否可以在截止日期到期时用占位符项完成 Uni 而无需取消处理管道?即使错过最后期限,我也希望管道能够进行到最后。
Vert.x 如果有帮助,可用。
谢谢
编辑:
这是我目前尝试过的方法:
Uni<Item> u = processingPipeline();
return Uni.createFrom().emitter(emitter -> {
vertx.executeBlocking(handler -> {
u.subscribe().with(emitter::complete);
}, resultHandler -> {});
vertx.setTimer(TimeUnit.SECONDS.toMillis(10), timerId -> {
emitter.complete(placeholderItem);
});
});
当处理在截止日期之前完成时,这工作正常,但如果截止日期到期并且计时器被触发,它会在发出占位符项目时崩溃并显示 javax.enterprise.context.ContextNotActiveException
,并且应用程序似乎也得到了陷入某种僵局。
编辑 2
原来我的大部分问题其实都是由于Hibernate使用不当造成的。在对 Hibernate 事务的管理方式进行一些重构之后,所有随机死锁和其他问题都消失了。
这似乎是对原始问题最优雅的解决方案,即如何在不中断处理的情况下用虚拟项目响应,除非它在截止日期前完成:
Uni<Item> u = processingPipeline();
return Uni.createFrom().emitter(emitter -> {
u.subscribe().with(emitter::complete);
vertx.setTimer(TimeUnit.SECONDS.toMillis(10), timerId -> {
emitter.complete(placeholderItem);
});
});
管道的取消是预料之中的,因为 ifNoItem().after(duration)
触发了 TimeoutException
。所以这个异常被传播为失败,并且这个特定点的上游被取消,这符合反应流语义。
recoverWith
是一个故障恢复操作符,订阅这个操作符之后的任何内容。
您可能想看看 recoverWithUni
,您可以在其中提供 Uni
作为恢复,而 Uni
将捕获管道的其余部分在此特定超时失败点后重新订阅。
希望对您有所帮助。
我有一个异步操作管道需要很长时间才能完成,我想 如果管道在截止日期之前没有生成项目,让 Uni 继续使用占位符项目,如下所示:
Uni<Item> u = processingPipeline();
return u.ifNoItem().after(Duration.of(10, SECONDS)).recoverWith(placeholderItem);
但是当使用这种方法时,处理管道被取消并且操作链被中断。 是否可以在截止日期到期时用占位符项完成 Uni 而无需取消处理管道?即使错过最后期限,我也希望管道能够进行到最后。 Vert.x 如果有帮助,可用。
谢谢
编辑:
这是我目前尝试过的方法:
Uni<Item> u = processingPipeline();
return Uni.createFrom().emitter(emitter -> {
vertx.executeBlocking(handler -> {
u.subscribe().with(emitter::complete);
}, resultHandler -> {});
vertx.setTimer(TimeUnit.SECONDS.toMillis(10), timerId -> {
emitter.complete(placeholderItem);
});
});
当处理在截止日期之前完成时,这工作正常,但如果截止日期到期并且计时器被触发,它会在发出占位符项目时崩溃并显示 javax.enterprise.context.ContextNotActiveException
,并且应用程序似乎也得到了陷入某种僵局。
编辑 2
原来我的大部分问题其实都是由于Hibernate使用不当造成的。在对 Hibernate 事务的管理方式进行一些重构之后,所有随机死锁和其他问题都消失了。
这似乎是对原始问题最优雅的解决方案,即如何在不中断处理的情况下用虚拟项目响应,除非它在截止日期前完成:
Uni<Item> u = processingPipeline();
return Uni.createFrom().emitter(emitter -> {
u.subscribe().with(emitter::complete);
vertx.setTimer(TimeUnit.SECONDS.toMillis(10), timerId -> {
emitter.complete(placeholderItem);
});
});
管道的取消是预料之中的,因为 ifNoItem().after(duration)
触发了 TimeoutException
。所以这个异常被传播为失败,并且这个特定点的上游被取消,这符合反应流语义。
recoverWith
是一个故障恢复操作符,订阅这个操作符之后的任何内容。
您可能想看看 recoverWithUni
,您可以在其中提供 Uni
作为恢复,而 Uni
将捕获管道的其余部分在此特定超时失败点后重新订阅。
希望对您有所帮助。