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

调整BlockingRunner内部实现,移除同步代码块和 wait/notify 的使用;为部分配置类增加直接配置 Executor 的API #743

Merged
merged 4 commits into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ if (!System.getenv("IS_CI").toBoolean()) {
include(":simbot-component-http-server-api")
}

//include(":simbot-project-tests:simbot-project-test-j21")


@Suppress("NOTHING_TO_INLINE")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

package love.forte.simboot.spring.autoconfigure.application

import kotlinx.coroutines.Job
import love.forte.simbot.ExperimentalSimbotApi
import love.forte.simbot.application.*
import love.forte.simbot.core.application.*
Expand Down Expand Up @@ -47,7 +48,7 @@ public object SpringBoot :
val configuration = SpringBootApplicationConfiguration().also(configurator)
return create(configuration, builder)
}

/**
* 直接提供配置类进行构建。
*/
Expand Down Expand Up @@ -109,7 +110,7 @@ public interface SpringBootApplication : Application
*/
public interface SpringBootApplicationBuilder : ApplicationBuilder<SpringBootApplication>,
EventProcessableApplicationBuilder<SpringBootApplication> {

/**
* 配置内部的 core listener manager.
*
Expand All @@ -126,88 +127,88 @@ private class SpringBootApplicationBuilderImpl : SpringBootApplicationBuilder,
BaseApplicationBuilder<SpringBootApplication>() {
private var listenerManagerConfigurator: SimpleListenerManagerConfiguration.(environment: Application.Environment) -> Unit =
{}


/**
* 配置内部的 listener manager.
*/
override fun eventProcessor(configurator: SimpleListenerManagerConfiguration.(environment: Application.Environment) -> Unit) {
val old = listenerManagerConfigurator
listenerManagerConfigurator = { env -> old(env); configurator(env) }
}

private fun buildListenerManager(
appConfig: SpringBootApplicationConfiguration,
environment: Application.Environment,
): SimpleEventListenerManager {
val initial = SimpleListenerManagerConfiguration {
// TODO job?
coroutineContext = appConfig.coroutineContext
// Init context from app context (without Job)
coroutineContext = appConfig.coroutineContext.minusKey(Job)
}

return simpleListenerManager(initial = initial, block = fun SimpleListenerManagerConfiguration.() {
listenerManagerConfigurator(environment)
})
}


@OptIn(ExperimentalSimbotApi::class)
@Suppress("DuplicatedCode")
suspend fun build(configuration: SpringBootApplicationConfiguration): SpringBootApplication {
val components = buildComponents()

val logger = configuration.logger

val environment = SpringBootEnvironment(
components, logger, configuration.coroutineContext
)

logger.debug("Building listener manager...")
val listenerManager = buildListenerManager(configuration, environment)
logger.debug("Listener manager is built: {}", listenerManager)


logger.debug("Building providers...")
val providers = buildProviders(listenerManager, components, configuration)
logger.info("The size of providers built is {}", providers.size)
if (providers.isNotEmpty()) {
logger.debug("The built providers: {}", providers)
}

val application = SpringBootApplicationImpl(configuration, environment, listenerManager, providers)
// set application attribute
listenerManager.globalScopeContext[ApplicationAttributes.Application] = application

// complete.
complete(application)

// region register bots
// after complete.
logger.debug("Registering bots...")
val bots = registerBots(providers)

logger.info("Bots all registered. The size of bots: {}", bots.size)
if (bots.isNotEmpty()) {
logger.debug("The all registered bots: {}", bots)
}
val isAutoStartBots = configuration.isAutoStartBots
logger.debug("Auto start bots: {}", isAutoStartBots)
if (isAutoStartBots && bots.isNotEmpty()) {
bots.forEach { bot ->
logger.info("Starting bot {}", bot)
val started = bot.start()
logger.info("Bot [{}] started: {}", bot, started)
}
bots.forEach { bot ->
logger.info("Starting bot {}", bot)
val started = bot.start()
logger.info("Bot [{}] started: {}", bot, started)
}
}

if (isAutoStartBots && bots.isEmpty()) {
logger.debug("But the registered bots are empty.")
}
// endregion

return application
}

}


Expand All @@ -218,7 +219,7 @@ private class SpringBootApplicationImpl(
providerList: List<EventProvider>,
) : SpringBootApplication, BaseApplication() {
override val providers: List<EventProvider> = providerList.view()

override val coroutineContext = environment.coroutineContext
override val logger: Logger = environment.logger
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@

package love.forte.simbot.application

import kotlinx.coroutines.asCoroutineDispatcher
import love.forte.plugin.suspendtrans.annotation.JvmBlocking
import love.forte.simbot.Api4J
import love.forte.simbot.Component
import love.forte.simbot.ComponentFactory
import love.forte.simbot.ability.CompletionPerceivable
import love.forte.simbot.bot.Bot
import love.forte.simbot.bot.BotVerifyInfo
import org.slf4j.Logger
import java.util.concurrent.Executor
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext

Expand All @@ -33,7 +36,7 @@ public interface ApplicationFactory<
Builder : ApplicationBuilder<A>,
A : Application,
> {

/**
* 提供配置函数和构建器函数,构建一个 [Application] 实例。
*/
Expand All @@ -51,7 +54,7 @@ public interface ApplicationFactory<
* @param A 目标 [Application] 类型
*/
public interface ApplicationBuilder<A : Application> : CompletionPerceivable<A> {

/**
* 注册一个 [组件][Component].
*/
Expand All @@ -60,7 +63,7 @@ public interface ApplicationBuilder<A : Application> : CompletionPerceivable<A>
componentFactory: ComponentFactory<C, Config>,
configurator: Config.(perceivable: CompletionPerceivable<A>) -> Unit = {},
)

/**
* 注册一个事件提供者。
*/
Expand All @@ -69,15 +72,15 @@ public interface ApplicationBuilder<A : Application> : CompletionPerceivable<A>
eventProviderFactory: EventProviderFactory<P, Config>,
configurator: Config.(perceivable: CompletionPerceivable<A>) -> Unit = {},
)


/**
* 提供一个可以使用 [BotVerifyInfo] 进行通用性bot注册的配置方式。
*/
@ApplicationBuilderDsl
public fun bots(registrar: suspend BotRegistrar.() -> Unit)


/**
* 注册一个当 [Application] 构建完成后的回调函数。
*
Expand All @@ -91,7 +94,7 @@ public interface ApplicationBuilder<A : Application> : CompletionPerceivable<A>
*/
@ApplicationBuilderDsl
override fun onCompletion(handle: suspend (application: A) -> Unit)

}


