Skip to content

Commit

Permalink
Merge pull request #195 from softeerbootcamp4th/feature/#194-local-cache
Browse files Browse the repository at this point in the history
Feature/#194 local cache
  • Loading branch information
k000927 authored Aug 20, 2024
2 parents 3ac281d + 7872f39 commit c0ae510
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 232 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableAspectJAutoProxy
@EnableScheduling
@EnableCaching
public class CasperEventApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public ResponseEntity<RushEventResultResponseDto> rushEventResult(HttpServletReq
@ApiResponse(responseCode = "204", description = "Successfully set today's event in Redis.")
@GetMapping("/today/test")
public ResponseEntity<Void> setTodayEvent() {
rushEventService.setTodayEventToRedis();
rushEventService.setRushEvents();
return ResponseEntity.noContent().build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package JGS.CasperEvent.domain.event.service.eventService;

import JGS.CasperEvent.domain.event.dto.ResponseDto.rushEventResponseDto.RushEventResponseDto;
import JGS.CasperEvent.domain.event.entity.event.RushEvent;
import JGS.CasperEvent.domain.event.repository.eventRepository.RushEventRepository;
import JGS.CasperEvent.global.enums.CustomErrorCode;
import JGS.CasperEvent.global.error.exception.CustomException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;

@Service
@RequiredArgsConstructor
@Slf4j
public class RushEventCacheService {

private final RushEventRepository rushEventRepository;

@Cacheable(value = "todayEventCache", key = "#today")
public RushEventResponseDto getTodayEvent(LocalDate today) {
log.info("오늘의 이벤트 캐싱 {}", today);
// 오늘 날짜에 해당하는 모든 이벤트 꺼내옴
List<RushEvent> rushEventList = rushEventRepository.findByEventDate(today);

if (rushEventList.isEmpty()) {
throw new CustomException("선착순 이벤트가 존재하지않습니다.", CustomErrorCode.NO_RUSH_EVENT);
}

if (rushEventList.size() > 1) {
throw new CustomException("선착순 이벤트가 2개 이상 존재합니다.", CustomErrorCode.MULTIPLE_RUSH_EVENTS_FOUND);
}

return RushEventResponseDto.of(rushEventList.get(0));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import JGS.CasperEvent.global.error.exception.CustomException;
import JGS.CasperEvent.global.util.RepositoryErrorHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -29,13 +28,15 @@
public class RushEventService {
private final RushEventRepository rushEventRepository;
private final RushParticipantsRepository rushParticipantsRepository;
private final RedisTemplate<String, RushEventResponseDto> rushEventRedisTemplate;
private final RushOptionRepository rushOptionRepository;
private final RushEventCacheService rushEventCacheService;

@Transactional
public RushEventListResponseDto getAllRushEvents() {
LocalDate today = LocalDate.now();

// 오늘의 선착순 이벤트 꺼내오기
RushEventResponseDto todayEvent = getTodayRushEventFromRedis();
RushEventResponseDto todayEvent = rushEventCacheService.getTodayEvent(today);

// DB에서 모든 RushEvent 가져오기
List<RushEvent> rushEventList = rushEventRepository.findAll();
Expand Down Expand Up @@ -67,13 +68,15 @@ public RushEventListResponseDto getAllRushEvents() {

// 응모 여부 조회
public boolean isExists(String userId) {
Long todayEventId = getTodayRushEventFromRedis().rushEventId();
LocalDate today = LocalDate.now();
Long todayEventId = rushEventCacheService.getTodayEvent(today).rushEventId();
return rushParticipantsRepository.existsByRushEvent_RushEventIdAndBaseUser_Id(todayEventId, userId);
}

@Transactional
public void apply(BaseUser user, int optionId) {
Long todayEventId = getTodayRushEventFromRedis().rushEventId();
LocalDate today = LocalDate.now();
Long todayEventId = rushEventCacheService.getTodayEvent(today).rushEventId();

// 이미 응모한 회원인지 검증
if (rushParticipantsRepository.existsByRushEvent_RushEventIdAndBaseUser_Id(todayEventId, user.getId())) {
Expand All @@ -90,7 +93,8 @@ public void apply(BaseUser user, int optionId) {

// 진행중인 게임의 응모 비율 반환
public RushEventRateResponseDto getRushEventRate(BaseUser user) {
Long todayEventId = getTodayRushEventFromRedis().rushEventId();
LocalDate today = LocalDate.now();
Long todayEventId = rushEventCacheService.getTodayEvent(today).rushEventId();
Optional<Integer> optionId = rushParticipantsRepository.getOptionIdByUserId(user.getId());
long leftOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(todayEventId, 1);
long rightOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(todayEventId, 2);
Expand All @@ -104,7 +108,8 @@ public RushEventRateResponseDto getRushEventRate(BaseUser user) {
// 응모하지 않은 유저가 요청하는 경우가 존재 -> 응모 비율만 반환하도록 수정
@Transactional
public RushEventResultResponseDto getRushEventResult(BaseUser user) {
RushEventResponseDto todayRushEvent = getTodayRushEventFromRedis();
LocalDate today = LocalDate.now();
RushEventResponseDto todayRushEvent = rushEventCacheService.getTodayEvent(today);
Long todayEventId = todayRushEvent.rushEventId();

// 최종 선택 비율을 조회
Expand Down Expand Up @@ -157,39 +162,8 @@ public RushEventResultResponseDto getRushEventResult(BaseUser user) {
return new RushEventResultResponseDto(optionId, leftOption, rightOption, rank, totalParticipants, isWinner);
}

// 오늘의 이벤트를 DB에 꺼내서 반환
public RushEventResponseDto getTodayRushEventFromRDB() {
LocalDate today = LocalDate.now();

// 오늘 날짜에 해당하는 모든 이벤트 꺼내옴
List<RushEvent> rushEventList = rushEventRepository.findByEventDate(today);

if (rushEventList.isEmpty()) {
throw new CustomException("선착순 이벤트가 존재하지않습니다.", CustomErrorCode.NO_RUSH_EVENT);
}

if (rushEventList.size() > 1) {
throw new CustomException("선착순 이벤트가 2개 이상 존재합니다.", CustomErrorCode.MULTIPLE_RUSH_EVENTS_FOUND);
}

return RushEventResponseDto.of(rushEventList.get(0));
}

// 오늘의 이벤트 꺼내오기
private RushEventResponseDto getTodayRushEventFromRedis() {
RushEventResponseDto todayEvent = rushEventRedisTemplate.opsForValue().get("todayEvent");

// Redis에 오늘의 이벤트가 없으면 DB에서 가져와서 Redis에 저장한 후 반환.
if (todayEvent == null) {
todayEvent = getTodayRushEventFromRDB();
rushEventRedisTemplate.opsForValue().set("todayEvent", todayEvent);
}

return todayEvent;
}

@Transactional
public void setTodayEventToRedis() {
public void setRushEvents() {
// 테이블 초기화
rushParticipantsRepository.deleteAllInBatch();
rushOptionRepository.deleteAllInBatch();
Expand Down Expand Up @@ -253,15 +227,13 @@ public void setTodayEventToRedis() {

rushEvents.add(rushEvent);
}

// 세 번째로 생성된 RushEvent를 Redis에 저장
rushEventRedisTemplate.opsForValue().set("todayEvent", RushEventResponseDto.of(rushEvents.get(2)));
}


// 오늘의 이벤트 옵션 정보를 반환
public MainRushEventOptionsResponseDto getTodayRushEventOptions() {
RushEventResponseDto todayEvent = getTodayRushEventFromRedis();
LocalDate today = LocalDate.now();
RushEventResponseDto todayEvent = rushEventCacheService.getTodayEvent(today);
Set<RushEventOptionResponseDto> options = todayEvent.options();

RushEventOptionResponseDto leftOption = options.stream()
Expand All @@ -282,7 +254,8 @@ public MainRushEventOptionsResponseDto getTodayRushEventOptions() {

public ResultRushEventOptionResponseDto getRushEventOptionResult(int optionId) {
Position position = Position.of(optionId);
RushEventResponseDto todayEvent = getTodayRushEventFromRedis();
LocalDate today = LocalDate.now();
RushEventResponseDto todayEvent = rushEventCacheService.getTodayEvent(today);
Set<RushEventOptionResponseDto> options = todayEvent.options();

if (options.size() != 2) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package JGS.CasperEvent.global.config;

import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CacheConfig {

@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("todayEventCache");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,4 @@ public RedisTemplate<String, CasperBotResponseDto> CasperBotRedisTemplate(){
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}

@Bean
public RedisTemplate<String, RushEventResponseDto> RushEventRedisTemplate(){
RedisTemplate<String, RushEventResponseDto> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}
}

This file was deleted.

Loading

0 comments on commit c0ae510

Please sign in to comment.