mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-24 15:00:38 +08:00
Ensure references is released after Job cancelling
This commit is contained in:
parent
9b191f6763
commit
8e37cdbf93
@ -14,10 +14,8 @@ import io.ktor.client.request.*
|
|||||||
import io.ktor.client.request.forms.MultiPartFormDataContent
|
import io.ktor.client.request.forms.MultiPartFormDataContent
|
||||||
import io.ktor.client.request.forms.formData
|
import io.ktor.client.request.forms.formData
|
||||||
import io.ktor.client.statement.HttpResponse
|
import io.ktor.client.statement.HttpResponse
|
||||||
import kotlinx.coroutines.CoroutineName
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.async
|
|
||||||
import kotlinx.coroutines.io.ByteReadChannel
|
import kotlinx.coroutines.io.ByteReadChannel
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import kotlinx.serialization.UnstableDefault
|
import kotlinx.serialization.UnstableDefault
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonConfiguration
|
import kotlinx.serialization.json.JsonConfiguration
|
||||||
@ -342,14 +340,15 @@ internal abstract class QQAndroidBotBase constructor(
|
|||||||
return json.parse(GroupAnnouncement.serializer(), rep)
|
return json.parse(GroupAnnouncement.serializer(), rep)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@LowLevelAPI
|
@LowLevelAPI
|
||||||
@MiraiExperimentalAPI
|
@MiraiExperimentalAPI
|
||||||
override suspend fun _lowLevelGetGroupActiveData(groupId: Long): GroupActiveData {
|
override suspend fun _lowLevelGetGroupActiveData(groupId: Long): GroupActiveData {
|
||||||
val data = network.async {
|
val data = network.async {
|
||||||
HttpClient().get<String> {
|
HttpClient().get<String> {
|
||||||
url("https://qqweb.qq.com/c/activedata/get_mygroup_data")
|
url("https://qqweb.qq.com/c/activedata/get_mygroup_data")
|
||||||
parameter("bkn",bkn)
|
parameter("bkn", bkn)
|
||||||
parameter("gc",groupId)
|
parameter("gc", groupId)
|
||||||
|
|
||||||
headers {
|
headers {
|
||||||
append(
|
append(
|
||||||
|
@ -180,6 +180,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
|||||||
// caches
|
// caches
|
||||||
private val _pendingEnabled = atomic(true)
|
private val _pendingEnabled = atomic(true)
|
||||||
internal val pendingEnabled get() = _pendingEnabled.value
|
internal val pendingEnabled get() = _pendingEnabled.value
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
internal var pendingIncomingPackets: LockFreeLinkedList<KnownPacketFactories.IncomingPacket<*>>? =
|
internal var pendingIncomingPackets: LockFreeLinkedList<KnownPacketFactories.IncomingPacket<*>>? =
|
||||||
LockFreeLinkedList()
|
LockFreeLinkedList()
|
||||||
@ -189,8 +190,10 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
|||||||
check(bot.isActive) { "bot is dead therefore network can't init" }
|
check(bot.isActive) { "bot is dead therefore network can't init" }
|
||||||
check(this@QQAndroidBotNetworkHandler.isActive) { "network is dead therefore can't init" }
|
check(this@QQAndroidBotNetworkHandler.isActive) { "network is dead therefore can't init" }
|
||||||
|
|
||||||
bot.friends.delegate.clear()
|
CancellationException("re-init").let { reInitCancellationException ->
|
||||||
bot.groups.delegate.clear()
|
bot.friends.delegate.clear { it.cancel(reInitCancellationException) }
|
||||||
|
bot.groups.delegate.clear { it.cancel(reInitCancellationException) }
|
||||||
|
}
|
||||||
|
|
||||||
if (!pendingEnabled) {
|
if (!pendingEnabled) {
|
||||||
pendingIncomingPackets = LockFreeLinkedList()
|
pendingIncomingPackets = LockFreeLinkedList()
|
||||||
|
@ -35,9 +35,14 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
|
|||||||
val configuration: BotConfiguration
|
val configuration: BotConfiguration
|
||||||
) : Bot(), CoroutineScope {
|
) : Bot(), CoroutineScope {
|
||||||
private val botJob = SupervisorJob(configuration.parentCoroutineContext[Job])
|
private val botJob = SupervisorJob(configuration.parentCoroutineContext[Job])
|
||||||
override val coroutineContext: CoroutineContext =
|
final override val coroutineContext: CoroutineContext =
|
||||||
configuration.parentCoroutineContext + botJob + (configuration.parentCoroutineContext[CoroutineExceptionHandler]
|
configuration.parentCoroutineContext + botJob + (configuration.parentCoroutineContext[CoroutineExceptionHandler]
|
||||||
?: CoroutineExceptionHandler { _, e -> logger.error("An exception was thrown under a coroutine of Bot", e) })
|
?: CoroutineExceptionHandler { _, e ->
|
||||||
|
logger.error(
|
||||||
|
"An exception was thrown under a coroutine of Bot",
|
||||||
|
e
|
||||||
|
)
|
||||||
|
})
|
||||||
override val context: Context by context.unsafeWeakRef()
|
override val context: Context by context.unsafeWeakRef()
|
||||||
|
|
||||||
@OptIn(LowLevelAPI::class)
|
@OptIn(LowLevelAPI::class)
|
||||||
@ -173,25 +178,28 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
|
|||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
|
||||||
|
init {
|
||||||
|
coroutineContext[Job]!!.invokeOnCompletion { throwable ->
|
||||||
|
network.close(throwable)
|
||||||
|
offlineListener.cancel(CancellationException("bot cancelled", throwable))
|
||||||
|
|
||||||
|
groups.delegate.clear() // job is cancelled, so child jobs are to be cancelled
|
||||||
|
friends.delegate.clear()
|
||||||
|
instances.removeIf { it.get()?.uin == this.uin }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(MiraiInternalAPI::class)
|
@OptIn(MiraiInternalAPI::class)
|
||||||
override fun close(cause: Throwable?) {
|
override fun close(cause: Throwable?) {
|
||||||
if (!this.botJob.isActive) {
|
if (!this.botJob.isActive) {
|
||||||
// already cancelled
|
// already cancelled
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
kotlin.runCatching {
|
|
||||||
if (cause == null) {
|
if (cause == null) {
|
||||||
this.botJob.cancel()
|
this.botJob.cancel()
|
||||||
network.close()
|
|
||||||
offlineListener.cancel()
|
|
||||||
} else {
|
} else {
|
||||||
this.botJob.cancel(CancellationException("bot cancelled", cause))
|
this.botJob.cancel(CancellationException("bot cancelled", cause))
|
||||||
network.close(cause)
|
|
||||||
offlineListener.cancel(CancellationException("bot cancelled", cause))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
groups.delegate.clear()
|
|
||||||
friends.delegate.clear()
|
|
||||||
instances.removeIf { it.get()?.uin == this.uin }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user