<현상>
- Async API Call 후 응답을 제대로 처리하지 못하는 현상이 있습니다.
- 그 여파로 내부적으로 AtomicInteger를 이용하여 호출Count를 처리하는 로직이 있는데 해당 로직이 수행되지 않아서 버그가 발생하고 있었습니다.
<원인>
contents = webClient
.post()
.uri(multiCountApiPath)
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.header("Authorization","Bearer " + token)
.body(BodyInserters.fromObject(inputs))
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofMillis(200000))
.onErrorReturn(null)
.flux()
.toStream()
.findFirst()
.orElse(null);
try {
...
} catch (IOException e) {
...
}
callCount.decrementAndGet();
return CompletableFuture.completedFuture(ret);
- 원래의 의도는 API Call 오류가 발생하였을 경우 null 로 처리하여 빈값을 가져가도록 하는 것이었습니다.
- 그러나 실제로 테스트해보면 try 이후 구문이 수행되지 않고 있습니다.
- API Call에서 오류가 발생했을 경우 null 처리를 잘못하여 flux() 이하 로직이 수행되지 않고 있습니다.
<수정사항>
contents = webClient
.post()
.uri(multiCountApiPath)
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.header("Authorization","Bearer " + token)
.body(BodyInserters.fromObject(inputs))
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofMillis(200000))
.onErrorReturn("")
.flux()
.toStream()
.findFirst()
.orElse("");
try {
...
} catch (IOException e) {
...
}
callCount.decrementAndGet();
return CompletableFuture.completedFuture(ret);
- 위와 같이 bodyToMono에서 우리가 사용하고자 했던 타입에 맞는 값(e.g String "" )으로 처리해주면 onErrorReturn 이후 로직이 정상적으로 수행되는 것을 확인할 수 있습니다.
<추가로 확인해야 할 사항>
- timeout 이 발생했을 때 특정 로직을 수행하도록 handler 가 가능하다면 decrement 로직을 그쪽으로 옮길 수 있을지 검토가 필요합니다.
- onErrorReturn 이후 로직이 Spring내부에서 어떻게 동작하는지 상세한 확인이 필요합니다.
'Java' 카테고리의 다른 글
Spring JPA, SecurityContext사용시 ThreadLocal 사용범위 관련 #1 (0) | 2021.09.10 |
---|---|
Redis 캐시사용시 생성되는 기본키 및 prefix 오류 (0) | 2021.09.01 |
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException (0) | 2021.05.07 |
Spring Security + MySQL 사용시 로그인 대소문자 구분 주의사항 (0) | 2019.09.11 |
Spring MVC를 이용한 Test 중 Controller Layer 의 Exception처리 (0) | 2019.06.03 |