Expand All @@ -105,7 +108,7 @@ public interface ApplicationBuilder<A : Application> : CompletionPerceivable<A>
*
*/
public interface BotRegistrar {

/**
* 当前环境中的所有事件提供者。
*
Expand All @@ -124,8 +127,8 @@ public interface BotRegistrar {
*
*/
public val providers: List<EventProvider>


/**
* 通过 [BotVerifyInfo] 中的 [组件信息][BotVerifyInfo.componentId]
* 去当前环境中寻找对应组件的、实现了 [Bot注册器][love.forte.simbot.bot.BotRegistrar] 的 [事件提供者][EventProvider],
Expand All @@ -150,7 +153,7 @@ public annotation class ApplicationBuilderDsl
* 整个应用程序进行构建所需的基本配置信息。
*/
public open class ApplicationConfiguration {

/**
* 当前application内所使用的协程上下文。
*
Expand All @@ -159,10 +162,21 @@ public open class ApplicationConfiguration {
*
*/
public open var coroutineContext: CoroutineContext = EmptyCoroutineContext

/**
* 提供一个用于Application内部的日志对象。
*/
public open var logger: Logger = love.forte.simbot.logger.LoggerFactory.getLogger("love.forte.simbot.application.ApplicationConfiguration")

public open var logger: Logger =
love.forte.simbot.logger.LoggerFactory.getLogger("love.forte.simbot.application.ApplicationConfiguration")

/**
* 向 [coroutineContext] 中应用一个 [Executor]。
* 面向Java开发者的友好API,在Java中可以更方便的指定一个调度器。
*
* @since 3.3.0
*/
@Api4J
public open fun appendExecutorToCoroutineContext(executor: Executor) {
coroutineContext += executor.asCoroutineDispatcher()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

package love.forte.simbot.core.application

import kotlinx.coroutines.Job
import love.forte.simbot.application.Application
import love.forte.simbot.application.ApplicationBuilder
import love.forte.simbot.application.ApplicationBuilderDsl
Expand Down Expand Up @@ -71,7 +72,7 @@ public abstract class BaseStandardApplicationBuilder<A : Application> : BaseAppl
environment: Application.Environment,
): SimpleEventListenerManager {
val initial = SimpleListenerManagerConfiguration {
coroutineContext = appConfig.coroutineContext
coroutineContext = appConfig.coroutineContext.minusKey(Job)
}

return simpleListenerManager(initial = initial) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@

package love.forte.simbot.core.event

import kotlinx.coroutines.Job
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.serialization.modules.EmptySerializersModule
import kotlinx.serialization.modules.SerializersModule
import love.forte.simbot.*
import love.forte.simbot.event.*
import love.forte.simbot.event.EventListenerRegistrationDescription.Companion.toRegistrationDescription
import love.forte.simbot.logger.LoggerFactory
import love.forte.simbot.logger.logger
import java.util.concurrent.Executor
import java.util.function.Function
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
Expand All @@ -43,7 +48,24 @@ public open class SimpleListenerManagerConfiguration {
*/
@SimpleEventManagerConfigDSL
public var coroutineContext: CoroutineContext = EmptyCoroutineContext

set(value) {
if (value[Job] != null) {
logger.warn("Job in SimpleListenerManagerConfiguration.coroutineContext will be dropped.")
}
field = value.minusKey(Job)
}

/**
* 向 [coroutineContext] 中应用一个 [Executor]。
* 面向Java开发者的友好API,在Java中可以更方便的指定一个调度器。
*
* @since 3.3.0
*/
@Api4J
public open fun appendExecutorToCoroutineContext(executor: Executor) {
coroutineContext += executor.asCoroutineDispatcher()
}

/**
* 事件流程拦截器的列表。
*/
Expand Down Expand Up @@ -266,6 +288,8 @@ public open class SimpleListenerManagerConfiguration {
public inline operator fun invoke(block: SimpleListenerManagerConfiguration.() -> Unit): SimpleListenerManagerConfiguration {
return SimpleListenerManagerConfiguration().also(block)
}

private val logger = LoggerFactory.logger<SimpleListenerManagerConfiguration>()
}

}
Expand Down
Loading
Loading