This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch fix/CAMEL-25784
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/fix/CAMEL-25784 by this push:
     new 777f82f9b41f CAMEL-25784: compare the times of the files for the log 
of a killed process, and keep no stale info after a failed keep
777f82f9b41f is described below

commit 777f82f9b41f6a2d0c9431dc83f5238309a80ca3
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Oct 19 13:28:21 2026 +0200

    CAMEL-25784: compare the times of the files for the log of a killed 
process, and keep no stale info after a failed keep
    
    From the review: the log of a killed process was compared with when the
    previous run ended (the clock of the JVM) instead of the time of its log 
(the
    clock of the file system, which a network file system has of its own). And a
    keep that failed (such as on a full disk) left what was kept about the run
    before next to the log of this one: that file now goes first.
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Claude-Session: https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m
---
 .../jbang/core/commands/action/CamelLogAction.java |  2 +-
 .../camel/dsl/jbang/core/common/PreviousRun.java   |  7 ++++-
 .../dsl/jbang/core/common/PreviousRunTest.java     | 35 ++++++++++++++++++++++
 3 files changed, 42 insertions(+), 2 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
index e87f8f9ee84e..f10009dbeb5d 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
@@ -267,7 +267,7 @@ public class CamelLogAction extends ActionBaseCommand {
     private void findRunning() {
         try {
             if (findProcesses(name).isEmpty()) {
-                // nothing runs
+                // nothing runs: the newest previous run (findAll is newest 
first)
                 List<PreviousRun.Info> found = PreviousRun.findAll();
                 if (!found.isEmpty()) {
                     printer().printTip(previousRunHint(found.get(0)));
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PreviousRun.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PreviousRun.java
index 134e5621c334..9415bc62eecf 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PreviousRun.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PreviousRun.java
@@ -164,6 +164,9 @@ public final class PreviousRun {
         String file = fileName(info.name());
         Path target = dir.resolve(file + LOG_SUFFIX);
         try {
+            // what was kept about the run before goes first, so a keep that 
fails (such as on a full disk) does not
+            // leave it next to the log of this run
+            Files.deleteIfExists(dir.resolve(file + INFO_SUFFIX));
             if (Files.size(log) > MAX_SIZE || !move(log, target)) {
                 copyEnd(log, target, MAX_SIZE);
                 try {
@@ -285,7 +288,9 @@ public final class PreviousRun {
                     ? context.getString("name") : null;
             if (name != null && !name.isBlank()) {
                 Info before = 
read(CommandLineHelper.getCamelDir().resolve(fileName(name) + INFO_SUFFIX));
-                if (before == null || before.ended() < modified) {
+                // the time of the kept log, not when its run ended, so both 
times come from the file system (a
+                // network file system has a clock of its own)
+                if (before == null || before.log().toFile().lastModified() < 
modified) {
                     String directory = status.get("runtime") instanceof 
JsonObject runtime
                             ? runtime.getString("directory") : null;
                     keep(f.toPath(), new Info(name, pid, directory, 0, 
modified, null, null, GONE, null));
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/PreviousRunTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/PreviousRunTest.java
index 981d81b14d11..7dfe2d5b71cc 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/PreviousRunTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/PreviousRunTest.java
@@ -22,6 +22,7 @@ import java.nio.file.attribute.FileTime;
 import java.time.Instant;
 import java.time.temporal.ChronoUnit;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.camel.util.json.JsonObject;
 import org.junit.jupiter.api.AfterEach;
@@ -160,6 +161,40 @@ class PreviousRunTest {
         assertThat(old).doesNotExist();
     }
 
+    @Test
+    void theLogOfAKilledProcessIsComparedByTheTimesOfTheFiles() throws 
Exception {
+        // a run kept by a JVM whose clock is a day ahead of the file system 
(a network file system)
+        long ahead = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1);
+        Path kept = PreviousRun.keep(writeLog("123.log", "older run"),
+                new PreviousRun.Info("orders", 123, null, 0, ahead, 0, null, 
null, null));
+        Files.setLastModifiedTime(kept, FileTime.from(Instant.now().minus(2, 
ChronoUnit.HOURS)));
+        Path killed = writeLog(GONE_PID + ".log", "newer run, killed");
+        Files.setLastModifiedTime(killed, FileTime.from(Instant.now().minus(1, 
ChronoUnit.HOURS)));
+        writeStatus(GONE_PID, "orders");
+
+        PreviousRun.Info info = only(PreviousRun.find("orders"));
+
+        assertThat(info.pid()).isEqualTo(GONE_PID);
+        assertThat(Files.readAllLines(info.log())).containsExactly("newer run, 
killed");
+    }
+
+    @Test
+    void aKeepThatFailsLeavesNoInfoOfTheRunBefore() throws Exception {
+        PreviousRun.keep(writeLog("123.log", "first run"), "orders", 123, 0, 
null);
+        // the log cannot be written: a directory that is not empty has its 
name
+        Path kept = camelDir.resolve("orders-previous.log");
+        Files.delete(kept);
+        Files.createDirectories(kept.resolve("in-the-way"));
+        Path log = writeLog("456.log", "second run");
+
+        assertThat(PreviousRun.keep(log, "orders", 456, 70, "boom")).isNull();
+
+        // what was kept about the first run is not left next to something 
else, and the log of the second run stays
+        assertThat(camelDir.resolve("orders-previous.json")).doesNotExist();
+        assertThat(PreviousRun.find("orders")).isEmpty();
+        assertThat(log).exists();
+    }
+
     @Test
     void theLogOfAProcessWithoutNameIsRemovedAfterADay() throws Exception {
         Path old = writeLog(GONE_PID + ".log", "old");

Reply via email to