Stream의 종류? Cold vs Hot

SSY·2025년 8월 5일
0

Flow

목록 보기
7/7
post-thumbnail

시작하며

Coroutine의 Flow를 처음 사용하면 이 스트림이 Cold인지, Hot인지 구분이 필요하다. 그래야만 생산자 <-> 구독자의 관계를 1:N으로 하냐, 1:1로하냐를 결정할 수 있으며, 생산자의 데이터 발행 시간 또한 정할 수 있기 때문이다.

HotStreamColdStream
구독자 갯수N개1개
데이터 생산 시점구독자 여부와 무관한 데이터 생산. 단, SharingStarted 전략에 따른 3가지 방식이 존재

1. Subscribed(1000L) : 구독자 생성 시, 데이터 생산 시작. 그 후, 모든 구독자 제거 후, 몇초 후에 데이터 생산을 중단할지 결정
2. Lazily : 구독자 생성시, 데이터 생산 시작
3. Eagerly : 구독자 생성과 무관한 데이터 생산(=일반적인 HotStream)
구독자가 생겨야만 데이터를 생산을 시작
데이터 종료 시점1. WhileSubscribed : 모든 구독자 삭제 후, 파라미터 초 경과 이후
2. Lazily, Eagerly : 안됨
구독자 종료 직후
데이터 생산 지점sharedIn, stateIn 또는
MutableStateFlow(),
MutableSharedFlow()를 통한 핫스트림 객체 생성
flow 빌더를 사용한 객체 생성
ㄴ> flowOf()
ㄴ> flow { emit() }
ㄴ> asFlow()
용도이벤트 전송, 상태값 갱신API 결과 수신

1. HotStream

HotStream은 구독자가 있든 없든 데이터를 생산할 수 있는 스트림이다. 즉, 구독자의 존재 여부와 무관하게 생산자가 데이터를 발행할 수 있다는 뜻이고, 구독자는 적절한 시기때 이를 구독할 수 있다. 하지만 생산자는 구독자를 신경쓰지 않을 수 있기에, 생산자가 이미 발행해버린 데이터를 구독자는 이를 복구할 수 없다는 것도 알아야 한다. 안드로이드에서 대표적인 예로 StateFlow, SharedFlow가 있다.

참고 : SharedFlow와 StateFlow의 차이?

또한 HotStream을 사용할 경우, 데이터 종료 시점 또한 조정이 가능하다. stateInWhileSubscribed의 인자를 넣어주었을 시, 해당 스트림의 모든 구독자가 사라진 후, 몇초 후에 해당 스트림을 제거할지 결정이 가능하다. 또한 Lazy, Eagerly의 경우는 모든 구독자가 제거된다 할지라도 해당 스트림은 제거되지 않으며, 생산자가 데이터 발행도 가능하다. 따라서 HotStream을 통해 구독자-생산자 관계가 N:1이란 것을 염두해두지 못한채로 코딩할 경우, 메모리 누수가 일어날 수 있는데, 이를 방지하기 위해 구독자가 중복으로 생기는지 또한 체크가 필요하다.

따라서 HotStream을 사용하면 좋은 경우는 아래와 같다.

  • 실시간 UI 상태 공유 (eg., 현재 화면 상태, 로그인 여부)
  • 여러 구독자에게 동시에 동일한 이벤트를 뿌릴 때 (eg., Repository에서 SharedFlow로 특정 이벤트를 viewModel로 통지할 때)

2. ColdStream

ColdStream은 HotStream과 반대로, 구독자가 생기기 전까지 데이터는 생산되지 않는다. 즉, 누군가 구독(=collect) 해줘야 흐르기 시작한다는 의미다. 따라서 단순 API 호출이나 단발성 연산에 적합하다. 대표적으로 데이터를 발행하는 예는 flow {}, flowOf(...), asFlow(...) 같은 표준 API가 있다.

fun loadUser(): Flow<User> = flow {
    val response = api.getUser()
    emit(response)
}

// 사용 예
lifecycleScope.launch {
    loadUser().collect { user ->
        println("받은 유저 정보: $user")
    }
}

또한 ColdStream을 사용할 경우, 데이터 종료 시점은 구독자의 제거 시점과 동일하다. ColdStream은 생산자와 구독자가 1:1관계이기에, 구독자가 사라질 경우, 생산자도 동일하게 사라지게 된다.

따라서 ColdStream을 사용하면 좋은 경우는 아래와 같다.

  • API 호출 결과를 1회성으로 받고 싶을 때
  • 연산이 매 collect마다 새로 일어나야 할 때
  • 구독마다 다른 데이터 흐름이 필요한 경우
profile
불가능보다 가능함에 몰입할 수 있는 개발자가 되기 위해 노력합니다.

0개의 댓글