Skip to content

feat: config-bounded targeting query (ADR 0011, slice 6b) - #33

Merged
kfeofantov merged 1 commit into
mainfrom
feat/ebpf-targeting-query
Aug 11, 2026
Merged

kfeofantov merged 1 commit into
mainfrom
feat/ebpf-targeting-query

Conversation

@kfeofantov

Copy link
Copy Markdown
Contributor

Slice 6b (plan, ADR 0011). The node asks the controller which workloads to profile; the controller answers the top-N by consumption from its rollups.

The carve-out, kept honest

This is the one node↔controller endpoint whose reply carries data the node acts on — a deliberate, config-bounded exception to ADR 0010 §1's ack-only discipline (ADR 0011 §3). It does not break invariant 1: the reply is workload identifiers derived from the cluster's own metrics, never a command; the external backend is untouched; and the node's ConfigMap — not the reply — bounds what may be profiled. The published list is already filtered to the eligible set and capped at TopN, and the node re-checks eligibility before acting (6c). Worst case for a rogue controller: reorder already-permitted targets within already-set ceilings.

Don't race the Accumulator

internal/targeting.Publisher is fed by the usage poller's snapshot callback (records already deep-copied), ranks eligible workloads by CPU.CoreNanoseconds, and publishes the top N into an atomic.Pointer. The handler reads only the atomic snapshot — never the single-owner, unsynchronized Accumulator.

Pieces

  • internal/targeting: the Publisher (rank → filter eligible → clamp TopN → publish).
  • internal/nodeintake: Target / TargetsResponse wire types, a TargetSource interface, and TargetsHandler on /v1/node-targets (same token auth, same port). NewServer now mounts three routes; targets is present only when a source is configured.
  • cmd/agent: publisher wired into the snapshot callback, gated on profiling.enabled (nil-safe TargetSource keeps the route absent otherwise); a node-side targetsClient that queries + decodes the reply (driven by the live pipeline in 6c).

Tests

Publisher: ranks + eligible filter + TopN clamp + per-workload sum + empty-eligible admits none + nil-before-publish. Handler: valid → 200 + snapshot; bad token → 401; GET → 405. Client: POST + Bearer round-trip; nil when no endpoint; non-2xx → error. go test -race ./..., build darwin + GOOS=linux, golangci-lint ./... — all clean.

Next

6c — the live pipeline: capture → group-by-container (cgroup resolve) → filter → serialize → validate → ship, on the cadence (duration / rotation / overhead), consuming the targets and the config.

🤖 Generated with Claude Code

The node asks the controller which workloads to profile; the controller answers
the top-N by consumption from its own rollups. This is the one node<->controller
endpoint whose reply carries data the node acts on — a deliberate, config-bounded
exception to ADR 0010 §1's ack-only discipline (ADR 0011 §3). It does not break
invariant 1: the reply is workload identifiers derived from the cluster's own
metrics, never a command; the external backend is untouched; and the node's
ConfigMap — not the reply — bounds what may be profiled. The published list is
already filtered to the eligible set and capped at TopN, and the node re-checks
eligibility before acting (slice 6c).

- internal/targeting: a Publisher fed by the usage poller's snapshot callback.
  It ranks eligible workloads by CPU consumption and publishes the top N into an
  atomic pointer. This exists to keep the query handler off the single-owner,
  unsynchronized Accumulator: the poller passes an already-deep-copied snapshot,
  and the handler reads only the atomically published result.
- internal/nodeintake: Target / TargetsResponse wire types, a TargetSource
  interface, and a TargetsHandler on /v1/node-targets (same token auth, same
  port). NewServer now mounts three routes; the targets route is present only
  when a source is configured.
- cmd/agent: the publisher is wired into the snapshot callback and gated on
  profiling being enabled; a nil-safe TargetSource keeps the route absent
  otherwise. A targetsClient (node side) queries the endpoint and decodes the
  reply; it is exercised by tests and driven by the live pipeline in slice 6c.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kfeofantov
kfeofantov merged commit 7e7b1f8 into main Aug 11, 2026
3 checks passed
@kfeofantov
kfeofantov deleted the feat/ebpf-targeting-query branch August 11, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant