Skip to content

Commit

Permalink
Feat/#543 로컬 캐시에 좋아요 데이터가 실시간으로 반영되도록 수정 (#549)
Browse files Browse the repository at this point in the history
* feat: 로컬 인터셉터 추가

* refactor: TreeMap 으로 노래 캐싱 및 좋아요 실시간 반영

* refactor: 삽입 정렬로 정렬 속도 개선

* refactor: 로컬 실행 시 토큰이 아닌 Authorization의 memberId 를 사용하도록 변경

* config: 로컬 config 롤백

* fix: 삽입 정렬 로직 추가

* refactor: EntityManager 의존성 이동 및 메서드, 필드 이름 리팩터링

* refactor: 조건문 메서드 분리

* refactor: 접근 제어자 private 으로 변경

* refactor: KillingPart 가 AtomicInteger 를 필드로 갖도록 수정

* refactor: 사용하지 않는 dto 클래스 삭제

* refactor: 사용하지 않는 메서드 삭제

* refactor: 접근 제어자 private 으로 변경

* refactor: 중복 범위 검증 제거

* refactor: 분기문 제거

* feat: likeCount AtomicInteger 로 변경 및 좋아요 개수 데이터베이스와 동기화하는 로직 추가

* fix: setUp 메서드 실행 시점 변경

* refactor: synchronized 로 동시성 처리

* fix: cache 재생성 제거
  • Loading branch information
Cyma-s authored Jan 17, 2024
1 parent 3745893 commit b007310
Show file tree
Hide file tree
Showing 27 changed files with 531 additions and 257 deletions.
2 changes: 2 additions & 0 deletions backend/src/main/java/shook/shook/auth/config/AuthConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
Expand All @@ -12,6 +13,7 @@
import shook.shook.auth.ui.interceptor.PathMethod;
import shook.shook.auth.ui.interceptor.TokenInterceptor;

@Profile("!local")
@Configuration
public class AuthConfig implements WebMvcConfigurer {

Expand Down
33 changes: 33 additions & 0 deletions backend/src/main/java/shook/shook/auth/config/LocalAuthConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package shook.shook.auth.config;

import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import shook.shook.auth.ui.argumentresolver.AuthArgumentResolver;
import shook.shook.auth.ui.interceptor.LocalInterceptor;

@Profile("local")
@Configuration
public class LocalAuthConfig implements WebMvcConfigurer {

private final AuthArgumentResolver authArgumentResolver;
private final LocalInterceptor localInterceptor;

public LocalAuthConfig(final AuthArgumentResolver authArgumentResolver, final LocalInterceptor localInterceptor) {
this.authArgumentResolver = authArgumentResolver;
this.localInterceptor = localInterceptor;
}

@Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(localInterceptor);
}

@Override
public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(authArgumentResolver);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package shook.shook.auth.ui.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import shook.shook.auth.ui.AuthContext;

@Profile("local")
@Component
public class LocalInterceptor implements HandlerInterceptor {

private final AuthContext authContext;

public LocalInterceptor(final AuthContext authContext) {
this.authContext = authContext;
}

@Override
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler)
throws Exception {
final long memberId = Long.parseLong(request.getHeader("Authorization"));
authContext.setAuthenticatedMember(memberId);

return true;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package shook.shook.song.application;

import jakarta.annotation.PostConstruct;
import jakarta.persistence.EntityManager;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import shook.shook.song.domain.InMemorySongs;
import shook.shook.song.domain.Song;
import shook.shook.song.domain.killingpart.KillingPart;
import shook.shook.song.domain.repository.SongRepository;

@RequiredArgsConstructor
Expand All @@ -17,6 +21,7 @@ public class InMemorySongsScheduler {

private final SongRepository songRepository;
private final InMemorySongs inMemorySongs;
private final EntityManager entityManager;

@PostConstruct
public void initialize() {
Expand All @@ -26,6 +31,25 @@ public void initialize() {
@Scheduled(cron = "${schedules.in-memory-song.cron}")
public void recreateCachedSong() {
log.info("InMemorySongsScheduler worked");
inMemorySongs.recreate(songRepository.findAllWithKillingParts());
final List<Song> songs = songRepository.findAllWithKillingPartsAndLikes();
detachSongs(songs);
inMemorySongs.refreshSongs(songs);
}

private void detachSongs(final List<Song> songs) {
songs.stream()
.peek(entityManager::detach)
.flatMap(song -> song.getKillingParts().stream())
.forEach(entityManager::detach);
}

@Transactional
@Scheduled(cron = "${schedules.in-memory-song.update-cron}")
public void updateCachedSong() {
log.info("InMemorySongsScheduler LikeCount update progressed");
final List<KillingPart> killingParts = inMemorySongs.getSongs().stream()
.flatMap(song -> song.getKillingParts().stream())
.toList();
killingParts.forEach(entityManager::merge);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import shook.shook.member.domain.Member;
import shook.shook.member.domain.repository.MemberRepository;
import shook.shook.member.exception.MemberException;
import shook.shook.song.application.dto.RecentSongCarouselResponse;
import shook.shook.member_part.domain.MemberPart;
import shook.shook.member_part.domain.repository.MemberPartRepository;
import shook.shook.song.application.dto.RecentSongCarouselResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import shook.shook.member.domain.repository.MemberRepository;
import shook.shook.member.exception.MemberException;
import shook.shook.song.application.killingpart.dto.KillingPartLikeRequest;
import shook.shook.song.domain.InMemorySongs;
import shook.shook.song.domain.killingpart.KillingPart;
import shook.shook.song.domain.killingpart.KillingPartLike;
import shook.shook.song.domain.killingpart.repository.KillingPartLikeRepository;
Expand All @@ -22,6 +23,7 @@ public class KillingPartLikeService {
private final KillingPartRepository killingPartRepository;
private final MemberRepository memberRepository;
private final KillingPartLikeRepository likeRepository;
private final InMemorySongs inMemorySongs;

@Transactional
public void updateLikeStatus(
Expand Down Expand Up @@ -54,8 +56,8 @@ private void create(final KillingPart killingPart, final Member member) {
final KillingPartLike likeOnKillingPart = likeRepository.findByKillingPartAndMember(killingPart, member)
.orElseGet(() -> createNewLike(killingPart, member));
if (likeOnKillingPart.isDeleted()) {
inMemorySongs.like(killingPart, likeOnKillingPart);
likeRepository.pressLike(likeOnKillingPart.getId());
killingPartRepository.increaseLikeCount(killingPart.getId());
}
}

Expand All @@ -68,8 +70,8 @@ private KillingPartLike createNewLike(final KillingPart killingPart, final Membe
private void delete(final KillingPart killingPart, final Member member) {
killingPart.findLikeByMember(member)
.ifPresent(likeOnKillingPart -> {
inMemorySongs.unlike(killingPart, likeOnKillingPart);
likeRepository.cancelLike(likeOnKillingPart.getId());
killingPartRepository.decreaseLikeCount(killingPart.getId());
});
}
}
Loading

0 comments on commit b007310

Please sign in to comment.