Spring/스프링으로 시작하는 리액티브 프로그래밍

[Reactor] Cold Sequence, Hot Sequence

꾸준함. 2024. 7. 17. 00:26

컴퓨터 시스템에서의 Cold, Hot 의미

  • Cold는 무언가를 새로 시작하고, Hot은 무언가를 새로 시작하지 않는다고 이해하는 것이 편함
    • ex) 암호화폐의 Hot Wallet은 인터넷에 연결되어 있기 때문에 즉시 사용이 가능하지만 보안에 취약
    • ex) 암호화폐의 Cold Wallet은 인터넷과 단절되어 있어서 사용성은 떨어지지만 보안이 강화됨 (사용하기 위해서는 인터넷에 다시 연결해야 함)

 

Sequence

  • Publisher가 내보내는 데이터의 연속적인 흐름을 정의해 놓은 것
  • 코드로 표현하면 Operator 체인 형태로 정의

 

Cold Sequence

  • Subscriber가 구독할 때마다 데이터 흐름이 처음부터 다시 시작되는 Sequence

 

https://velog.io/@rolroralra/Chapter07.-Cold-Sequence%EC%99%80-Hot-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가 전달받지 못하고 구독이 발생한 시점 이후에 내보내진 데이터만 전달받을 수 있음

 

https://velog.io/@rolroralra/Chapter07.-Cold-Sequence%EC%99%80-Hot-Sequence

 

부연 설명

  • 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

 

https://projectreactor.io/docs/core/release/api/

 

부연 설명

  • 직역하자면 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와 달리 두 구독자 모두 동일한 시점을 출력하는 것을 확인할 수 있음

 

https://projectreactor.io/docs/core/release/api/

 

 

cache() operator가 쓰이는 케이스

  • REST API 요청을 위해 인증 토큰이 필요한 경우 쓰임
    • 인증 토큰을 발급받으면 토큰이 만료되기 전까지 해당 인증 토큰을 사용해 인증이 필요한 API 요청에 사용할 수 있음
    • 인증 토큰 발급을 요청할 때마다 매번 새로운 인증 토큰을 전송할 경우 불필요한 HTTP 요청이 발생하기 때문에 이를 방지하기 위해 cache() Operator를 사용해서 캐싱된 인증 토큰을 사용하여 효율적인 동작 과정을 구성할 수 있음

 

참고

  • 스프링으로 시작하는 리액티브 프로그래밍 (황정식 저자)
반응형