From 25ddc6f181ed5011958ca460a7d7db7b909351ee Mon Sep 17 00:00:00 2001 From: slhafzjw Date: Sat, 7 Mar 2026 20:15:41 +0800 Subject: [PATCH] refactor(ActionExecutor): enforce action timeout with cancellation and move timeout defaults into Action base model --- .../slhaf/partner/core/action/entity/Action.kt | 10 ++++++++-- .../action/executor/ActionExecutor.java | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Partner-Core/src/main/java/work/slhaf/partner/core/action/entity/Action.kt b/Partner-Core/src/main/java/work/slhaf/partner/core/action/entity/Action.kt index c8737c86..5fc958e3 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/core/action/entity/Action.kt +++ b/Partner-Core/src/main/java/work/slhaf/partner/core/action/entity/Action.kt @@ -27,6 +27,11 @@ sealed class Action { */ abstract val description: String + abstract val timeout: Duration + + val timeoutMills: Long + get() = timeout.inWholeMilliseconds + /** * 行动状态 */ @@ -66,6 +71,7 @@ sealed interface Schedulable { val scheduleContent: String val uuid: String val timeout: Duration + val timeoutMills: Long var enabled: Boolean enum class ScheduleType { @@ -105,6 +111,7 @@ sealed class ExecutableAction : Action() { */ val additionalContext: MutableMap> = mutableMapOf() + override val timeout: Duration = 10.minutes } /** @@ -118,7 +125,6 @@ data class SchedulableExecutableAction @JvmOverloads constructor( override val source: String, override val scheduleType: Schedulable.ScheduleType, override val scheduleContent: String, - override val timeout: Duration = 10.minutes ) : ExecutableAction(), Schedulable { override var enabled = true @@ -157,7 +163,7 @@ data class ImmediateExecutableAction( ) : ExecutableAction() /** - * 用于计时的一次性触发或者针对某一数据源进行内容更新的行动 + * 用于计时的一次性或周期性触发或者针对某一数据源进行内容更新的行动 */ data class StateAction @JvmOverloads constructor( override val source: String, diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/executor/ActionExecutor.java b/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/executor/ActionExecutor.java index f2dba35c..79444127 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/executor/ActionExecutor.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/executor/ActionExecutor.java @@ -16,9 +16,7 @@ import work.slhaf.partner.module.modules.action.scheduler.ActionScheduler; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Phaser; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -50,7 +48,19 @@ public class ActionExecutor extends AbstractAgentModule.Standalone { } public void execute(Action action) { - virtualExecutor.execute(actionExecutionRouter(action)); + + Future future = virtualExecutor.submit(actionExecutionRouter(action)); + + virtualExecutor.execute(() -> { + try { + future.get(action.getTimeoutMills(), TimeUnit.MILLISECONDS); + } catch (TimeoutException e) { + future.cancel(true); + action.setStatus(Action.Status.FAILED); + log.warn("Action timeout, uuid: {}", action.getUuid()); + } catch (Exception ignored) { + } + }); } private Runnable actionExecutionRouter(Action action) {