Coroutine 탐험일지(5)

LeeChangMin
쓱싹팀 이야기
4 min readAug 6, 2022

StateFlow와 SharedFlow

Photo by engin akyurt on Unsplash

어플을 개발하면 상태이벤트를 다루게 됩니다.
이를 다루기에 적합한 플로우를 알아봅시다.

Flow builder로 생성한 flow 들은 기본적으로 cold stream 입니다.
오늘 알아볼 플로우인 StateFlowSharedFlow는 둘다 hot stream입니다.

우선, 둘을 간단하게 알아 봅시다.

  • cold stream : 모든 데이터는 스트림 내부에서 생성되고 구독자가 오직 1명
    오직 한명의 구독자에게 값을 보냄(unicast)
    구독자가 있어야 값을 보냄
  • hot stream : 모든 데이터가 스트림 외부에서 생성되고 0명 이상의 구독자
    동시에 여러 구독자에게 값을 보냄(multicast)
    구독자가 없어도 값을 계속 보내고 있음

StateFlow

현재의 상태를 관찰하는데 flow 이고 Hot으로 동작합니다.
어플리케이션을 예로 들면 데이터의 상태, 유저 인증 상태등을 생각할 수 있습니다.

MVVM 구조의 경우 UI와 관련된 상태들은 ViewModel에 위치해 ViewModel에 바인딩된 View 들이 상태를 표현할 수 있도록 합니다.
이런 상태를 정의할 때 보통 Sealed class나 Enum을 사용합니다.

이런 상태 데이터를 다루기 위해 예전에는 LiveData를 사용했습니다.
LiveData는 생명주기가 있는 UI와 상호작용하도록 디자인되어 비지니스 층에서 사용하기엔 무리가 있습니다.
이런 경우 과거 RxJava/Kotlin을 사용했지만 현재는 Reactive streams인 Flow를 사용해 이를 구현합니다.

상태를 다루는 flow이기 때문에 StateFlow는 초기 값을 가지고 모든 구독자에게 최신 상태를 전달합니다.

StateFlow의 특징에는 내부적으로 값을 conflate합니다.
같은 값을 2번 방출하지 않습니다.
만약 list에 값을 추가해 emit하면 해당 emit은 이전 emit과 같은 인스턴스를 방출하기 때문에 또 방출되지 않습니다. 값을 추가하거나 변경해 방출하기를 원하면 인스턴스를 변경해야 합니다.

SharedFlow

이벤트를 관찰하는데 적합한 flow이고 Hot으로 동작합니다.
어플리케이션을 예로 들면 일반적으로 사용자와 뷰의 상호작용으로 발생한 이벤트를 생각할 수 있습니다.

SharedFlow는 StateFlow와 다르게 초기 값을 가지고 있지 않습니다.

  • replay :
    collector가 연결됐을 때, 전달 받을 이전 데이터의 개수를 지정합니다.
    예를 들어, 0~9까지 emit이 되고 있을 때 4가 emit 되고 collect를 시작한 상황에서
    replay가 0 이면 5부터 수신합니다.
    replay가 1 이면 4부터 수신합니다.
  • extraBufferCapacity :
    replay 외 buffer의 개수를 지정합니다.
    emit은 buffer 공간이 남아있는 동안 suspend 되지 않습니다.
    즉, replay + extraBufferCapacity 값이 bufferSize입니다.
  • onBufferOverFlow :
    Buffer가 가득 찼을 때 수행할 옵션을 지정할 수 있습니다.
    3가지 옵션을 선택할 수 있습니다.

BufferOverflow.SUSPEND : emit이 block되고 buffer에 빈 공간이 생기면 다시 동작합니다.
BufferOverflow.Drop_OLDEST : 오래된 값을 삭제하고, 새로운 값을 넣습니다.
BufferOverflow.DROP_LATEST : 최근 값을 삭제하고, 새로운 값을 넣습니다.

--

--