시배's Android

Kotlin Coroutines Deep Dive | 16장. 채널 본문

Book/Kotlin Coroutines Deep Dive

Kotlin Coroutines Deep Dive | 16장. 채널

si8ae 2024. 2. 19. 21:27
  • 채널은 송신자와 수신자의 수에 제한이 없으며, 채널을 통해 전송된 모든 값은 단 한 번만 받을 수 있습니다.
  • Channel은 두 개의 서로 다른 인터페이스를 구현한 하나의 인터페이스입니다.
  • SendChannel은 원소를 보내거나 채널을 닫는 용도로 사용됩니다.
  • ReceiveChannel은 원소를 받을 때 사용됩니다.
  • 채널의 진입점을 제한하기 위해 ReceiveChannel이나 SendChannel 중 하나만 노출시키는 것도 가능합니다.
  • receive를 호출했는데 채널에 원소가 없다면 코루틴은 원소가 들어올 때 까지 중단됩니다.
  • 반면 send는 채널의 용량이 다 찼을 때 중단됩니다.
  • 용량이 제한적인 채널에서만 trySend tryReceive를 사용해야 합니다.
  • produce 함수는 빌도로 시작된 코루틴이 어떻게 종료되든 상관없이 채널을 닫습니다.

채널 타입

  • 무제한 : 제한이 없는 용량 버퍼를 가진 Channel.UNLIMITED로 설정된 채널로, send가 중단되지 않습니다.
  • 버퍼 : 특정 용량 크기 또는 Channel.BUFFERED(기본값은 64)로 설정된 채널입니다.
  • 랑데뷰 : 용량이 0이거나 Channel.RENDEZVOUS 인 채널입니다.
  • 융합 : 버퍼 크기가 1인 Channel.CONFLATED를 가진 채널로, 새로운 원소가 이전 원소를 대체합니다.

버퍼 오버플로일 때

채널을 커스텀하기 위해 버퍼가 꽉 찼을 때의 행동을 정의할 수 있습니다.

  • SUSPEND(기본) : 버퍼가 가득 찼을 때, send 메서드가 중단됩니다.
  • DROP_OLDEST : 버퍼가 가득 찼을 때, 가장 오래된 원소가 제거됩니다.
  • DROP_LATEST : 버퍼가 가득 찼을 때, 가장 최근의 원소가 제거됩니다.

Channel.CONFLATED는 용량을 1로 설정하고 onBufferOverFlow를 DROP_OLDEST로 설정한 것 임을 알 수 있습니다.

전달되지 않은 원소 핸들러

  • onUndeliveredElement는 원소가 어떠한 이유로 처리되지 않을 때 호출됩니다.
  • 대부분 채널이 닫히거나 취소되었음을 의미하지만, send, receive, receiveOrNull 또는 hasNext가 에러를 던질 때 발생할 수 있습니다.

팬아웃

  • 여러 개의 코루틴이 하나의 채널로부터 원소를 받을 수도 있습니다.
  • 채널은 원소를 기다리는 코루틴들을 FIFO 큐로 가지고 있습니다.

팬인

  • 다수의 채널을 하나의 채널로 합쳐야 할 경우가 있습니다.
  • 이런 경우 produce 함수로 여러 개의 채널을 합치는 fanIn 함수를 사용할 수 있습니다.

파이프 라인

  • 한 채널로부터 받은 원소를 다른 채널로 전송하는 경우가 있습니다.
  • 이를 파이프라인이라고 부릅니다.

통신의 기본 형태로서의 채널

  • 채널은 서로 다른 코루틴이 통신할 때 유용합니다.
  • 충돌이 발생하지 않으며 공평함을 보장합니다.
  • 채널은 처리해야 할 판매자를 가지고 있으며
  • 채널은 갱신해야 할 상품을 가지고 있습니다.
  • 두 채널은 모두 버퍼를 가지고 있습니다.
  • 두 번째 채널의 버퍼는 이미 처리해야 할 상품이 많을 경우 서비스가 더 많은 상품을 받는 걸 방지합니다.
  • 따라서 서버는 같은 시간에 갱신해야 할 상품의 수를 조절할 수 있습니다.