Skip to content

Commit

Permalink
Merge pull request #59 from GPGT-Algorithm-Study/develop
Browse files Browse the repository at this point in the history
[FEAT] 크론잡 실패 시 Retry 기능 추가
  • Loading branch information
fing9 authored Jul 18, 2024
2 parents 1367276 + 6b4a751 commit b8c376e
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 4 deletions.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ dependencies {
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'org.mockito:mockito-inline:3.6.0'

// spring-retry 설정
implementation 'org.springframework.retry:spring-retry'
implementation 'org.springframework:spring-aspects'

// aws s3 설정
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.retry.annotation.EnableRetry;

@EnableRetry
@EnableJpaAuditing
@EnableAspectJAutoProxy
@SpringBootApplication(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.randps.randomdefence.domain.statistics.controller;

import com.randps.randomdefence.domain.statistics.dto.RecentlyTodaySolvedProblemResponseDto;
import com.randps.randomdefence.domain.statistics.service.RecentSolvedProblemService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/stat/recent-solved-problem")
public class RecentSolvedProblemController {

private final RecentSolvedProblemService recentSolvedProblemService;

@GetMapping("/today")
public List<RecentlyTodaySolvedProblemResponseDto> getTodayRecentSolvedProblems() {
return recentSolvedProblemService.getTodayRecentSolvedProblems();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.randps.randomdefence.domain.statistics.dto;

import com.randps.randomdefence.domain.problem.dto.ProblemDto;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@NoArgsConstructor
public class RecentlyTodaySolvedProblemResponseDto {

private LocalDateTime solvedAt;

private String bojHandle;

private String notionId;

private String profileImg;

private String emoji;

private ProblemDto problem;

@Builder
public RecentlyTodaySolvedProblemResponseDto(LocalDateTime solvedAt, String bojHandle, String notionId, String profileImg, String emoji, ProblemDto problem) {
this.solvedAt = solvedAt;
this.bojHandle = bojHandle;
this.notionId = notionId;
this.profileImg = profileImg;
this.emoji = emoji;
this.problem = problem;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.randps.randomdefence.domain.statistics.service;

import com.randps.randomdefence.domain.problem.service.ProblemService;
import com.randps.randomdefence.domain.statistics.dto.RecentlyTodaySolvedProblemResponseDto;
import com.randps.randomdefence.domain.user.domain.User;
import com.randps.randomdefence.domain.user.domain.UserSolvedProblem;
import com.randps.randomdefence.domain.user.service.port.UserRepository;
import com.randps.randomdefence.domain.user.service.port.UserSolvedProblemRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;

@RequiredArgsConstructor
@Service
public class RecentSolvedProblemService {

private final UserSolvedProblemRepository userSolvedProblemRepository;

private final ProblemService problemService;

private final UserRepository userRepository;

/*
* 오늘 해결된 문제를 최신순으로 가져온다.
*/
@Transactional
public List<RecentlyTodaySolvedProblemResponseDto> getTodayRecentSolvedProblems() {

// 오늘 해결된 문제들을 가져온다.
List<UserSolvedProblem> todaySolvedProblems = userSolvedProblemRepository.findAllTodaySolvedProblem();

// 문제들을 최신순으로 정렬한다.
todaySolvedProblems.sort((a, b) -> b.getCreatedDate().compareTo(a.getCreatedDate()));

// 문제들을 최신순으로 정렬한 후, 최신순으로 정렬된 문제들을 RecentlyTodaySolvedProblemResponseDto로 변환한다.
List<RecentlyTodaySolvedProblemResponseDto> results = new ArrayList<>();
for (UserSolvedProblem userSolvedProblem : todaySolvedProblems) {
User user = userRepository.findByBojHandle(userSolvedProblem.getBojHandle())
.orElseThrow(() -> new IllegalArgumentException("해당하는 유저가 없습니다."));

RecentlyTodaySolvedProblemResponseDto userSolvedDto = RecentlyTodaySolvedProblemResponseDto.builder()
.solvedAt(userSolvedProblem.getCreatedDate())
.bojHandle(user.getBojHandle())
.notionId(user.getNotionId())
.profileImg(user.getProfileImg())
.emoji(user.getEmoji())
.problem(problemService.findProblem(userSolvedProblem.getProblemId()))
.build();
results.add(userSolvedDto);
}

return results;
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.randps.randomdefence.domain.user.infrastructure;

import com.randps.randomdefence.domain.user.domain.UserSolvedProblem;
import org.springframework.data.jpa.repository.JpaRepository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserSolvedProblemJpaRepository extends JpaRepository<UserSolvedProblem, Long> {
List<UserSolvedProblem> findAllByBojHandle(String bojHandle);

Optional<UserSolvedProblem> findByBojHandleAndProblemId(String bojHandle, Integer problemId);

List<UserSolvedProblem> findAllByCreatedDateAfter(LocalDateTime createdDate);

void deleteAllByBojHandle(String bojHandle);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

import com.randps.randomdefence.domain.user.domain.UserSolvedProblem;
import com.randps.randomdefence.domain.user.service.port.UserSolvedProblemRepository;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

import static com.randps.randomdefence.global.component.crawler.BojWebCrawler.is6AmAfter;

@Repository
@RequiredArgsConstructor
public class UserSolvedProblemRepositoryAdapter implements UserSolvedProblemRepository {
Expand All @@ -33,6 +37,21 @@ public List<UserSolvedProblem> saveAll(List<UserSolvedProblem> userSolvedProblem
return userSolvedProblemJpaRepository.saveAll(userSolvedProblems);
}

@Override
public List<UserSolvedProblem> findAllTodaySolvedProblem() {
// 오늘의 기준을 만든다.
LocalDateTime now = LocalDateTime.now();
LocalDateTime startOfDateTime;
if (is6AmAfter(now.getHour())) {
startOfDateTime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 6, 0, 0);
} else {
now = now.minusDays(1);
startOfDateTime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 6, 0, 0);
}

return userSolvedProblemJpaRepository.findAllByCreatedDateAfter(startOfDateTime);
}

@Override
public void deleteAllByBojHandle(String bojHandle) {
userSolvedProblemJpaRepository.deleteAllByBojHandle(bojHandle);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.randps.randomdefence.domain.user.service.port;

import com.randps.randomdefence.domain.user.domain.UserSolvedProblem;

import java.util.List;
import java.util.Optional;

Expand All @@ -11,6 +12,8 @@ public interface UserSolvedProblemRepository {
List<UserSolvedProblem> findAll();
List<UserSolvedProblem> saveAll(List<UserSolvedProblem> userSolvedProblems);

List<UserSolvedProblem> findAllTodaySolvedProblem();

void deleteAllByBojHandle(String bojHandle);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@
import com.randps.randomdefence.domain.user.service.UserSolvedProblemService;
import com.randps.randomdefence.global.aws.s3.service.S3BatchService;
import com.randps.randomdefence.global.component.util.CrawlingLock;
import javax.transaction.Transactional;
import lombok.Builder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import javax.transaction.Transactional;

@Slf4j
@Builder
@RequiredArgsConstructor
Expand Down Expand Up @@ -79,6 +82,11 @@ public void everyTermJob() throws JsonProcessingException {
/*
* 정해진 시간마다 실행되는 스크래핑 메서드 (하루 간격, 매일 새벽 6시 25분)
*/
@Retryable(
include = {Exception.class}, // 모든 Exception에 대해 재시도
maxAttempts = 3, // 최대 3번 재시도
backoff = @Backoff(delay = 300000) // 5분 뒤 재시도
)
@Transactional
@Scheduled(cron = "0 25 6 * * *")
public void everyDayTermJob() throws JsonProcessingException {
Expand All @@ -104,6 +112,11 @@ public void everyDayTermJob() throws JsonProcessingException {
/*
* 주간 초기화 메서드 (매 주 월요일 새벽 6시 26분)
*/
@Retryable(
include = {Exception.class}, // 모든 Exception에 대해 재시도
maxAttempts = 5, // 최대 5번 재시도
backoff = @Backoff(delay = 300000) // 5분 뒤 재시도
)
@Transactional
@Scheduled(cron = "0 26 6 * * 1")
public void weekInitJob() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.randps.randomdefence.domain.user.domain.UserSolvedProblem;
import com.randps.randomdefence.domain.user.service.port.UserSolvedProblemRepository;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -61,6 +62,11 @@ public List<UserSolvedProblem> saveAll(List<UserSolvedProblem> userSolvedProblem
return result;
}

@Override
public List<UserSolvedProblem> findAllTodaySolvedProblem() {
return List.of();
}

@Override
public void deleteAllByBojHandle(String bojHandle) {
data.removeIf(item -> item.getBojHandle().equals(bojHandle));
Expand Down

0 comments on commit b8c376e

Please sign in to comment.