commit
4eb433d372
|
@ -26,6 +26,7 @@ repositories {
|
|||
}
|
||||
|
||||
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-data-jpa")
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-redis")
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
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.cache.annotation.EnableCaching
|
||||
import org.springframework.context.annotation.Bean
|
||||
|
@ -26,6 +29,19 @@ class RedisConfig(
|
|||
@Value("\${spring.redis.port}")
|
||||
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
|
||||
fun redisConnectionFactory(): RedisConnectionFactory {
|
||||
val clientConfiguration = LettuceClientConfiguration.builder()
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
package kr.co.vividnext.sodalive.scheduler
|
||||
|
||||
import kr.co.vividnext.sodalive.content.AudioContentService
|
||||
import org.redisson.api.RedissonClient
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
|
||||
import org.springframework.scheduling.support.CronTrigger
|
||||
import org.springframework.stereotype.Component
|
||||
import java.util.concurrent.ScheduledFuture
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.annotation.PostConstruct
|
||||
import javax.annotation.PreDestroy
|
||||
|
||||
@Component
|
||||
class AudioContentReleaseScheduledTask(
|
||||
private val audioContentService: AudioContentService,
|
||||
private val redissonClient: RedissonClient,
|
||||
@Qualifier("audioContentReleaseScheduler") private val audioContentReleaseScheduler: ThreadPoolTaskScheduler
|
||||
) {
|
||||
private var scheduledTask: ScheduledFuture<*>? = null
|
||||
|
@ -19,7 +22,25 @@ class AudioContentReleaseScheduledTask(
|
|||
@PostConstruct
|
||||
fun release() {
|
||||
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 * * * *")
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue