mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-11 02:50:15 +08:00
Capture exceptions when saving
This commit is contained in:
parent
ad53f315ac
commit
2c38ce920a
@ -13,14 +13,12 @@ package net.mamoe.mirai.console.data
|
|||||||
|
|
||||||
import kotlinx.atomicfu.atomic
|
import kotlinx.atomicfu.atomic
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
import net.mamoe.mirai.console.MiraiConsole
|
||||||
import net.mamoe.mirai.console.internal.command.qualifiedNameOrTip
|
import net.mamoe.mirai.console.internal.command.qualifiedNameOrTip
|
||||||
import net.mamoe.mirai.console.internal.plugin.updateWhen
|
import net.mamoe.mirai.console.internal.plugin.updateWhen
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||||
import net.mamoe.mirai.console.util.ConsoleInternalAPI
|
import net.mamoe.mirai.console.util.ConsoleInternalAPI
|
||||||
import net.mamoe.mirai.utils.DefaultLogger
|
import net.mamoe.mirai.utils.*
|
||||||
import net.mamoe.mirai.utils.currentTimeMillis
|
|
||||||
import net.mamoe.mirai.utils.error
|
|
||||||
import net.mamoe.mirai.utils.withSwitch
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 链接自动保存的 [PluginData].
|
* 链接自动保存的 [PluginData].
|
||||||
@ -51,17 +49,35 @@ public open class AutoSavePluginData private constructor(
|
|||||||
this.storage_ = storage
|
this.storage_ = storage
|
||||||
this.owner_ = owner
|
this.owner_ = owner
|
||||||
|
|
||||||
owner_.coroutineContext[Job]?.invokeOnCompletion { doSave() }
|
owner_.coroutineContext[Job]?.invokeOnCompletion {
|
||||||
|
kotlin.runCatching {
|
||||||
|
doSave()
|
||||||
|
}.onFailure { e ->
|
||||||
|
owner_.coroutineContext[CoroutineExceptionHandler]?.handleException(owner_.coroutineContext, e)
|
||||||
|
?.let { return@invokeOnCompletion }
|
||||||
|
MiraiConsole.mainLogger.error(
|
||||||
|
"An exception occurred when saving config ${this@AutoSavePluginData::class.qualifiedNameOrTip} " +
|
||||||
|
"but CoroutineExceptionHandler not found in PluginDataHolder.coroutineContext for ${owner::class.qualifiedNameOrTip}",
|
||||||
|
e
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldPerformAutoSaveWheneverChanged()) {
|
if (shouldPerformAutoSaveWheneverChanged()) {
|
||||||
owner_.launch(CoroutineName("AutoSavePluginData.timedAutoSave: ${this::class.qualifiedNameOrTip}")) {
|
owner_.launch(CoroutineName("AutoSavePluginData.timedAutoSave: ${this::class.qualifiedNameOrTip}")) {
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
|
try {
|
||||||
delay(autoSaveIntervalMillis_.last) // 定时自动保存一次, 用于 kts 序列化的对象
|
delay(autoSaveIntervalMillis_.last) // 定时自动保存一次, 用于 kts 序列化的对象
|
||||||
|
} catch (e: CancellationException) {
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
withContext(owner_.coroutineContext) {
|
||||||
doSave()
|
doSave()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
@Volatile
|
@Volatile
|
||||||
@ -78,19 +94,29 @@ public open class AutoSavePluginData private constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private val updaterBlock: suspend CoroutineScope.() -> Unit = {
|
private val updaterBlock: suspend CoroutineScope.() -> Unit = l@{
|
||||||
if (::storage_.isInitialized) {
|
if (::storage_.isInitialized) {
|
||||||
currentFirstStartTime_.updateWhen({ it == 0L }, { currentTimeMillis })
|
currentFirstStartTime_.updateWhen({ it == 0L }, { currentTimeMillis })
|
||||||
|
try {
|
||||||
delay(autoSaveIntervalMillis_.first.coerceAtLeast(1000)) // for safety
|
delay(autoSaveIntervalMillis_.first.coerceAtLeast(1000)) // for safety
|
||||||
|
} catch (e: CancellationException) {
|
||||||
|
return@l
|
||||||
|
}
|
||||||
|
|
||||||
if (lastAutoSaveJob_ == this.coroutineContext[Job]) {
|
if (lastAutoSaveJob_ == this.coroutineContext[Job]) {
|
||||||
|
|
||||||
|
withContext(owner_.coroutineContext) {
|
||||||
doSave()
|
doSave()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (currentFirstStartTime_.updateWhen(
|
if (currentFirstStartTime_.updateWhen(
|
||||||
{ currentTimeMillis - it >= autoSaveIntervalMillis_.last },
|
{ currentTimeMillis - it >= autoSaveIntervalMillis_.last },
|
||||||
{ 0 })
|
{ 0 })
|
||||||
) doSave()
|
) {
|
||||||
|
withContext(owner_.coroutineContext) {
|
||||||
|
doSave()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,5 +140,25 @@ public open class AutoSavePluginData private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal val debuggingLogger1 by lazy {
|
internal val debuggingLogger1 by lazy {
|
||||||
DefaultLogger("debug").withSwitch(false)
|
DefaultLogger("debug").withSwitch(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun <R> MiraiLogger.runCatchingLog(message: String? = null, block: () -> R): R? {
|
||||||
|
return kotlin.runCatching {
|
||||||
|
block()
|
||||||
|
}.onFailure {
|
||||||
|
if (message != null) {
|
||||||
|
error(message, it)
|
||||||
|
} else error(it)
|
||||||
|
}.getOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||||
|
@kotlin.internal.LowPriorityInOverloadResolution
|
||||||
|
internal inline fun <R> MiraiLogger.runCatchingLog(message: (Throwable) -> String, block: () -> R): R? {
|
||||||
|
return kotlin.runCatching {
|
||||||
|
block()
|
||||||
|
}.onFailure {
|
||||||
|
error(message(it), it)
|
||||||
|
}.getOrNull()
|
||||||
}
|
}
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.console.data
|
package net.mamoe.mirai.console.data
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||||
@ -35,6 +36,9 @@ public interface PluginDataHolder {
|
|||||||
/**
|
/**
|
||||||
* 可以持有相关 [AutoSavePluginData] 的对象.
|
* 可以持有相关 [AutoSavePluginData] 的对象.
|
||||||
*
|
*
|
||||||
|
* ### 实现 [AutoSavePluginDataHolder]
|
||||||
|
* [CoroutineScope.coroutineContext] 中应用 [CoroutineExceptionHandler]
|
||||||
|
*
|
||||||
* @see net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
* @see net.mamoe.mirai.console.plugin.jvm.JvmPlugin
|
||||||
*/
|
*/
|
||||||
@ConsoleExperimentalAPI
|
@ConsoleExperimentalAPI
|
||||||
|
Loading…
Reference in New Issue
Block a user