Skip to content

Commit

Permalink
Add autocomplete coroutine context, switch to less delicate API
Browse files Browse the repository at this point in the history
Cache an Arguments object per-command for autocomplete purposes
  • Loading branch information
gdude2002 committed Jan 8, 2025
1 parent 62d21bb commit 88037bc
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 5 deletions.
18 changes: 15 additions & 3 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 java.util.concurrent.Executors
import kotlin.Throws
import kotlin.concurrent.thread

Expand All @@ -75,9 +76,20 @@ public open class ExtensibleBot(
override var mutex: Mutex? = Mutex()
override var locking: Boolean = settings.membersBuilder.lockMemberRequests

@OptIn(DelicateCoroutinesApi::class)
protected var autoCompleteCoroutineThreads: Int = 0
protected var interactionCoroutineThreads: Int = 0

public val autoCompleteCoroutineContext: CoroutineDispatcher =
Executors.newFixedThreadPool(settings.autoCompleteContextThreads) { r ->
autoCompleteCoroutineThreads++
Thread(r, "kordex-interactions-${autoCompleteCoroutineThreads - 1}")
}.asCoroutineDispatcher()

public val interactionCoroutineContext: CoroutineDispatcher =
newFixedThreadPoolContext(settings.interactionContextThreads, "kord-extensions-interactions")
Executors.newFixedThreadPool(settings.interactionContextThreads) { r ->
interactionCoroutineThreads++
Thread(r, "kordex-autocomplete-${interactionCoroutineThreads - 1}")
}.asCoroutineDispatcher()

/** @suppress Meant for internal use by public inline function. **/
public val kordRef: Kord by inject()
Expand Down Expand Up @@ -454,7 +466,7 @@ public open class ExtensibleBot(

is AutoCompleteInteractionCreateEvent ->
if (settings.applicationCommandsBuilder.enabled) {
kordRef.launch(interactionCoroutineContext) {
kordRef.launch(autoCompleteCoroutineContext) {
try {
getKoin().get<ApplicationCommandRegistry>().handle(event)
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,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 autocomplete event coroutines.
*
* Defaults to the available CPU cores, as returned by `Runtime.getRuntime().availableProcessors()`.
*/
public var autoCompleteContextThreads: Int = Runtime.getRuntime().availableProcessors()

/**
* The number of threads to use for interaction event coroutines.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,8 @@ public open class DefaultApplicationCommandRegistry : ApplicationCommandRegistry

option ?: return logger.trace { "Autocomplete event for command $command doesn't have a focused option." }

val arguments = command.arguments!!()
val arguments = command.cachedArguments
?: return logger.trace { "Command $command doesn't have a cached arguments object for some reason." }

val arg = arguments.args.firstOrNull {
it.getDefaultTranslatedDisplayName(translationsProvider, command) == option.first
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public open class StorageAwareApplicationCommandRegistry(

option ?: return logger.trace { "Autocomplete event for command $command doesn't have a focused option." }

val arguments = command.arguments!!()
val arguments = command.cachedArguments!!

val arg = arguments.args.firstOrNull {
it.getDefaultTranslatedDisplayName(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public abstract class SlashCommand<C : SlashCommandContext<*, A, M>, A : Argumen
public open val parentCommand: SlashCommand<*, *, *>? = null,
public open val parentGroup: SlashGroup? = null,
) : ApplicationCommand<ChatInputCommandInteractionCreateEvent>(extension) {
/** @suppress Cached arguments object only used by the autocomplete event handler. **/
public var cachedArguments: A? = null

/** @suppress This is only meant for use by code that extends the command system. **/
public val kxLogger: KLogger = KotlinLogging.logger {}

Expand Down Expand Up @@ -171,6 +174,8 @@ public abstract class SlashCommand<C : SlashCommandContext<*, A, M>, A : Argumen
"instead."
)
}

cachedArguments = arguments?.invoke()
}

/** Call this to supply a command [body], to be called when the command is executed. **/
Expand Down

0 comments on commit 88037bc

Please sign in to comment.