Project Reactor: About the side effect operator
Tags: java, reactiveprogramming, projectreactor
Published: 2024-04-13 14:59:43

# About side effect 

Side effect is the code that to monitor particular signals which flow in the operator chain. Following is available operator and please check the [javadoc](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html) on when these functions will be called.

- doOnSubscribe()
- doOnNext()
- doOnError()
- doOnComplete()
- doOnTerminate()
- doAfterTerminate()
- doOnRequest()
- doOnCancel()
- doOnEach()
- doFirst()
- doFinally()

# Direction of signal flow

In rare situation, 2 or more of the same operator will be chain together. There is a problem that will operator will be called first. This depends on the direction of the signal flow. On example below

```java
package example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;

public class SignalFlow {

    private static final Logger LOGGER = LoggerFactory.getLogger(SignalFlow.class);

    public static void main(String[] args) {
        Flux<Integer> f1 = Flux.just(1, 2, 3, 4)
                .doOnNext(v -> LOGGER.info("doOnNext (1): {}", v))  // doOnNext (1)
                .doOnNext(v -> LOGGER.info("doOnNext (2): {}", v))  // doOnNext (2)
                .map(v -> v * 2);
        f1.subscribe();

        Flux<Integer> f2 = Flux.just(1, 2, 3, 4)
                .doOnRequest(v -> LOGGER.info("doOnRequest (1): {}", v))    // doOnRequest (1)
                .doOnRequest(v -> LOGGER.info("doOnRequest (2): {}", v))    // doOnRequest (2)
                .map(v -> v * 2);
        f2.subscribe();
    }

}
```

And the result is

```
15:44:46.451 [main] INFO  example.SignalFlow -- doOnNext (1): 1
15:44:46.451 [main] INFO  example.SignalFlow -- doOnNext (2): 1
15:44:46.451 [main] INFO  example.SignalFlow -- doOnNext (1): 2
15:44:46.451 [main] INFO  example.SignalFlow -- doOnNext (2): 2
15:44:46.451 [main] INFO  example.SignalFlow -- doOnNext (1): 3
15:44:46.451 [main] INFO  example.SignalFlow -- doOnNext (2): 3
15:44:46.451 [main] INFO  example.SignalFlow -- doOnNext (1): 4
15:44:46.451 [main] INFO  example.SignalFlow -- doOnNext (2): 4
15:44:46.451 [main] INFO  example.SignalFlow -- doOnRequest (2): 9223372036854775807
15:44:46.451 [main] INFO  example.SignalFlow -- doOnRequest (1): 9223372036854775807
```

On operator doOnNext(), the flow is from Publisher to Subscriber, so the result is "doOnNext (1)" and then "doOnNext (2)". But on operator doOnRequest(), the flow is in reverse direction. So "doOnRequest (2)" will be shown first. Following is the summary

| Function | Direction of signal flow |
| -------- | ------- |
| doOnSubscribe() | Publisher to Subscriber |
| doOnNext() | Publisher to Subscriber |
| doOnError() | Publisher to Subscriber |
| doOnComplete() | Publisher to Subscriber |
| doOnTerminate() | Publisher to Subscriber |
| doAfterTerminate() | Subscriber to Publisher |
| doOnRequest() | Subscriber to Publisher |
| doOnCancel() | Subscriber to Publisher |
| doOnEach() | Publisher to Subscriber |
| doFirst() | Subscriber to Publisher |
| doFinally() | Subscriber to Publisher |