CompletableFuture


비동기 처리 -> CompletableFuture<T>

Future에서는 에러 핸들링을   없지만, 
java8 나온 CompletableFuture<T> 사용하면 에러 핸들링이 가능하다!

[기본적인 사용 방법]
- runAsync
반환 값이 없는 경우 비동기 작업 실행

- supplyAsync
반환 값이 있는 경우 비동기 작업 실행

[작업 콜백]
비동기 실행이 끝난 후에 다음과 같이 체이닝 형태로 작성하여 전달 받은 작업 콜백을 실행시켜 준다.

- thenApply
함수형 인터페이스 Function 타입을 파라미터로 받으며, 반환 값을 받아서 다른 값을 반환해주는 콜백이다.

- thenAccept
함수형 인터페이스 Consumer를 파라미터로 받으며, 반환 값을 받아 처리하고 값을 반환하지 않는 콜백이다.

- thenRun
함수형 인터페이스 Runnable을 파라미터로 받으며, 반환 값을 받지 않고 그냥 다른 작업을 처리하고 값을 반환하지 않는 콜백이다.

비동기 작업 콜백
- thenApplyAsync
앞선 계산의 결과를 콜백 함수로 전달된 Function을 별도의 스레드에서 비동기적으로 실행한다.

- thenAcceptAsync
앞선 계산의 결과를 콜백 함수로 전달된 Consumer를 별도의 스레드에서 비동기적으로 실행한다.

- thenRunAsync
앞선 계산의 결과와 상관없이 주어진 작업을 별도의 스레드에서 비동기적으로 실행한다.

[에러 핸들링]
- exceptionally
발생한 에러를 받아서 예외를 처리한다.
함수형 인터페이스 Function을 파라미터로 받는다.

- handle
(결과값, 에러) 반환받아 에러가 발생한 경우와 아닌 경우 모두를 처리할  있다.
함수형 인터페이스 BiFunction을 파라미터로 받는다.


비동기 처리  반환값이 있고 에러 핸들링이 가능하게 만들어보자!!
CompletableFuture.supplyAsync
CompletableFuture.exceptionally


@Async("threadPoolTaskExecutor")
public CompletableFuture<BatchStatus> handleVatCommonAsyncTask(SchScrapVO schScrapVo, int page) {

    return CompletableFuture.supplyAsync(() -> {
        HtxVatCommonRequestDto requestDto = HtxVatCommonRequestDto.builder()
                .scrapTargetDate(schScrapVo.getScrapTargetDate())
                .year(String.valueOf(LocalDate.now().getYear()))
                .offSet(page * schScrapVo.getChunkSize())
                .limit(schScrapVo.getChunkSize())
                .build();
        if (SvcCd.Z4050 == schScrapVo.getSvcCd()) {
            htxVatZ4050Service.save(requestDto); // 해당 서비스의 스크래핑 로직 
        } else if (SvcCd.Z4061 == schScrapVo.getSvcCd()) {
            htxVatZ4061Service.save(requestDto); // 해당 서비스의 스크래핑 로직
        }
        schScrapVo.updatePage(page);
        schScrapVo.updateStatus(BatchStatus.COMPLETED);
        schScrapHistService.saveSchScrapHistPageInfo(schScrapVo); // 페이징 정보 저장
        return BatchStatus.COMPLETED; // 성공 시 반환값 : COMPLETED
    }).exceptionally(e -> {
        schScrapVo.updatePage(page);
        schScrapVo.updateStatus(BatchStatus.FAILED);
        schScrapHistService.saveSchScrapHistPageInfo(schScrapVo);
        return BatchStatus.FAILED; // 에러 핸들링 - 반환값 : FAIL
    });
}



[다른 비동기 작업과 조합하기]

- thenCompose
 작업을 이어서 실행하도록 조합하며, 앞선 작업의 결과를 받아서 사용할  있다.
함수형 인터페이스 Function을 파라미터로 받는다.

- thenCombine
 작업을 독립적으로 실행하고, 모두 완료되었을  결과를 받아서 사용할  있다.
함수형 인터페이스 Function을 파라미터로 받는다.

- allOf
여러 작업들을 동시에 실행하고, 모든 작업 결과에 콜백을 실행한다.

- anyOf
여러 작업들 중에 가장 빨리 끝난 하나의 결과에 콜백을 실행한다.


ThreadPoolTaskExecutor 설정으로 보다 효과적으로 비동기 처리 하는 방법이 있으므로 정리해보자!