Commit 0f0ca8e2 authored by Him188's avatar Him188

Deprecate `Bot.subscribe*` for better Coroutine life cycle management; Add docs

parent 5db9d1d0
...@@ -391,6 +391,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo ...@@ -391,6 +391,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
init { init {
val listener = bot.subscribeAlways<BotReloginEvent>(priority = MONITOR) { val listener = bot.subscribeAlways<BotReloginEvent>(priority = MONITOR) {
if (bot != this.bot) return@subscribeAlways
this@QQAndroidBotNetworkHandler.launch { syncMessageSvc() } this@QQAndroidBotNetworkHandler.launch { syncMessageSvc() }
} }
supervisor.invokeOnCompletion { listener.cancel() } supervisor.invokeOnCompletion { listener.cancel() }
......
...@@ -92,6 +92,9 @@ abstract class BotImpl<N : BotNetworkHandler> constructor( ...@@ -92,6 +92,9 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
@Suppress("unused") @Suppress("unused")
private val offlineListener: Listener<BotOfflineEvent> = private val offlineListener: Listener<BotOfflineEvent> =
this@BotImpl.subscribeAlways(concurrency = Listener.ConcurrencyKind.LOCKED) { event -> this@BotImpl.subscribeAlways(concurrency = Listener.ConcurrencyKind.LOCKED) { event ->
if (event.bot != this.bot) {
return@subscribeAlways
}
if (network.areYouOk() && event !is BotOfflineEvent.Force) { if (network.areYouOk() && event !is BotOfflineEvent.Force) {
// avoid concurrent re-login tasks // avoid concurrent re-login tasks
return@subscribeAlways return@subscribeAlways
...@@ -108,8 +111,10 @@ abstract class BotImpl<N : BotNetworkHandler> constructor( ...@@ -108,8 +111,10 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
val time = measureTime { val time = measureTime {
tailrec suspend fun reconnect() { tailrec suspend fun reconnect() {
retryCatching<Unit>(configuration.reconnectionRetryTimes, retryCatching<Unit>(
except = LoginFailedException::class) { tryCount, _ -> configuration.reconnectionRetryTimes,
except = LoginFailedException::class
) { tryCount, _ ->
if (tryCount != 0) { if (tryCount != 0) {
delay(configuration.reconnectPeriodMillis) delay(configuration.reconnectPeriodMillis)
} }
......
...@@ -15,7 +15,6 @@ import kotlinx.atomicfu.atomic ...@@ -15,7 +15,6 @@ import kotlinx.atomicfu.atomic
import net.mamoe.mirai.event.internal.broadcastInternal import net.mamoe.mirai.event.internal.broadcastInternal
import net.mamoe.mirai.utils.MiraiExperimentalAPI import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.PlannedRemoval
import net.mamoe.mirai.utils.SinceMirai import net.mamoe.mirai.utils.SinceMirai
import kotlin.jvm.JvmSynthetic import kotlin.jvm.JvmSynthetic
import kotlin.jvm.Volatile import kotlin.jvm.Volatile
...@@ -161,11 +160,3 @@ interface BroadcastControllable : Event { ...@@ -161,11 +160,3 @@ interface BroadcastControllable : Event {
get() = true get() = true
} }
@PlannedRemoval("1.1.0")
@Deprecated(
"use AbstractEvent and implement CancellableEvent",
level = DeprecationLevel.ERROR,
replaceWith = ReplaceWith("AbstractEvent", "net.mamoe.mirai.event.AbstractEvent")
)
abstract class AbstractCancellableEvent : AbstractEvent(), CancellableEvent
...@@ -418,7 +418,6 @@ open class MessageSubscribersBuilder<M : MessageEvent, out Ret, R : RR, RR>( ...@@ -418,7 +418,6 @@ open class MessageSubscribersBuilder<M : MessageEvent, out Ret, R : RR, RR>(
//// DEPRECATED AND INTERNAL //// //// DEPRECATED AND INTERNAL ////
///////////////////////////////// /////////////////////////////////
@PublishedApi
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE", "UNCHECKED_CAST") // false positive @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE", "UNCHECKED_CAST") // false positive
internal suspend inline fun executeAndReply(m: M, replier: suspend M.(String) -> Any?): RR { internal suspend inline fun executeAndReply(m: M, replier: suspend M.(String) -> Any?): RR {
when (val message = replier(m, m.message.contentToString())) { when (val message = replier(m, m.message.contentToString())) {
...@@ -429,7 +428,6 @@ open class MessageSubscribersBuilder<M : MessageEvent, out Ret, R : RR, RR>( ...@@ -429,7 +428,6 @@ open class MessageSubscribersBuilder<M : MessageEvent, out Ret, R : RR, RR>(
return stub return stub
} }
@PublishedApi
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE", "UNCHECKED_CAST") // false positive @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE", "UNCHECKED_CAST") // false positive
internal suspend inline fun executeAndQuoteReply(m: M, replier: suspend M.(String) -> Any?): RR { internal suspend inline fun executeAndQuoteReply(m: M, replier: suspend M.(String) -> Any?): RR {
when (val message = replier(m, m.message.contentToString())) { when (val message = replier(m, m.message.contentToString())) {
......
...@@ -27,6 +27,8 @@ import kotlin.reflect.KClass ...@@ -27,6 +27,8 @@ import kotlin.reflect.KClass
* @see subscribe 普通地监听一个事件 * @see subscribe 普通地监听一个事件
* @see nextEvent 挂起当前协程, 并获取下一个事件实例 * @see nextEvent 挂起当前协程, 并获取下一个事件实例
* *
* @see syncFromEventOrNull 本函数的在超时后返回 `null` 的版本
*
* @throws TimeoutCancellationException 在超时后抛出. * @throws TimeoutCancellationException 在超时后抛出.
* @throws Throwable 当 [mapper] 抛出任何异常时, 本函数会抛出该异常 * @throws Throwable 当 [mapper] 抛出任何异常时, 本函数会抛出该异常
*/ */
......
...@@ -7,13 +7,14 @@ ...@@ -7,13 +7,14 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
@file:Suppress("unused") @file:Suppress("unused", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
package net.mamoe.mirai.event package net.mamoe.mirai.event
import kotlinx.coroutines.* import kotlinx.coroutines.*
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.BotEvent import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.utils.PlannedRemoval
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.jvm.JvmSynthetic import kotlin.jvm.JvmSynthetic
import kotlin.reflect.KClass import kotlin.reflect.KClass
...@@ -61,18 +62,20 @@ suspend inline fun <reified E : Event> nextEventOrNull( ...@@ -61,18 +62,20 @@ suspend inline fun <reified E : Event> nextEventOrNull(
} }
} }
//
//
// 以下为已弃用的函数
//
//
//
/**
* 挂起当前协程, 直到监听到事件 [E] 的广播, 返回这个事件实例. @PlannedRemoval("1.3.0")
* 将筛选 [BotEvent.bot] 与 [this] 相等的事件. @Suppress("DeprecatedCallableAddReplaceWith")
* @Deprecated(
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制. "Deprecated for better Coroutine life cycle management. Please filter bot instance on your own.",
* level = DeprecationLevel.HIDDEN
* @see subscribe 普通地监听一个事件 )
* @see syncFromEvent 挂起当前协程, 并尝试从事件中同步一个值
*
* @throws TimeoutCancellationException 在超时后抛出.
*/
@JvmSynthetic @JvmSynthetic
suspend inline fun <reified E : BotEvent> Bot.nextEvent( suspend inline fun <reified E : BotEvent> Bot.nextEvent(
timeoutMillis: Long = -1, timeoutMillis: Long = -1,
...@@ -84,27 +87,6 @@ suspend inline fun <reified E : BotEvent> Bot.nextEvent( ...@@ -84,27 +87,6 @@ suspend inline fun <reified E : BotEvent> Bot.nextEvent(
} }
} }
/**
* 挂起当前协程, 直到监听到事件 [E] 的广播, 返回这个事件实例.
* 将筛选 [BotEvent.bot] 与 [this] 相等的事件.
*
* @param timeoutMillis 超时. 单位为毫秒. `-1` 为不限制.
*
* @see subscribe 普通地监听一个事件
* @see syncFromEvent 挂起当前协程, 并尝试从事件中同步一个值
*
* @return 事件实例, 在超时后返回 `null`
*/
@JvmSynthetic
suspend inline fun <reified E : BotEvent> Bot.nextEventOrNull(
timeoutMillis: Long,
priority: Listener.EventPriority = Listener.EventPriority.MONITOR
): E? {
return withTimeoutOrNull(timeoutMillis) {
nextBotEventImpl(this@nextEventOrNull, E::class, this, priority)
}
}
@JvmSynthetic @JvmSynthetic
@PublishedApi @PublishedApi
internal suspend inline fun <E : Event> nextEventImpl( internal suspend inline fun <E : Event> nextEventImpl(
......
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.event
import kotlinx.coroutines.*
import net.mamoe.mirai.event.events.MemberJoinEvent
import net.mamoe.mirai.event.events.MemberMuteEvent
import org.junit.Test
import kotlin.test.assertFalse
internal class CancelScopeTest {
@Test
fun testCancelScope() {
val scope = CoroutineScope(SupervisorJob())
var got = false
scope.subscribeAlways<TestEvent> {
got = true
}
runBlocking {
scope.coroutineContext[Job]!!.cancelAndJoin()
TestEvent().broadcast()
}
assertFalse { got }
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment