Merge pull request 'test' (#244) from test into main

Reviewed-on: #244
This commit is contained in:
klaus 2024-12-02 12:05:30 +00:00
commit 4eb433d372
3 changed files with 39 additions and 1 deletions

View File

@ -26,6 +26,7 @@ repositories {
} }
dependencies { dependencies {
implementation("org.redisson:redisson-spring-data-27:3.19.2")
implementation("org.springframework.boot:spring-boot-starter-aop") implementation("org.springframework.boot:spring-boot-starter-aop")
implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-data-redis") implementation("org.springframework.boot:spring-boot-starter-data-redis")

View File

@ -1,5 +1,8 @@
package kr.co.vividnext.sodalive.configs package kr.co.vividnext.sodalive.configs
import org.redisson.Redisson
import org.redisson.api.RedissonClient
import org.redisson.config.Config
import org.springframework.beans.factory.annotation.Value import org.springframework.beans.factory.annotation.Value
import org.springframework.cache.annotation.EnableCaching import org.springframework.cache.annotation.EnableCaching
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
@ -26,6 +29,19 @@ class RedisConfig(
@Value("\${spring.redis.port}") @Value("\${spring.redis.port}")
private val port: Int private val port: Int
) { ) {
@Bean(destroyMethod = "shutdown")
fun redissonClient(): RedissonClient {
val config = Config()
config.useSingleServer()
.setAddress("rediss://$host:$port")
.setSslEnableEndpointIdentification(true)
.setSslTruststore(null)
.setDnsMonitoringInterval(30000)
.setConnectionMinimumIdleSize(0)
.setConnectionPoolSize(5)
return Redisson.create(config)
}
@Bean @Bean
fun redisConnectionFactory(): RedisConnectionFactory { fun redisConnectionFactory(): RedisConnectionFactory {
val clientConfiguration = LettuceClientConfiguration.builder() val clientConfiguration = LettuceClientConfiguration.builder()

View File

@ -1,17 +1,20 @@
package kr.co.vividnext.sodalive.scheduler package kr.co.vividnext.sodalive.scheduler
import kr.co.vividnext.sodalive.content.AudioContentService import kr.co.vividnext.sodalive.content.AudioContentService
import org.redisson.api.RedissonClient
import org.springframework.beans.factory.annotation.Qualifier import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
import org.springframework.scheduling.support.CronTrigger import org.springframework.scheduling.support.CronTrigger
import org.springframework.stereotype.Component import org.springframework.stereotype.Component
import java.util.concurrent.ScheduledFuture import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit
import javax.annotation.PostConstruct import javax.annotation.PostConstruct
import javax.annotation.PreDestroy import javax.annotation.PreDestroy
@Component @Component
class AudioContentReleaseScheduledTask( class AudioContentReleaseScheduledTask(
private val audioContentService: AudioContentService, private val audioContentService: AudioContentService,
private val redissonClient: RedissonClient,
@Qualifier("audioContentReleaseScheduler") private val audioContentReleaseScheduler: ThreadPoolTaskScheduler @Qualifier("audioContentReleaseScheduler") private val audioContentReleaseScheduler: ThreadPoolTaskScheduler
) { ) {
private var scheduledTask: ScheduledFuture<*>? = null private var scheduledTask: ScheduledFuture<*>? = null
@ -19,7 +22,25 @@ class AudioContentReleaseScheduledTask(
@PostConstruct @PostConstruct
fun release() { fun release() {
scheduledTask = audioContentReleaseScheduler.schedule( scheduledTask = audioContentReleaseScheduler.schedule(
{ audioContentService.releaseContent() }, {
val lockName = "lock:audioContentRelease"
val lock = redissonClient.getLock(lockName)
try {
// 5초 동안 락을 시도하고, Watchdog 활성화 (-1 설정)
if (lock.tryLock(5, -1, TimeUnit.SECONDS)) {
println("acquired : $lockName")
audioContentService.releaseContent()
} else {
println("Failed to acquire lock : $lockName")
}
} finally {
if (lock.isHeldByCurrentThread) {
lock.unlock()
println("release : $lockName")
}
}
},
CronTrigger("0 0/15 * * * *") CronTrigger("0 0/15 * * * *")
) )
} }