마블 다이어그램(Marble Diagram)이란?
마블 다이어그램이란 여러 도형을 사용하여 비동기적인 데이터 흐름을 시간의 흐름에 따라 시각적으로 표시한 다이어그램이다. 이는 비동기적으로 작동하는 Operator를 직관적으로 이해하기 유용하여, Operator의 API 문서를 확인하려 할 때 마블 다이어그램부터 먼저 확인하는 것이 좋다.
위는 Reactor Documentation에 있는 fluxOperator의 마블 다이어그램이다.
타임라인
마블 다이어그램에서의 타임라인은 왼쪽에서 오른쪽으로 흐른다. 따라서 왼쪽에 있는 데이터(구슬)가 더 먼저 emit(통지)된 데이터에 해당한다.
Source Flux
구슬이 줄줄이 있는 맨 윗줄 라인은 Publisher가 통지하는 데이터의 타임라인으로, 위 그림에선 Flux 타입을 의미한다. Mono의 경우엔 함수에 전달될 데이터는 단 하나이므로 구슬이 하나만 있게 된다. 이 Source는 현재 Operator 기준으로 Upstream Publisher로, 최초로 emit되는 데이터일 수도 있고 아닐 수도 있다.
Operator
Publisher로부터 전달받은 데이터를 처리하는 함수이다. 그림에서는 fluxOperator를 예시로 들고 있고, 함수의 종류에 따라 instance operator, static operator 로 분류된다.
Output Flux
Operator 함수에서 가공되어 출력된 데이터의 타임라인이다.
onComplete()
위 Source Flux의 끝 부분 수직선은 데이터 emit이 정상적으로 종료되었음을 의미하며, onComplete Signal에 해당한다.
onError()
Output Flux의 끝부분에 X 표시는 에러가 발생해 데이터 처리가 종료되었음을 의미하며, onError Signal에 해당한다.
마블 다이어그램으로 Reactor의 Publisher 이해하기
Mono
Mono는 데이터를 0건 또는 1건만 emit 하는 Publisher 타입이다. 위 마블 다이어그램에서도 Upstream line에 데이터가 한 개만 있는 것을 확인할 수 있다.
Mono는 다음과 같이 단일 데이터를 사용할 수 있다.
public static void main(String[] args) {
Mono.just("Hello Reactor")
.subscribe(System.out::println);
}
just()를 통해 데이터를 emit 하고 subscribe()로 전달받은 데이터를 사용한다. Mono의 just()에는 한 개의 파라미터만 전달할 수 있기 때문에 just("Hello", "Reactor")와 같이 작성하면 컴파일 오류가 발생한다.
public static void main(String[] args) {
Mono
.empty()
.subscribe(
none -> System.out.println("# emitted onNext signal"),
error -> {},
() -> System.out.println("# emitted onComplete signal")
);
}
public final Disposable subscribe(@Nullable Consumer<? super T> consumer, @Nullable Consumer<? super Throwable> errorConsumer, @Nullable Runnable completeConsumer) {
return this.subscribe(consumer, errorConsumer, completeConsumer, (Context)null);
}
위는 데이터를 한 건도 emit하지 않는 Mono 코드이다. empty() Operator는 데이터를 emit하지 않고 바로 onComplete Signal을 전송한다. subscribe 메서드를 확인해보면 세 번째 람다식이 onComplete 시그널의 consumer이다. 따라서 다음과 같은 결과를 얻을 수 있다.
Flux
Flux는 0개 또는 여러 건의 데이터를 emit할 수 있는 Publisher 타입이다(Mono를 포함한다). 위 마블 다이어그램에서 시간의 흐름에 따라 데이터가 emit되고 처리되는 것을 확인할 수 있다.
Flux는 다음과 같이 여러 건의 데이터를 emit하고 처리할 수 있다.
public static void main(String[] args) {
Flux.just(6, 9, 13)
.map(num -> num % 2)
.subscribe(System.out::println);
}
Flux.just()로 통지된 데이터가 순서대로 emit된 뒤 map operator로 가공되어 최종적으로 subscribe에서 출력된 것을 확인할 수 있다.
'Dev > Reactive Programming' 카테고리의 다른 글
[Reactive Programming] Backpressure (0) | 2024.08.06 |
---|---|
[Reactor] Cold Sequence와 Hot Sequence (0) | 2024.07.29 |
[Reactor] Reactor 개요 (0) | 2024.07.03 |
[Reactive Programming] 리액티브 프로그래밍을 위한 사전 지식 (0) | 2024.07.02 |
[Reactive Programming] Blocking I/O와 Non-Blocking I/O (0) | 2024.07.01 |