Hot Flow vs Cold Flow

eunsong·2024년 11월 23일

Android

목록 보기
7/9

Cold Flow?

Cold Flow 는 구독하기 전까진 아무 작업도 수행하지 않는 데이터 스트림입니다. 즉 lazy 하게 동작합니다. Flow 의 데이터는 collect 가 호출되기 전까지 생산되지 않습니다.

  • 데이터를 방출하는 생산자는 소비자가 데이터를 요청할 때(collect) 실행됩니다.
  • flow {} 로 생성된 모든 Flow 는 Cold Flow 입니다.
val coldFlow = flow {
    println("Flow started")
    emit(1)
    emit(2)
    emit(3)
}
coldFlow.collect { println("Collected $it") }
// 출력:
// Flow started
// Collected 1
// Collected 2
// Collected 3

위 코드에서 Flow started 는 collect 가 호출된 이후에 출력됩니다.

Hot Flow?

구독자(collector) 가 존재하지 않더라도 데이터를 계속 방출하는 데이터 스트림입니다. 구독자가 데이터 소비를 시작할 때 이미 방출된 데이터를 받을 수 없습니다.

  • Flow 의 데이터 방출은 구독 여부와 상관없이 지속됩니다.
  • SharedFlow 와 StateFlow 가 대표적인 Hot Flow 입니다.
  • 주로 이벤트 기반 데이터 스트림에 사용됩니다.

SharedFlow

이벤트 기반 데이터 스트림을 처리하기 위한 Hot Flow 입니다. 여러 구독자가 동시에 데이터를 수집할 수 있으며, 주로 이벤트 스트림 처리에 사용됩니다.

  • 구독자는 데이터를 동시에 공유합니다.
  • 이벤트 기반 스트림에 적합
  • 새로운 구독자는 이전에 방출된 데이터를 받을 수 없습니다.
  • 버퍼를 설정해 특정 개수의 이전 데이터를 저장할 수 있습니다.
val sharedFlow = MutableSharedFlow<Int>()

// 데이터 방출
GlobalScope.launch {
    sharedFlow.emit(1) // 1 방출
    sharedFlow.emit(2) // 2 방출
}

// 데이터 수집
GlobalScope.launch {
    sharedFlow.collect { println("Collector 1: $it") }
}
GlobalScope.launch {
    sharedFlow.collect { println("Collector 2: $it") }
}
Collector 1: 1
Collector 2: 1
Collector 1: 2
Collector 2: 2

UI 이벤트 처리 (클릭 이벤트 등), 여러 구독자에게 동일한 이벤트 전달 사례에 주로 쓰인다.

StateFlow

상태를 저장하고 관리하기 위한 Hot Flow 입니다. 구독자를 항상 최신 상태를 즉시 받을 수 있으며, 상태 관리에 적합합니다.

  • 항상 최신 상태를 유지하며, 구독자가 최신 상태를 즉시 받을 수 있습니다.
  • 구독자가 없는 동안에도 상태가 유지됩니다.
  • 초기 상태를 반드시 설정해야 합니다.
  • 주로 UI 상태 관리에 적합
val stateFlow = MutableStateFlow(0) // 초기 상태값 설정

// 상태 업데이트
GlobalScope.launch {
    stateFlow.value = 1
    stateFlow.value = 2
}

// 상태 수집
GlobalScope.launch {
    stateFlow.collect { println("Collector: $it") }
}
Collector: 0
Collector: 1
Collector: 2

UI 상태 관리 (로딩 상태, 사용자 입력 값), 최신 상태를 유지해야하는 데이터 스트림 사례에 적합

버퍼의 차이

SharedFlow 의 버퍼
reply 파라미터를 사용해 이전 데이터를 버퍼링할 수 있습니다. 버퍼 크기만큼의 이전데이터는 새 구독자에게 제공됩니다.

val sharedFlow = MutableSharedFlow<Int>(replay = 2) // 이전 데이터 2개 저장

GlobalScope.launch {
    sharedFlow.emit(1) // 방출
    sharedFlow.emit(2) // 방출
    sharedFlow.emit(3) // 방출
}

GlobalScope.launch {
    delay(1000)
    sharedFlow.collect { println("Collector: $it") }
}
Collector: 2
Collector: 3

StateFlow 의 상태 저장
항상 하나의 최신 상태만 저장합니다. 이저 ㄴ상태를 버퍼링하지 않으며, 새 구독자는 최신 상태를 즉시 수신합니다.

val stateFlow = MutableStateFlow(0)

GlobalScope.launch {
    stateFlow.value = 1
    stateFlow.value = 2
}

GlobalScope.launch {
    delay(1000)
    stateFlow.collect { println("Collector: $it") }
}

profile
A place to study and explore my GitHub projects: github.com/freeskyES

0개의 댓글