컴퓨터 시스템에서의 Cold, Hot 의미
- Cold는 무언가를 새로 시작하고, Hot은 무언가를 새로 시작하지 않는다고 이해하는 것이 편함
- ex) 암호화폐의 Hot Wallet은 인터넷에 연결되어 있기 때문에 즉시 사용이 가능하지만 보안에 취약
- ex) 암호화폐의 Cold Wallet은 인터넷과 단절되어 있어서 사용성은 떨어지지만 보안이 강화됨 (사용하기 위해서는 인터넷에 다시 연결해야 함)
Sequence
- Publisher가 내보내는 데이터의 연속적인 흐름을 정의해 놓은 것
- 코드로 표현하면 Operator 체인 형태로 정의
Cold Sequence
- Subscriber가 구독할 때마다 데이터 흐름이 처음부터 다시 시작되는 Sequence
부연 설명
- 위 쪽에 위치한 Subscriber가 구독을 하면 Publisher는 네 개의 데이터를 내보냄
- 아래쪽에 위치한 Subscriber가 구독을 해도 마찬가지로 Publisher는 네 개의 데이터를 내보내는 것을 확인할 수 있음
- 두 Subscriber의 구독 시점이 다르지만 두 Subscriber 모두 동일한 데이터를 전달받는 것을 확인할 수 있음
- 정리하자면 Cold Sequence는 Subscriber의 구독 시점이 달라도 구독을 할 때마다 Publisher가 데이터를 내보내는 과정을 처음부터 다시 시작하는 데이터의 흐름이기 때문에 두 Subscriber 모두 네 개의 데이터를 모두 전달받음
- Cold Sequence 흐름으로 동작하는 Publisher를 Cold Publisher라고 지칭
Cold Sequence 예제 #1
부연 설명
- fromIterable() Operator를 사용하여 List로 전달받은 데이터 소스를 내보내는 예제
- 구독이 발생할 때마다 내보낸 데이터를 처음부터 다시 전달받고 있음
Cold Sequence 예제 #2
부연 설명
- WebClient는 RestTemplate과 달리 non-blocking 통신을 지원
- Cold Sequence에서는 구독이 발생할 때마다 새로운 데이터를 내보내기 때문에 두 Subscriber가 구독한 시점(api를 호출한 시점)이 다르므로 출력하는 값도 다른 것을 확인할 수 있음
Hot Sequence
- 구독이 발생한 시점 이전에 Publisher로부터 내보내진 데이터는 Subscriber가 전달받지 못하고 구독이 발생한 시점 이후에 내보내진 데이터만 전달받을 수 있음
부연 설명
- Cold Sequence의 경우 N번의 구독이 발생하면 타임라인이 N번 생성되는 반면 마블 다이어그램의 Hot Sequence 경우 세 번의 구독이 발생했는데도 불구하고 타임라인은 하나 밖에 생성되지 않았음
- 즉 Hot Sequence의 경우 구독이 아무리 많이 발생하더라도 Publisher가 데이터를 처음부터 내보내지 않음
Hot Sequence 예제 #1
부연 설명
- 뮤직 콘서트에는 총 5명의 Singer가 1분에 한 명씩 출연하여 노래를 부른다고 가정
- 첫 번째 관객은 뮤직 콘서트가 시작하기 전 이미 입장해 있는 상태
- 두 번째 관객은 콘서트가 이미 시작되고 일정 시간이 지났을 때 입장
- delayElements() Operator는 데이터 소스로 입력된 각 데이터의 emit을 일정 시간 동안 지연시키는 Operator
- delayElements() Operator의 디폴트 쓰레드 스케줄러가 parallel
- share() Operator는 Cold Sequence를 Hot Sequence로 동작하게 지원해 주는 Operator
share() operator
부연 설명
- 직역하자면 share() operator는 원본 Flux를 멀티캐스트(공유)
- 원본 Flux는 Operator를 통해 가공되지 않은 즉 원본 데이터 소스를 처음으로 내보내는 Flux를 의미
- Hot Sequence 예제 코드 내 fromArray()에서 처음으로 Flux를 반환하고 이어서 delayElements()도 Flux를 반환하며 share() 역시도 Flux를 반환함
- 이렇게 Operator 체인 형태로 반환되는 Flux들은 모두 다른 참조 값을 가지는 객체
- 이렇게 반환되는 Flux 중 fromArray()에서 처음으로 반환하는 Flux가 바로 원본 Flux
- 정리하자면 share() operator 사용 시 여러 Subscriber가 하나의 원본 Flux를 공유
- 하나의 원본 Flux를 공유해서 다 같이 사용하기 때문에 어떤 Subscriber가 원본 Flux를 먼저 구독해 버리면 데이터 emit이 시작되고 이후에 다른 Subscriber가 구독하는 시점에는 원본 Flux에서 이미 내보내진 데이터를 전달받을 수 없게 됨
Hot Sequence 예제 #2
부연 설명
- cache() Operator를 추가함으로써 Cold Sequence가 Hot Sequence로 동작
- cache() Operator는 Cold Sequence로 동작하는 Mono를 Hot Sequence로 변경하고 내보낸 데이터를 캐싱한 뒤 구독이 발생할 때마다 캐시 된 데이터를 전달
- Cold Sequence 예제 #2와 달리 두 구독자 모두 동일한 시점을 출력하는 것을 확인할 수 있음
cache() operator가 쓰이는 케이스
- REST API 요청을 위해 인증 토큰이 필요한 경우 쓰임
- 인증 토큰을 발급받으면 토큰이 만료되기 전까지 해당 인증 토큰을 사용해 인증이 필요한 API 요청에 사용할 수 있음
- 인증 토큰 발급을 요청할 때마다 매번 새로운 인증 토큰을 전송할 경우 불필요한 HTTP 요청이 발생하기 때문에 이를 방지하기 위해 cache() Operator를 사용해서 캐싱된 인증 토큰을 사용하여 효율적인 동작 과정을 구성할 수 있음
참고
- 스프링으로 시작하는 리액티브 프로그래밍 (황정식 저자)
반응형
'Spring > 스프링으로 시작하는 리액티브 프로그래밍' 카테고리의 다른 글
[Reactor] Sinks (0) | 2024.07.23 |
---|---|
[Reactor] Backpressure (0) | 2024.07.18 |
마블 다이어그램 (Marble Diagram) (0) | 2024.07.15 |
[Java] Reactor 간단 정리 (0) | 2024.07.14 |
[Java] 리액티브 프로그래밍 (1) | 2024.06.11 |