Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- list remove
- 코드포스
- hashcode override
- Spring Aspect
- Java
- github action
- kotest
- lombok Builder
- AWS Codedeploy
- Java lombok
- java 비동기처리
- github deploy
- github ec2 deploy
- github CI
- SpringBootApplication
- java hashCode
- stream groupingby
- vanilla js image slider
- java CompletableFuture
- github action codedeploy
- image slider
- AliasFor
- Java Wrapper Class
- equals
- java stream api
- github CI/CD
- c++ 빌드
- equals override
- javascript image slider
- Github action deploy
Archives
- Today
- Total
기록창고
CompletableFuture 을 이용한 비동기 요청 본문
Spring boot 개인 프로젝트 할 때, 다른 사이트의 API 를 요청해야 할 필요가 있었습니다.
레인보우식스 라는 게임의 Rank 정보를 가져와야 하는데
region와 season을 파라미터로 가지고 있고, region 은 3개, season 1 ~ 17(현재시즌) 까지 조회를 하여
플레이어의 전체 시즌정보를 가져와야했습니다.
하나씩 for 문으로 돌리니 51개의 요청이 생성되고, 응답이 올때까지 기다려야 다음 포문을 실행하기 때문에
응답시간이 되게 오래걸렸습니다
for(int season = 1; season <= currentSeason; season++) {
RankStatDto rankstatDto = ubiApi.getRankStat(platform, id, region, season);
if(rankstatDto.getMaxMmr() == 0 && season != currentSeason) {
continue; // 현재 시즌은 저장하지만, 이전 시즌이 플레이를 안한 경우는 무시
}
RankStat rankStat = new RankStat(rankstatDto, player);
rankRepository.save(rankStat);
player.getRankList().add(rankStat);
}
그래서 요청을 한번에 다 보내고, 모든 요청이 끝나면 종합하는 방식으로 바꿨습니다.
List<CompletableFuture<RankStatDto>> completableFutureList = new ArrayList<>();
for(int season = 1; season <= currentSeason; season++) {
int finalSeason = season;
completableFutureList.add(CompletableFuture.supplyAsync(() -> {
return ubiApi.getRankStat(platform, id, region, finalSeason);
}));
}
CompletableFuture.allOf(completableFutureList.toArray(new CompletableFuture[completableFutureList.size()])).join();
List<RankStatDto> dtoList = completableFutureList.stream().map(CompletableFuture::join).collect(Collectors.toList());
for(RankStatDto dto : dtoList) {
if(dto.getMaxMmr() == 0 && dto.getSeason() != currentSeason) {
// 현재 시즌에 플레이 하지 않더라도 DB 에 저장해놔서, 이 메소드가 검색할 때 마다 호출되는 것을 막음
continue;
}
RankStat rankStat = new RankStat(dto, player);
rankRepository.save(rankStat);
player.getRankList().add(rankStat);
}
한 지역별 시즌을 한번에 요청하는 코드입니다.
supplyAsync 함수를 이용하여 api 호출 결과를 가져옵니다.
allOf 는 List를 받지 않으므로, 배열로 만들어 준다. 그리고 join 을 이용해 모든 비동기처리가 다 되길 기다리고 있습니다.
allOf 의 리턴 Void 이기 때문에, 따로 리턴값을 가지고 있지 않고, List 에 넣어놨던 비동처리가 모든 끝났기 때문에,
자바 스트림을 이용해 결과값을 가져와서 리스트로 만들어준 후, 그 이후 작업을 합니다..
- 비동기처리안에 DB 에 저장하는 코드도 넣을까 생각중입니다..
한번에 요청을 보내니, 약 2초정도가 걸리는데, 기존 20초 이상에서 굉장히 단축된 효과를 볼 수 있었습니다
'JAVA' 카테고리의 다른 글
@Lombok 생성자가 2개에 builder 적용하기 (0) | 2020.06.26 |
---|---|
Java Stream api 를 이용한 파싱 (0) | 2020.06.18 |
기본형과 래퍼 클래스(Wrapper Class) (0) | 2020.02.18 |
String.equals() (0) | 2020.01.19 |
Collectors GroupingBy (0) | 2020.01.16 |
Comments