mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-15 05:29:28 +00:00
fix(target-health): keep sweep timestamp first for atomic alignment
targetHealthLastSweepUnixNano moves to Gateway's first field. It is read and written only through sync/atomic's 64-bit functions, and the sync/atomic package guarantees 64-bit alignment on ARM, x86-32, and 32-bit MIPS only for a struct's first word — Traefik ships armv7 and 386 builds alongside amd64/arm64. Every other field keeps golangci-lint fieldalignment's pointer-grouped ordering; verified with the standalone fieldalignment analyzer that this is the only field out of place and adds no struct-size padding, only a documented +8 GC-scan-prefix cost. docs: catches up README's admin `health` object and Target health "State" bullet to F4 (previous commit, a0c8607) — three ways to read `state: "unknown"`, and that consecutiveFailures/lastCheck/ lastError/latencyMs/source stay present when a target has been observed but never succeeded. Claude-Session: https://claude.ai/code/session_01EebV5jyWvYocByNQ3oss1w
This commit is contained in:
@@ -1549,9 +1549,11 @@ or in CI.
|
||||
`health` is `{"state","lastCheck","lastError","consecutiveFailures","latencyMs","source"}`
|
||||
— see [MCP and A2A](#mcp-and-a2a)'s "Target health" section for the
|
||||
full contract. `state` is `"unknown"`, `"healthy"`, or `"unhealthy"`,
|
||||
and `consecutiveFailures` is always present; every other field is
|
||||
omitted while `state` is `"unknown"` (this target has never been
|
||||
observed). This route always reads existing state; when
|
||||
and `consecutiveFailures` is always present. Every other field is
|
||||
omitted only while this target has never once been observed; `state`
|
||||
alone does not decide the omission, since `"unknown"` also covers a
|
||||
target that has been observed but has not yet succeeded, and that case
|
||||
keeps every field. This route always reads existing state; when
|
||||
`targetHealth.enabled`, it additionally triggers a background probe
|
||||
sweep when one is due, so the response itself never waits on that
|
||||
sweep. Polled every 5 seconds, in the same batch as `overview` and
|
||||
@@ -1921,11 +1923,27 @@ plugin's config.
|
||||
or the default `/.well-known/agent-card.json`); a `404` still
|
||||
counts as reachable — for example an umbrella agent whose root
|
||||
carries no card of its own.
|
||||
- **State**: `"unknown"` (never observed), `"healthy"` (recorded at
|
||||
least once, `consecutiveFailures` below `targetHealth.failureThreshold`),
|
||||
or `"unhealthy"` (`consecutiveFailures` at or above the threshold). A
|
||||
target with one or two recent failures after a success still reads
|
||||
`"healthy"` until the threshold is actually crossed.
|
||||
- **State**: `"healthy"` (succeeded at least once,
|
||||
`consecutiveFailures` below `targetHealth.failureThreshold`), or
|
||||
`"unhealthy"` (`consecutiveFailures` at or above the threshold,
|
||||
whether or not the target has ever succeeded). A target with one or
|
||||
two recent failures after a success still reads `"healthy"` until the
|
||||
threshold is actually crossed.
|
||||
- **`"unknown"` reads three ways**, all sharing one JSON `state`
|
||||
value:
|
||||
1. never observed at all — no probe or passive traffic has reached
|
||||
this target yet. `GET /admin/api/targets` omits every health field
|
||||
but `state`/`consecutiveFailures` for this case.
|
||||
2. observed, but never once succeeded, and still below
|
||||
`targetHealth.failureThreshold` — the threshold's protection
|
||||
against a single transient first failure still applies, so this
|
||||
does not jump straight to `"unhealthy"`, but a target this tracker
|
||||
has never seen answer is not `"healthy"` either. Every other
|
||||
health field is still present here, since there is a real
|
||||
observation to show.
|
||||
3. either way, `llmgateway_target_healthy` emits no sample while
|
||||
`state` is `"unknown"` — a gap in the series is honest, a
|
||||
fabricated `1` is not.
|
||||
|
||||
## Security notes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user