Skip to content

feat(asap-precompute-go): HttpPollChannel + OpAmpChannel (Phase 2 step 2.10) - #223

Merged
zzylol merged 1 commit into
mainfrom
phase2/control-channel-http-poll-opamp
May 2, 2026
Merged

zzylol merged 1 commit into
mainfrom
phase2/control-channel-http-poll-opamp

Conversation

@zzylol

@zzylol zzylol commented May 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Lands the two concrete ControlChannel implementations introduced as a trait in #219, completing Phase 2 step 2.10 of the precompute-runtime extraction. The interface itself only earns its keep when at least one real impl exists, so HTTP-poll and the OpAMP stub land together.

  • HttpPollChannel — pull-based, controller-driven channel: ETag-aware GET against a configurable URL, JSON body decoded into precompute.PrecomputeConfigSet, optional POST to an AckURL for plan-version receipts. Bearer tokens are read from disk on every request so credential rotation does not require a runtime restart. Errors are stashed on LastErr() (the trait is errorless by design — adapters should never crash a runtime over a transient control-plane hiccup).
  • OpAmpChannel — interface-satisfying stub. Validates ServerEndpoint at construction, logs a once-per-instance warn from Poll, debug-logs each Ack, returns nil from Close. Real OpAMP wiring (github.com/open-telemetry/opamp-go/client) is deferred to Phase 5 per ADR-0003; landing it now would force a transitive dep into Phase 2 for no functional gain.

Wire format

The HTTP body is the standard encoding/json marshalling of precompute.PrecomputeConfigSet. No json tags exist on the struct yet, so field names follow Go-export casing (Version, Configs, AggID, …). Plan freshness is tracked via the HTTP ETag header: the first 200 stores the tag; subsequent polls send it back as If-None-Match and treat 304 as no-change. Ack POSTs {\"plan_version\": N} to AckURL (no-op when empty). Documented in the http_poll.go package comment so future schema work has a stable starting point.

Test plan

  • go build ./... clean
  • go vet ./... clean
  • go test ./controlchannel/... — all green
  • go test -race ./controlchannel/... — race detector clean
  • httptest-driven cases:
    • first poll returns plan + stores ETag; second poll with same ETag receives 304 → returns nil
    • server rotates ETag → poll returns the new plan
    • 5xx response → Poll returns nil, LastErr reports status
    • decode failure path covered
    • bearer-token rotation: file rewritten between polls, server-side handler asserts both tokens were observed
    • missing token file → poll fails closed (server is never reached)
    • context cancellation: in-flight poll aborted by Close on another goroutine
    • AckURL POSTs {\"plan_version\": N}; empty AckURL is a no-op
    • 5xx on Ack records error without panicking
    • Close is idempotent; subsequent Poll/Ack record ErrChannelClosed
    • 8-goroutine concurrent Poll/Ack racing against Close (race-detector hardening)
  • OpAmp tests: empty endpoint rejected; Poll returns nil; once-per-instance warn does not repeat; Ack/Close/idempotent-Close no-ops; trait satisfaction check

Notes

  • ControlChannel interface is unchanged. Both impls are additive.
  • No new external imports — stdlib only on the production path; testify is intentionally avoided to match the existing module's stdlib-testing style.
  • Submodule pointer drift on opentelemetry-collector / opentelemetry-go is intentionally not committed.

🤖 Generated with Claude Code

…p 2.10)

- HttpPollChannel: ETag-aware HTTP polling with bearer-token rotation,
  configurable Ack endpoint, race-tested concurrency.
- OpAmpChannel: interface-satisfying stub; full OpAMP integration deferred
  to Phase 5 per ADR-0003.
- httptest-driven coverage for ETag/304, errors, token rotation, cancellation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zzylol
zzylol merged commit 4ec7954 into main May 2, 2026
@zzylol
zzylol deleted the phase2/control-channel-http-poll-opamp branch May 2, 2026 13:52
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