-
사이드 프로젝트 수행기 (2)사이드 프로젝트 2022. 6. 12. 18:06
이번에 진행했던 부분은
어드민 서버에서 지정된 조건의 유저들에게
푸시 서버로 API 를 호출하면
푸시 서버에서 해당 API를 받아서 단말기로 푸시를 보내는 기능을 구현하였다.
(소스레벨에서는 어드민 모듈과 푸시 모듈로 구성)
푸시 보내는 어드민 화면은 다음과 같다.
푸시 서버는 별도로 구현하였고,
여기서는 위 화면의 '푸시 종류' 중에서 여러 종류 중 '이벤트 전체 알림' 인 경우에 대해 진행하였다.
푸시 서버에서 이벤트 푸시 보내는 경우 내용 소스이다.
// 해당 이벤트 존재하는지 체크 Event event = eventService.findById(requestDTO.getEventId()); List<User> allEventUsers = userService.findAllForEvent(); int successCnt = 0; int failCnt = 0; Exception exception = null; for (User user : allEventUsers) { try { if (user.getProfile().isPushEvent() && user.getProfile().getUserOs() != null && user.getProfile().getUserOs().equals(UserOS.AOS)) { boolean isResult = firebaseCloudMessageService.sendPushMessage(user.getPushToken(), requestDTO.getTitle(), requestDTO.getPushContent(), PushType.EVENT_ALL_USER, requestDTO.getEventId()); if (isResult) { successCnt += 1; } else { failCnt += 1; } Thread.sleep(300); } } catch (IOException e) { failCnt += 1; throw new RuntimeException(e); } catch (InterruptedException e) { failCnt += 1; throw new RuntimeException(e); } catch (Exception e) { failCnt += 1; throw new RuntimeException(e); } } pushHistoryService.updatePushHistory(requestDTO.getPushHistoryId(), successCnt, failCnt); if (failCnt > 0) { throw new RuntimeException(exception); }
처음에 대충 이런식으로 개발 진행했었는데,
동작은 하긴 했지만 보다보니 문제가 좀 보이던게
} catch (IOException e) { failCnt += 1; throw new RuntimeException(e); } catch (InterruptedException e) { failCnt += 1; throw new RuntimeException(e); } catch (Exception e) { failCnt += 1; throw new RuntimeException(e); }
이 부분에 관한 내용이었다.
에러가 발생하게 되면 이 부분에서 문제가 발생하게 될 것인데,
boolean isResult = firebaseCloudMessageService.sendPushMessage(user.getPushToken(), requestDTO.getTitle(), requestDTO.getPushContent(), PushType.EVENT_ALL_USER, requestDTO.getEventId());
위처럼 처리를 하게 되면
문제 발생시 throw new RuntimeException(e); 로 처리하게 되어
failCnt += 1; 연산은 필요가 없어지게 되어 매번 해당 블락에서
불필요하게 pushHistoryService.updatePushHistory() 로 호출하게 되는 문제가 생길 수가 있다.
그래서, 생각해낸 방법은
} catch (IOException e) { failCnt += 1; exception = e; } catch (InterruptedException e) { failCnt += 1; exception = e; } catch (Exception e) { failCnt += 1; exception = e; }
처럼 Exception exception = null; 로 초기화해주고,
에러가 발생한 곳에서 실패 카운트를 + 1 해주고,
어떤 에러인지 파악하기 위한 부분은 exception = e; 로 받아서
해당 로직이 끝난 뒤,
pushHistoryService.updatePushHistory(requestDTO.getPushHistoryId(), successCnt, failCnt); if (failCnt > 0) { throw new RuntimeException(exception); }
해당 푸시 히스토리 값의 성공과 실패 카운트를 업데이트 해준뒤,
실패 카운트가 있는 경우 결과에서 알려주도록 처리하도록 하였다.
* 아직은 유저가 많은 경우에 푸시를 보내는 부분에 대한 처리가 없는 상태인데,
향후에는 스프링에서 제공하는 비동기 메시지 방법이나 카프카 같은걸 사용해서 처리가 필요할 것 같다.
'사이드 프로젝트' 카테고리의 다른 글
사이드 프로젝트 수행기 (3) (1) 2022.06.22 사이드 프로젝트 수행기 (1) (0) 2022.05.29