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 @PostConstruct fun release() { scheduledTask = audioContentReleaseScheduler.schedule( { 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 * * * *") ) } @PreDestroy fun stopReleaseScheduler() { scheduledTask?.cancel(false) audioContentReleaseScheduler.shutdown() } }