Skip to content

Commit

Permalink
Create ThreadPoolManager for command and message processing
Browse files Browse the repository at this point in the history
  • Loading branch information
WinG4merBR committed Jan 12, 2025
1 parent 1285bee commit 15c9815
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 10 deletions.
2 changes: 2 additions & 0 deletions foxy/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ dependencies {
implementation("io.ktor:ktor-client-cio:${Versions.KTOR}")
implementation("io.ktor:ktor-server-content-negotiation:${Versions.KTOR}")

implementation("com.google.guava:guava:32.1.3-jre")

// Caching
implementation("com.github.ben-manes.caffeine:caffeine:${Versions.CAFFEINE}")

Expand Down
21 changes: 11 additions & 10 deletions foxy/src/main/kotlin/net/cakeyfox/foxy/FoxyInstance.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,21 @@ import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.coroutines.Job
import mu.KotlinLogging
import net.cakeyfox.artistry.ArtistryClient
import net.cakeyfox.common.Constants
import net.cakeyfox.foxy.command.FoxyCommandManager
import net.cakeyfox.foxy.command.component.FoxyComponentManager
import net.cakeyfox.foxy.listeners.GuildEventListener
import net.cakeyfox.foxy.listeners.InteractionEventListener
import net.cakeyfox.foxy.listeners.MajorEventListener
import net.cakeyfox.foxy.listeners.GuildListener
import net.cakeyfox.foxy.listeners.InteractionsListener
import net.cakeyfox.foxy.listeners.MessageListener
import net.cakeyfox.foxy.utils.ActivityUpdater
import net.cakeyfox.foxy.utils.config.FoxyConfig
import net.cakeyfox.foxy.utils.FoxyUtils
import net.cakeyfox.foxy.utils.analytics.TopggStatsSender
import net.cakeyfox.foxy.utils.database.MongoDBClient
import net.cakeyfox.foxy.utils.threads.ThreadPoolManager
import net.cakeyfox.foxy.utils.threads.ThreadUtils
import net.dv8tion.jda.api.OnlineStatus
import net.dv8tion.jda.api.entities.Activity
import net.dv8tion.jda.api.entities.User
Expand All @@ -28,7 +29,6 @@ import net.dv8tion.jda.api.sharding.ShardManager
import net.dv8tion.jda.api.utils.ChunkingFilter
import net.dv8tion.jda.api.utils.MemberCachePolicy
import net.dv8tion.jda.api.utils.cache.CacheFlag
import java.util.concurrent.ConcurrentLinkedQueue
import kotlin.concurrent.thread
import kotlin.reflect.jvm.jvmName

Expand All @@ -46,6 +46,8 @@ class FoxyInstance(
lateinit var selfUser: User
private lateinit var topggStatsSender: TopggStatsSender
private lateinit var environment: String
private val activeJobs = ThreadUtils.activeJobs
val threadPoolManager = ThreadPoolManager()

suspend fun start() {
val logger = KotlinLogging.logger(this::class.jvmName)
Expand Down Expand Up @@ -75,10 +77,11 @@ class FoxyInstance(
GatewayIntent.GUILD_EMOJIS_AND_STICKERS,
GatewayIntent.SCHEDULED_EVENTS
).addEventListeners(
MajorEventListener(this),
GuildEventListener(this),
InteractionEventListener(this)
GuildListener(this),
InteractionsListener(this),
MessageListener(this)
)
.setAutoReconnect(true)
.setStatus(OnlineStatus.ONLINE)
.setActivity(Activity.customStatus(Constants.DEFAULT_ACTIVITY(config.environment)))
.setShardsTotal(config.discord.totalShards)
Expand Down Expand Up @@ -121,6 +124,4 @@ class FoxyInstance(
}
})
}

private val activeJobs = ConcurrentLinkedQueue<Job>()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package net.cakeyfox.foxy.utils.threads

import kotlinx.coroutines.*
import mu.KotlinLogging
import net.dv8tion.jda.api.events.Event
import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
import java.util.concurrent.ExecutorService

class ThreadPoolManager {
private val coroutineMessageExecutor: ExecutorService = ThreadUtils.createThreadPool("MessageExecutor [%d]")
private val coroutineMessageDispatcher = coroutineMessageExecutor.asCoroutineDispatcher()
private val activeJobs = ThreadUtils.activeJobs

@OptIn(DelicateCoroutinesApi::class)
fun launchMessageJob(event: Event, block: suspend CoroutineScope.() -> Unit) {
val coroutineName = when (event) {
is MessageReceivedEvent -> "Message ${event.message} by user ${event.author}"
is SlashCommandInteractionEvent -> "Slash Command ${event.fullCommandName} by user ${event.user}"
is MessageContextInteractionEvent -> "User Command ${event.fullCommandName} by user ${event.user}"
else -> throw IllegalArgumentException("Event $event is not supported")
}

val start = System.currentTimeMillis()
val job = GlobalScope.launch(
coroutineMessageDispatcher + CoroutineName(coroutineName),
block = block
)

activeJobs.add(job)
job.invokeOnCompletion {
activeJobs.remove(job)
val end = System.currentTimeMillis()
val time = end - start
if (time > 10_000) {
KotlinLogging.logger("MessageExecutor").warn { "Job $job took ${time}ms to complete" }
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package net.cakeyfox.foxy.utils.threads

import com.google.common.util.concurrent.ThreadFactoryBuilder
import kotlinx.coroutines.Job
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

object ThreadUtils {
fun createThreadPool(name: String): ExecutorService =
Executors.newCachedThreadPool(ThreadFactoryBuilder().setNameFormat(name).build())

val activeJobs = ConcurrentLinkedQueue<Job>()
}

0 comments on commit 15c9815

Please sign in to comment.