Skip to content

Commit

Permalink
[fix] 뷰 카운팅 중복 문제 해결 (#117)
Browse files Browse the repository at this point in the history
* #106 fix: ChatRoom 생성자 매개변수 변경

* #106 fix: null 처리

* #106 fix: validateIsSeller 개선

* #106 fix: 상품을 찾지 못한 경우 에러 코드를 NOT_FOUND로 설정

* #106 fix: 주석 제거

* #106 fix: 중복된 메소드 제거

* #106 fix: deleteAllInBatch 제거

* #106 fix: 매직넘버 제거

* #106 fix: 정적 임포트 제거

* #106 fix: 레디스 서비스에서 Oauth 도메인 부분을 따로 빼서 OauthRedisService로 분리

* #106 fix: 레디스 서비스 도메인별 분리

* #106 fix: 회원 동네 선택시 쿼리 개선

* #106 fix: 디미터의 법칙 개선

* #96 feat: 한 채팅방안에 채팅 메시지 조회 API 구현

* #96 feat: messageIndex를 이용한 채팅 로그 목록 조회

* #96 feat: toString 정의

* #96 test: readMessages 테스트 코드 추가

* #96 feat: 채팅 메시지 목록 요청시 대기시간 10초로 증가 및 조건문 추가

- 조건문 내용은 messageIndex가 채팅 리스트의 개수보다 큰 경우 빈 컬렉션을 반환하도록 합니다.

* #96 fix: 응답형식 변경

* #96 fix: 응답형식 변경

* #114 feat: 채팅방 목록 조회 서비스 구현

* #114 docs: 채팅 샘플 데이터 추가

* #114 test: 채팅방 목록 조회 테스트 코드 추가

* #114 feat: 채팅방 목록 조회 API 구현

* #114 test: 채팅방 목록 조회 API 테스트 코드 추가

* #114 test: 테스트 코드 수정

* #114 feat: sendMessage 메소드에서 ChatLog 객체 생성 코드 개선

* #114 feat: 조회수 증가에 로그 추가

* #114 style: 코드 정리

* #115 fix: RedisTemplate value 타입을 Long -> String 타입으로 변환

* #115 fix: 코드 수정

* #115 fix: 뷰 카운팅 중복 문제 해결
  • Loading branch information
yonghwankim-dev authored Sep 30, 2023
1 parent 3bf8de1 commit ac3bb66
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public ApiResponse<ItemResponses> findAll(@RequestParam String region,
@GetMapping("/{itemId}")
public ApiResponse<ItemDetailResponse> findDetailItem(@PathVariable Long itemId,
@AuthPrincipal Principal principal) {
itemViewRedisService.addViewCount(itemId);
itemViewRedisService.addViewCount(itemId, principal);
ItemDetailResponse response = itemService.findDetailItemBy(itemId, principal.getMemberId());
return ApiResponse.ok("상품 상세 조회에 성공하였습니다.", response);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.springframework.transaction.annotation.Transactional;

import codesquard.app.domain.item.ItemRepository;
import codesquard.app.domain.oauth.support.Principal;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

Expand All @@ -31,14 +32,30 @@ public String get(String key) {
return redisTemplate.opsForValue().get(key);
}

public void addViewCount(Long itemId) {
public void addViewCount(Long itemId, Principal principal) {
String key = ITEM_ID_PREFIX + itemId;
String itemViewKey = principal.createItemViewKey(key);
if (!isFirstItemView(itemViewKey)) {
return;
}
ValueOperations<String, String> value = redisTemplate.opsForValue();
value.set(itemViewKey, "true", Duration.ofDays(1L));

if (value.get(key) != null) {
value.increment(key);
log.debug("상품 게시글 조회수 증가 결과 : key={}, value={}", key, value.get(key));
return;
}

value.set(key, "1", Duration.ofMinutes(1));
log.debug("상품 게시글 조회수 증가 결과 : key={}, value={}", key, value.get(key));
}

private boolean isFirstItemView(String key) {
if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
return false;
}
return true;
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ public RedisConnectionFactory redisConnectionFactory() {
}

@Bean
public RedisTemplate<String, Long> redisTemplate() {
RedisTemplate<String, Long> redisTemplate = new RedisTemplate<>();
public RedisTemplate<String, String> redisTemplate() {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,8 @@ public String toString() {
return String.format("%s, %s(id=%d, email=%s, loginId=%s)", "Principal", this.getClass().getSimpleName(),
memberId, email, loginId);
}

public String createItemViewKey(String key) {
return loginId + "-" + key;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.assertj.core.api.Assertions.*;
import static org.awaitility.Awaitility.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

import java.util.Optional;
Expand All @@ -16,12 +17,14 @@
import org.springframework.test.context.ActiveProfiles;

import codesquard.app.CacheTestSupport;
import codesquard.app.MemberTestSupport;
import codesquard.app.api.item.request.ItemRegisterRequest;
import codesquard.app.domain.category.Category;
import codesquard.app.domain.item.Item;
import codesquard.app.domain.item.ItemRepository;
import codesquard.app.domain.item.ItemStatus;
import codesquard.app.domain.member.Member;
import codesquard.app.domain.oauth.support.Principal;
import codesquard.support.SupportRepository;

@ActiveProfiles("test")
Expand Down Expand Up @@ -50,9 +53,10 @@ void viewCountTest() {
ItemRegisterRequest request1 = new ItemRegisterRequest(
"선풍기", 12000L, null, "가양 1동", ItemStatus.ON_SALE, category.getId(), null);
Member member = supportRepository.save(new Member("avatar", "pie@pie", "pieeeeeee"));
Principal principal = Principal.from(member);
Item item = supportRepository.save(request1.toEntity(member, "thumbnail"));
itemViewRedisService.addViewCount(item.getId());
itemViewRedisService.addViewCount(item.getId());
itemViewRedisService.addViewCount(item.getId(), principal);
itemViewRedisService.addViewCount(item.getId(), principal);

// when
await().atMost(2, TimeUnit.MINUTES).untilAsserted(
Expand All @@ -66,4 +70,23 @@ void viewCountTest() {
Optional<Item> saveItem = itemRepository.findById(item.getId());
assertThat(saveItem.get().getViewCount()).isEqualTo(2);
}

@DisplayName("회원이 두번째로 상품 상세 조회시 뷰 카운트는 증가하지 않는다")
@Test
public void addViewCount() {
// given
Member member = MemberTestSupport.createMember("avatarUrl", "[email protected]", "23Yong");
Principal principal = Principal.from(member);
// when
itemViewRedisService.addViewCount(1L, principal);
itemViewRedisService.addViewCount(1L, principal);
// then
Long viewCount = Long.valueOf(itemViewRedisService.get("itemId: 1"));
String itemViewValue = itemViewRedisService.get(principal.createItemViewKey("itemId: 1"));
assertAll(
() -> assertThat(viewCount).isEqualTo(1L),
() -> assertThat(itemViewValue).isEqualTo("true")
);

}
}

0 comments on commit ac3bb66

Please sign in to comment.