데이터 / 어댑터 계층

데이터 계층에서는 JVM의 인기있는 라이브러리 차원에서 지원을 해줘서 손쉽게 지원을 해줘, 다루는게 상대적으로 쉽다.

Retrofit

요청을 블로킹함수 중단함수로 보내고 싶으면, suspend 제어자를 추가하면 된다.

Room

안드로이드에서 SQLLite 데이터베이스와 통신시 사용

중단 함수로 만들기 위해서는 suspend 제어자를 넣어주는 것이 가능하며, 테이블 상태를 감지하기 위한 flow도 지원한다.

콜백 함수

코루틴을 지원하지 않는 라이브러리 사용시에는 suspendCancellableCoroutine 을 사용해 콜백 함수를 중단함수로 변경해서 사용한다.

suspend fun requestNews (): News {
	return suspendCancellableCoroutine <News> { cont ->
		val call = requestNewsApi { news ->
			cont.resume (news)
		}
		cont.invokeOnCancellation {
			call.cancel()
		}
	}
}

콜백 함수 호출시 코루틴을 재개할수도 있고, 취소할수도 있다.

다른 방법으로는 콜백함수를 래핑하고 Result를 반환 타입으로 설정하는 것이다.

suspend fun requestNews (): Result<News> {
	return suspendCancellableCoroutine <News> { cont ->
		val call = requestNewsApi(
			onSucess = { news ->
				cont.resume(Result.success(news))
			},
			onError = { e ->
				cont.resume(Result.failure(e))
			}
		)
		cont.invokeOnCancellation{
			call.cancel()
		}
	}
}

다른 방법은 성공 시 결과를 반환하고, 실패 시 null값으로 코루틴을 재개한다.

suspend fun requestNews (): News? {
	return suspendCancellableCoroutine <News> { cont ->
		val call = requestNewsApi(
			onSucess = { news ->
				cont.resume(news)
			},
			onError = { e ->
				cont.resume(null)
			}
		)
		cont.invokeOnCancellation{
			call.cancel()
		}
	}
}

마지막으로는, 실패했을 때 예외를 던진다.

suspend fun requestNews (): News? {
	return suspendCancellableCoroutine <News> { cont ->
		val call = requestNewsApi(
			onSucess = { news ->
				cont.resume(news)
			},
			onError = { e ->
				cont.resumeWithException(e)
			}
		)
		cont.invokeOnCancellation{
			call.cancel()
		}
	}
}

블로킹 함수

어쩔수 없이 블로킹 함수를 사용해야 하는 경우도 있는데, 중단함수에서는 블로킹 함수를 호출해서는 안된다. → 본인의 경우도 메시지 컨슈머에서 블로킹 함수를 호출해서 문제가 됐던 경우가 있음

안드로이드에서 Main 스레드가 블로킹 되면, 전체 애플리케이션 실행이 멈추게 된다.