Skip to content

Commit e79cda3

Browse files
authored
Merge pull request #85 from CommitField/feat/#65
feat: ์‹ค์‹œ๊ฐ„ ์ปค๋ฐ‹ ์ˆ˜ ์ถ”์  ๊ธฐ๋Šฅ ์ ์šฉ
2 parents ff309e5 + 8a568e1 commit e79cda3

File tree

9 files changed

+146
-28
lines changed

9 files changed

+146
-28
lines changed
Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,102 @@
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.TimeUnit;
18+
import java.util.concurrent.atomic.AtomicInteger;
1419

1520
@Slf4j
1621
@Service
1722
@RequiredArgsConstructor
1823
public class CommitScheduler {
19-
private final GithubService githubService;
24+
private final TotalCommitService totalCommitService;
2025
private final CommitCacheService commitCacheService;
2126
private final RedpandaProducer redpandaProducer;
2227
private final UserRepository userRepository;
28+
private final StringRedisTemplate redisTemplate;
29+
private final AtomicInteger counter = new AtomicInteger(0);
2330

2431
@Scheduled(fixedRate = 60000) // 1๋ถ„๋งˆ๋‹ค ์‹คํ–‰
2532
public void updateUserCommits() {
2633
log.info("๐Ÿ” updateUserCommits ์‹คํ–‰์ค‘");
27-
List<User> activeUsers = userRepository.findAll(); // ๐Ÿ’ซ ๋ณ€๊ฒฝ ํ•„์š”, ์ฐจํ›„ active ์ƒํƒœ์ธ user๋งŒ ์ฐพ๊ฒŒ๋” ๋ณ€๊ฒฝํ•ด์•ผ ํ•จ.
34+
int count = counter.incrementAndGet();
2835

29-
log.info("๐Ÿ” Active User Count: {}", activeUsers.size());
36+
if (count % 10 == 0) {
37+
List<User> allUsers = userRepository.findAll();
38+
log.info("๐Ÿ” All User Count: {}", allUsers.size());
3039

31-
for (User user : activeUsers) {
32-
Integer cachedCount = commitCacheService.getCachedCommitCount(user.getUsername());
33-
int newCommitCount = githubService.getUserCommitCount(user.getUsername());
34-
35-
log.info("๐Ÿ” User: {}, Commit Count: {}", user.getUsername(), newCommitCount);
40+
for (User user : allUsers) {
41+
processUserCommit(user);
42+
}
43+
} else {
44+
Set<String> activeUsers = redisTemplate.keys("commit_active:*");
45+
log.info("๐Ÿ” Active User Count: {}", activeUsers.size());
3646

37-
if (cachedCount == null || cachedCount != newCommitCount) { // ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๋•Œ๋งŒ ์ฒ˜๋ฆฌ
38-
commitCacheService.updateCachedCommitCount(user.getUsername(), newCommitCount);
39-
redpandaProducer.sendCommitUpdate(user.getUsername(), newCommitCount);
47+
for (String key : activeUsers) {
48+
String username = key.replace("commit_active:", "");
49+
User user = userRepository.findByUsername(username).orElse(null);
50+
if (user != null) {
51+
processUserCommit(user);
52+
}
4053
}
4154
}
4255
}
56+
57+
// ๐Ÿ”น ์œ ์ € ์ปค๋ฐ‹ ๊ฒ€์‚ฌ ๋ฐ ๋ฐ˜์˜
58+
private void processUserCommit(User user) {
59+
// Redis์—์„œ lastCommitted ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ
60+
String redisKey = "commit_last:" + user.getUsername();
61+
String lastCommittedStr = redisTemplate.opsForValue().get(redisKey);
62+
LocalDateTime lastCommitted;
63+
if(lastCommittedStr != null){
64+
lastCommitted=LocalDateTime.parse(lastCommittedStr);
65+
}else{
66+
user.setLastCommitted(LocalDateTime.now()); // ๋ ˆ๋””์Šค์— ์ €์žฅ๋˜์–ด์žˆ์ง€ ์•Š์•˜๋‹ค๋ฉด ๋“ฑ๋ก ์‹œ์ ์— lastCommitted๋ฅผ ๊ฐฑ์‹ 
67+
lastCommitted=user.getLastCommitted(); // Redis์— ์—†์œผ๋ฉด DB๊ฐ’ ์‚ฌ์šฉ;
68+
}
69+
70+
// ํ˜„์žฌ ์ปค๋ฐ‹ ๊ฐœ์ˆ˜ ์กฐํšŒ
71+
long currentCommitCount = totalCommitService.getSeasonCommits(
72+
user.getUsername(),
73+
lastCommitted, // ๐Ÿš€ Redis์— ์ €์žฅ๋œ lastCommitted ๊ธฐ์ค€์œผ๋กœ ์กฐํšŒ
74+
LocalDateTime.now()
75+
).getTotalCommitContributions();
76+
77+
// Redis์—์„œ ์ด์ „ ์ปค๋ฐ‹ ๊ฐœ์ˆ˜ ๊ฐ€์ ธ์˜ค๊ธฐ
78+
Integer previousCommitCount = commitCacheService.getCachedCommitCount(user.getUsername());
79+
long newCommitCount = previousCommitCount == null ? 0 : (currentCommitCount - previousCommitCount);
80+
81+
if (newCommitCount > 0) {
82+
updateCommitData(user, currentCommitCount, newCommitCount);
83+
}
84+
85+
log.info("๐Ÿ” User: {}, New Commits: {}, Total Commits: {}", user.getUsername(), newCommitCount, currentCommitCount);
86+
}
87+
88+
// ๐Ÿ”น ์ƒˆ ์ปค๋ฐ‹์ด ์žˆ์œผ๋ฉด ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ
89+
private void updateCommitData(User user, long currentCommitCount, long newCommitCount) {
90+
// 1๏ธโƒฃ Redis์— lastCommitted ์—…๋ฐ์ดํŠธ (3์‹œ๊ฐ„ TTL)
91+
String redisKey = "commit_last:" + user.getUsername();
92+
redisTemplate.opsForValue().set(redisKey, LocalDateTime.now().toString(), 3, TimeUnit.HOURS);
93+
94+
// 2๏ธโƒฃ Redis์— ์ตœ์‹  ์ปค๋ฐ‹ ๊ฐœ์ˆ˜ ์ €์žฅ (3์‹œ๊ฐ„ ๋™์•ˆ ์œ ์ง€)
95+
commitCacheService.updateCachedCommitCount(user.getUsername(), currentCommitCount);
96+
97+
// 3๏ธโƒฃ ๋ฉ”์‹œ์ง€ ํ ์ „์†ก
98+
redpandaProducer.sendCommitUpdate(user.getUsername(), newCommitCount);
99+
100+
log.info("โœ… ์ปค๋ฐ‹ ๋ฐ˜์˜ ์™„๋ฃŒ - User: {}, New Commits: {}", user.getUsername(), newCommitCount);
101+
}
43102
}

โ€Ž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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@ public class Noti extends BaseEntity {
3434
// TODO: ์•Œ๋ฆผ์ด ์—ฐ๊ฒฐ๋œ ๊ฐ์ฒด ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ์ง€ ๊ณ ๋ฏผ ํ•„์š”.
3535
// private String relTypeCode; // ์•Œ๋ฆผ์ด ์—ฐ๊ฒฐ๋œ ์‹ค์ œ ๊ฐ์ฒด ์œ ํ˜•
3636
// private long relId; // ์•Œ๋ฆผ ๊ฐ์ฒด์˜ Id
37+
3738
}

โ€Žsrc/main/java/cmf/commitField/domain/pet/entity/Pet.javaโ€Ž

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import lombok.Setter;
1010
import lombok.experimental.SuperBuilder;
1111

12+
import java.util.Random;
13+
1214
@Entity
1315
@Getter
1416
@Setter
@@ -17,11 +19,36 @@
1719
@SuperBuilder
1820
@Table(name = "pet")
1921
public class Pet extends BaseEntity {
20-
private int type; // ํŽซ ํƒ€์ž… ๋„˜๋ฒ„, ํ˜„์žฌ 1~3๊นŒ์ง€ ์กด์žฌ
22+
private int type; // ํŽซ ํƒ€์ž… ๋„˜๋ฒ„, ํ˜„์žฌ 0~2๊นŒ์ง€ ์กด์žฌ
2123
private String name;
2224
private String imageUrl;
25+
private int exp; // ํŽซ ๊ฒฝํ—˜์น˜
26+
27+
@Enumerated(EnumType.STRING) // DB์— ์ €์žฅ๋  ๋•Œ String ํ˜•ํƒœ๋กœ ์ €์žฅ๋จ
28+
private Grow grow; // ์„ฑ์žฅ ์ •๋„
29+
30+
public enum Grow {
31+
EGG, HATCH, GROWN
32+
}
2333

2434
@ManyToOne(fetch = FetchType.LAZY)
2535
@JoinColumn(name = "user_id", nullable = false)
2636
private User user;
37+
38+
public Pet(String name, User user){
39+
Random random = new Random();
40+
this.type = random.nextInt(3);
41+
switch (type){ //์ •ํ•ด์ง„ ์•Œ ํƒ€์ž…์— ๋”ฐ๋ผ ๋‹ค๋ฅธ url์„ ์ฃผ์ž…
42+
case 0: this.imageUrl = "temp0";
43+
break;
44+
case 1: this.imageUrl = "temp1";
45+
break;
46+
case 2: this.imageUrl = "temp2";
47+
break;
48+
}
49+
this.name = name;
50+
this.exp = 0;
51+
this.grow = Grow.EGG;
52+
this.user = user;
53+
}
2754
}

โ€Žsrc/main/java/cmf/commitField/domain/pet/service/PetService.javaโ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public Pet createPet(String name, MultipartFile imageFile, User user) throws IOE
2929
imageUrl = s3Service.uploadFile(imageFile, "pet-images");
3030
}
3131
Random random = new Random();
32-
Pet pet = new Pet(random.nextInt(3), name, imageUrl, user);
32+
Pet pet = new Pet(name, user);
3333
return petRepository.save(pet);
3434
}
3535

