ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20.03.30 ~ 20.04.03 TWIL
    개발 일기장/TWIL 2020. 4. 4. 16:01

    rxJava로 retry 처리

    스케줄러가 돌아가면서 외부업체 api를 날리다 실패했을 경우 retry가 필요할 것 같아, retry로직을 작성했다. 처음에 생각한 코드는 다음과 같다.

    
    publc class BookingRequestService {
    
        private final BookingApiService bookingApiService;
    
        public Booking(BookingApiService bookingApiService) {
            this.bookingApiService = bookingApiService;
        }
    
        private static final String MAX_RETRY = 3;
    
        public BookingResponse requestBooking() {
            int reqeustCount = 1;
            while(requestCount <= MAX_RETRY) {
            
                try {
                    return bookingApiService.requestBooking();
                } catch(RestClientException e) {
                    log.error("api 요청 중 실패, 요청 횟수 : {}회", reqeustCount, e);
                    reqeustCount++;
                }
                
            }
        }
    }    
    

     

    rxJava로 retry를 굳이 처리한 이유는 프로젝트 내부에서 rxJava를 적용한 곳이 있고, 코드를 봤을 때 rxJava는 retry를 라이브러리로 제공하고 있어 더 깔끔하게 처리할 수 있고, 위와 같은 retry 코드를 여러 곳에 작성하면 길고 중복된 코드를 줄이기 위함이었다.

     

    
    publc class BookingRequestService {
    
        private final BookingApiService bookingApiService;
    
        public Booking(BookingApiService bookingApiService) {
            this.bookingApiService = bookingApiService;
        }
    
        private static final String MAX_RETRY = 3;
    
        public BookingResponse requestBooking(OrderForm orderForm) {
            return Maybe.fromCallable(() -> bookingApiService.requestBooking(orderForm))
                    .retry((retryCount, throwable) -> isRetry(retryCount, throwable, orderForm.getBookingId()))
                    .blockingGet();
        }
    
        private boolean isRetry(Integer retryCount, Throwable throwable, String bookingId) {
            if (retryCount > MAX_RETRY) {
                return false;
            }
            if(!(throwable instanceof RestClientException)) {
                return false;
            }
            logger.info("api 요청 중 실패, 요청 횟수 : {}회, booking Id : {} ", retryCount, bookingId);
            return true;
        }
    
    
    }    

    rxJava를 배운적은 없지만 알아먹을 수 있었던 건 카카오 때 Spring WebFlux에서 사용하는 reactor를 잠깐 써본 경험이 있어서 알아먹을 수 있었다. (개념적으로 많이 유사하다)

     

    Maybe는 rxJava에서 나오는 개념으로 Single의 값이 발행되거나, null이거나 exception이 떨어질 수 있음을 나타내는 클래스이다. Maybe는 지연 연산 및 로딩으로 수행한다.

    참고: Maybe javaDoc

     

    Maybe.fromCallable이 아닌 Maybe.just를 사용할 경우, null이 떨어지면 NPE(Null Pointer Exception)가 떨어진다. fromCallable을 사용할 경우, 빈 값이 오고, NPE가 발생하지 않는다. retry하면서 NPE를 체크할 필요가 없었기에 fromCallable을 사용했다.

    참고: Maybe null handling 참고 사이트

     

    (사실 이 코드를 작성한 시간보다 다른 영향 가는 부분 체크하는데 시간을 훨씬 많이썼다......)

    '개발 일기장 > TWIL' 카테고리의 다른 글

    20.05.04 ~ 20.05.08 TWIL  (0) 2020.05.09
    20.04.20 ~ 20.04.24 TWIL  (0) 2020.04.26
    20.03.23 ~ 20.03.27 TWIL  (0) 2020.03.30
    20.03.16 ~ 20.03.20 TWIL  (0) 2020.03.21
    20.03.09 ~ 20.03.14 TWIL  (0) 2020.03.15
Designed by Tistory.