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); + } +}
