I have this issue with Webflux which I don't seem to have a valid solution for: I have an item, T, which I need to process using n Webflux actions. Each action is a function that takes T and returns Mono<T>.
I could execute the actions on the item using flatMapSequential, but the issue is that I want to terminate the sequential actions if prior actions has been failed.
For example, say T = User and we want to support deletion of users. So deletion will require the following actions: "deleting from db" > "delete pictures" > "publish delete message on Kafka".
I must follow these exact steps, and not publish a message to Kafka if the DB deletion has been failed. However, ATM each action that's being executed is a standalone one, so my "publish to Kafka" action is being executed even when my "remove from db" action fails and throws.
I'd love to understand what am I missing...
My execute method:
public Mono<T> execute(final T item) {
if (actions.isEmpty()) {
LOG.warn("No actions to execute on item {}", item);
return Mono.just(item);
}
return Flux.fromIterable(actions)
.as(this::doBeforeItemApply)
.flatMapSequential(this::applyAction, 1)
.onErrorStop()
.contextWrite(ctx -> ctx.put(getItemClass(), item))
.last()
.then(Mono.just(item));
}
protected Mono<A> applyAction(final A action) {
return Mono.deferContextual(ctx -> applyAction(ctx, action, ctx.get(getItemClass()))
.as(this::doOnApplyError)
.as(this::doAfterItemApply)
.contextWrite(innerCtx -> innerCtx.put(getActionClass(), action))
.then(Mono.just(action)));
}
The actions are being injected using Spring Boot.