본문으로 바로가기

[Kotlin] Coroutine의 배신

category 개발이야기/Kotlin 2019. 5. 8. 14:47
반응형


최근에 Coroutine을 메인 프로젝트에 반영해서 썼습니다.


"쓰레드 따위...개나 줘버려.."라는 생각으로 코루틴을 적용해 보니 신세계 입니다.

지긋지긋한 콜백구조와 Thread safe를 신경써야 했던 부분들이 너무나도 손쉽게 해결되면서 "역시 사람은 배워야되"를 연발했었죠.


획기적으로? 줄어든 코드량과 더불어 복잡도가 떨어지는 코드등 장점도 많은 반면에, 개념을 모르면 리뷰도 못한다라는 막강한 단점까지 있습니다.


하여튼..코루틴을 적용해 보면서 겪었던 문제들을 나열해 보려 합니다.

그리고 결론적으로 코루틴은 다음 프로젝트 부터는 사용하지 않는걸로 결정 내렸습니다.


정확하게 말하면 사용 못합니다.

사용할때 신세계 였는데, 배포하고나서 crash난걸 보니..@.@


장점은 찾아보면 다른 블로그에도 여기저기 많이 나옵니다.

그래서 아무도 정리해서 쓰지 않는 Critical한 단점만 나열해 보겠습니다.


초기 로딩 시간이 느리다.

corouitne을 처음으로 사용할때 로딩시간이 필요합니다. 대략 300~400ms 정도 걸리더군요.

매우 critical한 버그 입니다.

App process가 올라오고 나서 처음으로 coroutine의 빌더를 사용할때 발생하는 이슈로 호출한 thread가 해당 시간만큼 멈춤니다.

그지같은 동작이지만, 실제 동작시 delay를 막기위해 Application 상속 클래스에서 Sub Thread를 띄워서 더미로 corouitne을 불러주는 작업으로 해결했습니다.


GlobalScope.launch(Dispatchers.Default) {

                    GlobalScope.launch(Dispatchers.IO) {}

                    GlobalScope.launch(Dispatchers.Main) {}

                    GlobalScope.launch(Dispatchers.Unconfined) {}

                }

                

이렇게 Background threa를 하나 띄워서 GlobalScope의 launch를 Dispatcher 별로 한번씩 다 불러주는거죠.


다행이도 v1.2.0에서 이 버그는 수정되었습니다.

개발 완료하고 배포 3일전에 1.2.0 버전이 나오는 바람에 MR로 배포해야 했습니다.ㅠ.ㅠ


cancelAndJoin 의 배신..

코루틴에서 job을 하나 만들고 공유해서 쓰면서 job.cancelAndJoin() 명령어로 관련 작업들을 다 취소할 수 있습니다.

안드로이드에서 Activity가 종료되거나, 화면이 전환되어 딸려있던 작업들을 한번에 정리하기 딱 좋습니다.


하지만 cancelAndJoin은 말 그대로 취소하고, 자식 coroutine이 전부 취소 될때까지 기다립니다.

즉..시간이 걸리는 거죠..


따라서 아래와 같은 형태로 사용했었는데, 이럴경우 타이밍 이슈가 발생합니다.

GlobalScope.launch { 
job.cancelAndJoin() 
}


해당 코드를 호출하고 관련된 작업에 접근하면 분명 취소 되었어야 하나, 아직 취소가 수행되지 않은 상태에서 접근하니 원하지 않은 상황과 마딱드립니다.

이건..그냥

job.cancel()을 호출하는걸로 해결이 가능합니다.

자식 코루틴들이 끝나는거 까지는 기다리지 않는다는거죠.

그냥 AsyncTask의 cancel()과 동일한 형태로 신경쓰면서 cancel 처리를 하면 됩니다.


삼성단말 OS 5.0.x 버전에서는 코루틴 crash가 발생..

막강한 이슈입니다.

삼성단말중에 L OS에서 코루틴 시작부터 crash가 발생하는 단말이 종종 있습니다.

노트3...갤럭시 S4가 요주의 단말인데, 이 단말의 Android OS가 5.0.x 입니다.

아무래도 삼성에서 해당 버전의 framework을 수정하고, corouitne이 initialize 과정중에 호출하는 기본 library에서 오류가 발생하면서 아예 app이 죽어버립니다.

근데..

이게 100% 재현이 아니라서 동일 단말 테스트를 진행했는데도 불구하고 걸러내지 못했습니다.


정확히는 java.lang.ExceptionInInitializerError 에러가 발생합니다.

여기에 이미 이슈 라이징이 되어 있습니다.

https://github.com/Kotlin/kotlinx.coroutines/issues/490


결론적으로 "L OS를 지원하는 App이면 corouitne을 사용할수 없다" 입니다.

난 노트3 정도는 가볍게 버린다..라고 한다면야 상관 없겠지요.


삼성이 고리짝 단말의 MR 업데이트를 하기는 어려워 보입니다..

아니면..추후에 코루틴 라이브러리에서 crash 나는 부분을 우회시켜주거나...ㅠ..ㅠ

여튼 min sdk에 따라서 코루틴이 정상 동작 하지 않을수 있다라는걸 염두하고 써야 합니다.

반응형