Skip to content

Commit

Permalink
feat: ws에 score 기능 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
DongGeon0908 committed Aug 21, 2024
1 parent 61f5daa commit 1c8305b
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 7 deletions.
1 change: 1 addition & 0 deletions sql/DDL.sql
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ CREATE TABLE `group_user_score`
) ENGINE=InnoDB AUTO_INCREMENT=200000 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='그룹 유저 스코어';
CREATE UNIQUE INDEX uidx__group_user_id ON group_user_score (group_user_id);
CREATE INDEX idx__group_id__group_user_id ON group_user_score (group_id, group_user_id);
CREATE INDEX idx__uid ON group_user_score (uid);

-- 포즈 스냅샵
CREATE TABLE `pose_snapshot`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.hero.alignlab.domain.group.infrastructure.GroupUserScoreRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
class GroupUserScoreService(
Expand All @@ -15,4 +16,30 @@ class GroupUserScoreService(
groupUserScoreRepository.findAllByGroupId(groupId)
}
}

suspend fun findByUidOrNull(uid: Long): GroupUserScore? {
return withContext(Dispatchers.IO) {
groupUserScoreRepository.findByUid(uid)
}
}

suspend fun findAllByGroupUserIdIn(groupdUserIds: List<Long>): List<GroupUserScore> {
return withContext(Dispatchers.IO) {
groupUserScoreRepository.findAllByGroupUserIdIn(groupdUserIds)
}
}

@Transactional
fun saveSync(groupUserScore: GroupUserScore): GroupUserScore {
return groupUserScoreRepository.save(groupUserScore)
}

@Transactional
fun saveAllSync(groupUserScores: List<GroupUserScore>): List<GroupUserScore> {
return groupUserScoreRepository.saveAll(groupUserScores)
}

