every를 사용해 응답값을 설정할 때의 문제점 이전 글에서 다루었던 UserProfileFetcher이 리모트 저장소로부터 데이터를 가져오는 I/O 작업을 한다고 가정하고, 함수를 모두 다음과 같이 일시 중단 함수로 바꿔보자. class UserProfileFetcher( private val userRepository: UserRepository, ) { suspend fun getUserProfileById(id: String): UserProfile { return UserProfile( id = id, name = userRepository.getNameByUserId(id) ) } } interface UserRepository { suspend fun saveUserName(id: Strin..
코루틴
로그를 사용한 디버깅의 필요성 Kotlin Coroutines는 같은 Coroutine Builder(launch, async 등) 의 중괄호 내부의 코드들이 다른 스레드에서 실행될 수 있다. 예를 들어 아래 코드에서 "task1 : start" 는 메인 스레드에서 실행되지만, "task1 : end"는 DefaultExecutor 스레드에서 실행된다. import kotlinx.coroutines.* fun main() = runBlocking { val task1 = launch(Dispatchers.Unconfined) { log("task1 : start") delay(100) log("task1 : end") } val task2 = launch { log("task2 : start") dela..
디버깅을 하기 위한 준비 Kotlin Coroutines는 일시 중단 후에는 다른 스레드에서 실행될 수 있기 때문에 디버깅을 하기가 매우 어렵다. 이 글에서는 디버깅을 하기 어려운 예 중에 가장 간단한 예시를 제시할 것이다. 다음의 코드를 보자. import kotlinx.coroutines.* fun main() = runBlocking { launch(Dispatchers.Unconfined) { println("launch1 Working Thread : ${Thread.currentThread().name}") delay(100) println("launch1 Working Thread : ${Thread.currentThread().name}") } launch { println("launch2..
Coroutine의 Flow는 데이터 스트림이며, 코루틴 상에서 리액티브 프로그래밍 지원 하기 위한 구성요소이다. 이를 이해하기 위해서는 먼저 리액티브(반응형) 프로그래밍이 무엇인지, 그리고 Flow가 리액티브 프로그래밍에 대응하여 어떠한 역할을 하는지를 알아야 한다. 리액티브 프로그래밍이란? 리액티브 프로그래밍이란 데이터가 변경 될 때 이벤트를 발생시켜서 데이터를 계속해서 전달하도록 하는 프로그래밍 방식을 뜻한다. 이는 기존의 명령형 프로그래밍과 대응되는 개념인데 이에 대한 내용은 [RxJava] 반응형 프로그래밍 이해하기 글에 잘 설명되어 있다. 만약 리액티브 프로그래밍에 대해 잘 모른다면 위 글을 읽고 오자. 기존 명령형 프로그래밍에서는 데이터의 소비자는 데이터를 요청한 후 받은 결과값을 일회성으로..
Coroutine의 Exception Handling Coroutine은 비동기 프로그래밍을 위한 일시중단가능한 경량 스레드이기 때문에 코루틴 내부에서 코루틴이 수행될 수 있으며, 그 깊이는 무한해질 수 있다. 하지만, 코루틴 내부에서 수행되는 자식 코루틴에 애러가 생겼을 때 별도의 Exception Handler을 설정해주지 않으면 자식 코루틴은 부모 코루틴까지 취소시키게 된다. 부모 코루틴이 취소되면 당연히 부모의 자식으로 있는 코루틴이 모두 취소된다. 예를 들어 아래와 같은 구조의 코루틴이 수행된다고 해보자 만약 Child Coroutine1에서 애러가 생겨서 Coroutine이 취소되었다고 하면 아래와 같은 일이 일어난다. Child Coroutine1의 취소가 부모 Coroutine에게 전파된다..