โ€Žsrc/main/java/cmf/commitField/domain/redpanda/RedpandaProducer.javaโ€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ public void sendMessage(String message) {
2020
}
2121

2222
// ์ปค๋ฐ‹ ์—…๋ฐ์ดํŠธ ์ „์†ก ๋ฉ”์„œ๋“œ
23-
public void sendCommitUpdate(String username, int commitCount) {
24-
String message = String.format("{\"user\": \"%s\", \"commits\": %d}", username, commitCount);
23+
public void sendCommitUpdate(String username, long commitCount) {
24+
String message = String.format("{\"user\": \"%s\", \"update-commits\": %d}", username, commitCount);
2525
kafkaTemplate.send(TOPIC, message);
2626
System.out.println("๐Ÿ“จ Sent commit update to Redpanda: " + message);
2727
}

โ€Ž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 // ๋‚˜๋ฌด

โ€Žsrc/main/java/cmf/commitField/domain/user/entity/User.javaโ€Ž

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import cmf.commitField.domain.chat.chatMessage.entity.ChatMsg;
44
import cmf.commitField.domain.chat.chatRoom.entity.ChatRoom;
55
import cmf.commitField.domain.chat.userChatRoom.entity.UserChatRoom;
6+
import cmf.commitField.domain.pet.entity.Pet;
67
import cmf.commitField.global.jpa.BaseEntity;
78
import jakarta.persistence.*;
89
import lombok.AllArgsConstructor;
@@ -11,6 +12,7 @@
1112
import lombok.Setter;
1213
import lombok.experimental.SuperBuilder;
1314

15+
import java.time.LocalDateTime;
1416
import java.util.ArrayList;
1517
import java.util.List;
1618

@@ -25,14 +27,15 @@ public class User extends BaseEntity {
2527
private String email; // ์ด๋ฉ”์ผ
2628
private String nickname; // ๋‹‰๋„ค์ž„
2729
private String avatarUrl; //์•„๋ฐ”ํƒ€
30+
private LocalDateTime lastCommitted; // ๋งˆ์ง€๋ง‰ ์ปค๋ฐ‹ ์‹œ๊ฐ„
2831

2932
@Enumerated(EnumType.STRING) // DB์— ์ €์žฅ๋  ๋•Œ String ํ˜•ํƒœ๋กœ ์ €์žฅ๋จ
3033
private Role role;
3134

3235
public enum Role {
3336
USER, ADMIN
3437
}
35-
//์ถ”๊ฐ€
38+
3639
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
3740
private List<ChatRoom> chatRooms = new ArrayList<>();
3841

@@ -42,4 +45,22 @@ public enum Role {
4245
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
4346
private List<ChatMsg> chatMsgs = new ArrayList<>();
4447

48+
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
49+
private List<Pet> pets = new ArrayList<>();
50+
51+
public void addPets(Pet pet){
52+
pets.add(pet);
53+
}
54+
55+
public User(String username, String email, String nickname, String avatarUrl, List<ChatRoom> cr, List<UserChatRoom> ucr, List<ChatMsg> cmsg){
56+
this.username=username;
57+
this.email=email;
58+
this.nickname=nickname;
59+
this.avatarUrl=avatarUrl;
60+
this.role = Role.USER;
61+
this.chatRooms = cr;
62+
this.userChatRooms = ucr;
63+
this.chatMsgs = cmsg;
64+
this.lastCommitted = LocalDateTime.now();
65+
}
4566
}

โ€Žsrc/main/java/cmf/commitField/domain/user/service/CustomOAuth2UserService.javaโ€Ž

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cmf.commitField.domain.user.service;
22

3+
import cmf.commitField.domain.commit.sinceCommit.service.CommitCacheService;
34
import cmf.commitField.domain.pet.entity.Pet;
45
import cmf.commitField.domain.pet.repository.PetRepository;
56
import cmf.commitField.domain.user.entity.CustomOAuth2User;
@@ -14,13 +15,13 @@
1415
import java.util.ArrayList;
1516
import java.util.Map;
1617
import java.util.Optional;
17-
import java.util.Random;
1818

1919
@Service
2020
@RequiredArgsConstructor
2121
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
2222
private final UserRepository userRepository;
2323
private final PetRepository petRepository;
24+
private final CommitCacheService commitCacheService;
2425

2526
@Override
2627
public OAuth2User loadUser(OAuth2UserRequest userRequest) {
@@ -49,12 +50,16 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) {
4950
} else {
5051
//์œ ์ € ์ •๋ณด๊ฐ€ db์— ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ํšŒ์›๊ฐ€์ž… ์‹œํ‚จ๋‹ค.
5152
//์œ ์ € ์ƒ์„ฑ ๋ฐ ํŽซ ์ƒ์„ฑ
52-
user = new User(username, email, name, avatarUrl, User.Role.USER, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
53+
user = new User(username, email, name, avatarUrl, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
5354
userRepository.save(user);
5455

55-
Random random = new Random(); //ํŽซ ๋žœ๋ค ์ƒ์„ฑ
56-
pet = new Pet(random.nextInt(3), "์•Œ์•Œ", "temp-Url", user); // ๋ณ€๊ฒฝ ํ•„์š”
56+
pet = new Pet("์•Œ์•Œ", user); // ๋ณ€๊ฒฝ ํ•„์š”
5757
petRepository.save(pet);
58+
59+
user.addPets(pet);
60+
61+
// ํšŒ์›๊ฐ€์ž…ํ•œ ์œ ์ €๋Š” ์ปค๋ฐ‹ ๊ธฐ๋ก์— ์ƒ๊ด€์—†์ด Redis์— ์ž…๋ ฅํ•ด๋‘”๋‹ค.
62+
commitCacheService.updateCachedCommitCount(user.getUsername(),0);
5863
}
5964

6065
return new CustomOAuth2User(oauthUser, user);

0 commit comments

Comments
ย (0)