fun findAllByGroupIdAndUidsSync(groupId: Long, uids: Set<Long>): List<GroupUserScore> {
return groupUserScoreRepository.findAllByGroupIdAndUidIn(groupId, uids)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class GroupUserService(

suspend fun findAllByUid(uid: Long): List<GroupUser> {
return withContext(Dispatchers.IO) {
findAllByUid(uid)
findAllByUidSync(uid)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@ import org.springframework.transaction.annotation.Transactional
@Repository
interface GroupUserScoreRepository : JpaRepository<GroupUserScore, Long> {
fun findAllByGroupId(groupId: Long): List<GroupUserScore>

fun findByUid(uid: Long): GroupUserScore?

fun findAllByGroupUserIdIn(groupUserIds: List<Long>): List<GroupUserScore>

fun findAllByGroupIdAndUidIn(groupId: Long, uids: Set<Long>): List<GroupUserScore>
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ enum class PoseType(val nameKor: String) {
@JsonEnumDefaultValue
UNKNOWN("예외 타입"),
;

companion object {
val BAD_POSE = setOf(TURTLE_NECK, SHOULDER_TWIST, CHIN_UTP, TURTLE_NECK)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ package com.hero.alignlab.event.listener

import com.hero.alignlab.common.extension.coExecuteOrNull
import com.hero.alignlab.config.database.TransactionTemplates
import com.hero.alignlab.domain.group.application.GroupUserScoreService
import com.hero.alignlab.domain.group.application.GroupUserService
import com.hero.alignlab.domain.group.domain.GroupUserScore
import com.hero.alignlab.domain.pose.application.PoseCountService
import com.hero.alignlab.domain.pose.application.PoseKeyPointSnapshotService
import com.hero.alignlab.domain.pose.domain.PoseCount
import com.hero.alignlab.domain.pose.domain.PoseKeyPointSnapshot
import com.hero.alignlab.domain.pose.domain.vo.PoseTotalCount
import com.hero.alignlab.domain.pose.domain.vo.PoseType.Companion.BAD_POSE
import com.hero.alignlab.event.model.LoadPoseSnapshot
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand All @@ -19,6 +23,8 @@ import org.springframework.transaction.event.TransactionalEventListener
class PoseSnapshotListener(
private val poseKeyPointSnapshotService: PoseKeyPointSnapshotService,
private val poseCountService: PoseCountService,
private val groupUserScoreService: GroupUserScoreService,
private val groupUserService: GroupUserService,
private val txTemplates: TransactionTemplates,
) {
@TransactionalEventListener
Expand Down Expand Up @@ -52,9 +58,28 @@ class PoseSnapshotListener(
date = targetDate
)

val score = poseCount.totalCount.count
.filter { (key, _) -> key in BAD_POSE }
.values
.sum()

val groupUsers = groupUserService.findAllByUid(event.poseSnapshot.uid)
val groupUserScore = groupUserScoreService.findAllByGroupUserIdIn(groupUsers.map { it.id })
.associateBy { it.groupUserId }

val needToUpdateScores = groupUsers.map { groupUser ->
groupUserScore[groupUser.id] ?: GroupUserScore(
groupId = groupUser.groupId,
groupUserId = groupUser.id,
uid = groupUser.uid,
score = score
)
}

txTemplates.writer.coExecuteOrNull {
poseKeyPointSnapshotService.bulkSave(keyPoints)
poseCountService.saveSync(poseCount)
groupUserScoreService.saveAllSync(needToUpdateScores)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.hero.alignlab.common.extension.mapper
import com.hero.alignlab.domain.auth.application.AuthFacade
import com.hero.alignlab.domain.auth.model.AUTH_TOKEN_KEY
import com.hero.alignlab.domain.auth.model.AuthUserToken
import com.hero.alignlab.domain.group.application.GroupUserScoreService
import com.hero.alignlab.domain.group.application.GroupUserService
import com.hero.alignlab.domain.user.application.UserInfoService
import com.hero.alignlab.exception.ErrorCode
Expand All @@ -27,6 +28,7 @@ class ReactiveConcurrentUserWebSocketHandler(
private val authFacade: AuthFacade,
private val userInfoService: UserInfoService,
private val groupUserService: GroupUserService,
private val groupUserScoreService: GroupUserScoreService,
) : WebSocketHandler {
private val logger = KotlinLogging.logger { }

Expand Down Expand Up @@ -78,9 +80,11 @@ class ReactiveConcurrentUserWebSocketHandler(
val userInfoByUid = userInfoService.findAllByIdsSync(uids.toList()).associateBy { it.id }
val groupUserss = groupUserService.findAllByGroupIdAndUidsSync(groupId, userInfoByUid.keys)
.associateBy { it.uid }
val groupUserScores = groupUserScoreService.findAllByGroupIdAndUidsSync(groupId, userInfoByUid.keys)
.associateBy { it.uid }

uidBySession.forEach { (_, websocketSession) ->
val message = ConcurrentMessage.of(groupId, userInfoByUid, groupUserss)
val message = ConcurrentMessage.of(groupId, userInfoByUid, groupUserss, groupUserScores)
.run { mapper.writeValueAsString(this) }

websocketSession
Expand Down Expand Up @@ -130,8 +134,10 @@ class ReactiveConcurrentUserWebSocketHandler(
private suspend fun sendUpdatedGroupStatus(groupId: Long, uidBySession: MutableMap<Long, WebSocketSession>) {
val userInfoByUid = userInfoService.findAllByIds(uidBySession.keys.toList()).associateBy { it.id }
val groupUsers = groupUserService.findAllByGroupIdAndUids(groupId, userInfoByUid.keys).associateBy { it.uid }
val groupUserScores = groupUserScoreService.findAllByGroupIdAndUidsSync(groupId, userInfoByUid.keys)
.associateBy { it.uid }

val message = ConcurrentMessage.of(groupId, userInfoByUid, groupUsers)
val message = ConcurrentMessage.of(groupId, userInfoByUid, groupUsers, groupUserScores)
.run { mapper.writeValueAsString(this) }

uidBySession.forEach { (_, websocketSession) ->
Expand Down
12 changes: 8 additions & 4 deletions src/main/kotlin/com/hero/alignlab/ws/model/ConcurrentMessage.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.hero.alignlab.ws.model

import com.hero.alignlab.domain.group.domain.GroupUser
import com.hero.alignlab.domain.group.domain.GroupUserScore
import com.hero.alignlab.domain.user.domain.UserInfo
import java.time.LocalDateTime
import java.util.concurrent.atomic.AtomicInteger

data class ConcurrentMessage(
val timestamp: LocalDateTime = LocalDateTime.now(),
Expand All @@ -21,8 +23,11 @@ data class ConcurrentMessage(
fun of(
groupId: Long,
userInfoByUid: Map<Long, UserInfo>,
groupUserss: Map<Long, GroupUser>
groupUserss: Map<Long, GroupUser>,
groupUserSocres: Map<Long, GroupUserScore>
): ConcurrentMessage {
val rank = AtomicInteger(1)

return ConcurrentMessage(
groupId = groupId,
groupUsers = userInfoByUid.mapNotNull { (uid, info) ->
Expand All @@ -32,9 +37,8 @@ data class ConcurrentMessage(
groupUserId = groupUSer.id,
uid = uid,
nickname = info.nickname,
// 더미 데이터
rank = 1,
score = 1
rank = rank.getAndIncrement(),
score = groupUserSocres[uid]?.score ?: 0,
)
}
)
Expand Down

0 comments on commit 1c8305b

Please sign in to comment.