기존의 RxJava와 같은 코드 스타일은 콜백을 사용하여 백그라운드 스레드의 작업을 처리하였다. 작업 완료 여부를 메인 스레드가 busy-waiting하고 있지 않고, 완료 되었을 때 콜백 코드가 호출되어 Main-Safe하게 작업을 처리할 수 있다.

// RxJava Callback 방식
fun createUser(id: String, password: String){
		repository.checkUser(id, password)
			.observeOn(scheduler)
			.toObservable
			.subscribe{ user -> 
				repository.signIn(user)
					.doOnSuccess{
						// 로그인 성공
						Timber.d("login success")
					}
			}.let(compositeDisposable::add)
}

하지만 콜백 요청이 많아지고 중첩으로 하게된다면 코드의 가독성을 해치게 된다. 코루틴은 이러한 콜백 기반 코드를 **Sequential Code(동기 코드 같이)**로 작성할 수 있게 해준다.

// Coroutine 방식
suspend fun createUser(id: String, password: String){
		val user = repository.checkUser(id, password)
		repository.signIn(user)
		// 로그인 성공
		Timber.d("login success")
}

다음과 같이 코루틴을 사용하면 비동기 동작을 동기 코드처럼 표현함으로써 코드의 가독성이 향상되었다. 더욱 직관적이고 추론하기 쉬운 코드는 예측 가능한 프로그램을 만들며 이는 에러 핸들링 및 디버깅 작업에 이점을 준다.

위의 예시에서 함수 앞에 suspend키워드가 붙은 것을 볼 수 있다. suspend 키워드가 붙은 함수는 Kotlin 컴파일러가 어떤 작업을 해주길래 동기 코드 처럼 작성할 수 있는지 알아보자.

Continuation

https://tech.devsisters.com/posts/crunchy-concurrency-kotlin/

코루틴은 Continuation Passing Style(CPS) 형태로 동작한다.

https://kotlinlang.org/spec/asynchronous-programming-with-coroutines.html

CPS호출되는 함수에 Continuation을 전달하고, 각 함수의 작업이 완료되는 대로 전달받은 Continuation을 호출하는 방식을 말한다.

Untitled

Continuation 인터페이스에는 context와 resumeWith가 있다.

즉, CPS에선 Continuation을 전달하면서, 현재 일시 중단된 부분에서 재개가 가능하게 한다. Continuation은 재개되었을 때의 동작 관리를 위한 객체로, 연속적인 상태 간의 communicator라고 볼 수 있다.


Suspend 내부 동작

컴파일에서 suspend