diff --git a/src/main/java/DiffLens/back_end/domain/library/controller/LibraryController.java b/src/main/java/DiffLens/back_end/domain/library/controller/LibraryController.java index 3272908..a242a2a 100644 --- a/src/main/java/DiffLens/back_end/domain/library/controller/LibraryController.java +++ b/src/main/java/DiffLens/back_end/domain/library/controller/LibraryController.java @@ -146,13 +146,13 @@ public ApiResponse addSearchHistoryToLibrary( @PathVariable Long libraryId, @PathVariable Long searchHistoryId) { Member member = currentUserService.getCurrentUser(); - LibraryCreateResult createResult = libraryCommandService.addSearchHistoryToLibrary(libraryId, - searchHistoryId, member); + LibraryCreateResult createResult = libraryCommandService.addSearchHistoryToLibrary(libraryId, searchHistoryId, member); LibraryResponseDTO.CreateResult result = LibraryResponseDTO.CreateResult.from( createResult.library(), searchHistoryId, - createResult.panelCount()); + createResult.panelCount() + ); return ApiResponse.onSuccess(result); } diff --git a/src/main/java/DiffLens/back_end/domain/library/dto/LibraryCompareRedisKeySuffix.java b/src/main/java/DiffLens/back_end/domain/library/dto/LibraryCompareRedisKeySuffix.java new file mode 100644 index 0000000..b67b492 --- /dev/null +++ b/src/main/java/DiffLens/back_end/domain/library/dto/LibraryCompareRedisKeySuffix.java @@ -0,0 +1,18 @@ +package DiffLens.back_end.domain.library.dto; + +import DiffLens.back_end.domain.library.entity.Library; + +public record LibraryCompareRedisKeySuffix( + Long lib1Id, + Long lib2Id +) { + + public static LibraryCompareRedisKeySuffix of(Library lib1, Library lib2) { + return new LibraryCompareRedisKeySuffix(lib1.getId(), lib2.getId()); + } + + public static LibraryCompareRedisKeySuffix of(Long lib1, Long lib2) { + return new LibraryCompareRedisKeySuffix(lib1, lib2); + } + +} diff --git a/src/main/java/DiffLens/back_end/domain/library/service/analysis/LibraryAnalysisServiceImpl.java b/src/main/java/DiffLens/back_end/domain/library/service/analysis/LibraryAnalysisServiceImpl.java index 82f29d8..184f048 100644 --- a/src/main/java/DiffLens/back_end/domain/library/service/analysis/LibraryAnalysisServiceImpl.java +++ b/src/main/java/DiffLens/back_end/domain/library/service/analysis/LibraryAnalysisServiceImpl.java @@ -1,10 +1,12 @@ package DiffLens.back_end.domain.library.service.analysis; +import DiffLens.back_end.domain.library.dto.LibraryCompareRedisKeySuffix; import DiffLens.back_end.domain.library.dto.LibraryCompareRequestDTO; import DiffLens.back_end.domain.library.dto.LibraryCompareResponseDTO; import DiffLens.back_end.domain.library.dto.LibraryResponseDTO; import DiffLens.back_end.domain.library.entity.Library; import DiffLens.back_end.domain.library.repository.LibraryRepository; +import DiffLens.back_end.domain.library.service.cache.LibraryCompareCacheService; import DiffLens.back_end.domain.library.utils.LibraryConvertUtils; import DiffLens.back_end.domain.members.entity.Member; import DiffLens.back_end.global.fastapi.FastApiService; @@ -14,11 +16,13 @@ import DiffLens.back_end.global.responses.code.status.error.ErrorStatus; import DiffLens.back_end.global.responses.exception.handler.ErrorHandler; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +@Slf4j @Service @RequiredArgsConstructor public class LibraryAnalysisServiceImpl implements LibraryAnalysisService { @@ -26,20 +30,46 @@ public class LibraryAnalysisServiceImpl implements LibraryAnalysisService { private final LibraryRepository libraryRepository; private final FastApiService fastApiService; private final LibraryConvertUtils convertUtils; + private final LibraryCompareCacheService compareCacheService; @Transactional(readOnly = true) public LibraryCompareResponseDTO.CompareResult compareLibraries(LibraryCompareRequestDTO.Compare request, Member member) { - if (request.getLibraryId1().equals(request.getLibraryId2())) throw new ErrorHandler(ErrorStatus.BAD_REQUEST); + // 1. 두 라이브러리의 id가 같으면 예외 발생 + if (request.getLibraryId1().equals(request.getLibraryId2())) + throw new ErrorHandler(ErrorStatus.BAD_REQUEST); + + // 1-1. 라이브러리 객체 2개 생성 Library lib1 = libraryRepository.findById(request.getLibraryId1()).orElseThrow(() -> new ErrorHandler(ErrorStatus.BAD_REQUEST)); Library lib2 = libraryRepository.findById(request.getLibraryId2()).orElseThrow(() -> new ErrorHandler(ErrorStatus.BAD_REQUEST)); + // 2. 캐시 조회 + // 2-1. redis Key에 쓰이는 정보 생성 + LibraryCompareRedisKeySuffix suffix = LibraryCompareRedisKeySuffix.of(request.getLibraryId1(), request.getLibraryId2()); + + // 2-2. redis에서 조회 + LibraryCompareResponseDTO.CompareResult cacheInfo = compareCacheService.getCacheInfo(suffix); + + // 2-3. redis에 데이터가 있으면 조회한거를 반환 + if( cacheInfo != null ){ + log.info("[API 호출중] 라이브러리 비교 정보를 정보를 캐시에서 조회"); + return cacheInfo; + } + + log.info("[API 호출중] 검색 추천 정보를 조회하기 위해 AI 로직 호출"); + + // 3. 조회된 라이브러리가 내꺼가 아니면 예외 발생 if (!lib1.getMember().getId().equals(member.getId()) || !lib2.getMember().getId().equals(member.getId())) throw new ErrorHandler(ErrorStatus.FORBIDDEN); + // 4. 서브서버 요청해서 var apiResp = fastApiService.compareLibraries(lib1.getId(), lib2.getId()); + LibraryCompareResponseDTO.CompareResult compareResult = makeCompareResult(apiResp, lib1, lib2); + + // 5. 캐시 저장 + compareCacheService.saveCacheInfo(suffix, compareResult); - return makeCompareResult(apiResp, lib1, lib2); + return compareResult; } /** diff --git a/src/main/java/DiffLens/back_end/domain/library/service/cache/LibraryCompareCacheService.java b/src/main/java/DiffLens/back_end/domain/library/service/cache/LibraryCompareCacheService.java new file mode 100644 index 0000000..592a921 --- /dev/null +++ b/src/main/java/DiffLens/back_end/domain/library/service/cache/LibraryCompareCacheService.java @@ -0,0 +1,7 @@ +package DiffLens.back_end.domain.library.service.cache; + +import DiffLens.back_end.domain.library.dto.LibraryCompareRedisKeySuffix; +import DiffLens.back_end.global.redis.CacheService; + +public interface LibraryCompareCacheService extends CacheService { +} diff --git a/src/main/java/DiffLens/back_end/domain/library/service/cache/LibraryCompareCacheServiceImpl.java b/src/main/java/DiffLens/back_end/domain/library/service/cache/LibraryCompareCacheServiceImpl.java new file mode 100644 index 0000000..804f7f3 --- /dev/null +++ b/src/main/java/DiffLens/back_end/domain/library/service/cache/LibraryCompareCacheServiceImpl.java @@ -0,0 +1,43 @@ +package DiffLens.back_end.domain.library.service.cache; + +import DiffLens.back_end.domain.library.dto.LibraryCompareRedisKeySuffix; +import DiffLens.back_end.domain.library.dto.LibraryCompareResponseDTO; +import DiffLens.back_end.domain.search.repository.cache.RedisObjectCacheRepository; +import DiffLens.back_end.global.redis.CacheInfo; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class LibraryCompareCacheServiceImpl implements LibraryCompareCacheService { + + // 캐시 정보를 관리하는 repository + private final RedisObjectCacheRepository cacheRepository; + + // 캐싱 정보 + private final CacheInfo cacheInfo = CacheInfo.Library_Compare; + + @Override + public LibraryCompareResponseDTO.CompareResult getCacheInfo(LibraryCompareRedisKeySuffix key) { + return cacheRepository.findByKey(getKey(key)); + } + + @Override + public void saveCacheInfo(LibraryCompareRedisKeySuffix key, LibraryCompareResponseDTO.CompareResult compareData) { + + String redisKey = getKey(key); + cacheRepository.save(redisKey, compareData, cacheInfo); + + } + + private String getKey(LibraryCompareRedisKeySuffix suffix){ + + Long lib1Id = suffix.lib1Id(); + Long lib2Id = suffix.lib2Id(); + + // 18-17 -> X + // 17-18 -> O + return cacheInfo.getPrefix() + Math.min(lib1Id, lib2Id) + "-" + Math.max(lib1Id, lib2Id); + } + +} diff --git a/src/main/java/DiffLens/back_end/domain/search/repository/cache/RedisObjectCacheRepository.java b/src/main/java/DiffLens/back_end/domain/search/repository/cache/RedisObjectCacheRepository.java index 572ed17..71ac39a 100644 --- a/src/main/java/DiffLens/back_end/domain/search/repository/cache/RedisObjectCacheRepository.java +++ b/src/main/java/DiffLens/back_end/domain/search/repository/cache/RedisObjectCacheRepository.java @@ -3,14 +3,16 @@ import DiffLens.back_end.global.redis.CacheInfo; import DiffLens.back_end.global.redis.RedisCacheRepository; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Repository; import java.util.function.Supplier; /** - * 추천 검색어를 관리하는 redis Repository + * 캐시 데이터를 관리하는 redis Repository */ +@Slf4j @Repository @RequiredArgsConstructor public class RedisObjectCacheRepository implements RedisCacheRepository { @@ -23,6 +25,7 @@ public boolean save(String key, Object value, CacheInfo cacheInfo) { try{ redisTemplate.opsForValue().set(key, value, cacheInfo.getTTL(), cacheInfo.getTimeUnit()); }catch(Exception e){ + log.error("[캐싱] 캐시 저장 중 오류 발생 - {}", e.getMessage()); return false; } return true; @@ -49,6 +52,7 @@ public boolean delete(String key) { try{ redisTemplate.delete(key); }catch(Exception e){ + log.error("[캐싱] 캐시 삭제 중 오류 발생 - {}", e.getMessage()); return false; } return true;