mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
refactor(Action): rename Scheduled interfaces/classes to Schedulable
This commit is contained in:
@@ -27,7 +27,7 @@ sealed class Action {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed interface Scheduled {
|
sealed interface Schedulable {
|
||||||
|
|
||||||
val scheduleType: ScheduleType
|
val scheduleType: ScheduleType
|
||||||
val scheduleContent: String
|
val scheduleContent: String
|
||||||
@@ -103,17 +103,17 @@ sealed class ExecutableAction : Action() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计划行动数据类,继承自[Action],扩展了[Scheduled]相关调度属性,用于标识计划类型(单次还是周期性任务)和计划内容
|
* 计划行动数据类,继承自[Action],扩展了[Schedulable]相关调度属性,用于标识计划类型(单次还是周期性任务)和计划内容
|
||||||
*/
|
*/
|
||||||
data class ScheduledExecutableAction(
|
data class SchedulableExecutableAction(
|
||||||
override val tendency: String,
|
override val tendency: String,
|
||||||
override val actionChain: MutableMap<Int, MutableList<MetaAction>>,
|
override val actionChain: MutableMap<Int, MutableList<MetaAction>>,
|
||||||
override val reason: String,
|
override val reason: String,
|
||||||
override val description: String,
|
override val description: String,
|
||||||
override val source: String,
|
override val source: String,
|
||||||
override val scheduleType: Scheduled.ScheduleType,
|
override val scheduleType: Schedulable.ScheduleType,
|
||||||
override val scheduleContent: String
|
override val scheduleContent: String
|
||||||
) : ExecutableAction(), Scheduled {
|
) : ExecutableAction(), Schedulable {
|
||||||
|
|
||||||
val scheduleHistories = ArrayList<ScheduleHistory>()
|
val scheduleHistories = ArrayList<ScheduleHistory>()
|
||||||
|
|
||||||
@@ -159,11 +159,11 @@ data class StateAction(
|
|||||||
override val reason: String,
|
override val reason: String,
|
||||||
override val description: String,
|
override val description: String,
|
||||||
|
|
||||||
override val scheduleType: Scheduled.ScheduleType,
|
override val scheduleType: Schedulable.ScheduleType,
|
||||||
override val scheduleContent: String,
|
override val scheduleContent: String,
|
||||||
|
|
||||||
val trigger: Trigger
|
val trigger: Trigger
|
||||||
) : Action(), Scheduled {
|
) : Action(), Schedulable {
|
||||||
|
|
||||||
sealed interface Trigger {
|
sealed interface Trigger {
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import work.slhaf.partner.core.action.ActionCapability;
|
|||||||
import work.slhaf.partner.core.action.ActionCore;
|
import work.slhaf.partner.core.action.ActionCore;
|
||||||
import work.slhaf.partner.core.action.entity.ExecutableAction;
|
import work.slhaf.partner.core.action.entity.ExecutableAction;
|
||||||
import work.slhaf.partner.core.action.entity.ImmediateExecutableAction;
|
import work.slhaf.partner.core.action.entity.ImmediateExecutableAction;
|
||||||
import work.slhaf.partner.core.action.entity.ScheduledExecutableAction;
|
import work.slhaf.partner.core.action.entity.SchedulableExecutableAction;
|
||||||
import work.slhaf.partner.module.common.module.PostRunningModule;
|
import work.slhaf.partner.module.common.module.PostRunningModule;
|
||||||
import work.slhaf.partner.module.modules.action.dispatcher.executor.ActionExecutor;
|
import work.slhaf.partner.module.modules.action.dispatcher.executor.ActionExecutor;
|
||||||
import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput;
|
import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput;
|
||||||
@@ -48,10 +48,10 @@ public class ActionDispatcher extends PostRunningModule {
|
|||||||
String userId = context.getUserId();
|
String userId = context.getUserId();
|
||||||
val preparedActions = actionCapability.listActions(ExecutableAction.Status.PREPARE, userId);
|
val preparedActions = actionCapability.listActions(ExecutableAction.Status.PREPARE, userId);
|
||||||
// 分类成PLANNING和IMMEDIATE两类
|
// 分类成PLANNING和IMMEDIATE两类
|
||||||
Set<ScheduledExecutableAction> scheduledActions = new HashSet<>();
|
Set<SchedulableExecutableAction> scheduledActions = new HashSet<>();
|
||||||
Set<ImmediateExecutableAction> immediateActions = new HashSet<>();
|
Set<ImmediateExecutableAction> immediateActions = new HashSet<>();
|
||||||
for (ExecutableAction preparedAction : preparedActions) {
|
for (ExecutableAction preparedAction : preparedActions) {
|
||||||
if (preparedAction instanceof ScheduledExecutableAction actionInfo) {
|
if (preparedAction instanceof SchedulableExecutableAction actionInfo) {
|
||||||
scheduledActions.add(actionInfo);
|
scheduledActions.add(actionInfo);
|
||||||
} else if (preparedAction instanceof ImmediateExecutableAction actionInfo) {
|
} else if (preparedAction instanceof ImmediateExecutableAction actionInfo) {
|
||||||
immediateActions.add(actionInfo);
|
immediateActions.add(actionInfo);
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ public class ActionExecutor extends AgentRunningSubModule<ActionExecutorInput, V
|
|||||||
actionCapability.removePhaserRecord(phaser);
|
actionCapability.removePhaserRecord(phaser);
|
||||||
if (executableAction.getStatus() != Status.FAILED) {
|
if (executableAction.getStatus() != Status.FAILED) {
|
||||||
// 如果是 ScheduledActionData, 则重置 ActionData 内容,记录执行历史与最终结果
|
// 如果是 ScheduledActionData, 则重置 ActionData 内容,记录执行历史与最终结果
|
||||||
if (executableAction instanceof ScheduledExecutableAction scheduledActionData) {
|
if (executableAction instanceof SchedulableExecutableAction scheduledActionData) {
|
||||||
scheduledActionData.recordAndReset();
|
scheduledActionData.recordAndReset();
|
||||||
actionScheduler.execute(Set.of(scheduledActionData));
|
actionScheduler.execute(Set.of(scheduledActionData));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ import work.slhaf.partner.api.agent.factory.module.annotation.InjectModule
|
|||||||
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule
|
import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.AgentRunningSubModule
|
||||||
import work.slhaf.partner.core.action.ActionCapability
|
import work.slhaf.partner.core.action.ActionCapability
|
||||||
import work.slhaf.partner.core.action.entity.ExecutableAction
|
import work.slhaf.partner.core.action.entity.ExecutableAction
|
||||||
import work.slhaf.partner.core.action.entity.Scheduled
|
import work.slhaf.partner.core.action.entity.Schedulable
|
||||||
import work.slhaf.partner.core.action.entity.ScheduledExecutableAction
|
import work.slhaf.partner.core.action.entity.SchedulableExecutableAction
|
||||||
import work.slhaf.partner.module.modules.action.dispatcher.executor.ActionExecutor
|
import work.slhaf.partner.module.modules.action.dispatcher.executor.ActionExecutor
|
||||||
import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput
|
import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
@@ -30,7 +30,7 @@ import java.util.stream.Collectors
|
|||||||
import kotlin.jvm.optionals.getOrNull
|
import kotlin.jvm.optionals.getOrNull
|
||||||
|
|
||||||
@AgentSubModule
|
@AgentSubModule
|
||||||
class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Void>() {
|
class ActionScheduler : AgentRunningSubModule<Set<SchedulableExecutableAction>, Void>() {
|
||||||
|
|
||||||
@InjectCapability
|
@InjectCapability
|
||||||
private lateinit var actionCapability: ActionCapability
|
private lateinit var actionCapability: ActionCapability
|
||||||
@@ -49,15 +49,15 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
|
|
||||||
@Init
|
@Init
|
||||||
fun init() {
|
fun init() {
|
||||||
val listScheduledActions: () -> Set<ScheduledExecutableAction> = {
|
val listScheduledActions: () -> Set<SchedulableExecutableAction> = {
|
||||||
actionCapability.listActions(null, null)
|
actionCapability.listActions(null, null)
|
||||||
.stream()
|
.stream()
|
||||||
.filter { it is ScheduledExecutableAction }
|
.filter { it is SchedulableExecutableAction }
|
||||||
.map { it as ScheduledExecutableAction }
|
.map { it as SchedulableExecutableAction }
|
||||||
.collect(Collectors.toSet())
|
.collect(Collectors.toSet())
|
||||||
}
|
}
|
||||||
|
|
||||||
val onTrigger: (Set<ScheduledExecutableAction>) -> Unit = { actionExecutor.execute(ActionExecutorInput(it)) }
|
val onTrigger: (Set<SchedulableExecutableAction>) -> Unit = { actionExecutor.execute(ActionExecutorInput(it)) }
|
||||||
|
|
||||||
timeWheel = TimeWheel(listScheduledActions, onTrigger)
|
timeWheel = TimeWheel(listScheduledActions, onTrigger)
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO 如果要将 TimeWheel 作为 Agent 内部的循环周期,那么不依赖 Action 链路的内容,将不适合参与到 ActionExecutor,因此需要将 ActionData 的触发类型进行分类:SILENT TRIGGER(仅限更新 ActionData 内部状态,通过属性 copy 完成,不开放过多权限,防止序列化失败)、EXECUTOR、AGENT TURN。考虑将时间轮下放至 ActionCapability,作为底层行动语义的一部分
|
// TODO 如果要将 TimeWheel 作为 Agent 内部的循环周期,那么不依赖 Action 链路的内容,将不适合参与到 ActionExecutor,因此需要将 ActionData 的触发类型进行分类:SILENT TRIGGER(仅限更新 ActionData 内部状态,通过属性 copy 完成,不开放过多权限,防止序列化失败)、EXECUTOR、AGENT TURN。考虑将时间轮下放至 ActionCapability,作为底层行动语义的一部分
|
||||||
override fun execute(scheduledActionDataSet: Set<ScheduledExecutableAction>?): Void? {
|
override fun execute(scheduledActionDataSet: Set<SchedulableExecutableAction>?): Void? {
|
||||||
schedulerScope.launch {
|
schedulerScope.launch {
|
||||||
scheduledActionDataSet?.run {
|
scheduledActionDataSet?.run {
|
||||||
for (scheduledActionData in scheduledActionDataSet) {
|
for (scheduledActionData in scheduledActionDataSet) {
|
||||||
@@ -86,12 +86,12 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class TimeWheel(
|
private class TimeWheel(
|
||||||
val listScheduledActions: () -> Set<ScheduledExecutableAction>,
|
val listScheduledActions: () -> Set<SchedulableExecutableAction>,
|
||||||
val onTrigger: (toTrigger: Set<ScheduledExecutableAction>) -> Unit
|
val onTrigger: (toTrigger: Set<SchedulableExecutableAction>) -> Unit
|
||||||
) : Closeable {
|
) : Closeable {
|
||||||
|
|
||||||
private val actionsGroupByHour = Array<MutableSet<ScheduledExecutableAction>>(24) { mutableSetOf() }
|
private val actionsGroupByHour = Array<MutableSet<SchedulableExecutableAction>>(24) { mutableSetOf() }
|
||||||
private val wheel = Array<MutableSet<ScheduledExecutableAction>>(60 * 60) { mutableSetOf() }
|
private val wheel = Array<MutableSet<SchedulableExecutableAction>>(60 * 60) { mutableSetOf() }
|
||||||
private var recordHour: Int = -1
|
private var recordHour: Int = -1
|
||||||
private var recordDay: Int = -1
|
private var recordDay: Int = -1
|
||||||
private val state = MutableStateFlow(WheelState.SLEEPING)
|
private val state = MutableStateFlow(WheelState.SLEEPING)
|
||||||
@@ -110,7 +110,7 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
launchWheel()
|
launchWheel()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun schedule(actionData: ScheduledExecutableAction) {
|
suspend fun schedule(actionData: SchedulableExecutableAction) {
|
||||||
if (actionData.status != ExecutableAction.Status.PREPARE) {
|
if (actionData.status != ExecutableAction.Status.PREPARE) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -142,9 +142,9 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
|
|
||||||
private fun launchWheel() {
|
private fun launchWheel() {
|
||||||
|
|
||||||
fun collectToTrigger(tick: Int, previousTick: Int, triggerHour: Int): Set<ScheduledExecutableAction>? {
|
fun collectToTrigger(tick: Int, previousTick: Int, triggerHour: Int): Set<SchedulableExecutableAction>? {
|
||||||
if (tick > previousTick) {
|
if (tick > previousTick) {
|
||||||
val toTrigger = mutableSetOf<ScheduledExecutableAction>()
|
val toTrigger = mutableSetOf<SchedulableExecutableAction>()
|
||||||
for (i in previousTick..tick) {
|
for (i in previousTick..tick) {
|
||||||
val bucket = wheel[i]
|
val bucket = wheel[i]
|
||||||
if (bucket.isNotEmpty()) {
|
if (bucket.isNotEmpty()) {
|
||||||
@@ -179,7 +179,7 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
nextTickNanos += step.toLong() * 1_000_000_000L
|
nextTickNanos += step.toLong() * 1_000_000_000L
|
||||||
|
|
||||||
var shouldBreak = false
|
var shouldBreak = false
|
||||||
var toTrigger: Set<ScheduledExecutableAction>? = null
|
var toTrigger: Set<SchedulableExecutableAction>? = null
|
||||||
|
|
||||||
checkThenExecute(false) {
|
checkThenExecute(false) {
|
||||||
if (it.hour != launchingHour) {
|
if (it.hour != launchingHour) {
|
||||||
@@ -266,9 +266,9 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
suspend fun checkThenExecute(finallyToExecute: Boolean = true, then: (currentTime: ZonedDateTime) -> Unit) =
|
suspend fun checkThenExecute(finallyToExecute: Boolean = true, then: (currentTime: ZonedDateTime) -> Unit) =
|
||||||
wheelActionsLock.withLock {
|
wheelActionsLock.withLock {
|
||||||
fun loadActions(
|
fun loadActions(
|
||||||
source: Set<ScheduledExecutableAction>,
|
source: Set<SchedulableExecutableAction>,
|
||||||
now: ZonedDateTime,
|
now: ZonedDateTime,
|
||||||
load: (latestExecutingTime: ZonedDateTime, actionData: ScheduledExecutableAction) -> Unit,
|
load: (latestExecutingTime: ZonedDateTime, actionData: SchedulableExecutableAction) -> Unit,
|
||||||
repair: () -> Unit
|
repair: () -> Unit
|
||||||
) {
|
) {
|
||||||
val runLoading = {
|
val runLoading = {
|
||||||
@@ -292,7 +292,8 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun loadHourActions(currentTime: ZonedDateTime) {
|
fun loadHourActions(currentTime: ZonedDateTime) {
|
||||||
val load: (ZonedDateTime, ScheduledExecutableAction) -> Unit = { latestExecutionTime, actionData ->
|
val load: (ZonedDateTime, SchedulableExecutableAction) -> Unit =
|
||||||
|
{ latestExecutionTime, actionData ->
|
||||||
val secondsTime = latestExecutionTime.minute * 60 + latestExecutionTime.second
|
val secondsTime = latestExecutionTime.minute * 60 + latestExecutionTime.second
|
||||||
wheel[secondsTime].add(actionData)
|
wheel[secondsTime].add(actionData)
|
||||||
log.debug("Action loaded to hour: {}", actionData)
|
log.debug("Action loaded to hour: {}", actionData)
|
||||||
@@ -308,7 +309,8 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun loadDayActions(currentTime: ZonedDateTime) {
|
fun loadDayActions(currentTime: ZonedDateTime) {
|
||||||
val load: (ZonedDateTime, ScheduledExecutableAction) -> Unit = { latestExecutingTime, actionData ->
|
val load: (ZonedDateTime, SchedulableExecutableAction) -> Unit =
|
||||||
|
{ latestExecutingTime, actionData ->
|
||||||
actionsGroupByHour[latestExecutingTime.hour].add(actionData)
|
actionsGroupByHour[latestExecutingTime.hour].add(actionData)
|
||||||
log.debug("Action loaded to day: {}", actionData)
|
log.debug("Action loaded to day: {}", actionData)
|
||||||
}
|
}
|
||||||
@@ -348,12 +350,12 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun parseToZonedDateTime(
|
private fun parseToZonedDateTime(
|
||||||
scheduleType: Scheduled.ScheduleType,
|
scheduleType: Schedulable.ScheduleType,
|
||||||
scheduleContent: String,
|
scheduleContent: String,
|
||||||
now: ZonedDateTime
|
now: ZonedDateTime
|
||||||
): ZonedDateTime? {
|
): ZonedDateTime? {
|
||||||
return when (scheduleType) {
|
return when (scheduleType) {
|
||||||
Scheduled.ScheduleType.CYCLE
|
Schedulable.ScheduleType.CYCLE
|
||||||
-> {
|
-> {
|
||||||
val cron = try {
|
val cron = try {
|
||||||
cronParser.parse(scheduleContent).validate()
|
cronParser.parse(scheduleContent).validate()
|
||||||
@@ -364,7 +366,7 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
executionTime.nextExecution(now).getOrNull()
|
executionTime.nextExecution(now).getOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheduled.ScheduleType.ONCE -> {
|
Schedulable.ScheduleType.ONCE -> {
|
||||||
val executionTime = try {
|
val executionTime = try {
|
||||||
ZonedDateTime.parse(scheduleContent)
|
ZonedDateTime.parse(scheduleContent)
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
@@ -380,7 +382,7 @@ class ActionScheduler : AgentRunningSubModule<Set<ScheduledExecutableAction>, Vo
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun logFailedStatus(actionData: ScheduledExecutableAction) {
|
private fun logFailedStatus(actionData: SchedulableExecutableAction) {
|
||||||
log.warn(
|
log.warn(
|
||||||
"行动未加载,uuid: {}, source: {}, tendency: {}, scheduleContent: {}",
|
"行动未加载,uuid: {}, source: {}, tendency: {}, scheduleContent: {}",
|
||||||
actionData.uuid,
|
actionData.uuid,
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ public class ActionPlanner extends PreRunningModule {
|
|||||||
private ExecutableAction buildActionData(EvaluatorResult evaluatorResult, String userId) {
|
private ExecutableAction buildActionData(EvaluatorResult evaluatorResult, String userId) {
|
||||||
Map<Integer, List<MetaAction>> actionChain = getActionChain(evaluatorResult);
|
Map<Integer, List<MetaAction>> actionChain = getActionChain(evaluatorResult);
|
||||||
return switch (evaluatorResult.getType()) {
|
return switch (evaluatorResult.getType()) {
|
||||||
case PLANNING -> new ScheduledExecutableAction(
|
case PLANNING -> new SchedulableExecutableAction(
|
||||||
evaluatorResult.getTendency(),
|
evaluatorResult.getTendency(),
|
||||||
actionChain,
|
actionChain,
|
||||||
evaluatorResult.getReason(),
|
evaluatorResult.getReason(),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package work.slhaf.partner.module.modules.action.planner.evaluator.entity;
|
package work.slhaf.partner.module.modules.action.planner.evaluator.entity;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import work.slhaf.partner.core.action.entity.ScheduledExecutableAction;
|
import work.slhaf.partner.core.action.entity.SchedulableExecutableAction;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -12,7 +12,7 @@ public class EvaluatorResult {
|
|||||||
private boolean needConfirm;
|
private boolean needConfirm;
|
||||||
private ActionType type;
|
private ActionType type;
|
||||||
private String scheduleContent;
|
private String scheduleContent;
|
||||||
private ScheduledExecutableAction.ScheduleType scheduleType;
|
private SchedulableExecutableAction.ScheduleType scheduleType;
|
||||||
private Map<Integer, List<String>> primaryActionChain;
|
private Map<Integer, List<String>> primaryActionChain;
|
||||||
private String tendency;
|
private String tendency;
|
||||||
private String reason;
|
private String reason;
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import org.mockito.junit.jupiter.MockitoExtension
|
|||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import work.slhaf.partner.core.action.ActionCapability
|
import work.slhaf.partner.core.action.ActionCapability
|
||||||
import work.slhaf.partner.core.action.entity.ExecutableAction
|
import work.slhaf.partner.core.action.entity.ExecutableAction
|
||||||
import work.slhaf.partner.core.action.entity.Scheduled
|
import work.slhaf.partner.core.action.entity.Schedulable
|
||||||
import work.slhaf.partner.core.action.entity.ScheduledExecutableAction
|
import work.slhaf.partner.core.action.entity.SchedulableExecutableAction
|
||||||
import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput
|
import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ActionExecutorInput
|
||||||
import work.slhaf.partner.module.modules.action.dispatcher.scheduler.ActionScheduler
|
import work.slhaf.partner.module.modules.action.dispatcher.scheduler.ActionScheduler
|
||||||
import java.time.ZonedDateTime
|
import java.time.ZonedDateTime
|
||||||
@@ -61,14 +61,14 @@ class ActionSchedulerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `running test`() {
|
fun `running test`() {
|
||||||
fun buildAction(time: ZonedDateTime): ScheduledExecutableAction {
|
fun buildAction(time: ZonedDateTime): SchedulableExecutableAction {
|
||||||
return ScheduledExecutableAction(
|
return SchedulableExecutableAction(
|
||||||
"tendency",
|
"tendency",
|
||||||
mutableMapOf(),
|
mutableMapOf(),
|
||||||
"reason",
|
"reason",
|
||||||
"description",
|
"description",
|
||||||
"source",
|
"source",
|
||||||
Scheduled.ScheduleType.ONCE,
|
Schedulable.ScheduleType.ONCE,
|
||||||
time.toString()
|
time.toString()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ class ActionSchedulerTest {
|
|||||||
// 场景编号:2;路径:B2 → B2.3;目的:验证正常入轮与副作用
|
// 场景编号:2;路径:B2 → B2.3;目的:验证正常入轮与副作用
|
||||||
initTimeWheelWithPrimaryActions(emptySet())
|
initTimeWheelWithPrimaryActions(emptySet())
|
||||||
val action = buildScheduledAction(
|
val action = buildScheduledAction(
|
||||||
type = Scheduled.ScheduleType.ONCE,
|
type = Schedulable.ScheduleType.ONCE,
|
||||||
ZonedDateTime.now().plusHours(1).toString()
|
ZonedDateTime.now().plusHours(1).toString()
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ class ActionSchedulerTest {
|
|||||||
// 场景编号:3;路径:B2 → B2.1;目的:验证忽略非 PREPARE 状态
|
// 场景编号:3;路径:B2 → B2.1;目的:验证忽略非 PREPARE 状态
|
||||||
initTimeWheelWithPrimaryActions(emptySet())
|
initTimeWheelWithPrimaryActions(emptySet())
|
||||||
val action = buildScheduledAction(
|
val action = buildScheduledAction(
|
||||||
type = Scheduled.ScheduleType.ONCE
|
type = Schedulable.ScheduleType.ONCE
|
||||||
)
|
)
|
||||||
|
|
||||||
actionScheduler.execute(setOf(action))
|
actionScheduler.execute(setOf(action))
|
||||||
@@ -148,7 +148,7 @@ class ActionSchedulerTest {
|
|||||||
// 场景编号:4;路径:B2 → B2.2;目的:验证解析失败被跳过
|
// 场景编号:4;路径:B2 → B2.2;目的:验证解析失败被跳过
|
||||||
initTimeWheelWithPrimaryActions(emptySet())
|
initTimeWheelWithPrimaryActions(emptySet())
|
||||||
val action = buildScheduledAction(
|
val action = buildScheduledAction(
|
||||||
type = Scheduled.ScheduleType.ONCE
|
type = Schedulable.ScheduleType.ONCE
|
||||||
)
|
)
|
||||||
|
|
||||||
actionScheduler.execute(setOf(action))
|
actionScheduler.execute(setOf(action))
|
||||||
@@ -162,7 +162,7 @@ class ActionSchedulerTest {
|
|||||||
// 场景编号:5;路径:B2 → B2.2;目的:验证 cron 解析失败被跳过
|
// 场景编号:5;路径:B2 → B2.2;目的:验证 cron 解析失败被跳过
|
||||||
initTimeWheelWithPrimaryActions(emptySet())
|
initTimeWheelWithPrimaryActions(emptySet())
|
||||||
val action = buildScheduledAction(
|
val action = buildScheduledAction(
|
||||||
type = Scheduled.ScheduleType.CYCLE,
|
type = Schedulable.ScheduleType.CYCLE,
|
||||||
scheduleContentOverride = "invalid-cron"
|
scheduleContentOverride = "invalid-cron"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -177,7 +177,7 @@ class ActionSchedulerTest {
|
|||||||
// 场景编号:6;路径:B2 异常中断;目的:验证异常传播
|
// 场景编号:6;路径:B2 异常中断;目的:验证异常传播
|
||||||
initTimeWheelWithPrimaryActions(emptySet())
|
initTimeWheelWithPrimaryActions(emptySet())
|
||||||
val action = buildScheduledAction(
|
val action = buildScheduledAction(
|
||||||
type = Scheduled.ScheduleType.ONCE
|
type = Schedulable.ScheduleType.ONCE
|
||||||
)
|
)
|
||||||
Mockito.doThrow(RuntimeException("boom"))
|
Mockito.doThrow(RuntimeException("boom"))
|
||||||
.`when`(actionCapability)
|
.`when`(actionCapability)
|
||||||
@@ -193,7 +193,7 @@ class ActionSchedulerTest {
|
|||||||
// 场景编号:7;路径:B2.3;目的:验证同小时调度触发 ACTIVE
|
// 场景编号:7;路径:B2.3;目的:验证同小时调度触发 ACTIVE
|
||||||
initTimeWheelWithPrimaryActions(emptySet())
|
initTimeWheelWithPrimaryActions(emptySet())
|
||||||
val action = buildScheduledAction(
|
val action = buildScheduledAction(
|
||||||
type = Scheduled.ScheduleType.ONCE,
|
type = Schedulable.ScheduleType.ONCE,
|
||||||
scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString()
|
scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString()
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -212,16 +212,16 @@ class ActionSchedulerTest {
|
|||||||
// 场景编号:15;路径:B2 + B2.1/B2.2/B2.3;目的:验证混合输入行为
|
// 场景编号:15;路径:B2 + B2.1/B2.2/B2.3;目的:验证混合输入行为
|
||||||
initTimeWheelWithPrimaryActions(emptySet())
|
initTimeWheelWithPrimaryActions(emptySet())
|
||||||
val ok = buildScheduledAction(
|
val ok = buildScheduledAction(
|
||||||
type = Scheduled.ScheduleType.ONCE,
|
type = Schedulable.ScheduleType.ONCE,
|
||||||
scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString()
|
scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString()
|
||||||
)
|
)
|
||||||
val nonPrepare = buildScheduledAction(
|
val nonPrepare = buildScheduledAction(
|
||||||
type = Scheduled.ScheduleType.ONCE,
|
type = Schedulable.ScheduleType.ONCE,
|
||||||
scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString()
|
scheduleContentOverride = ZonedDateTime.now().plusMinutes(2).toString()
|
||||||
)
|
)
|
||||||
nonPrepare.status = ExecutableAction.Status.FAILED
|
nonPrepare.status = ExecutableAction.Status.FAILED
|
||||||
val invalid = buildScheduledAction(
|
val invalid = buildScheduledAction(
|
||||||
type = Scheduled.ScheduleType.CYCLE,
|
type = Schedulable.ScheduleType.CYCLE,
|
||||||
scheduleContentOverride = "invalid-cron"
|
scheduleContentOverride = "invalid-cron"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ class ActionSchedulerTest {
|
|||||||
assertFalse(allScheduled.contains(invalid))
|
assertFalse(allScheduled.contains(invalid))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initTimeWheelWithPrimaryActions(actions: Set<ScheduledExecutableAction>) {
|
private fun initTimeWheelWithPrimaryActions(actions: Set<SchedulableExecutableAction>) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
Mockito.`when`(actionCapability.listActions(null, null))
|
Mockito.`when`(actionCapability.listActions(null, null))
|
||||||
.thenReturn(actions as Set<ExecutableAction>)
|
.thenReturn(actions as Set<ExecutableAction>)
|
||||||
@@ -244,10 +244,10 @@ class ActionSchedulerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun buildScheduledAction(
|
private fun buildScheduledAction(
|
||||||
type: Scheduled.ScheduleType,
|
type: Schedulable.ScheduleType,
|
||||||
scheduleContentOverride: String? = null
|
scheduleContentOverride: String? = null
|
||||||
): ScheduledExecutableAction {
|
): SchedulableExecutableAction {
|
||||||
val action = ScheduledExecutableAction(
|
val action = SchedulableExecutableAction(
|
||||||
"test",
|
"test",
|
||||||
mutableMapOf(),
|
mutableMapOf(),
|
||||||
"reason",
|
"reason",
|
||||||
@@ -259,7 +259,7 @@ class ActionSchedulerTest {
|
|||||||
return action
|
return action
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ScheduledExecutableAction.scheduleContentHour(): Int {
|
private fun SchedulableExecutableAction.scheduleContentHour(): Int {
|
||||||
return ZonedDateTime.parse(this.scheduleContent).hour
|
return ZonedDateTime.parse(this.scheduleContent).hour
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,14 +270,14 @@ class ActionSchedulerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private fun actionsGroupByHour(timeWheel: Any): Array<MutableSet<ScheduledExecutableAction>> {
|
private fun actionsGroupByHour(timeWheel: Any): Array<MutableSet<SchedulableExecutableAction>> {
|
||||||
val field = timeWheel.javaClass.getDeclaredField("actionsGroupByHour")
|
val field = timeWheel.javaClass.getDeclaredField("actionsGroupByHour")
|
||||||
field.isAccessible = true
|
field.isAccessible = true
|
||||||
return field.get(timeWheel) as Array<MutableSet<ScheduledExecutableAction>>
|
return field.get(timeWheel) as Array<MutableSet<SchedulableExecutableAction>>
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun allScheduledActions(timeWheel: Any): Set<ScheduledExecutableAction> {
|
private fun allScheduledActions(timeWheel: Any): Set<SchedulableExecutableAction> {
|
||||||
val result = linkedSetOf<ScheduledExecutableAction>()
|
val result = linkedSetOf<SchedulableExecutableAction>()
|
||||||
for (bucket in actionsGroupByHour(timeWheel)) {
|
for (bucket in actionsGroupByHour(timeWheel)) {
|
||||||
result.addAll(bucket)
|
result.addAll(bucket)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user