Skip to main content
Pass a nexus.StreamObserver via Config.Observer to receive structured callbacks for every SSE lifecycle transition. The observer is the canonical way to wire SDK state into ops dashboards, custom telemetry, or load-test tooling - far more reliable than scraping Logger output by substring match. The observer is opt-in. When Config.Observer == nil the SDK uses NoopStreamObserver at zero overhead.

The interface

Embed nexus.NoopStreamObserver to override only the hooks you care about:

Hook semantics

What counts as a “whitelisted event”

OnEvent fires only for events on the SDK’s documented event-type list:
  • resync
  • config.created / config.updated / config.deleted
  • flag.created / flag.updated / flag.toggled / flag.deleted
  • secret.created / secret.updated / secret.deleted
Unknown events (or the WIF auth_expiring control event) do NOT trigger OnEvent.

OnFallback reasons

FallbackReasonRateLimited - active-recovery semantics (v0.4.0+)

FallbackReasonRateLimited is dispatched in both of the following situations:
  • Terminate case (no Retry-After) - the server returned 429 without a parseable Retry-After header. The SDK closes the stream, RunStream returns, and TTL polling takes over.
  • Active-recovery case (Retry-After present) - the server returned 429 with a parseable Retry-After header. The SDK fires OnFallback("rate-limited") for visibility, then sleeps the indicated delay (clamped [5 s, 5 min]) and reconnects automatically. RunStream does NOT return, the transport-failure counter is NOT incremented, and the stream resumes without intervention.
Observers that previously treated FallbackReasonRateLimited as a hard “stream is gone” signal should be aware that in v0.4.0+ the stream may recover on its own. A subsequent OnConnected() callback will fire when the reconnect succeeds.

OnQuarantined - quarantine semantics (v0.4.0+)

OnQuarantined(reason string, expiresAt time.Time) fires when the backend returns 429 Too Many Requests with a structured quarantine body:
SDK behaviour while quarantined:
  • Background sync (ensureFresh) is skipped entirely - no requests are sent to the backend.
  • The in-memory cache continues to be served for all reads (GetConfig, GetSecret, GetFlag).
  • The quarantine state clears automatically when expiresAt passes.

Threading contract

Observer methods are called synchronously from the SDK’s own goroutine. They MUST return promptly. The SDK does not protect against blocking observers.
If your observer does anything substantial (network I/O, mutex contention, disk writes), copy the argument and dispatch the work to your own goroutine before returning:

Counter pattern

The most common use - counting events for a dashboard or load-test report:

Active-connection gauge pattern

Maintain a live “is the SDK connected” gauge:
OnFallback is included because after the 3-strike fallback the SDK will not reconnect - the gauge should stay false until you spin up a new client or the next manual RunStream(ctx) call. Note: with FallbackReasonRateLimited (v0.4.0+) the SDK may auto-recover via Retry-After; the subsequent OnConnected will flip the gauge back to true.

Per-event-type counter

Independence from Logger

The observer is independent of Logger. The two are complementary:
  • Logger carries human-readable text for operators ("nexus: SSE stream connected").
  • StreamObserver carries structured metrics for tooling.
A consumer can set both, neither, or just one. Setting only the observer is the right choice when you don’t want any text output from the SDK.

Compatibility note

If you previously relied on substring-matching Logger.Errorf lines to count reconnects/fallbacks, switch to the observer - log line wording is not a stable contract and may change between SDK releases.