Webflux execute a sequence of actions in sequential order and get their result

Viewed 20

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.

0 Answers
Related