From 534aaecb6e78a91c41858c069f2d5aab1c5216e1 Mon Sep 17 00:00:00 2001 From: dalbodeule <11470513+dalbodeule@users.noreply.github.com> Date: Wed, 28 Aug 2024 21:01:35 +0900 Subject: [PATCH] debug on eagerLoading (1x) --- .../chzzk_bot/common/services/UserService.kt | 24 +++++++++--- .../chzzk_bot/webserver/routes/ApiRoutes.kt | 3 +- .../webserver/utils/ChzzkUserCache.kt | 38 +++++++++++++++++++ 3 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/utils/ChzzkUserCache.kt diff --git a/common/src/main/kotlin/space/mori/chzzk_bot/common/services/UserService.kt b/common/src/main/kotlin/space/mori/chzzk_bot/common/services/UserService.kt index 1e1242f..05896eb 100644 --- a/common/src/main/kotlin/space/mori/chzzk_bot/common/services/UserService.kt +++ b/common/src/main/kotlin/space/mori/chzzk_bot/common/services/UserService.kt @@ -1,5 +1,6 @@ package space.mori.chzzk_bot.common.services +import org.jetbrains.exposed.dao.load import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction import space.mori.chzzk_bot.common.models.User @@ -27,13 +28,16 @@ object UserService { fun updateUser(user: User, discordID: Long): User { return transaction { user.discord = discordID + user.load(User::subordinates, User::managers) user } } fun getUser(id: Int): User? { return transaction { - User.findById(id) + val user = User.findById(id) + user?.load(User::subordinates, User::managers) + user } } @@ -41,7 +45,9 @@ object UserService { return transaction { val users = User.find(Users.discord eq discordID) - users.firstOrNull() + val user = users.firstOrNull() + user?.load(User::subordinates, User::managers) + user } } @@ -49,7 +55,9 @@ object UserService { return transaction { val users = User.find(Users.token eq chzzkID) - users.firstOrNull() + val user = users.firstOrNull() + user?.load(User::subordinates, User::managers) + user } } @@ -57,7 +65,9 @@ object UserService { return transaction { val users = User.find(Users.liveAlertGuild eq discordGuildId) - users.firstOrNull() + val user = users.firstOrNull() + user?.load(User::subordinates, User::managers) + user } } @@ -65,7 +75,9 @@ object UserService { return transaction { val users = User.find(Users.naverId eq naverId) - users.firstOrNull() + val user = users.firstOrNull() + user?.load(User::subordinates, User::managers) + user } } @@ -81,6 +93,8 @@ object UserService { user.liveAlertChannel = channelId user.liveAlertMessage = alertMessage ?: "" + user.load(User::subordinates, User::managers) + user } } diff --git a/webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/routes/ApiRoutes.kt b/webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/routes/ApiRoutes.kt index a84b57a..20aafbf 100644 --- a/webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/routes/ApiRoutes.kt +++ b/webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/routes/ApiRoutes.kt @@ -18,6 +18,7 @@ import space.mori.chzzk_bot.common.services.UserService import space.mori.chzzk_bot.common.utils.getStreamInfo import space.mori.chzzk_bot.common.utils.getUserInfo import space.mori.chzzk_bot.webserver.UserSession +import space.mori.chzzk_bot.webserver.utils.ChzzkUsercache @Serializable data class GetUserDTO( @@ -119,7 +120,7 @@ fun Routing.apiRoutes() { val subordinates = user.subordinates println(subordinates) returnUsers.addAll(subordinates.map { - val subStatus = it.token?.let { it1 -> getStreamInfo(it1) } + val subStatus = it.token?.let { token -> ChzzkUsercache.getCachedUser(token) } return@map if (it.token == null || subStatus?.content == null) { null } else { diff --git a/webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/utils/ChzzkUserCache.kt b/webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/utils/ChzzkUserCache.kt new file mode 100644 index 0000000..ca6b479 --- /dev/null +++ b/webserver/src/main/kotlin/space/mori/chzzk_bot/webserver/utils/ChzzkUserCache.kt @@ -0,0 +1,38 @@ +package space.mori.chzzk_bot.webserver.utils + +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import org.slf4j.LoggerFactory +import space.mori.chzzk_bot.common.utils.IData +import space.mori.chzzk_bot.common.utils.IStreamInfo +import space.mori.chzzk_bot.common.utils.getStreamInfo +import java.time.Instant +import java.util.concurrent.ConcurrentHashMap + +object ChzzkUsercache { + private val cache = ConcurrentHashMap() + private const val EXP_SECONDS = 600L + private val mutex = Mutex() + private val logger = LoggerFactory.getLogger(this::class.java) + + suspend fun getCachedUser(id: String): IData? { + val now = Instant.now() + var user = cache[id] + + if(user == null || user.timestamp.plusSeconds(EXP_SECONDS).isBefore(now)) { + mutex.withLock { + if(user == null || user?.timestamp?.plusSeconds(EXP_SECONDS)?.isBefore(now) != false) { + user = CachedUser(getStreamInfo(id)) + user?.let { cache[id] = user!! } + } + } + } + + return cache[id]?.user + } +} + +data class CachedUser( + val user: IData, + val timestamp: Instant = Instant.now(), +) \ No newline at end of file