Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat/#173] 디스코드 훅 비동기 처리 풀 설정 #189

Merged
merged 9 commits into from
Jul 13, 2024
2 changes: 2 additions & 0 deletions api/src/main/kotlin/com/few/api/config/ApiConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.few.api.repo.config.ApiRepoConfig
import com.few.batch.config.BatchConfig
import com.few.storage.document.config.DocumentStorageConfig
import com.few.storage.image.config.ImageStorageConfig
import org.springframework.boot.context.properties.ConfigurationPropertiesScan
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import
Expand All @@ -15,6 +16,7 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc
@Import(ApiRepoConfig::class, BatchConfig::class, ImageStorageConfig::class, DocumentStorageConfig::class)
@EnableWebMvc
@EnableAsync
@ConfigurationPropertiesScan(basePackages = [ApiConfig.BASE_PACKAGE])
class ApiConfig {
companion object {
const val BASE_PACKAGE = "com.few.api"
Expand Down
39 changes: 39 additions & 0 deletions api/src/main/kotlin/com/few/api/config/ApiThreadPoolConfig.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.few.api.config

import com.few.api.config.properties.ThreadPoolProperties
import org.apache.juli.logging.LogFactory
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor

@Configuration
class ApiThreadPoolConfig {

private val log = LogFactory.getLog(ApiThreadPoolConfig::class.java)

companion object {
const val DISCORD_HOOK_EVENT_POOL = "discord-task-"
}

@Bean
@ConfigurationProperties(prefix = "discord.thread-pool")
fun disCordThreadPoolProperties(): ThreadPoolProperties {
return ThreadPoolProperties()
}

@Bean(DISCORD_HOOK_EVENT_POOL)
fun discordHookThreadPool() = ThreadPoolTaskExecutor().apply {
val properties = disCordThreadPoolProperties()
corePoolSize = properties.getCorePoolSize()
maxPoolSize = properties.getMaxPoolSize()
queueCapacity = properties.getQueueCapacity()
setWaitForTasksToCompleteOnShutdown(properties.getWaitForTasksToCompleteOnShutdown())
setAwaitTerminationSeconds(properties.getAwaitTerminationSeconds())
setThreadNamePrefix("discordHookThreadPool-")
setRejectedExecutionHandler { r, _ ->
log.warn("Discord Hook Event Task Rejected: $r")
}
initialize()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.few.api.config.properties

import com.few.api.exception.properties.NotSetPropertyException

data class ThreadPoolProperties(
var corePoolSize: Int? = null,
var maxPoolSize: Int? = null,
var queueCapacity: Int? = null,
var waitForTasksToCompleteOnShutdown: Boolean? = null,
var awaitTerminationSeconds: Int? = null
) {
fun getCorePoolSize(): Int {
return corePoolSize ?: throw NotSetPropertyException("core pool size")
}

fun getMaxPoolSize(): Int {
return maxPoolSize ?: throw NotSetPropertyException("max pool size")
}

fun getQueueCapacity(): Int {
return queueCapacity ?: throw NotSetPropertyException("queue capacity")
}

fun getWaitForTasksToCompleteOnShutdown(): Boolean {
return waitForTasksToCompleteOnShutdown ?: throw NotSetPropertyException("waitForTasksToCompleteOnShutdown")
}

fun getAwaitTerminationSeconds(): Int {
return awaitTerminationSeconds ?: throw NotSetPropertyException("awaitTerminationSeconds")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.few.api.domain.subscription.event

import com.few.api.client.subscription.SubscriptionClient
import com.few.api.client.subscription.dto.WorkbookSubscriptionArgs
import com.few.api.config.ApiThreadPoolConfig.Companion.DISCORD_HOOK_EVENT_POOL
import com.few.api.domain.subscription.event.dto.WorkbookSubscriptionEvent
import com.few.api.domain.subscription.service.WorkbookService
import com.few.api.domain.subscription.service.dto.ReadWorkbookTitleInDto
Expand All @@ -18,7 +19,7 @@ class WorkbookSubscriptionEventListener(
private val workbookService: WorkbookService
) {

@Async
@Async(value = DISCORD_HOOK_EVENT_POOL)
@EventListener
fun handleWorkbookSubscriptionEvent(event: WorkbookSubscriptionEvent) {
val title = ReadWorkbookTitleInDto(event.workbookId).let { dto ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.few.api.exception.properties

class NotSetPropertyException(property: String) : RuntimeException("$property is not set")
8 changes: 8 additions & 0 deletions api/src/main/resources/application-client-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ client:

webhook:
discord: "localhost:8080/webhook/discord/unused"

discord:
thread-pool:
core-pool-size: 5
max-pool-size: 15
queue-capacity: 30
wait-for-tasks-to-complete-on-shutdown: true
await-termination-seconds: 60
Comment on lines +10 to +15
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳굳 좋습니다. 혹시 몰라서 설정 정보 메모용으로 남겨둘께요

  • core-pool-size: 풀 최소 사이즈
  • max-pool-size: 풀 최대 사이즈
  • queue-capacity: 모두 사용중일 때 기다리게 할 개수
  • wait-for-tasks-to-complete-on-shutdown: 애플리케이션 셧다운 시 graceful 지원여부
  • await-termination-seconds: 애플리케이숀 셧다운 시 최대 기다릴 시간(초)

8 changes: 8 additions & 0 deletions api/src/main/resources/application-client-prd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ client:

webhook:
discord: ${WEBHOOK_DISCORD}

discord:
thread-pool:
core-pool-size: ${DISCORD_THREAD_POOL_CORE_POOL_SIZE:5}
max-pool-size: ${DISCORD_THREAD_POOL_MAX_POOL_SIZE:15}
queue-capacity: ${DISCORD_THREAD_POOL_QUEUE_CAPACITY:30}
wait-for-tasks-to-complete-on-shutdown: ${DISCORD_THREAD_POOL_WAIT_FOR_TASKS_TO_COMPLETE_ON_SHUTDOWN:true}
await-termination-seconds: ${DISCORD_THREAD_POOL_AWAIT_TERMINATION_SECONDS:60}
8 changes: 8 additions & 0 deletions api/src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,11 @@ client:

webhook:
discord: https://discord.com/api/webhooks/1234567890/abcdefg

discord:
thread-pool:
core-pool-size: 5
max-pool-size: 15
queue-capacity: 30
wait-for-tasks-to-complete-on-shutdown: true
await-termination-seconds: 60
Loading