mirror of
https://github.com/jie65535/mirai-console-jcf-plugin.git
synced 2025-06-02 17:39:15 +08:00
完善任务调度工具
- 添加暂停、关闭、中继调度的函数 - 添加插入和移除时刻表、任务表内容的函数 - 添加调度器名称 - 默认无日志接口 - 补充日志输出
This commit is contained in:
parent
8132a1ab4c
commit
4118ff10e8
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user