You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2026/06/30 17:45:09 UTC
(camel) 03/08: chore(tui): speed up process discovery by scanning status files instead of all OS processes
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch fix/CAMEL-23862
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 3f5188ee4039473d7cb83331501ff74c67a55a6b
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jun 30 16:08:15 2026 +0200
chore(tui): speed up process discovery by scanning status files instead of all OS processes
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
Signed-off-by: Claus Ibsen <cl...@gmail.com>
---
.../core/commands/tui/DataRefreshService.java | 16 +++++
.../dsl/jbang/core/commands/tui/TuiHelper.java | 81 ++++++++++++++++------
2 files changed, 76 insertions(+), 21 deletions(-)
diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java
index 2556eae8eef3..1120c041aa92 100644
--- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java
+++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java
@@ -50,6 +50,7 @@ import org.apache.camel.util.json.Jsoner;
class DataRefreshService {
private static final long VANISH_DURATION_MS = 6000;
+ private static final long LIVENESS_CHECK_INTERVAL_MS = 30_000;
private static final int MAX_TRACES = 200;
/**
@@ -81,6 +82,7 @@ class DataRefreshService {
// Cached PID list -- full process scan throttled to every 2 seconds (1 second in burst mode)
private volatile List<Long> cachedPids = Collections.emptyList();
private volatile long lastFullScanTime;
+ private volatile long lastLivenessCheckTime;
private volatile long burstModeUntil;
final Set<String> stoppingPids = ConcurrentHashMap.newKeySet();
@@ -266,9 +268,23 @@ class DataRefreshService {
}
}
if (!fullScan && ctx.selectedPid != null) {
+ boolean checkLiveness = now - lastLivenessCheckTime >= LIVENESS_CHECK_INTERVAL_MS;
+ if (checkLiveness) {
+ lastLivenessCheckTime = now;
+ }
List<IntegrationInfo> previous = data.get();
for (IntegrationInfo prev : previous) {
if (!prev.vanishing && !ctx.selectedPid.equals(prev.pid)) {
+ if (checkLiveness) {
+ try {
+ long pid = Long.parseLong(prev.pid);
+ if (!ProcessHandle.of(pid).map(ProcessHandle::isAlive).orElse(false)) {
+ continue;
+ }
+ } catch (NumberFormatException e) {
+ // keep it
+ }
+ }
infos.add(prev);
}
}
diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java
index d7335aab1f9e..586d04ec5a0c 100644
--- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java
+++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java
@@ -16,6 +16,7 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
+import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -28,6 +29,7 @@ import dev.tamboui.style.Style;
import dev.tamboui.text.CharWidth;
import dev.tamboui.text.Line;
import dev.tamboui.text.Span;
+import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
import org.apache.camel.dsl.jbang.core.common.ProcessHelper;
import org.apache.camel.support.PatternHelper;
import org.apache.camel.util.FileUtil;
@@ -43,7 +45,8 @@ final class TuiHelper {
}
/**
- * Find PIDs of running Camel integrations matching the given name pattern.
+ * Find PIDs of running Camel integrations matching the given name pattern. Scans the {@code ~/.camel/} directory
+ * for status files rather than iterating all OS processes, which is significantly faster.
*/
static List<Long> findPids(String name, Function<String, Path> statusFileResolver) {
List<Long> pids = new ArrayList<>();
@@ -53,29 +56,65 @@ final class TuiHelper {
pattern = pattern + "*";
}
final String pat = pattern;
- ProcessHandle.allProcesses()
- .filter(ph -> ph.pid() != cur)
- .forEach(ph -> {
- JsonObject root = loadStatus(ph.pid(), statusFileResolver);
- if (root != null) {
- String pName = ProcessHelper.extractName(root, ph);
- pName = FileUtil.onlyName(pName);
+
+ for (long pid : findCandidatePids()) {
+ if (pid == cur) {
+ continue;
+ }
+ // check process is still alive
+ if (!ProcessHandle.of(pid).map(ProcessHandle::isAlive).orElse(false)) {
+ continue;
+ }
+ JsonObject root = loadStatus(pid, statusFileResolver);
+ if (root != null) {
+ ProcessHandle ph = ProcessHandle.of(pid).orElse(null);
+ String pName = ProcessHelper.extractName(root, ph);
+ pName = FileUtil.onlyName(pName);
+ if (pName != null && !pName.isEmpty() && PatternHelper.matchPattern(pName, pat)) {
+ pids.add(pid);
+ } else {
+ JsonObject context = (JsonObject) root.get("context");
+ if (context != null) {
+ pName = context.getString("name");
+ if ("CamelJBang".equals(pName)) {
+ pName = null;
+ }
if (pName != null && !pName.isEmpty() && PatternHelper.matchPattern(pName, pat)) {
- pids.add(ph.pid());
- } else {
- JsonObject context = (JsonObject) root.get("context");
- if (context != null) {
- pName = context.getString("name");
- if ("CamelJBang".equals(pName)) {
- pName = null;
- }
- if (pName != null && !pName.isEmpty() && PatternHelper.matchPattern(pName, pat)) {
- pids.add(ph.pid());
- }
- }
+ pids.add(pid);
}
}
- });
+ }
+ }
+ }
+ return pids;
+ }
+
+ /**
+ * List candidate PIDs by scanning {@code ~/.camel/} for {@code *-status.json} files. This is O(number of status
+ * files) rather than O(total OS processes).
+ */
+ static List<Long> findCandidatePids() {
+ List<Long> pids = new ArrayList<>();
+ try {
+ Path camelDir = CommandLineHelper.getCamelDir();
+ if (Files.isDirectory(camelDir)) {
+ try (var files = Files.list(camelDir)) {
+ files.forEach(p -> {
+ String fn = p.getFileName().toString();
+ if (fn.endsWith("-status.json")) {
+ try {
+ long pid = Long.parseLong(fn.substring(0, fn.length() - "-status.json".length()));
+ pids.add(pid);
+ } catch (NumberFormatException e) {
+ // not a PID-based status file
+ }
+ }
+ });
+ }
+ }
+ } catch (IOException e) {
+ // ignore
+ }
return pids;
}