From ff46d97eedc60f36c9bd1276e7d76b1c234b50a4 Mon Sep 17 00:00:00 2001 From: slhafzjw Date: Sat, 21 Mar 2026 22:39:18 +0800 Subject: [PATCH] feat(scheduler): add cancel method to ActionScheduler --- .../action/scheduler/ActionScheduler.kt | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/scheduler/ActionScheduler.kt b/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/scheduler/ActionScheduler.kt index 8abc5ec4..1153e0f4 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/scheduler/ActionScheduler.kt +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/modules/action/scheduler/ActionScheduler.kt @@ -30,11 +30,13 @@ import kotlin.jvm.optionals.getOrNull import kotlin.time.Duration.Companion.milliseconds class ActionScheduler : AbstractAgentModule.Standalone() { + @InjectCapability private lateinit var actionCapability: ActionCapability @InjectModule private lateinit var actionExecutor: ActionExecutor + private lateinit var timeWheel: TimeWheel private val runtimeSchedulables: MutableSet = Collections.synchronizedSet(mutableSetOf()) @@ -96,6 +98,29 @@ class ActionScheduler : AbstractAgentModule.Standalone() { } } + fun cancel(actionId: String): Boolean { + val runtimeMatches = synchronized(runtimeSchedulables) { + runtimeSchedulables.filter { it.uuid == actionId }.toSet() + } + val persistedMatches = actionCapability.listActions(null, null) + .asSequence() + .filterIsInstance() + .filter { it.uuid == actionId } + .toSet() + + val matches = LinkedHashSet() + matches.addAll(runtimeMatches) + matches.addAll(persistedMatches) + matches.forEach { it.enabled = false } + + val removedFromWheel = if (::timeWheel.isInitialized) { + runBlocking { timeWheel.cancel(actionId) } + } else { + false + } + return matches.isNotEmpty() || removedFromWheel + } + private class TimeWheel( val listSource: () -> Set, val onTrigger: (toTrigger: Set) -> Unit, @@ -139,6 +164,37 @@ class ActionScheduler : AbstractAgentModule.Standalone() { } } + suspend fun cancel(actionId: String): Boolean = wheelActionsLock.withLock { + var found = false + for (bucket in schedulableGroupByHour) { + var bucketFound = false + bucket.removeIf { + if (it.uuid == actionId) { + it.enabled = false + bucketFound = true + true + } else { + false + } + } + found = found || bucketFound + } + for (bucket in wheel) { + var bucketFound = false + bucket.removeIf { + if (it.uuid == actionId) { + it.enabled = false + bucketFound = true + true + } else { + false + } + } + found = found || bucketFound + } + found + } + private fun wheel() { data class WheelStepResult( val toTrigger: Set?,