This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit f7c000e561f83ff67156803f89779826fe8334be Author: Claus Ibsen <[email protected]> AuthorDate: Fri Jul 10 16:25:38 2026 +0200 TUI: Add timeouts to blocking I/O on event/render thread - LaunchManager/DoctorPopup: Use bounded waitFor(5s) + destroyForcibly for container runtime checks - DocHelper: Use HttpURLConnection with connect/read timeouts instead of URL.openStream - EndpointsTab: Cache catalog load failures to prevent retry-every-frame when offline Co-Authored-By: Claude Opus 4.6 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../dsl/jbang/core/commands/tui/DocHelper.java | 12 ++++++++-- .../dsl/jbang/core/commands/tui/DoctorPopup.java | 9 ++++++-- .../dsl/jbang/core/commands/tui/EndpointsTab.java | 27 +++++++++++++++++----- .../dsl/jbang/core/commands/tui/LaunchManager.java | 9 ++++++-- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocHelper.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocHelper.java index 009dcf92dcf3..53335ecdd091 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocHelper.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocHelper.java @@ -18,6 +18,7 @@ package org.apache.camel.dsl.jbang.core.commands.tui; import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URI; import java.nio.charset.StandardCharsets; @@ -40,8 +41,15 @@ final class DocHelper { } static String downloadContent(String url) { - try (InputStream is = URI.create(url).toURL().openStream()) { - return new String(is.readAllBytes(), StandardCharsets.UTF_8); + try { + HttpURLConnection conn = (HttpURLConnection) URI.create(url).toURL().openConnection(); + conn.setConnectTimeout(5000); + conn.setReadTimeout(10000); + try (InputStream is = conn.getInputStream()) { + return new String(is.readAllBytes(), StandardCharsets.UTF_8); + } finally { + conn.disconnect(); + } } catch (Exception e) { return null; } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java index 90d6fe509171..d0c4f3d43c35 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DoctorPopup.java @@ -22,6 +22,7 @@ import java.net.ServerSocket; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import dev.tamboui.layout.Rect; @@ -217,8 +218,12 @@ class DoctorPopup { .redirectErrorStream(true) .start(); p.getInputStream().transferTo(OutputStream.nullOutputStream()); - int exit = p.waitFor(); - if (exit == 0) { + boolean done = p.waitFor(5, TimeUnit.SECONDS); + if (!done) { + p.destroyForcibly(); + continue; + } + if (p.exitValue() == 0) { String name = Character.toUpperCase(cmd.charAt(0)) + cmd.substring(1); result.add(Line.from( Span.raw(TuiIcons.indent(TuiIcons.DOCKER)), diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java index e254dc1681a1..cea37c2025fd 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/EndpointsTab.java @@ -19,11 +19,13 @@ package org.apache.camel.dsl.jbang.core.commands.tui; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import dev.tamboui.layout.Constraint; import dev.tamboui.layout.Layout; @@ -88,6 +90,7 @@ class EndpointsTab extends AbstractTableTab { private final DragSplit hSplit = new DragSplit(); private final Map<String, CamelCatalog> catalogCache = new HashMap<>(); + private final Set<String> catalogLoadFailed = new HashSet<>(); EndpointsTab(MonitorContext ctx, MetricsCollector metrics) { super(ctx, "component", "route", "dir", "total", "body", "hdr", "uri"); @@ -824,13 +827,25 @@ class EndpointsTab extends AbstractTableTab { if (version == null) { return null; } - return catalogCache.computeIfAbsent(version, v -> { - try { - return CatalogLoader.loadCatalog(null, v, true); - } catch (Exception e) { - return null; + CamelCatalog cached = catalogCache.get(version); + if (cached != null) { + return cached; + } + if (catalogLoadFailed.contains(version)) { + return null; + } + try { + cached = CatalogLoader.loadCatalog(null, version, true); + if (cached != null) { + catalogCache.put(version, cached); + } else { + catalogLoadFailed.add(version); } - }); + return cached; + } catch (Exception e) { + catalogLoadFailed.add(version); + return null; + } } private static long unbox(Long value) { diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LaunchManager.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LaunchManager.java index 5ec6d2df7c39..fcc62fc54c67 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LaunchManager.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LaunchManager.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -137,8 +138,12 @@ class LaunchManager { .redirectErrorStream(true) .start(); p.getInputStream().transferTo(OutputStream.nullOutputStream()); - int exit = p.waitFor(); - if (exit == 0) { + boolean done = p.waitFor(5, TimeUnit.SECONDS); + if (!done) { + p.destroyForcibly(); + continue; + } + if (p.exitValue() == 0) { return true; } } catch (Exception e) {
