Skip to content

Commit 71c3462

Browse files
committed
feat: 스케쥴러 및 레디스 로직 수정
1 parent 7927758 commit 71c3462

File tree

5 files changed

+92
-22
lines changed

5 files changed

+92
-22
lines changed
Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,101 @@
11
package cmf.commitField.domain.commit.scheduler;
22

33
import cmf.commitField.domain.commit.sinceCommit.service.CommitCacheService;
4-
import cmf.commitField.domain.commit.sinceCommit.service.GithubService;
4+
import cmf.commitField.domain.commit.totalCommit.service.TotalCommitService;
55
import cmf.commitField.domain.redpanda.RedpandaProducer;
66
import cmf.commitField.domain.user.entity.User;
77
import cmf.commitField.domain.user.repository.UserRepository;
88
import lombok.RequiredArgsConstructor;
99
import lombok.extern.slf4j.Slf4j;
10+
import org.springframework.data.redis.core.StringRedisTemplate;
1011
import org.springframework.scheduling.annotation.Scheduled;
1112
import org.springframework.stereotype.Service;
1213

14+
import java.time.LocalDateTime;
1315
import java.util.List;
16+
import java.util.Set;
17+
import java.util.concurrent.atomic.AtomicInteger;
1418

1519
@Slf4j
1620
@Service
1721
@RequiredArgsConstructor
1822
public class CommitScheduler {
19-
private final GithubService githubService;
23+
private final TotalCommitService totalCommitService;
2024
private final CommitCacheService commitCacheService;
2125
private final RedpandaProducer redpandaProducer;
2226
private final UserRepository userRepository;
23-
27+
private final StringRedisTemplate redisTemplate;
28+
private final AtomicInteger counter = new AtomicInteger(0); // 카운터 변수
2429
@Scheduled(fixedRate = 60000) // 1분마다 실행
2530
public void updateUserCommits() {
31+
// 최근 3시간 이내에 커밋 기록이 없는 유저는 주기적으로 검사하지 않고, 10분에 한 번씩 검사함 -> 전체 검사
32+
// 최근 3시간 이내에 커밋 기록이 있는 유저는 1분에 한번씩 검사함. -> 일부 검사
33+
// Redis에 커밋 기록이 있는 유저를 기록하고, 이 유저들에 한해서만 API를 검색함
34+
// Redis에 저장되지 않은 유저는 1시간에 한 번씩 검사하는 메소드를 실행
35+
// 검사를 실행한 후, 커밋 기록이 갱신된 유저는 반영 후 Redis에 3시간동안 지속되게끔 값을 생성해준다.
2636
log.info("🔍 updateUserCommits 실행중");
27-
List<User> activeUsers = userRepository.findAll(); // 💫 변경 필요, 차후 active 상태인 user만 찾게끔 변경해야 함.
37+
int count = counter.incrementAndGet(); // 실행 횟수 증가
38+
39+
if (count % 10 == 0) {
40+
// 🔹 10분마다 전체 유저 검색
41+
List<User> allUsers = userRepository.findAll();
42+
log.info("🔍 All User Count: {}", allUsers.size());
43+
44+
for (User user : allUsers) {
45+
// 🔹 API에서 해당 유저의 최근 커밋 개수 가져오기
46+
long newCommitCount = totalCommitService.getSeasonCommits(
47+
user.getUsername(),
48+
user.getLastCommitted(),
49+
LocalDateTime.now()
50+
).getTotalCommitContributions();
51+
52+
if (newCommitCount > 0) {
53+
// 🔹 커밋 기록이 있으면 DB, Redis, 메시지 큐 반영
54+
updateCommitData(user, newCommitCount);
55+
}
56+
57+
log.info("🔍 User: {}, Commit Count: {}", user.getUsername(), newCommitCount);
58+
}
59+
} else {
60+
// 🔹 1분마다 Redis에 저장된 유저만 검색
61+
Set<String> activeUsers = redisTemplate.keys("commit_active:*"); // Redis에서 저장된 유저 키 가져오기
62+
log.info("🔍 Active User Count: {}", activeUsers.size());
2863

29-
log.info("🔍 Active User Count: {}", activeUsers.size());
64+
for (String key : activeUsers) {
65+
String username = key.replace("commit_active:", ""); // Redis 키에서 유저명 추출
66+
User user = userRepository.findByUsername(username).orElse(null);
67+
if (user == null) continue;
3068

31-
for (User user : activeUsers) {
32-
Integer cachedCount = commitCacheService.getCachedCommitCount(user.getUsername());
33-
int newCommitCount = githubService.getUserCommitCount(user.getUsername());
69+
// 🔹 API에서 해당 유저의 최근 커밋 개수 가져오기
70+
long newCommitCount = totalCommitService.getSeasonCommits(
71+
user.getUsername(),
72+
user.getLastCommitted(),
73+
LocalDateTime.now()
74+
).getTotalCommitContributions();
3475

35-
log.info("🔍 User: {}, Commit Count: {}", user.getUsername(), newCommitCount);
76+
if (newCommitCount > 0) {
77+
// 🔹 커밋 기록이 있으면 DB, Redis, 메시지 큐 반영
78+
updateCommitData(user, newCommitCount);
79+
}
3680

37-
if (cachedCount == null || cachedCount != newCommitCount) { // 변화가 있을 때만 처리
38-
commitCacheService.updateCachedCommitCount(user.getUsername(), newCommitCount);
39-
redpandaProducer.sendCommitUpdate(user.getUsername(), newCommitCount);
81+
log.info("🔍 Active User: {}, Commit Count: {}", user.getUsername(), newCommitCount);
4082
}
4183
}
4284
}
85+
86+
// 🔹 커밋 기록이 있으면 DB + Redis + 메시지 큐 반영하는 메소드
87+
private void updateCommitData(User user, long newCommitCount) {
88+
// 1️⃣ DB의 lastCommitted 갱신
89+
user.setLastCommitted(LocalDateTime.now());
90+
userRepository.save(user);
91+
92+
// 2️⃣ Redis에 갱신 (3시간 동안 유지)
93+
commitCacheService.updateCachedCommitCount(user.getUsername(), newCommitCount);
94+
95+
// 3️⃣ 레드판다 메시지 전송
96+
redpandaProducer.sendCommitUpdate(user.getUsername(), newCommitCount);
97+
98+
log.info("✅ 커밋 반영 완료 - User: {}, New Commits: {}", user.getUsername(), newCommitCount);
99+
}
100+
43101
}

src/main/java/cmf/commitField/domain/commit/sinceCommit/service/CommitCacheService.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,20 @@ public class CommitCacheService {
1414
private final StringRedisTemplate redisTemplate;
1515

1616
public Integer getCachedCommitCount(String username) {
17-
log.info("Redis Template: {}", redisTemplate);
18-
String key = "commit:" + username; // Redis 키 생성 (ex: commit:hongildong)
17+
String key = "commit_active:" + username; // Redis 키 생성 (ex: commit:hongildong)
1918
String value = redisTemplate.opsForValue().get(key); // Redis에서 값 가져오기
20-
return value != null ? Integer.parseInt(value) : null; // 값이 있으면 정수 변환, 없으면 null 반환
19+
20+
if (value != null) {
21+
log.info("✅ Redis Hit - {} : {}", key, value);
22+
return Integer.parseInt(value);
23+
} else {
24+
log.info("❌ Redis Miss - {}", key);
25+
return null;
26+
}
2127
}
2228

23-
public void updateCachedCommitCount(String username, int count) {
24-
String key = "commit:" + username;
25-
redisTemplate.opsForValue().set(key, String.valueOf(count), Duration.ofHours(1)); // 1시간 캐싱
29+
public void updateCachedCommitCount(String username, long count) {
30+
String key = "commit_active:" + username;
31+
redisTemplate.opsForValue().set(key, String.valueOf(count), Duration.ofHours(3)); // 3시간 캐싱
2632
}
2733
}

src/main/java/cmf/commitField/domain/noti/noti/entity/Noti.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import cmf.commitField.domain.user.entity.User;
44
import cmf.commitField.global.jpa.BaseEntity;
55
import jakarta.persistence.Entity;
6+
import jakarta.persistence.FetchType;
7+
import jakarta.persistence.JoinColumn;
68
import jakarta.persistence.ManyToOne;
79
import lombok.AllArgsConstructor;
810
import lombok.Getter;
@@ -19,10 +21,15 @@
1921
@Getter
2022
@Setter
2123
public class Noti extends BaseEntity {
22-
@ManyToOne
24+
25+
@ManyToOne(fetch = FetchType.LAZY)
26+
@JoinColumn(name = "actor_id", nullable = false)
2327
private User actor;
24-
@ManyToOne
28+
29+
@ManyToOne(fetch = FetchType.LAZY)
30+
@JoinColumn(name = "receiver_id", nullable = false)
2531
private User receiver;
32+
2633
private String relTypeCode;
2734
private long relId;
2835
private String typeCode;

src/main/java/cmf/commitField/domain/redpanda/RedpandaProducer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public void sendMessage(String message) {
2020
}
2121

2222
// 커밋 업데이트 전송 메서드
23-
public void sendCommitUpdate(String username, int commitCount) {
23+
public void sendCommitUpdate(String username, long commitCount) {
2424
String message = String.format("{\"user\": \"%s\", \"commits\": %d}", username, commitCount);
2525
kafkaTemplate.send(TOPIC, message);
2626
System.out.println("📨 Sent commit update to Redpanda: " + message);

src/main/java/cmf/commitField/domain/season/entity/Rank.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
public enum Rank {
44
SEED, // 씨앗
55
SPROUT, // 새싹
6-
STEM, // 줄기
76
FLOWER, // 꽃
87
FRUIT, // 열매
98
TREE // 나무

0 commit comments

Comments
 (0)