Kakao API의 일일 쿼터는 10만회이다.

내 데이터 기준 960개의 라이드를 가지진 사람이 약 28000회의 API 조회가 필요한 것을 생각하면 매우 적은 쿼터이긴 하다. 뭐 근데 이걸 늘릴수는 없는거니까

아무튼 API 쿼터 이상의 호출을 하게 되면 http 409 에러가 발생하게 된다. 이 에러가 발생하게 되면 해당 유저의 Location Mapping 작업이 중단된다. 이 중단시점은 언제 발생할 지 알 수 없으며 중단되기 까지의 진행상황이 전부 날라가게된다.

예를 들어 20000번의 API조회가 필요한 유저의 데이터를 처리하던 도중 18000번째에서 API의 쿼터를 넘어서 에러가 발생한 경우 전부 다 날아가고 쿼터가 초기화 된 이후 다시 시도하면 처음부터 다시 20000번 조회해야 하는 것이다.

이런 불편함을 방지하기 위해서 만약 409에러가 발생하게 되면 그때 까지의 작업과정을 저장하고 다시 API 쿼터가 초기화 되는 00시에 이 작업을 다시 이어서 하는 기능을 추가한다.


우선 여러모로 테스트등의 용이성을 위해 KakaoAPI를 호출하는 로직을 별도의 클래스로 분리했다.

private HashMap<String, Object> parallelProcessing(List<Ride> rideList){
        log.info("{} ~ {} ride data assigned in {}.   DataSize : {}   processing start", rideList.get(0).getStart_date_local(), rideList.get(rideList.size()-1).getStart_date_local(), Thread.currentThread().getName(), rideList.size());
        HashMap<String, Object> hashMap = new HashMap<>();

        int position = 0;

        HashSet<String> hashSet = new HashSet<>();

        try {
            for(Ride ride : rideList){
                position = rideList.indexOf(ride);
                String polyline = ride.getSummary_polyline();
                HashSet<String> location;
                if(polyline.equals("")) continue;
                try{
                    location = getAddress(polyline);
                } catch (StringIndexOutOfBoundsException e){
                    continue;
                }
                log.info("rideName : {} complete. ", ride.getName());
                hashSet.addAll(location);
            }
        } catch (WebClientResponseException e){
            log.info("kakao api request capacity full");

            hashMap.put("result", hashSet);
            hashMap.put("status", "exception");
            hashMap.put("remain", rideList.subList(position, rideList.size()));
            return hashMap;
        }
        hashMap.put("result", hashSet);
        hashMap.put("status", "finish");
        log.info("{} ~ {} ride data processing complete.  {} ", rideList.get(0).getStart_date_local(), rideList.get(rideList.size()-1).getStart_date_local(), Thread.currentThread().getName());

        return hashMap;
    }

location = getAddress(polyline); 부분이 내부에서 kakaoAPI를 호출하는 부분이다.

parallelProcessing() 메소드는 여러개의 쓰레드에서 각각 부여받은 Ride들의 Polyline에 대해 getAddress()을 수행한다.

기존에는 결과값인 Set<String>의 오브젝트를 리턴했지만 이제는 작업의 진행결과, 상황등의 정보를 전달하기 위해 Map<String, Object>를 리턴하도록 했다.

만약 이때 HTTP 429에러가 발생해 getAddress() 메소드에서 WebClientResponseException가 발생한다면 Map 타입의 오브젝트를 생성해 진행상황을 저장한다.

원래대로라면 DTO 클래스를 만들어서 사용해야 하지만 굳이 여기에서만 쓸 DTO를 따로 만드는 건 지금 시점에서는 과도하다고 생각되어 단순히 Map을 사용하기로 했다.