Commit c1736124 authored by ryoii's avatar ryoii

Http api automatic release AuthSession

parent a1e262ce
......@@ -116,7 +116,8 @@ fun main() {
```
使用此方式释放session及其相关资源(Bot不会被释放)
**不使用的Session应当被释放,否则Session持续保存Bot收到的消息,将会导致内存泄露**
**不使用的Session应当被释放,否则Session持续保存Bot收到的消息**
**长时间(30分钟)未被使用的Session会被系统自动释放,以避免内存泄露**
#### 请求:
......
......@@ -15,8 +15,7 @@ import net.mamoe.mirai.api.http.queue.MessageQueue
import net.mamoe.mirai.event.Listener
import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.event.subscribeMessages
import net.mamoe.mirai.message.MessagePacket
import net.mamoe.mirai.utils.currentTimeSeconds
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
......@@ -57,7 +56,13 @@ internal object SessionManager {
}
}
operator fun get(sessionKey: String) = allSession[sessionKey]
fun createAuthedSession(bot: Bot, originKey: String): AuthedSession = AuthedSession(bot, originKey, EmptyCoroutineContext).also { session ->
closeSession(originKey)
allSession[originKey] = session
}
operator fun get(sessionKey: String) = allSession[sessionKey]?.also {
if (it is AuthedSession) it.latestUsed = currentTimeSeconds }
fun containSession(sessionKey: String): Boolean = allSession.containsKey(sessionKey)
......@@ -76,14 +81,12 @@ internal object SessionManager {
* 需使用[SessionManager]
*/
abstract class Session internal constructor(
coroutineContext: CoroutineContext
coroutineContext: CoroutineContext,
val key: String = generateSessionKey()
) : CoroutineScope {
val supervisorJob = SupervisorJob(coroutineContext[Job])
final override val coroutineContext: CoroutineContext = supervisorJob + coroutineContext
val key: String = generateSessionKey()
internal open fun close() {
supervisorJob.complete()
}
......@@ -101,16 +104,33 @@ class TempSession internal constructor(coroutineContext: CoroutineContext) : Ses
* 任何[TempSession]认证后转化为一个[AuthedSession]
* 在这一步[AuthedSession]应该已经有assigned的bot
*/
class AuthedSession internal constructor(val bot: Bot, coroutineContext: CoroutineContext) : Session(coroutineContext) {
class AuthedSession internal constructor(val bot: Bot, originKey: String, coroutineContext: CoroutineContext) : Session(coroutineContext, originKey) {
companion object {
const val CHECK_TIME = 1800L // 1800s aka 30min
}
val messageQueue = MessageQueue()
private val _listener: Listener<BotEvent>
private val releaseJob: Job //手动释放将会在下一次检查时回收Session
internal var latestUsed = currentTimeSeconds
init {
_listener = bot.subscribeAlways{ this.run(messageQueue::add) }
releaseJob = launch {
while (true) {
delay(CHECK_TIME * 1000)
if (currentTimeSeconds - latestUsed >= CHECK_TIME) {
SessionManager.closeSession(this@AuthedSession)
break
}
}
}
}
override fun close() {
messageQueue.clear()
_listener.complete()
super.close()
}
......
......@@ -35,10 +35,7 @@ fun Application.authModule() {
miraiVerify<BindDTO>("/verify", verifiedSessionKey = false) {
val bot = getBotOrThrow(it.qq)
with(SessionManager) {
closeSession(it.sessionKey)
allSession[it.sessionKey] = AuthedSession(bot, EmptyCoroutineContext)
}
SessionManager.createAuthedSession(bot, it.sessionKey)
call.respondStateCode(StateCode.Success)
}
......
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