fix(recommend-live): 차단 관계를 추천 조회에 반영하고 캐시를 무효화한다

This commit is contained in:
2026-02-26 03:33:09 +09:00
parent e7252574d2
commit dd9cd788ca
8 changed files with 368 additions and 13 deletions

View File

@@ -7,6 +7,7 @@ import kr.co.vividnext.sodalive.live.recommend.QRecommendLiveCreatorBanner.recom
import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom
import kr.co.vividnext.sodalive.member.MemberRole
import kr.co.vividnext.sodalive.member.QMember.member
import kr.co.vividnext.sodalive.member.block.QBlockMember.blockMember
import kr.co.vividnext.sodalive.member.following.QCreatorFollowing.creatorFollowing
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Repository
@@ -20,7 +21,7 @@ class LiveRecommendRepository(
private val cloudFrontHost: String
) {
fun getRecommendLive(
isBlocked: (Long) -> Boolean,
memberId: Long?,
isAdult: Boolean
): List<GetRecommendLiveResponse> {
val dateNow = LocalDateTime.now()
@@ -32,7 +33,7 @@ class LiveRecommendRepository(
where = where.and(recommendLiveCreatorBanner.isAdult.isFalse)
}
return queryFactory
var select = queryFactory
.select(
Projections.constructor(
GetRecommendLiveResponse::class.java,
@@ -41,12 +42,26 @@ class LiveRecommendRepository(
)
)
.from(recommendLiveCreatorBanner)
if (memberId != null) {
val blockMemberCondition = blockMember.isActive.isTrue
.and(
blockMember.member.id.eq(recommendLiveCreatorBanner.creator.id)
.and(blockMember.blockedMember.id.eq(memberId))
.or(
blockMember.member.id.eq(memberId)
.and(blockMember.blockedMember.id.eq(recommendLiveCreatorBanner.creator.id))
)
)
where = where.and(blockMember.id.isNull)
select = select.leftJoin(blockMember).on(blockMemberCondition)
}
return select
.where(where)
.orderBy(recommendLiveCreatorBanner.orders.asc())
.fetch()
.asSequence()
.filter { !isBlocked(it.creatorId) }
.toList()
}
fun getOnAirRecommendChannelList(

View File

@@ -16,17 +16,11 @@ class LiveRecommendService(
@Transactional(readOnly = true)
@Cacheable(
cacheNames = ["cache_ttl_3_hours"],
key = "'getRecommendLive:' + (#member ?: 'guest')"
key = "'getRecommendLive:' + (#member?.id ?: 'guest')"
)
fun getRecommendLive(member: Member?): List<GetRecommendLiveResponse> {
return repository.getRecommendLive(
isBlocked = {
if (member != null) {
isBlockedBetweenMembers(memberId = member.id!!, creatorId = it)
} else {
false
}
},
memberId = member?.id,
isAdult = member?.auth != null
)
}

View File

@@ -54,6 +54,7 @@ import kr.co.vividnext.sodalive.point.MemberPointRepository
import kr.co.vividnext.sodalive.utils.generateFileName
import kr.co.vividnext.sodalive.utils.generatePassword
import org.springframework.beans.factory.annotation.Value
import org.springframework.cache.CacheManager
import org.springframework.data.repository.findByIdOrNull
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
@@ -107,6 +108,7 @@ class MemberService(
private val countryContext: CountryContext,
private val objectMapper: ObjectMapper,
private val cacheManager: CacheManager,
@Value("\${cloud.aws.s3.bucket}")
private val s3Bucket: String,
@@ -117,6 +119,8 @@ class MemberService(
private val tokenLocks: MutableMap<Long, ReentrantReadWriteLock> = mutableMapOf()
private val recommendLiveCacheKeyPrefix = "getRecommendLive:"
@Transactional
fun signUpV2(request: SignUpRequestV2): SignUpResponse {
val stipulationTermsOfService = stipulationRepository.findByIdOrNull(StipulationIds.TERMS_OF_SERVICE_ID)
@@ -558,6 +562,9 @@ class MemberService(
blockMember.isActive = true
}
}
evictRecommendLiveCache(memberId)
blockTargetMemberIds.forEach { evictRecommendLiveCache(it) }
}
@Transactional
@@ -570,6 +577,9 @@ class MemberService(
if (blockMember != null) {
blockMember.isActive = false
}
evictRecommendLiveCache(memberId)
evictRecommendLiveCache(request.blockMemberId)
}
fun isBlocked(blockedMemberId: Long, memberId: Long) = blockMemberRepository.isBlocked(blockedMemberId, memberId)
@@ -829,6 +839,10 @@ class MemberService(
return tokenLocks.computeIfAbsent(memberId) { ReentrantReadWriteLock() }
}
private fun evictRecommendLiveCache(memberId: Long) {
cacheManager.getCache("cache_ttl_3_hours")?.evict(recommendLiveCacheKeyPrefix + memberId)
}
@Transactional
fun updateMarketingInfo(memberId: Long, adid: String, pid: String): String? {
val member = repository.findByIdOrNull(id = memberId)