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

davsclaus pushed a commit to branch feature/CAMEL-23672-tui-diagram
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 3bed0284614acaf9358d0ce713abc18b4446f95b
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Jun 4 11:08:30 2026 +0200

    CAMEL-23672: camel-tui - Show Stopping status immediately when process is 
stopped
    
    Track PIDs that received SIGTERM so the overview tab can show Stopping
    in yellow immediately, rather than staying on Running until the process
    disappears. Also map Terminating/Terminated phases to Stopping/Stopped
    for friendlier labels. Works for both single stop (x) and stop all.
    
    Signed-off-by: Claus Ibsen <[email protected]>
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../dsl/jbang/core/commands/tui/ActionsPopup.java  |  4 ++--
 .../dsl/jbang/core/commands/tui/CamelMonitor.java  | 24 +++++++++++++---------
 .../dsl/jbang/core/commands/tui/OverviewTab.java   | 11 +++++++++-
 .../dsl/jbang/core/commands/tui/StopAllPopup.java  | 10 +++++++--
 4 files changed, 34 insertions(+), 15 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
index 8f9a52013245..6dcfcc91f5c0 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
@@ -161,7 +161,7 @@ class ActionsPopup {
                  Supplier<List<InfraInfo>> infraServices, CaptionOverlay 
captionOverlay,
                  Runnable screenshotAction, Runnable toggleKeystrokes, 
Supplier<Boolean> keystrokesEnabled,
                  Runnable toggleTapeRecording, Supplier<Boolean> 
tapeRecordingActive,
-                 Runnable burstCallback) {
+                 Runnable burstCallback, Set<String> stoppingPids) {
         this.runningNames = runningNames;
         this.integrations = integrations;
         this.infraServices = infraServices;
@@ -172,7 +172,7 @@ class ActionsPopup {
         this.toggleTapeRecording = toggleTapeRecording;
         this.tapeRecordingActive = tapeRecordingActive;
         this.burstCallback = burstCallback;
-        this.stopAllPopup = new StopAllPopup(integrations, infraServices, 
burstCallback);
+        this.stopAllPopup = new StopAllPopup(integrations, infraServices, 
burstCallback, stoppingPids);
     }
 
     void setContext(MonitorContext ctx) {
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
index d0ec5640685d..f4fd4a981036 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
@@ -202,6 +202,7 @@ public class CamelMonitor extends CamelCommand {
     private volatile List<Long> cachedPids = Collections.emptyList();
     private volatile long lastFullScanTime;
     private volatile long burstModeUntil;
+    final Set<String> stoppingPids = ConcurrentHashMap.newKeySet();
 
     // Trace/history data — shared between CamelMonitor and tabs
     private final AtomicReference<List<TraceEntry>> traces = new 
AtomicReference<>(Collections.emptyList());
@@ -247,7 +248,7 @@ public class CamelMonitor extends CamelCommand {
             () -> recording,
             this::toggleTapeRecording,
             () -> tapeRecorder != null && tapeRecorder.isActive(),
-            this::enableBurstMode);
+            this::enableBurstMode, stoppingPids);
 
     private final AtomicBoolean refreshInProgress = new AtomicBoolean(false);
     private TuiRunner runner;
@@ -344,7 +345,7 @@ public class CamelMonitor extends CamelCommand {
         memoryTab = new MemoryTab(ctx, heapMemHistory);
         threadsTab = new ThreadsTab(ctx);
         overviewTab = new OverviewTab(
-                ctx, throughputHistory, failedHistory, cpuLoadAvg,
+                ctx, throughputHistory, failedHistory, cpuLoadAvg, 
stoppingPids,
                 this::resetIntegrationTabState);
 
         // Initial data load (synchronous before TUI starts)
@@ -1369,19 +1370,21 @@ public class CamelMonitor extends CamelCommand {
                 
ProcessHandle.of(pid).ifPresent(ProcessHandle::destroyForcibly);
             }
         } else {
+            String pidStr = ctx.selectedPid;
             ProcessHandle.of(pid).ifPresent(ph -> {
                 if (forceKill) {
                     ph.destroyForcibly();
                     Path camelDir = CommandLineHelper.getCamelDir();
-                    PathUtils.deleteFile(camelDir.resolve(ctx.selectedPid + 
".log"));
-                    PathUtils.deleteFile(camelDir.resolve(ctx.selectedPid + 
"-status.json"));
-                    PathUtils.deleteFile(camelDir.resolve(ctx.selectedPid + 
"-action.json"));
-                    PathUtils.deleteFile(camelDir.resolve(ctx.selectedPid + 
"-output.json"));
-                    PathUtils.deleteFile(camelDir.resolve(ctx.selectedPid + 
"-trace.json"));
-                    PathUtils.deleteFile(camelDir.resolve(ctx.selectedPid + 
"-history.json"));
-                    PathUtils.deleteFile(camelDir.resolve(ctx.selectedPid + 
"-debug.json"));
-                    PathUtils.deleteFile(camelDir.resolve(ctx.selectedPid + 
"-receive.json"));
+                    PathUtils.deleteFile(camelDir.resolve(pidStr + ".log"));
+                    PathUtils.deleteFile(camelDir.resolve(pidStr + 
"-status.json"));
+                    PathUtils.deleteFile(camelDir.resolve(pidStr + 
"-action.json"));
+                    PathUtils.deleteFile(camelDir.resolve(pidStr + 
"-output.json"));
+                    PathUtils.deleteFile(camelDir.resolve(pidStr + 
"-trace.json"));
+                    PathUtils.deleteFile(camelDir.resolve(pidStr + 
"-history.json"));
+                    PathUtils.deleteFile(camelDir.resolve(pidStr + 
"-debug.json"));
+                    PathUtils.deleteFile(camelDir.resolve(pidStr + 
"-receive.json"));
                 } else {
+                    stoppingPids.add(pidStr);
                     ph.destroy();
                 }
             });
@@ -1882,6 +1885,7 @@ public class CamelMonitor extends CamelCommand {
             List<IntegrationInfo> previous = data.get();
             for (IntegrationInfo prev : previous) {
                 if (!prev.vanishing && !livePids.contains(prev.pid) && 
!vanishing.containsKey(prev.pid)) {
+                    stoppingPids.remove(prev.pid);
                     vanishing.put(prev.pid, new VanishingInfo(prev, 
System.currentTimeMillis()));
                 }
             }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java
index a6411a3c701b..d5d09d4d3a04 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/OverviewTab.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import dev.tamboui.layout.Constraint;
 import dev.tamboui.layout.Layout;
@@ -63,6 +64,7 @@ class OverviewTab implements MonitorTab {
     private final Map<String, LinkedList<Long>> throughputHistory;
     private final Map<String, LinkedList<Long>> failedHistory;
     private final Map<String, LoadAvg> cpuLoadAvg;
+    private final Set<String> stoppingPids;
     private final Runnable onPidChanged;
 
     final TableState tableState = new TableState();
@@ -78,11 +80,13 @@ class OverviewTab implements MonitorTab {
                 Map<String, LinkedList<Long>> throughputHistory,
                 Map<String, LinkedList<Long>> failedHistory,
                 Map<String, LoadAvg> cpuLoadAvg,
+                Set<String> stoppingPids,
                 Runnable onPidChanged) {
         this.ctx = ctx;
         this.throughputHistory = throughputHistory;
         this.failedHistory = failedHistory;
         this.cpuLoadAvg = cpuLoadAvg;
+        this.stoppingPids = stoppingPids;
         this.onPidChanged = onPidChanged;
     }
 
@@ -193,11 +197,16 @@ class OverviewTab implements MonitorTab {
                         Cell.from(Span.styled("", dimStyle))));
             } else {
                 String stateText = extractState(info.state);
-                if ("Running".equals(stateText) && info.routeStarted == 0 && 
info.routeTotal > 0) {
+                if (stoppingPids.contains(info.pid) || 
"Terminating".equals(stateText)) {
+                    stateText = "Stopping";
+                } else if ("Terminated".equals(stateText)) {
+                    stateText = "Stopped";
+                } else if ("Running".equals(stateText) && info.routeStarted == 
0 && info.routeTotal > 0) {
                     stateText = "Stopped";
                 }
                 Style statusStyle = switch (stateText) {
                     case "Started", "Running" -> Style.EMPTY.fg(Color.GREEN);
+                    case "Stopping" -> Style.EMPTY.fg(Color.YELLOW);
                     case "Stopped" -> Style.EMPTY.fg(Color.LIGHT_RED);
                     default -> Style.EMPTY.fg(Color.YELLOW);
                 };
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StopAllPopup.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StopAllPopup.java
index 62de8db3b0bd..377723feedff 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StopAllPopup.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StopAllPopup.java
@@ -18,6 +18,7 @@ package org.apache.camel.dsl.jbang.core.commands.tui;
 
 import java.nio.file.Path;
 import java.util.List;
+import java.util.Set;
 import java.util.function.Supplier;
 
 import dev.tamboui.layout.Rect;
@@ -43,6 +44,7 @@ class StopAllPopup {
     private final Supplier<List<IntegrationInfo>> integrations;
     private final Supplier<List<InfraInfo>> infraServices;
     private final Runnable burstCallback;
+    private final Set<String> stoppingPids;
 
     private boolean visible;
     private boolean checkIntegrations = true;
@@ -54,10 +56,11 @@ class StopAllPopup {
     private String notification;
 
     StopAllPopup(Supplier<List<IntegrationInfo>> integrations, 
Supplier<List<InfraInfo>> infraServices,
-                 Runnable burstCallback) {
+                 Runnable burstCallback, Set<String> stoppingPids) {
         this.integrations = integrations;
         this.infraServices = infraServices;
         this.burstCallback = burstCallback;
+        this.stoppingPids = stoppingPids;
     }
 
     boolean isVisible() {
@@ -197,7 +200,10 @@ class StopAllPopup {
             }
             try {
                 long pid = Long.parseLong(info.pid);
-                ProcessHandle.of(pid).ifPresent(ProcessHandle::destroy);
+                ProcessHandle.of(pid).ifPresent(ph -> {
+                    stoppingPids.add(info.pid);
+                    ph.destroy();
+                });
                 count++;
             } catch (NumberFormatException e) {
                 // skip

Reply via email to