You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
회원 탈퇴 시, 회원의 출발 알림 스케줄링 취소 -> 회원 탈퇴시 출발 알림이 다른 사람에게 전송되는 문제 해결
약속방 나가기 기능이 없어서, 탈퇴만 고려했어요.
탈퇴한 회원의 출발 알림 스케줄링만 취소하는 이유
현재 스케줄링은(eta notice, departure reminder) 모두에게 발송되는 메시지(GroupMessage) 예약만 걸고 있어요.
따라서, 예약 메시지 스케줄링을 취소하는 경우는 2가지 입니다.
(1) eta notice 취소 - 조건 : eta 오픈 시간 전 + 참여자 0명 <- 알림 DB에 저장X
(2) departure reminder 취소 - 조건 : 출발알림 시간 전 + 해당 회원의 탈퇴 <- 알림이 DB에 저장O
(1) 스케줄링 취소 구현하지 않는 이유(일단보류..)
회원 탈퇴 시, fcmTopic 구독 해지하기 때문에 불필요한 알림이 가는 문제는 없어요.
스프링이 꺼지면 해당 다시 스케줄링 되지 않고 있어요.(이게 맞나?)
지금 구조에선 eta 오픈 전 모든 참여자가 탈퇴하는 경우가 발생할 순 있지만, 특수한 경우라고 판단했어요. Q. 다들 어떻게 생각하시나요?
(2) 구현 방법
1. 예약된 스케줄링 취소
taskScheduler.schedule() 후 반환되는 ScheduledFuture 객체 저장
scheduledFuture.cancel()로 취소 가능
저장을 위해 캐싱 사용
장점: 스케줄링 낭비 리소스 제거 가능, DB를 거치지 않고 작업 가능
단점: 취소를 위해 객체를 들고 있어야 함. 스케줄링 취소가 누락되면 알림이 갈 수 있음
MessageScheduler
package com.ody.meeting.service;
import com.ody.notification.domain.message.GroupMessage;
import com.ody.notification.service.FcmPushSender;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Slf4j
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MessageScheduler {
private static final Map<GroupMessage, ScheduledFuture<?>> SCHEDULED_GROUP_MESSAGES = new ConcurrentHashMap<>();
private final TaskScheduler taskScheduler;
private final FcmPushSender fcmPushSender;
public void scheduleGroupMessage(GroupMessage groupMessage, Instant startTime) {
ScheduledFuture<?> scheduled = taskScheduler.schedule(
() -> fcmPushSender.sendNoticeMessage(groupMessage), startTime
);
SCHEDULED_GROUP_MESSAGES.put(groupMessage, scheduled);
}
public int cancelAllGroupMessages(long meetingId) {
List<GroupMessage> groupMessages = SCHEDULED_GROUP_MESSAGES.keySet().stream()
.filter(groupMessage -> groupMessage.meetingId() == meetingId)
.toList();
groupMessages.forEach(groupMessage -> SCHEDULED_GROUP_MESSAGES.remove(groupMessage).cancel(true));
log.info("스케줄링 취소 - meetingId={}의 {}개 그룹 메시지 스케줄링 취소", meetingId, groupMessages.size());
return groupMessages.size();
}
}
fcm 알림 보낼 때, Notification Status=DISMISSED 이면 발송 하지 않기
장점: 스케줄링 객체를 저장하지 않고 있어도 됨. 간단함
단점: 푸시 알림을 보낼 때마다 DB를 조회해야 함
참고) noti 로직이 헷갈려서 정리했어요
The text was updated successfully, but these errors were encountered:
📝 작업 내용
회원 탈퇴 시, 회원의 출발 알림 스케줄링 취소-> 회원 탈퇴시 출발 알림이 다른 사람에게 전송되는 문제 해결탈퇴한 회원의 출발 알림 스케줄링만 취소하는 이유
eta notice
,departure reminder
) 모두에게 발송되는 메시지(GroupMessage
) 예약만 걸고 있어요.(1)
eta notice
취소 - 조건 :eta 오픈 시간 전 + 참여자 0명
<- 알림 DB에 저장X(2)
departure reminder
취소 - 조건 :출발알림 시간 전 + 해당 회원의 탈퇴
<- 알림이 DB에 저장O(1) 스케줄링 취소 구현하지 않는 이유(일단보류..)
Q. 다들 어떻게 생각하시나요?
(2) 구현 방법
1. 예약된 스케줄링 취소
taskScheduler.schedule()
후 반환되는ScheduledFuture
객체 저장scheduledFuture.cancel()
로 취소 가능장점: 스케줄링 낭비 리소스 제거 가능, DB를 거치지 않고 작업 가능
단점: 취소를 위해 객체를 들고 있어야 함. 스케줄링 취소가 누락되면 알림이 갈 수 있음
MessageScheduler
장점: 스케줄링 객체를 저장하지 않고 있어도 됨. 간단함
단점: 푸시 알림을 보낼 때마다 DB를 조회해야 함
참고) noti 로직이 헷갈려서 정리했어요
The text was updated successfully, but these errors were encountered: