Kotlin Channel

Arakene·2024년 10월 9일

Channel이란?

코루틴간에 데이터를 순차적으로, 동기적으로 교환할 수 있는 통로를 뜻한다. 자바의 BlockingQueue와 비슷하지만 채널은 suspend를 통해 통신한다.
채널은 shared mutable state 없이 효과적으로 코루틴 간에 통신이 가능하다.

Channel의 장점?

구조화된 접근 방식을 제공해주기에 데이터 이동, 공유 자원 관리 등에 이점이 있으며
비동기 처리 시에도 유연하고 직관적인 관리 방안을 제공해준다. 채널을 활용하면 코루틴간의 복잡한 협력관계 처리, 코루틴 간의 데이터 플로우 관리, 복수의 코루틴 동기화 처리도 가능하다.
그리고 suspend 함수를 채널과 같이 사용하는 것 만으로도 간단하게 처리해줄 수 있다.

Channel 간단 구조

Channel 생성

Channel(capacity) 팩토리는 capacity값에 따라서 채널의 종류가 달라진다.

val channel = Channel<String>()

capacity가 0인 경우

rendezvous 채널로 생성, 해당 채널은 버퍼가 없으며 데이터는 sendreceive의 호출이 한번 맞았을때 (rendezvous)때만 옮겨간다.

capacity가 Channel.UNLIMITED 인 경우

무제한 버퍼로 생성, 해당 채널은 linked-list 버퍼로 무제한 버퍼가 생성된다.
send 가 suspend 함수는 일시정지 안되고 trySend는 항상 성공한다.

capacity가 Channel.CONFLATED 인 경우

conflated 채널로 생성, 해당 채널의 버퍼는 collectLatest처럼 항상 마지막 값만 보낸다.

데이터 sending, receiving

// Sending data to the channel
channel.send("Hello, Kotlin!")

// Receiving data from the channel
val message = channel.receive()

Flow VS Channel

Channel

  • 양방향 통신: 채널을 통해 양방향으로 데이터를 주고받을 수 있음
  • 동기화 작업: 코루틴 간에 순차적으로 데이터 교환 가능
  • 버퍼링 채널: 버퍼를 제공해서 효율적인 처리와 관리 가능
  • producer - receiver 패턴 사용

Flow

  • 단방향 데이터 흐름
  • 선언적 데이터 처리: 파이프라인을 선언하는 걸로 데이터 변환같은 처리 가능
  • Cold stream: 기본적으로 콜드 스트림이며 데이터를 수집할 때만 데이터를 보냄
  • Hot stream으로도 가능

한 채널로 여러 코루틴 핸들링

발생 가능한 이슈

동시성 제어

공유된 채널에 대해서 동시에 접근하는 것은 조심해서 사용해야하며 race condition과 데이터 손실을 예방하기 위해 적절한 동기화 메커니즘을 추가해야한다.

데드락

채널 작업의 완료를 기다리는동안 코루틴을 블럭하는 경우 데드락이 발생할 수 있다.

채널 닫기

채널이 더 이상 사용이 불가능해질 때 코루틴이 블락당하지않도록 채널 클로저에 적절한 핸들링을 해줘야한다.

해결방안

동시성 제어

Mutex, Semaphore같은 locking 메커니즘을 사용

에러 핸들링

에러 복구 메커니즘, 여러 영역에 대한 에러 핸들링을 권장

채널 LifeCycle 관리

공유된 채널의 생성 및 파괴를 적절하게 관리해줘야한다. 채널 closure 이벤트에서 코루틴 관리를 해줘야한다.

Buffer Channel

profile
안녕하세요 삽질하는걸 좋아하는 4년차 안드로이드 개발자입니다.

0개의 댓글