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

davsclaus pushed a commit to branch tui-health-strip-gap
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 076ab58b72ad0b658f8b5c9808f64522142601f2
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Nov 14 19:07:52 2026 +0100

    chore: camel-jbang - the ready and live strip of Health has no gap where a 
second was skipped between two reads that say the same
    
    While a diagram is on screen the TUI reads an integration about once a
    second, a little over a second apart, so now and then a second has no read
    of its own. The strip showed it as a gap, as if not known, though the reads
    on both sides said the same. A second or two between two reads that say
    the same now takes their state; a longer time without reads, or two reads
    that differ, stays not known.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../dsl/jbang/core/commands/tui/HealthHistory.java | 13 +++-
 .../jbang/core/commands/tui/HealthHistoryTest.java | 72 ++++++++++++++++++++++
 2 files changed, 83 insertions(+), 2 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HealthHistory.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HealthHistory.java
index 9bf0e4510e70..da08c8287817 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HealthHistory.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HealthHistory.java
@@ -31,6 +31,12 @@ final class HealthHistory {
     static final byte UNKNOWN = -1;
     static final byte READY = 1;
     static final byte LIVE = 2;
+    /**
+     * The most seconds between two reads that say the same that are taken to 
have said it too. The TUI reads about once
+     * a second while a diagram is on screen, a little over a second apart, so 
now and then a second has no read of its
+     * own: a gap in the strip that was never a change.
+     */
+    static final int BRIDGED_SECONDS = 2;
 
     // per pid: a ring of the last SECONDS seconds, and the second its last 
value is of
     private final Map<String, Ring> rings = new ConcurrentHashMap<>();
@@ -56,9 +62,12 @@ final class HealthHistory {
         Ring ring = rings.computeIfAbsent(info.pid, k -> new Ring());
         synchronized (ring) {
             if (ring.last >= 0 && second > ring.last) {
-                // the seconds in between were not read: not known
+                // the seconds in between were not read: not known, unless 
only a second or two between two reads
+                // that say the same
+                byte before = ring.values[(int) (ring.last % SECONDS)];
+                byte between = second - ring.last - 1 <= BRIDGED_SECONDS && 
before == value ? value : UNKNOWN;
                 for (long s = ring.last + 1; s < second && s <= ring.last + 
SECONDS; s++) {
-                    ring.values[(int) (s % SECONDS)] = UNKNOWN;
+                    ring.values[(int) (s % SECONDS)] = between;
                 }
             }
             if (second >= ring.last) {
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/HealthHistoryTest.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/HealthHistoryTest.java
new file mode 100644
index 000000000000..e10b1b99faaa
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/HealthHistoryTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.tui;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Ready and live second by second: a second with no read of its own between 
two reads that say the same is no gap in
+ * the strip, a longer time without reads is.
+ */
+class HealthHistoryTest {
+
+    private static final byte UP = HealthHistory.READY | HealthHistory.LIVE;
+
+    private final HealthHistory history = new HealthHistory();
+    private final IntegrationInfo info = new IntegrationInfo();
+
+    @Test
+    void aSecondSkippedBetweenTwoReadsThatSayTheSameIsNoGap() {
+        // read a little over a second apart, as while a diagram is on screen: 
second 102 has no read of its own
+        read(100, true);
+        read(101, true);
+        read(103, true);
+
+        assertThat(history.strip("1", 103, 4)).containsExactly(UP, UP, UP, UP);
+    }
+
+    @Test
+    void aLongerTimeWithoutReadsIsNotKnown() {
+        read(100, true);
+        read(110, true);
+
+        byte[] strip = history.strip("1", 110, 11);
+        assertThat(strip[0]).isEqualTo(UP);
+        assertThat(strip[5]).isEqualTo(HealthHistory.UNKNOWN);
+        assertThat(strip[10]).isEqualTo(UP);
+    }
+
+    @Test
+    void aSkippedSecondBetweenTwoReadsThatDifferIsNotKnown() {
+        read(100, true);
+        read(102, false);
+
+        byte[] strip = history.strip("1", 102, 3);
+        assertThat(strip[0]).isEqualTo(UP);
+        assertThat(strip[1]).as("when it went down is not 
known").isEqualTo(HealthHistory.UNKNOWN);
+        assertThat(strip[2]).isEqualTo(HealthHistory.LIVE);
+    }
+
+    private void read(long second, boolean ready) {
+        info.pid = "1";
+        info.healthReady = ready;
+        info.healthLive = true;
+        history.record(info, second);
+    }
+}

Reply via email to