Home > Mobile >  How do Hooks in Webflux / Spring Reactor work (using switchIfEmpty as an example)?
How do Hooks in Webflux / Spring Reactor work (using switchIfEmpty as an example)?

Time:08-25

If I use switchIfEmpty for a Mono for example, I have a hard time locating where the actual comparison (if the Mono is in fact empty) is happening. The first thing my IDE jumps to, is the snippet below.

    public final Mono<T> switchIfEmpty(Mono<? extends T> alternate) {
        return onAssembly(new MonoSwitchIfEmpty(this, alternate));
    }

However, onAssembly only calls a static method / value in the Hooks abstract class. That hook "onEachOperatorHook" does seem to use an Functional Interface, but I can't seem to find where this is placed / coded.

The comments also mention pointcuts, but I also don't find any hints into any @Aspect annotated classes, so I assume it's implemented with the Hooks only.

Can anyone point me in the right direction, where the Hooks actually take the information from (supposedly a Lambda) for comparing the two Monos in case of switchIfEmpty?

Many thanks.

CodePudding user response:

The logic is taking place inside SwitchIfEmptySubscriber<T>:

  static final class SwitchIfEmptySubscriber<T> extends Operators.MultiSubscriptionSubscriber<T, T> {
    final Publisher<? extends T> other;
    boolean once;

    SwitchIfEmptySubscriber(CoreSubscriber<? super T> actual, Publisher<? extends T> other) {
      super(actual);
      this.other = other;
    }

    public void onNext(T t) {
      if (!this.once) {
        this.once = true;
      }

      this.actual.onNext(t);
    }

    public void onComplete() {
      if (!this.once) {
        this.once = true;
        this.other.subscribe(this);
      } else {
        this.actual.onComplete();
      }

    }

    public Object scanUnsafe(Scannable.Attr key) {
      return key == Attr.RUN_STYLE ? RunStyle.SYNC : super.scanUnsafe(key);
    }
  }

In case of an empty Mono:

  • onComplete() is triggered
  • this.once is false since onNext() has not been executed
  • this.other publisher (the alternative Mono given in switchIfEmpty) gets subscribed
  • Related