Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,13 @@ public ApiResponse<LibraryResponseDTO.CreateResult> 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);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -14,32 +16,60 @@
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 {

private final LibraryRepository libraryRepository;
private final FastApiService fastApiService;
private final LibraryConvertUtils convertUtils;
private final LibraryCompareCacheService<LibraryCompareResponseDTO.CompareResult> 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;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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<T> extends CacheService<T, LibraryCompareRedisKeySuffix> {
}
Original file line number Diff line number Diff line change
@@ -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<T> implements LibraryCompareCacheService<LibraryCompareResponseDTO.CompareResult> {

// 캐시 정보를 관리하는 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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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<Object> {
Expand All @@ -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;
Expand All @@ -49,6 +52,7 @@ public boolean delete(String key) {
try{
redisTemplate.delete(key);
}catch(Exception e){
log.error("[캐싱] 캐시 삭제 중 오류 발생 - {}", e.getMessage());
return false;
}
return true;
Expand Down