Skip to content

Commit

Permalink
Add threadpool context for interaction events.
Browse files Browse the repository at this point in the history
  • Loading branch information
gdude2002 committed Dec 31, 2024
1 parent d8a8aec commit 8a2fc89
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 58 deletions.
152 changes: 94 additions & 58 deletions kord-extensions/src/main/kotlin/dev/kordex/core/ExtensibleBot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromJsonElement
import org.koin.core.component.inject
import org.koin.dsl.bind
import kotlin.Throws
import kotlin.concurrent.thread

/**
Expand All @@ -74,6 +75,10 @@ public open class ExtensibleBot(
override var mutex: Mutex? = Mutex()
override var locking: Boolean = settings.membersBuilder.lockMemberRequests

@OptIn(DelicateCoroutinesApi::class)
public val interactionCoroutineContext: CoroutineDispatcher =
newFixedThreadPoolContext(settings.interactionContextThreads, "kord-extensions-interactions")

/** @suppress Meant for internal use by public inline function. **/
public val kordRef: Kord by inject()

Expand Down Expand Up @@ -185,6 +190,7 @@ public open class ExtensibleBot(
**/
public open suspend fun stop() {
dataCollector.stop()
interactionCoroutineContext.cancel()

getKoin().get<Kord>().logout()
}
Expand Down Expand Up @@ -215,6 +221,8 @@ public open class ExtensibleBot(
}

dataCollector.stop()
interactionCoroutineContext.cancel()

getKoin().get<Kord>().shutdown()

KordExContext.stopKoin()
Expand Down Expand Up @@ -288,30 +296,6 @@ public open class ExtensibleBot(
logger.warn { "Disconnected: $closeCode" }
}

on<ButtonInteractionCreateEvent> {
try {
getKoin().get<ComponentRegistry>().handle(this)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling button interaction event" }
}
}

on<SelectMenuInteractionCreateEvent> {
try {
getKoin().get<ComponentRegistry>().handle(this)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling select menu interaction event" }
}
}

on<ModalSubmitInteractionCreateEvent> {
try {
getKoin().get<ComponentRegistry>().handle(this)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling modal interaction event" }
}
}

if (settings.chatCommandsBuilder.enabled) {
on<MessageCreateEvent> {
try {
Expand All @@ -328,38 +312,6 @@ public open class ExtensibleBot(
}

if (settings.applicationCommandsBuilder.enabled) {
on<ChatInputCommandInteractionCreateEvent> {
try {
getKoin().get<ApplicationCommandRegistry>().handle(this)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling slash command interaction event" }
}
}

on<MessageCommandInteractionCreateEvent> {
try {
getKoin().get<ApplicationCommandRegistry>().handle(this)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling message command interaction event" }
}
}

on<UserCommandInteractionCreateEvent> {
try {
getKoin().get<ApplicationCommandRegistry>().handle(this)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling user command interaction event" }
}
}

on<AutoCompleteInteractionCreateEvent> {
try {
getKoin().get<ApplicationCommandRegistry>().handle(this)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling autocomplete interaction event" }
}
}

try {
getKoin().get<ApplicationCommandRegistry>().initialRegistration()
} catch (e: Exception) {
Expand Down Expand Up @@ -431,11 +383,95 @@ public open class ExtensibleBot(
}.catch { logger.error(it) { "Exception thrown from low-level event handler: $consumer" } }
.launchIn(kordRef)

/**
* @suppress Internal function used to additionally process all events. Don't call this yourself.
*/
@Suppress("TooGenericExceptionCaught")
public suspend inline fun publishEvent(event: Event) {
when (event) {
// General interaction events
is ButtonInteractionCreateEvent ->
kordRef.launch(interactionCoroutineContext) {
try {
getKoin().get<ComponentRegistry>().handle(event)

} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling button interaction event" }
}
}

is SelectMenuInteractionCreateEvent ->
kordRef.launch(interactionCoroutineContext) {
try {
getKoin().get<ComponentRegistry>().handle(event)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling select menu interaction event" }
}
}

is ModalSubmitInteractionCreateEvent ->
kordRef.launch(interactionCoroutineContext) {
try {
getKoin().get<ComponentRegistry>().handle(event)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling modal interaction event" }
}
}

// Interaction command events
is ChatInputCommandInteractionCreateEvent ->
if (settings.applicationCommandsBuilder.enabled) {
kordRef.launch(interactionCoroutineContext) {
try {
getKoin().get<ApplicationCommandRegistry>().handle(event)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling slash command interaction event" }
}
}
}

is MessageCommandInteractionCreateEvent ->
if (settings.applicationCommandsBuilder.enabled) {
kordRef.launch(interactionCoroutineContext) {
try {
getKoin().get<ApplicationCommandRegistry>().handle(event)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling message command interaction event" }
}
}
}

is UserCommandInteractionCreateEvent ->
if (settings.applicationCommandsBuilder.enabled) {
kordRef.launch(interactionCoroutineContext) {
try {
getKoin().get<ApplicationCommandRegistry>().handle(event)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling user command interaction event" }
}
}
}

is AutoCompleteInteractionCreateEvent ->
if (settings.applicationCommandsBuilder.enabled) {
kordRef.launch(interactionCoroutineContext) {
try {
getKoin().get<ApplicationCommandRegistry>().handle(event)
} catch (e: Exception) {
logger.error(e) { "Exception thrown while handling autocomplete interaction event" }
}
}
}
}

eventPublisher.emit(event)
}

/**
* @suppress Internal function used to process Kord events. Don't call this yourself.
*/
protected suspend inline fun sendKord(event: Event) {
eventPublisher.emit(event)
publishEvent(event)
}

/**
Expand All @@ -445,7 +481,7 @@ public open class ExtensibleBot(
*/
public suspend inline fun send(event: Event, filter: Boolean = true) {
if (!filter || settings.kordExEventFilter?.invoke(event) != false) {
eventPublisher.emit(event)
publishEvent(event)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ public open class ExtensibleBotBuilder {
/** Called to create an [ExtensibleBot], can be set to the constructor of your own subtype if needed. **/
public var constructor: (ExtensibleBotBuilder, String) -> ExtensibleBot = ::ExtensibleBot

/**
* The number of threads to use for interaction event coroutines.
*
* Defaults to double the available CPU cores, as returned by `Runtime.getRuntime().availableProcessors()`.
*/
public var interactionContextThreads: Int = Runtime.getRuntime().availableProcessors() * 2

/** @suppress Builder that shouldn't be set directly by the user. **/
public val aboutBuilder: AboutBuilder = AboutBuilder()

Expand Down

0 comments on commit 8a2fc89

Please sign in to comment.