코루틴끼리의 통신을 위한 기본적인 방법으로 채널 API가 추가되었다.
많은 사람들은 채널을 파이프로 떠올리지만 필자는 책을 교환하는데 사용되는 공공 책장과 비슷하다고 한다.
채널은 송신자와 수신자의 수의 제한이 없으며, 채널을 통해 전송된 모든 값은 단 한번만 받을 수 있다.
Channel은 두개의 서로 다른 인터페이스를 구현한 하나의 인터페이스다.
- SendChennel은 원소를 보내거나(또는 더하거나) 채널을 닫는 용도로 사용된다.
- ReceiveChennel 은 원소를 받을 때(또는 꺼낼때) 사용된다.
interface SendChannel<in E> {
suspend fun send(element: E)
fun close(): Boolean
//..
}
interface ReceiveChannel<out E> {
suspend fun receive(): E
fun cancel(cause: CancellationException? = null)
//..
}
interface Channel<E> : SendChannel<E>, ReceiveChannel<E>
두 인터페이스는 구분되어 있으며, 채널의 진입점을 제한하기 위해 ReceiveChennel이나 SendChennel 중 하나만 노출시키는 것도 가능하다. send 와 receive 모두 중단 함수라는 것을 확인할 수 있다. 원소를 보내고 받는 함수가 중단 함수인 것은 필수적인 특징이다.
- receive 를 호출했을때 채널에 원소가 없다면 코루틴은 원소가 들어올 때까지 중단한다. 공유 책장으로 비교하면, 누군가 책을 찾으러 갔는데 책장이 비어 있는 경우, 다른 사람이 책을 넣을 때까지 기다려야 하는 상황이다.
- 반면 send는 채널의 용량이 다 찼을 때 중단된다. 대부분의 채널은 용량이 제한되어 있다는걸 나중에 확인할 수 있다.공유 책장으로 비유하면, 누군가 책을 넣으러 갔는데 책장이 가득 찬 경우, 다른 사람이 책을 가져가 공간이 생길때까지 기다려야 한다.
중단 함수가 아닌 함수로 보내거나 받아야 한다면 trySend와 tryReceive를 사용할 수 있다. 두 연산 모두 연산이 성공했는지 실패했는지에 대한 정보를 담고 있는 ChennelResult를 즉시 반환한다. 용량이 제한적인 채널에서만 trySend와 tryReceive를 사용해야 하는데, (버퍼가 없는) 랑데뷰 채널에서는 작동하지 않기 때문이다.
채널은 송신자와 수신자의 수에 제한이 없다. 하지만 채널의 양쪽 끝에 각각 하나의 코루틴만 있는 경우가 가장 일반적이다. 채널의 가장 간단한 예를 보려면 각기 다른 코루틴에 생성자(송신자)와 소비자(수신자)가 있어야 합니다. 생성자는 원소를 보내고 소비자는 원소를 받습니다. 다음은 이러한 상황을 구현한 예이다.
(코드)
위와 같은 구현 방식은 불완전하다. 우선 수신자는 얼마나 많은 원소를 보내는지 알아야 한다. 수신자가 이런 정보를 아는 경우는 별로 없기 때문에 송신자가 보내는 만큼 수신자가 기다리는 방식을 선호한다. 채널이 닫힐 때까지 원소를 받기 위해 for 루프나 consumeEach 함수를 사용할 수 있다.
(코드)
위와 같이 원소를 보내는 방식의 문제점은 (특히 예외가 발생했을 때) 채널을 닫는 걸 깜박하기 쉽다는 것이다. 예외로 인해 코루틴이 원소를 보내는 걸 중단하면, 다른 코루틴은 원소를 영원히 기다려야 한다. ReceiveChennel을 반환하는 코루틴 빌더인 produce함수를 사용하는 것이 좀더 편리하다.
(코드)
produce 함수는 빌더로 시작된 코루틴이 어떻게 종료되든 상관없이 (끝나거나, 중단되거나, 취소되거나) 채널을 닫는다. 따라서 close를 반드시 호출해야 한다. produce 빌더는 채널을 만드는 가장 인기 있는 방법이며, 안전하고 편리하다는 등의 많은 등의 많은 장점이 있다.
(코드)
'도서 > 코틀린 코루틴' 카테고리의 다른 글
핫 데이터 소스와 콜드 데이터 소스 (0) | 2024.03.24 |
---|---|
플로우란 무엇인가? (0) | 2024.03.24 |
2장 코루틴 라이브러리 - 공유 상태로 인한 문제 (1) | 2024.02.10 |
2장 코루틴 라이브러리 - 코루틴 스코프 만들기 (1) | 2024.02.10 |
2장 코루틴 라이브러리 - 디스패쳐 (0) | 2024.02.09 |