어떤 과제를 해결하기 위해 의사 결정이 필요했나요?
- 특정한 유저에게 알림을 보내는 기능의 구현 과정에서 문제점이 생겨 이를 해결하기 위한 방식을 계속해서 고민함
의사 결정 과정을 적어주세요.
최종 결정에 대한 근거를 적어주세요.
- 여러 구현 방식을 구상하고 문제점을 보완해나감
- map에 key-로그인한 유저 아이디, value-SseEmitter 넣기 & 뒹글/캐치 등록 시 알림을 보내야 하는 유저 아이디(key)가 map에 있다면 value인 SseEmitter로 데이터 전송
- 문제 : 만약 브라우저를 두 개 이상 연다면 같은 key로 마지막 SseEmitter가 저장되므로 마지막 브라우저에서만 알림을 받을 수 있음
- map에 key-로그인한 유저 아이디+시간, value-SseEmitter 넣기
- 브라우저를 여러 개 열어도 각각의 키로 저장되므로 모두에게 알림을 보낼 수 있음
- 문제 : map의 entrySet에서 일일이 key를 startsWith(유저 아이디)로 찾아야 함
- map에 key-로그인한 유저 아이디, value-list<SseEmitter> 넣기
- 브라우저를 여러 개 열어도 list에 하나씩 저장되므로 모두에게 알림을 보낼 수 있음
- 유저 아이디로 key를 한 번에 찾을 수 있음
- 우리가 구현하려는 특정 유저에게 알림을 전송하는 기능은 3번째 구현 방식으로 충분했음
- 이때 thread-safe한 자료구조인 concurrentHashMap, copyOnWriteArrayList 사용
- 타임아웃 발생 시 브라우저가 재연결 요청을 보내면 Emitter 객체를 다시 생성함. 그래서 onCompletion 콜백에서 자기 자신을 지우도록 해야 함. 문제는 이 콜백이 다른 스레드에서 실행됨.
- thread-safe한 자료구조 사용하지 않으면 ConcurrentModificationException 발생함.