RetryWhen 으로 다시 시도 (Retry) 구현하기 #RxJava
네트워크를 한다던지, 서버 클라이언트 관계를 만들경우,
연결이 되어있지 않거나, 원하는 정보를 아직 받지 못할 경우가 있습니다.
이럴 때, RxJava의 Operator인 RetryWhen을 사용하면 한결 쉽게 이러한 처리를 할 수 있는데요.
오늘은 이 retryWhen에 대해서 정리해보도록 하겠습니다.
1. RetryWhen 오퍼레이터
RxJava의 Retry 오퍼레이터는 error가 생기면, 자동으로 다시 subscribe해주는 메소드인데요.
이 retry에 조건 when을 붙인것이 retryWhen 입니다.
우선 마블다이어그램 먼저 보시죠.
굉장히 복잡하지만, 조금씩 정리해 보겠습니다.
참고로 마블 다이어그램에 대해서는 아래 글을 참조해주세요.
>>> RxJava (RxAndroid) 의 마블 다이어그램을 이해해보자. <<<
아래 다이어그램에서 X는 비정상적으로 종료된 Error를 의미하는데요.
에러가 발생하면 Error객체인 throwable로 변환해서 흘려보내줍니다.
이것이 retryWhen 에서 정해진 시간만큼의 delay 후에,
특정 요소를 받아서, 다시 subscribe한다는 것입니다.
한마디로 에러가 나도 다시 retryWhen메소드를 통해 다시 재subscribe시켜준다는 것입니다.
여전히 복잡한데요. 실제코드를 구현해보면서 더 정리해 보겠습니다.
실제 코드를 넣으면 아래와 같이 볼 수 있습니다.
Generic을 굉장히 많이 사용하였는데요. 물음표만 4개가 되네요.
마블다이어그램을 보면서 정리했듯이, Error가 나면 retryWhen이 호출됩니다.
retryWhen이 가지는 인자는 Observable<? extends Throwable> 로 Throwable을 상속받았다는 것을 알 수 있죠.
그럼 이제 코드를 작성하면서 상황을 만들어 보겠습니다.
2. RetryWhen 구현
조금 억지스럽지만, RuntimeException을 상속받은 NoResponseException 클래스를 생성해서 사용하겠습니다.
이제 RetryWhen을 본격적으로 구현해보겠습니다.
먼저 error를 인자로 받아서, flatMap을 해줍니다.
이 flatMap에서 받은 인자인 throwable이, 위에서 저희가 생성한 NoResponseException이라면, 재Subscription을 해 주고요,
아니라면 그냥 재구독을 하지않고, onError를 호출해주도록 하였습니다.
재구독시에는 3초에 한번씩 Subscribe 하도록 timer를 걸어놓았습니다.
3. RetryWhen 횟수 제한
마지막으로 RetryWhen에 횟수에 제한을 주는 것에 대해서 정리해보도록 하겠습니다.
5번만 하도록 take Operator를 사용한 경우는 아래와 같이 쓸 수 있습니다.
retrofit과 okhttp를 이용하여 interceptor를 이용해서 네트워크 에러를 발생시킬 수 있을 텐데요.
retryWhen을 사용해서 retry를 시키되, 원하는 Exception에 대해서, 횟수에 제한을 두고 사용해보도록 하겠습니다.
제일 쉬운 방법 중 하나는 take오퍼레이터를 아래와 같이 이용하는 것입니다.