davsclaus opened a new pull request, #26269:
URL: https://github.com/apache/camel/pull/26269

   ## CAMEL-24678
   
   `camel infra ps` renders a PID column, but it could only ever show **one 
instance per service alias**, and the PID it showed was picked 
non-deterministically.
   
   `InfraBaseCommand.listServices()` built its rows from a `Map<String, 
InfraServiceAlias>` keyed by alias, so there was exactly one `Row` per alias 
regardless of how many instances were running. The PID for that row came from 
`findPid(alias)`, which returned the first `~/.camel/infra-<alias>-<pid>.json` 
that `File.list()` happened to yield — and `getServiceData(alias, pid)` then 
rendered that same arbitrary instance. So:
   
   * a second instance of an already-running service was invisible in `infra 
ps`;
   * the PID and `SERVICE_DATA` columns could describe a stale instance, which 
is misleading when you are connecting to the service;
   * anything keying off the reported PID was unreliable. This surfaced in 
`InfrastructureITCase`, where a leaked `ftp` instance made `infra ps` keep 
reporting the old PID.
   
   ## Changes
   
   ### `infra ps` emits one row per running instance
   
   Row construction is split from the table rendering. `listServices()` now 
delegates to an overridable `buildRows()` and keeps only the rendering; the 
default `buildRows()` is the catalog view that `infra list` needs, and 
`InfraPs` overrides it to expand the pid files instead. `findPid()` and 
`getServiceData()` are replaced by `findRunningServices()`, which reads the 
Camel directory once and returns one `RunningService` per pid file.
   
   Two consequences beyond the reported bug:
   
   * **Deterministic output.** Instances are ordered by alias and then 
numerically by pid, instead of depending on `File.list()` order. The table sort 
is by alias only, which is a stable sort, so the pid ordering is preserved.
   * **A running service absent from the catalog metadata is now listed.** 
Previously rows originated from the metadata and were only filtered down, so 
such a service produced no row at all.
   
   ### Instances whose process is gone are dropped and their files pruned
   
   A service is stopped by *deleting its pid file*, and `infra run` removes 
both the pid file and the log file in its shutdown hook. A pid file with no 
live process behind it therefore means the process was killed hard and never 
ran that hook. Those instances are no longer reported as running, and the 
leftover `infra-<service>-<pid>.json` / `.log` files are pruned.
   
   The liveness check sits behind an overridable `aliveCheck` predicate 
(default `ProcessHandle`), so tests can use synthetic pids without their pid 
files being pruned as stale.
   
   ### `infra log` gets the same fix
   
   `infra log <alias>` followed only the first log file matching the alias 
(`findFirst()`) — the identical non-determinism. It now tails **every** running 
instance, prefixing lines with `<alias>-<pid>` instead of `<alias>` only when a 
service has more than one instance, so the interleaved output stays 
attributable. It also no longer tails a service that is not running.
   
   ### `pid` added to `--json`
   
   `InfraBaseDTO` had no `pid` field, so even with the table fixed, `infra ps 
--json` would emit two indistinguishable objects for two instances. Added via a 
new 6-arg constructor; the existing 5-arg constructor delegates with `null`, so 
this is backwards compatible. The key is omitted when null, leaving `infra list 
--json` unchanged.
   
   ### Deliberately unchanged
   
   * **`infra list`** keeps its one-row-per-alias shape, no PID column, and 
still lists services that are not running. When an alias does happen to be 
running, the lowest pid of its instances supplies `SERVICE_DATA`, so that 
column does not regress.
   * **`infra get`, `infra stop`, `infra restart`** already enumerate every 
instance through `findPids()`. `stop` and `restart` must keep seeing stale pid 
files, because deleting them is precisely how they clean up.
   
   Reading the pid files once also removes the per-alias directory listing 
`findPid()` performed for each of the 54 catalog aliases on every `infra ps` / 
`infra list` invocation.
   
   ## Testing
   
   25 infra unit tests pass. New coverage in `InfraPsTest`:
   
   * two instances of the same alias, each with its own PID and `SERVICE_DATA`, 
and exactly one row per instance;
   * ordering by alias then numerically by pid;
   * filtering by service name;
   * a dead instance is neither listed nor left on disk, while the live sibling 
keeps both its files;
   * the real `ProcessHandle`-based `aliveCheck` against this JVM's own pid, so 
the default predicate is exercised and not just a stub;
   * a running alias missing from the catalog is still listed;
   * `pid` and per-instance `serviceData` present in `--json`.
   
   New `InfraListTest` pins the `infra list` shape that must *not* change (one 
row per alias, no PID column, non-running services still listed). New 
`InfraLogTest` covers the paths that return without blocking: no running 
services, a named service with no log, and a dead instance being pruned rather 
than tailed.
   
   `mvn install -Psourcecheck` is clean with no uncommitted generated files, 
and `camel-jbang-it` test-compiles.
   
   The full `camel-jbang-core` suite is 928 tests with one failure, 
`OllamaDoctorSupportTest.detectReturnsNotRunningWhenEndpointUnreachable`, which 
fails identically on a clean tree without this branch. It is environmental — 
unrelated to these changes.
   
   ## Docs
   
   * `camel-jbang-dev-services.adoc` — the `infra ps` example predated the PID 
column entirely; refreshed it and documented the multi-instance output, name 
filtering, `--json`, and the `infra log` prefixing.
   * `camel-4x-upgrade-guide-4_23.adoc` — upgrade note covering the 
row-per-instance change, the pruning of stale files, the new `pid` JSON field, 
and the `infra log` prefix change.
   * `InfrastructureITCase` — its `@AfterEach` is kept, since stopping leaked 
containers still earns its place by releasing ports and resources, but the 
comment documenting the now-fixed `infra ps` limitation is corrected.
   
   ---
   _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]

Reply via email to