davsclaus opened a new pull request, #27720: URL: https://github.com/apache/camel/pull/27720
The camel-jbang TUI timed its durations, deadlines, refresh intervals and animations with the wall clock (`System.currentTimeMillis()`). The wall clock can be set back or forward (an NTP step, a manual change, a VM resume). A timer measured with it then freezes until the clock catches up, or fires at once. They now run on `MonotonicClock.millis()`, a small package-private helper that reads `System.nanoTime()`. This prepares the TamboUI 0.6 upgrade, [CAMEL-25580](https://issues.apache.org/jira/browse/CAMEL-25580). TamboUI makes the same move in [tamboui/tamboui#548](https://github.com/tamboui/tamboui/pull/548): `TickEvent.elapsed()` is removed and effects are timed with a monotonic render clock. The TUI does not call `TickEvent.elapsed()`. `MonotonicClock` compares `nanoTime` values only by their difference. It starts a day in, so a time field still at 0 (never set) reads as long ago, as it did on the wall clock. Times that pass between classes state their clock where they are declared: `PendingKey.fireAt`, `IntegrationInfo.startingSince` and `vanishStart`, `KeyRecord.pressedAt` (renamed from `timestamp`), and the `tick(now)` methods. `CaptionOverlay` takes a clock for tests, as `EditReplay` already does. 131 of the 147 `currentTimeMillis()` calls (in 31 files) became monotonic. The other 16 (in 6 files) stay on the wall clock: | Clock | What | Why | |---|---|---| | Monotonic | Durations ("thinking 12s"; LLM, tool, HTTP and confirm-wait times), deadlines and timeouts (MCP tool waits, launch and infra watch, JFR results poll), refresh, throttle and cache intervals, locally measured rates (throughput sparklines, CPU load, Ollama decode and prefill), animations and overlays (captions, drawings, notifications, vanishing rows, spinners, recent keys, edit replay), MCP pending keys and tape sleeps | Only the time between two moments in this TUI matters | | Wall clock | Memory leak recording start and end, JFR snapshot age | Epoch times from the integration's JFR status | | Wall clock | Activity rate and time filter, "since last" exchange, internal task "next" | Exchange and task times from the integration | | Wall clock | Overview `uptimeMillis` | The process start time from its status file | | Wall clock | Ollama `lastPoll`, slot and host `sampledAt`, a question's start time (`Instant.now()`) | Shown or exported as a time of day | ### Tests - `MonotonicClockTest`: the clock never goes back, it moves on with the time that passes (Awaitility, no sleep), and a time never set reads as long ago. - `MonotonicTimersTest`: a pending MCP key fires on time, a caption expires on its (fake) clock, and a drawing expires on time. Their times are far from any wall-clock time, so a timer that reads the wall clock fires at once or never. Putting `currentTimeMillis()` back into `McpFacade.injectKeys` or `DrawOverlay` makes them fail. - Tests that pass times into converted code now use `MonotonicClock.millis()`. The two `Thread.sleep` polling loops in `LaunchManagerInfraTest` now use Awaitility. - In the module, `mvn test` passes (1907 tests, 1 skipped), and so does `mvn -Psourcecheck verify -DskipTests`. _Claude Code on behalf of davsclaus_ -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
