I have a pipeline of asynchronous operations that takes a long time to complete, and I would like to let the Uni continue with a placeholder item if the pipeline has not produced an item before a deadline, like this:
Uni<Item> u = processingPipeline();
return u.ifNoItem().after(Duration.of(10, SECONDS)).recoverWith(placeholderItem);
But when this method is used the processing pipeline is cancelled and the chain of operations are interrupted. Is it possible to complete the Uni with a placeholder item when the deadline expires without cancelling the processing pipeline? I would like the pipeline to carry on to the end even if the deadline is missed. Vert.x is available if that helps.
Thanks
Edit:
This is what I've tried so far:
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);
});
});
And this works fine when the processing is completed before the deadline, but if the deadline expires and the timer is fired it crashes with javax.enterprise.context.ContextNotActiveException
when the placeholder item is emitted, and also the application seems to get stuck in some sort of deadlock.
Edit 2
Turns out most of my problems were actually caused by improper use of Hibernate. After some refactoring of how the Hibernate transactions are managed all random deadlocks and other issues went away.
This seems to be the most elegant solution to the original question, i.e. how to respond with a dummy item without interrupting the processing unless it completed before a deadline:
Uni<Item> u = processingPipeline();
return Uni.createFrom().emitter(emitter -> {
u.subscribe().with(emitter::complete);
vertx.setTimer(TimeUnit.SECONDS.toMillis(10), timerId -> {
emitter.complete(placeholderItem);
});
});