From 6197824e219879da84ddd553fc606e4d1af44e4d Mon Sep 17 00:00:00 2001 From: semen-flamingo Date: Tue, 3 Nov 2026 00:29:36 +0700 Subject: [PATCH 1/4] fix(delivery): a waiting batch follows the schedule's script list, a machine missed fires get one catch-up CU-86akkb8f5 The batch a machine waits for on the engine is the schedule as the user sees it now: a script added to the schedule joins the batch and gets a leaf under the same fire, one removed leaves it and its leaf closes with the reason. A machine still offline and waiting for an earlier fire of a repeating schedule gets the next fire instead of both, the way the reconnect sentinel merged them. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_018qx6NqA97kwRxQ4hnD5jtu --- .../schedule/ScheduleDeliveryRefresher.java | 105 +++++++++++++----- .../rmm/ScheduleDeliveryRefresherTest.java | 67 ++++++++++- .../service/rmm/ScheduleFireDispatcher.java | 38 +++++++ .../service/ScheduleFireDispatcherTest.java | 32 +++++- 4 files changed, 213 insertions(+), 29 deletions(-) diff --git a/openframe-api-lib/src/main/java/com/openframe/api/service/rmm/schedule/ScheduleDeliveryRefresher.java b/openframe-api-lib/src/main/java/com/openframe/api/service/rmm/schedule/ScheduleDeliveryRefresher.java index cb6540f18..a2171abef 100644 --- a/openframe-api-lib/src/main/java/com/openframe/api/service/rmm/schedule/ScheduleDeliveryRefresher.java +++ b/openframe-api-lib/src/main/java/com/openframe/api/service/rmm/schedule/ScheduleDeliveryRefresher.java @@ -4,6 +4,7 @@ import com.openframe.data.document.delivery.DeliveryType; import com.openframe.data.document.rmm.schedule.ScheduleScript; import com.openframe.data.document.rmm.schedule.ScheduledScriptCustomParams; +import com.openframe.data.document.rmm.script.ExecutionSource; import com.openframe.data.document.rmm.script.ExecutionStatus; import com.openframe.data.document.rmm.script.Script; import com.openframe.data.document.rmm.script.ScriptExecution; @@ -23,7 +24,9 @@ import org.springframework.stereotype.Service; import java.time.Instant; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -36,14 +39,16 @@ import static java.util.stream.Collectors.toSet; // a batch waiting on the engine for a machine carries what the user sees now, not what was there when the schedule -// fired: an edit of a script or of the schedule's parameters replaces the waiting bodies, a schedule or a device that -// is gone withdraws them. A leaf still QUEUED is the sign the machine has not received the batch +// fired: an edit of a script or of the schedule replaces the waiting bodies and the leaves follow (a script added to +// the schedule gets a leaf, one removed closes), a schedule or a device that is gone withdraws them. A leaf still +// QUEUED is the sign the machine has not received the batch @Slf4j @Service @RequiredArgsConstructor public class ScheduleDeliveryRefresher { private static final String NOTHING_LEFT_TO_RUN = "no runnable script left in the batch"; + private static final String REMOVED_FROM_SCHEDULE = "Script was removed from the schedule before the agent received it"; private final ScriptExecutionRepository scriptExecutionRepository; private final ScriptScheduleRepository scheduleRepository; @@ -109,7 +114,7 @@ private void refreshExecution(String tenantId, String executionId, List scripts = runnableScriptsOf(tenantId, executionId, current); + List