mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-08 09:10:11 +08:00
Adjust job cancelling hence fix #65
This commit is contained in:
parent
0643e9eac9
commit
b2e0114e4f
@ -78,7 +78,9 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
} catch (e: CancellationException) {
|
||||
return@launch
|
||||
} catch (e: Throwable) {
|
||||
BotOfflineEvent.Dropped(bot).broadcast()
|
||||
if (this@QQAndroidBotNetworkHandler.isActive) {
|
||||
BotOfflineEvent.Dropped(bot).broadcast()
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
packetReceiveLock.withLock {
|
||||
@ -185,6 +187,8 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
|
||||
@UseExperimental(MiraiExperimentalAPI::class, ExperimentalTime::class)
|
||||
override suspend fun init(): Unit = coroutineScope {
|
||||
check(bot.isActive) { "bot is dead therefore network can't init" }
|
||||
check(this@QQAndroidBotNetworkHandler.isActive) { "network is dead therefore can't init" }
|
||||
MessageSvc.PbGetMsg(bot.client, MsgSvc.SyncFlag.START, currentTimeSeconds).sendWithoutExpect()
|
||||
|
||||
bot.qqs.delegate.clear()
|
||||
@ -494,6 +498,8 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
* 发送一个包, 但不期待任何返回.
|
||||
*/
|
||||
suspend fun OutgoingPacket.sendWithoutExpect() {
|
||||
check(bot.isActive) { "bot is dead therefore can't send any packet" }
|
||||
check(this@QQAndroidBotNetworkHandler.isActive) { "network is dead therefore can't send any packet" }
|
||||
logger.info("Send: ${this.commandName}")
|
||||
withContext(this@QQAndroidBotNetworkHandler.coroutineContext + CoroutineName("Packet sender")) {
|
||||
channel.send(delegate)
|
||||
@ -509,6 +515,9 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
require(timeoutMillis > 0) { "timeoutMillis must > 0" }
|
||||
require(retry >= 0) { "retry must >= 0" }
|
||||
|
||||
check(bot.isActive) { "bot is dead therefore can't send any packet" }
|
||||
check(this@QQAndroidBotNetworkHandler.isActive) { "network is dead therefore can't send any packet" }
|
||||
|
||||
var lastException: Exception? = null
|
||||
if (retry == 0) {
|
||||
val handler = PacketListener(commandName = commandName, sequenceId = sequenceId)
|
||||
|
@ -7,7 +7,7 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE", "unused", "FunctionName", "NOTHING_TO_INLINE")
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE", "unused", "FunctionName", "NOTHING_TO_INLINE", "UnusedImport")
|
||||
|
||||
package net.mamoe.mirai
|
||||
|
||||
@ -35,7 +35,8 @@ import kotlin.jvm.JvmStatic
|
||||
*
|
||||
* 注: Bot 为全协程实现, 没有其他任务时若不使用 [join], 主线程将会退出.
|
||||
*
|
||||
* @see Contact
|
||||
* @see Contact 联系人
|
||||
* @see kotlinx.coroutines.isActive 判断 [Bot] 是否正常运行中. (在线, 且没有被 [close])
|
||||
*/
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
abstract class Bot : CoroutineScope {
|
||||
@ -195,7 +196,9 @@ abstract class Bot : CoroutineScope {
|
||||
|
||||
/**
|
||||
* 登录, 或重新登录.
|
||||
* 重新登录时不会再次拉取联系人列表.
|
||||
* 这个函数总是关闭一切现有网路任务, 然后重新登录并重新缓存好友列表和群列表.
|
||||
*
|
||||
* 一般情况下不需要重新登录. Mirai 能够自动处理掉线情况.
|
||||
*
|
||||
* 最终调用 [net.mamoe.mirai.network.BotNetworkHandler.relogin]
|
||||
*
|
||||
@ -231,24 +234,19 @@ abstract class Bot : CoroutineScope {
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* 关闭这个 [Bot], 停止一切相关活动. 所有引用都会被释放.
|
||||
* 关闭这个 [Bot], 立即取消 [Bot] 的 [kotlinx.coroutines.SupervisorJob].
|
||||
* 之后 [kotlinx.coroutines.isActive] 将会返回 `false`.
|
||||
*
|
||||
* 注: 不可重新登录. 必须重新实例化一个 [Bot].
|
||||
* **注意:** 不可重新登录. 必须重新实例化一个 [Bot].
|
||||
*
|
||||
* @param cause 原因. 为 null 时视为正常关闭, 非 null 时视为异常关闭
|
||||
*
|
||||
* @see closeAndJoin
|
||||
* @see closeAndJoin 取消并 [Bot.join], 以确保 [Bot] 相关的活动被完全关闭
|
||||
*/
|
||||
abstract fun close(cause: Throwable? = null)
|
||||
|
||||
// region extensions
|
||||
|
||||
@Deprecated(message = "这个函数有歧义, 将在不久后删除", replaceWith = ReplaceWith("getFriend(this.toLong())"))
|
||||
fun Int.qq(): QQ = getFriend(this.toLong())
|
||||
|
||||
@Deprecated(message = "这个函数有歧义, 将在不久后删除", replaceWith = ReplaceWith("getFriend(this)"))
|
||||
fun Long.qq(): QQ = getFriend(this)
|
||||
|
||||
final override fun toString(): String {
|
||||
return "Bot(${uin})"
|
||||
}
|
||||
|
@ -89,22 +89,17 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
|
||||
private val offlineListener: Listener<BotOfflineEvent> = this.subscribeAlways { event ->
|
||||
when (event) {
|
||||
is BotOfflineEvent.Dropped -> {
|
||||
if (!_network.isActive) {
|
||||
return@subscribeAlways
|
||||
}
|
||||
bot.logger.info("Connection dropped or lost by server, retrying login")
|
||||
|
||||
var lastFailedException: Throwable? = null
|
||||
repeat(configuration.reconnectionRetryTimes) {
|
||||
try {
|
||||
network.relogin()
|
||||
logger.info("Reconnected successfully")
|
||||
return@subscribeAlways
|
||||
} catch (e: Throwable) {
|
||||
lastFailedException = e
|
||||
delay(configuration.reconnectPeriodMillis)
|
||||
}
|
||||
}
|
||||
if (lastFailedException != null) {
|
||||
throw lastFailedException!!
|
||||
}
|
||||
tryNTimesOrException(configuration.reconnectionRetryTimes) {
|
||||
delay(configuration.reconnectPeriodMillis)
|
||||
network.relogin()
|
||||
logger.info("Reconnected successfully")
|
||||
return@subscribeAlways
|
||||
}?.let { throw it }
|
||||
}
|
||||
is BotOfflineEvent.Active -> {
|
||||
val msg = if (event.cause == null) {
|
||||
@ -112,12 +107,12 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
|
||||
} else {
|
||||
" with exception: " + event.cause.message
|
||||
}
|
||||
bot.logger.info("Bot is closed manually$msg")
|
||||
close(CancellationException(event.toString()))
|
||||
bot.logger.info { "Bot is closed manually$msg" }
|
||||
closeAndJoin(CancellationException(event.toString()))
|
||||
}
|
||||
is BotOfflineEvent.Force -> {
|
||||
bot.logger.info("Connection occupied by another android device: ${event.message}")
|
||||
close(ForceOfflineException(event.toString()))
|
||||
bot.logger.info { "Connection occupied by another android device: ${event.message}" }
|
||||
closeAndJoin(ForceOfflineException(event.toString()))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,15 +171,19 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
|
||||
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
override fun close(cause: Throwable?) {
|
||||
if (!this.botJob.isActive) {
|
||||
// already cancelled
|
||||
return
|
||||
}
|
||||
kotlin.runCatching {
|
||||
if (cause == null) {
|
||||
this.botJob.cancel()
|
||||
network.close()
|
||||
this.botJob.complete()
|
||||
offlineListener.complete()
|
||||
offlineListener.cancel()
|
||||
} else {
|
||||
this.botJob.cancel(CancellationException("bot cancelled", cause))
|
||||
network.close(cause)
|
||||
this.botJob.completeExceptionally(cause)
|
||||
offlineListener.completeExceptionally(cause)
|
||||
offlineListener.cancel(CancellationException("bot cancelled", cause))
|
||||
}
|
||||
}
|
||||
groups.delegate.clear()
|
||||
|
Loading…
Reference in New Issue
Block a user