完善任务调度工具

- 添加暂停、关闭、中继调度的函数
- 添加插入和移除时刻表、任务表内容的函数
- 添加调度器名称
- 默认无日志接口
- 补充日志输出
This commit is contained in:
dongRogen 2022-07-27 00:54:11 +08:00
parent 8132a1ab4c
commit 4118ff10e8

View File

@ -1,7 +1,6 @@
package top.jie65535.jcf package top.jie65535.jcf
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.command.ConsoleCommandSender.name
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import top.jie65535.jcf.util.LockUtil import top.jie65535.jcf.util.LockUtil
import java.util.* import java.util.*
@ -10,10 +9,13 @@ import kotlin.concurrent.thread
/** /**
* 任务调度 * 任务调度
* *
* @property bot 每个 bot 维护一个调度器 * @param bot 每个 bot 维护一个调度器
* @property logger 日志 * @param logger 日志默认无
*/ */
class ScheduleHandler(private val bot: Bot, private val logger: MiraiLogger) { class ScheduleHandler(
private val bot: Bot,
private val logger: MiraiLogger? = null,
) {
// region -- 常量、变量 // region -- 常量、变量
/** /**
* 任务表 * 任务表
@ -48,10 +50,18 @@ class ScheduleHandler(private val bot: Bot, private val logger: MiraiLogger) {
*/ */
private var swap: Calendar? = null private var swap: Calendar? = null
/**
* 调度器名称
*/
private val name = "sch:${bot.id}:" + UUID.randomUUID().toString()
/** /**
* 线程循环执行核对与调度 * 线程循环执行核对与调度
*/ */
private val loopThread = thread(name = "schedule:${bot.id}:${bot.nick}") { loop() } private val loopThread = thread(name = "$name:thr") {
logger?.info("调度器[$name]启动")
loop()
}
// endregion // endregion
@ -69,7 +79,7 @@ class ScheduleHandler(private val bot: Bot, private val logger: MiraiLogger) {
/** /**
* 取反 [eq] 函数 * 取反 [eq] 函数
*/ */
private infix fun Calendar.neq(then: Calendar): Boolean = !eq(then) private infix fun Calendar.neq(then: Calendar?): Boolean = !eq(then)
/** /**
* 暂存的时刻重入时刻表 * 暂存的时刻重入时刻表
@ -112,9 +122,10 @@ class ScheduleHandler(private val bot: Bot, private val logger: MiraiLogger) {
*/ */
private fun Thread.delay(time: Long): Boolean = private fun Thread.delay(time: Long): Boolean =
try { try {
Thread.sleep(1000 * 20) Thread.sleep(time)
true true
} catch (_: Exception) { } catch (e: Exception) {
logger?.warning("调度器[$name]异常", e)
false false
} }
@ -126,24 +137,161 @@ class ScheduleHandler(private val bot: Bot, private val logger: MiraiLogger) {
while (!thread.isInterrupted) { while (!thread.isInterrupted) {
if (pause) continue if (pause) continue
if (periodList.isEmpty()) continue if (periodList.isEmpty()) continue
if (!thread.delay(1000 * 20)) if (!thread.delay(1000 * 20)) break
break
val now = Calendar.getInstance() val now = Calendar.getInstance()
reSwap(now) reSwap(now)
if (!isThen(now)) continue if (!isThen(now)) continue
logger?.info("调度器[$name]执行任务...")
taskLock.withLock { taskLock.withLock {
// TODO 异步、限时 // TODO 异步、限时
forEach { (id, task) -> task(id) } for ((id, task) in this) {
if (pause) {
logger?.info("调度器[$name]执行在任务中暂停")
break
}
else task(id)
}
} }
}// while }
logger.info("线程[$name]已结束") taskLock.withLock { clear() }
// TODO clean periodLock.withLock { clear() }
logger?.info("调度器[$name]已关闭")
} }
// endregion // endregion
// region -- TODO 参数与状态 // region -- 状态
/**
* 暂停调度
*/
fun pause() {
pause = true
logger?.info("暂停调度器[$name]...")
}
/**
* 关闭调度清理资源
*/
fun close() {
pause = true
loopThread.interrupt()
taskLock.withLock { clear() }
periodLock.withLock { clear() }
logger?.info("已关闭调度器[$name]")
}
/**
* 继续执行调度
*/
fun rerun(): Boolean {
pause = false
logger?.apply {
if (loopThread.isAlive) info("调度器[$name]继续运转...")
else warning("调度器[$name]已关闭,无法继续")
}
return loopThread.isAlive
}
/**
* 是否暂停
*/
fun isPause() = pause
/**
* 是否可用
*/
fun isAlive() = loopThread.isAlive
// endregion
// region -- 参数
/**
* 检查 id 是否已添加
*/
infix fun haveTask(id: String): Boolean = taskLock.withLock {
id in this
}
/**
* 添加任务
* 不允许覆盖任务
* 若要修改任务需删除后重新添加
*
* @param id 任务 id
* @param action 待执行的任务
* @return id 是否已添加
*/
fun addTask(id: String, action: (String) -> Unit): Boolean = taskLock.withLock {
if (id in this)
false
else {
put(id, action)
logger?.info("新增任务[$id],总任务量:$size")
true
}
}
/**
* 删除任务
*
* @param id 任务 id
*/
infix fun rmTask(id: String) = taskLock.withLock {
if (id in this) {
this -= id
logger?.info("移除任务[$id],总任务量:$size")
}
}
/**
* 任务数量
*/
fun taskCount(): Int = taskSet.size
/**
* 是否存在于时刻表
*/
infix fun havePeriod(then: Calendar): Boolean = periodLock.withLock {
any { it eq then } || then eq swap
}
/**
* 添加时刻
* 时刻表中时与分作为唯一检查
* 因此若参数所包含的时与分已存在与时刻表则本次输入被忽视
*/
infix fun addPeriod(then: Calendar) = periodLock.withLock {
if (none { it eq then } && then neq swap) {
add(then)
logger?.apply {
val m = then.get(Calendar.MINUTE)
val h = then.get(Calendar.HOUR_OF_DAY)
info("添加时刻[$h:$m],时刻表长度:${periodList.size}")
}
}
}
/**
* 移除匹配的时刻
*/
infix fun rmPeriod(then: Calendar) = periodLock.withLock {
if (isThen(then)) {
swap = null
logger?.apply {
val m = then.get(Calendar.MINUTE)
val h = then.get(Calendar.HOUR_OF_DAY)
info("移除时刻[$h:$m],时刻表长度:${periodList.size}")
}
}
}
/**
* 时刻表长度
*/
fun periodCount(): Int = periodList.size
// endregion // endregion
} }