Skip to content

Commit

Permalink
Merge pull request #144 from softeerbootcamp4th/feature/143-fix-sched…
Browse files Browse the repository at this point in the history
…uler

[fix] 스케줄러 의도대로 동작하지 않는 버그 수정 (#143)
  • Loading branch information
win-luck authored Aug 23, 2024
2 parents 4a7cf09 + 564da2f commit dd75b82
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import lombok.RequiredArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

Expand All @@ -15,13 +17,15 @@
@Component
public class FcfsScheduler {

private static final Logger log = LoggerFactory.getLogger(FcfsScheduler.class);
// 분산 환경에서 메서드가 여러 번 실행되는 것을 방지하기 위해 분산 락 도입
private final RedissonClient redissonClient;
private final FcfsManageService fcfsManageService;

// 매일 자정 1분마다 실행되며, 오늘의 선착순 이벤트에 대한 정보를 DB에서 Redis로 이동시킨다.
@Scheduled(cron = "0 1 0 * * *")
public void registerFcfsEvents() {
log.info("Move the information of FCFS Events from DB to Redis");
RLock lock = redissonClient.getLock(ConstantUtil.DB_TO_REDIS_LOCK);
try {
// 5분동안 락 점유
Expand All @@ -40,6 +44,7 @@ public void registerFcfsEvents() {
// 매일 자정마다 실행되며, 선착순 이벤트 당첨자들을 Redis에서 DB로 이동시킨다.
@Scheduled(cron = "0 0 0 * * *")
public void registerWinners() {
log.info("Move the result of FCFS Events from Redis to DB");
RLock lock = redissonClient.getLock(ConstantUtil.REDIS_TO_DB_LOCK);
try {
// 5분동안 락 점유
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,38 +49,44 @@ public void registerFcfsEvents() {
// redis에 저장된 모든 선착순 이벤트의 당첨자 정보를 DB로 이관
@Transactional
public void registerWinners() {
Set<String> fcfsIds = stringRedisTemplate.keys("*:count");
if (fcfsIds == null || fcfsIds.isEmpty()) {
Set<String> fcfsKeys = stringRedisTemplate.keys("*:count");
if (fcfsKeys == null || fcfsKeys.isEmpty()) {
log.info("There are no FCFS events in yesterday");
return;
}

for(String fcfsId : fcfsIds) {
String eventId = fcfsId.replace(":count", "").replace("fcfs:", "");
Set<String> userIds = stringRedisTemplate.opsForZSet().range(FcfsUtil.winnerFormatting(eventId), 0, -1);
// 당첨자 관련 정보 조합하여 Entity 생성
log.info("keys for FCFS Events: {}", fcfsKeys);
for(String key : fcfsKeys) {
String fcfsEventId = key.replace(":count", "").replace("fcfs:", "");
Set<String> userIds = stringRedisTemplate.opsForZSet().range(FcfsUtil.winnerFormatting(fcfsEventId), 0, -1);
if(userIds == null || userIds.isEmpty()) {
return;
log.info("No winners in FCFS Event {}", fcfsEventId);
continue;
}

FcfsEvent event = fcfsEventRepository.findById(Long.parseLong(eventId))
FcfsEvent event = fcfsEventRepository.findById(Long.parseLong(fcfsEventId))
.orElseThrow(() -> new FcfsEventException(ErrorCode.FCFS_EVENT_NOT_FOUND));

List<EventUser> users = eventUserRepository.findAllByUserId(userIds.stream().toList());
List<FcfsEventWinningInfo> winningInfos = users
.stream()
.map(user -> FcfsEventWinningInfo.of(event, user, getTimeFromScore(stringRedisTemplate.opsForZSet().score(FcfsUtil.winnerFormatting(eventId), user.getUserId()))))
.map(user -> FcfsEventWinningInfo.of(event, user, getTimeFromScore(stringRedisTemplate.opsForZSet().score(FcfsUtil.winnerFormatting(fcfsEventId), user.getUserId()))))
.toList();

log.info("Winners of FCFS event {} were registered in DB", fcfsEventId);
fcfsEventWinningInfoRepository.saveAll(winningInfos);
deleteEventInfo(eventId);
deleteEventInfo(fcfsEventId);
}

// PK를 간접적으로 보관하던 eventId 제거
Set<String> eventIds = stringRedisTemplate.keys("*:eventId");
if(eventIds != null && !eventIds.isEmpty()) {
for(String eventId : eventIds) {
stringRedisTemplate.delete(eventId);
}
}
log.info("Winners of all FCFS events were registered in DB");
log.info("Registering winners of FCFS events in DB is completed");
}

// 특정 선착순 이벤트의 정보 조회
Expand Down

0 comments on commit dd75b82

Please sign in to comment.