TIL(사전캠프)

리액티브 스트림즈(Reactive Streams) (2024-06-25)

note994 2024. 6. 25. 17:15

1. 리액티브 스트림즈(Reactive Streams)란?

개발자가 리액티브 코드를 작성하기 위해서는 이러한 코드 구성을 용이하게 해주는 리액티브 라이브러리가 있어야 한다. 이 리액티브 라이브러리를 어떻게 구현할지 정의해 놓은 표준 사양을 바로 리액티브 스트림즈라고 한다. 

 

리액티브 스트림즈는 '데이터 스트림을 Non-Blocking이면서 비동기적인 방식으로 처리하기 위한 리액티브 라이브러리의 표준 사양'이라고 표현할 수 있다.


2. 리액티브 스트림즈 구성요소

리액티브 스트림즈를 통해 구현해야 하는 API 컴포넌트에는 Publisher, Subscriber, Subscription, Processor가 있다.

표 2-1 리액티브 스트림즈 컴포넌트
그림2-1 Publisher와 Subscriber의 동작 과정

 

그림 2-1을 통해 컴포넌트들이 구체적으로 어떻게 동작하는지 진행 과정을 살펴보자(Processor는 Publisher와 Subscriber 기능을 모두 가지고 있기 때문에 제외)

 

1. Subscriber는 전달받을 데이터를 구독한다(subscribe)

 

2. 다음으로 Publisher는 데이터를 통지(발행, 게시, 방출)할 준비가 되었음을 Subscriber에 알린다(onSubscribe)

 

3. Publisher가 데이터를 통지할 준비가 되었다는 알림을 받은 Subscriber는 전달받기를 원하는 데이터의 개수를 Publisher에게 요청한다. (Subscription.request)

 

4. Publisher는 Subscriber로부터 요청받은 만큼의 데이터를 통지한다(onNext)

 

5. 이렇게 Publisher와 Subscriber 간에 데이터 통지, 데이터 수신, 데이터 요청의 과정을 반복하다가 Publisher가 모든 데이터를 통지하게 되면 Subscriber에게 데이터 전송이 완료되었음을 알린다.(onComplete)

 

만약 Publisher가 데이터를 처리하는 과정에서 에러가 발생하면 에러가 발생했음을 Subscriber에게 알린다(onError)

 

그런데 Sunscriber가 Subscription.request를 통해 왜 굳이 데이터의 요청 개수를 지정하는 걸까? 그림상으로는 Publisher와 Subscriber가 마치 같은 스레드에서 동기적으로 상호작용하는 것처럼 보이지만 실제로 Publisher와 Subscriber는 각각 다른 스레드에서 비동기적으로 상호작용하는 경우가 대부분이다.

 

이럴 경우 Publisher가 통지하는 속도가 Subscriber가 통지된 데이터를  처리하는 속도보다 빠르다면 처리를 기다리는 데이터는 쌓이게 되고, 이는 결과적으로 시스템 부하가 커지는 겨로가를 낳게 된다. 이러한 문제를 방지하기 위해 Subscription.request를 통해 데이터 개수를 제어하는 것이다.