Skip to content

Commit

Permalink
Merge pull request #221 from softeerbootcamp4th/feature/#203-rush-eve…
Browse files Browse the repository at this point in the history
…nt-apply-stress-test

Feature/#203 rush event apply stress test
  • Loading branch information
wjddn2165 authored Aug 22, 2024
2 parents 9a37d85 + f1847ec commit 5c231e9
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import JGS.CasperEvent.domain.event.dto.ResponseDto.lotteryEventResponseDto.CasperBotResponseDto;
import JGS.CasperEvent.domain.event.dto.ResponseDto.lotteryEventResponseDto.LotteryEventResponseDto;
import JGS.CasperEvent.domain.event.dto.ResponseDto.lotteryEventResponseDto.LotteryParticipantResponseDto;
import JGS.CasperEvent.domain.event.service.redisService.RedisService;
import JGS.CasperEvent.domain.event.service.redisService.LotteryEventRedisService;
import JGS.CasperEvent.domain.event.service.eventService.LotteryEventService;
import JGS.CasperEvent.global.entity.BaseUser;
import io.swagger.v3.oas.annotations.Operation;
Expand All @@ -31,12 +31,12 @@
public class LotteryEventController {

private final LotteryEventService lotteryEventService;
private final RedisService redisService;
private final LotteryEventRedisService lotteryEventRedisService;

@Autowired
public LotteryEventController(LotteryEventService lotteryEventService, RedisService redisService) {
public LotteryEventController(LotteryEventService lotteryEventService, LotteryEventRedisService lotteryEventRedisService) {
this.lotteryEventService = lotteryEventService;
this.redisService = redisService;
this.lotteryEventRedisService = lotteryEventRedisService;
}

@Operation(summary = "추첨 이벤트 조회", description = "현재 진행 중인 추첨 이벤트의 정보를 조회합니다.")
Expand Down Expand Up @@ -88,6 +88,6 @@ public ResponseEntity<LotteryParticipantResponseDto> getLotteryParticipant(HttpS
@GetMapping("/caspers")
public ResponseEntity<List<CasperBotResponseDto>> getCasperBots() {
return ResponseEntity.status(HttpStatus.OK)
.body(redisService.getRecentData());
.body(lotteryEventRedisService.getRecentData());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import JGS.CasperEvent.domain.event.entity.participants.LotteryParticipants;
import JGS.CasperEvent.domain.event.repository.CasperBotRepository;
import JGS.CasperEvent.domain.event.repository.participantsRepository.LotteryParticipantsRepository;
import JGS.CasperEvent.domain.event.service.redisService.RedisService;
import JGS.CasperEvent.domain.event.service.redisService.LotteryEventRedisService;
import JGS.CasperEvent.global.entity.BaseUser;
import JGS.CasperEvent.global.enums.CustomErrorCode;
import JGS.CasperEvent.global.error.exception.CustomException;
Expand Down Expand Up @@ -37,7 +37,7 @@ public class LotteryEventService {
private final UserRepository userRepository;
private final LotteryParticipantsRepository lotteryParticipantsRepository;
private final CasperBotRepository casperBotRepository;
private final RedisService redisService;
private final LotteryEventRedisService lotteryEventRedisService;
private final SecretKey secretKey;
private final EventCacheService eventCacheService;

Expand All @@ -57,7 +57,7 @@ public CasperBotResponseDto postCasperBot(BaseUser user, CasperBotRequestDto cas
}

CasperBotResponseDto casperBotDto = CasperBotResponseDto.of(casperBot);
redisService.addData(casperBotDto);
lotteryEventRedisService.addData(casperBotDto);

return casperBotDto;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
import JGS.CasperEvent.domain.event.repository.eventRepository.RushEventRepository;
import JGS.CasperEvent.domain.event.repository.eventRepository.RushOptionRepository;
import JGS.CasperEvent.domain.event.repository.participantsRepository.RushParticipantsRepository;
import JGS.CasperEvent.domain.event.service.redisService.RushEventRedisService;
import JGS.CasperEvent.global.entity.BaseUser;
import JGS.CasperEvent.global.enums.CustomErrorCode;
import JGS.CasperEvent.global.enums.Position;
import JGS.CasperEvent.global.error.exception.CustomException;
import JGS.CasperEvent.global.util.RepositoryErrorHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -31,6 +31,7 @@ public class RushEventService {
private final RushParticipantsRepository rushParticipantsRepository;
private final RushOptionRepository rushOptionRepository;
private final EventCacheService eventCacheService;
private final RushEventRedisService rushEventRedisService;

@Transactional
public RushEventListResponseDto getAllRushEvents() {
Expand Down Expand Up @@ -83,6 +84,9 @@ public void apply(BaseUser user, int optionId) {
// eventId 를 이용하여 rushEvent 를 꺼냄
RushEvent rushEvent = RepositoryErrorHandler.findByIdOrElseThrow(rushEventRepository, todayEventId, CustomErrorCode.NO_RUSH_EVENT);

// redis incr 호출
rushEventRedisService.incrementOptionCount(todayEventId, optionId);

// 새로운 RushParticipants 를 생성하여 DB 에 저장
RushParticipants rushParticipants = new RushParticipants(user, rushEvent, optionId);
rushParticipantsRepository.save(rushParticipants);
Expand All @@ -93,8 +97,13 @@ public RushEventRateResponseDto getRushEventRate(BaseUser user) {
LocalDate today = LocalDate.now();
Long todayEventId = eventCacheService.getTodayEvent(today).rushEventId();
Optional<Integer> optionId = rushParticipantsRepository.getOptionIdByUserId(user.getPhoneNumber());
long leftOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(todayEventId, 1);
long rightOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(todayEventId, 2);

// long leftOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(todayEventId, 1);
// long rightOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(todayEventId, 2);

// redis 에 캐싱 값 가져옴
long leftOptionCount = rushEventRedisService.getOptionCount(todayEventId, 1);
long rightOptionCount = rushEventRedisService.getOptionCount(todayEventId, 2);

return new RushEventRateResponseDto(
optionId.orElseThrow(() -> new CustomException("유저가 응모한 선택지가 존재하지 않습니다.", CustomErrorCode.USER_NOT_FOUND)),
Expand Down Expand Up @@ -227,6 +236,7 @@ public void setRushEvents() {

eventCacheService.setCacheValue(LocalDate.now());
eventCacheService.setAllRushEvent();
rushEventRedisService.clearAllrushEventRate();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
import java.util.List;

@Service
public class RedisService {
public class LotteryEventRedisService {
private static final String LIST_KEY = "recentData";
private static final int MAX_SIZE = 100;

private final RedisTemplate<String, CasperBotResponseDto> redisTemplate;

@Autowired
public RedisService(RedisTemplate<String, CasperBotResponseDto> redisTemplate) {
public LotteryEventRedisService(RedisTemplate<String, CasperBotResponseDto> redisTemplate) {
this.redisTemplate = redisTemplate;
}

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

import JGS.CasperEvent.domain.event.repository.participantsRepository.RushParticipantsRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Set;

@Service
@RequiredArgsConstructor
public class RushEventRedisService {

private final RedisTemplate<String, String> redisTemplate;
private final RushParticipantsRepository rushParticipantsRepository;

public Long getOptionCount(Long eventId, int optionId) {
String redisKey = getRedisKey(eventId, optionId);

// Redis에서 값 조회
String cachedCount = redisTemplate.opsForValue().get(redisKey);

if (cachedCount != null) {
// Redis에 값이 있으면 캐시된 값 반환
return Long.valueOf(cachedCount);
} else {
// Redis에 값이 없으면 DB에서 값 조회
long countFromDb = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(eventId, optionId);

// 조회한 값을 Redis에 저장
redisTemplate.opsForValue().set(redisKey, String.valueOf(countFromDb));

return countFromDb;
}
}

public void incrementOptionCount(Long eventId, int optionId) {
String redisKey = getRedisKey(eventId, optionId);

// Redis에서 해당 키의 값을 증가시킴
redisTemplate.opsForValue().increment(redisKey);
}

private String getRedisKey(Long eventId, int optionId) {
return "rushEvent:" + eventId + ":option:" + optionId;
}

public void clearAllrushEventRate() {
// 특정 rushEventId에 대한 모든 옵션 키들을 가져와 삭제
String pattern = "rushEvent:*" + ":option:*";
Set<String> keys = redisTemplate.keys(pattern);
if (keys != null && !keys.isEmpty()) {
redisTemplate.delete(keys);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class BaseUser extends BaseEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;

@Column(unique = true)
String phoneNumber;
Role role;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import JGS.CasperEvent.domain.event.entity.participants.LotteryParticipants;
import JGS.CasperEvent.domain.event.service.adminService.AdminService;
import JGS.CasperEvent.domain.event.service.eventService.LotteryEventService;
import JGS.CasperEvent.domain.event.service.redisService.RedisService;
import JGS.CasperEvent.domain.event.service.redisService.LotteryEventRedisService;
import JGS.CasperEvent.global.entity.BaseUser;
import JGS.CasperEvent.global.enums.Role;
import JGS.CasperEvent.global.jwt.service.UserService;
Expand All @@ -23,7 +23,6 @@
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
Expand Down Expand Up @@ -54,7 +53,7 @@ class LotteryEventControllerTest {
@MockBean
private AdminService adminService;
@MockBean
private RedisService redisService;
private LotteryEventRedisService lotteryEventRedisService;

private BaseUser user;
private String phoneNumber;
Expand Down Expand Up @@ -192,7 +191,7 @@ void getCasperBotsSuccessTest() throws Exception {
for (int i = 0; i < 100; i++) {
recentData.add(casperBotResponse);
}
given(redisService.getRecentData())
given(lotteryEventRedisService.getRecentData())
.willReturn(recentData);

//when
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import JGS.CasperEvent.domain.event.repository.CasperBotRepository;
import JGS.CasperEvent.domain.event.repository.eventRepository.LotteryEventRepository;
import JGS.CasperEvent.domain.event.repository.participantsRepository.LotteryParticipantsRepository;
import JGS.CasperEvent.domain.event.service.redisService.RedisService;
import JGS.CasperEvent.domain.event.service.redisService.LotteryEventRedisService;
import JGS.CasperEvent.global.entity.BaseUser;
import JGS.CasperEvent.global.enums.CustomErrorCode;
import JGS.CasperEvent.global.enums.Role;
Expand Down Expand Up @@ -52,7 +52,7 @@ class LotteryEventServiceTest {
@Mock
private CasperBotRepository casperBotRepository;
@Mock
private RedisService redisService;
private LotteryEventRedisService lotteryEventRedisService;


@InjectMocks
Expand Down

0 comments on commit 5c231e9

Please sign in to comment.