Skip to main content
The SDK keeps every config / secret / flag in an in-memory snapshot that is replaced atomically as a whole on each sync. Reads never block on the network; only the periodic background refresh does.

When does the SDK hit the network

The atomic snapshot guarantee

The snapshot is replaced as one immutable record reference, behind an AtomicReference. Two threads reading concurrently either see the same old state or the same new state - never a mix. This means you can iterate getAllConfigs() or getAllFlags() without worrying about an entry being added or removed mid-loop.

ETag / 304

Every successful sync stores the server’s ETag. The next sync sends If-None-Match: <etag>. If nothing has changed:
…the SDK resets its syncedAt timestamp and serves the existing snapshot. No payload transferred.

Background sync errors

Background syncs never throw to the application. If the network call fails:
  1. The error is logged via NexusLogger.error(...) (SLF4J at error level by default)
  2. The existing cache continues to be served
  3. The next read after the TTL elapses retries automatically

Cache lifetime

The cache lives as long as the NexusClient bean - typically the entire application lifetime. The auto-configuration registers the bean with destroyMethod = "close", so the SSE stream is stopped automatically on context shutdown.

Diagnostics

If you set the SDK logger to DEBUG level via SLF4J:
…you’ll see one line per sync:

Spring Actuator integration

Exposing a custom health indicator that reports the SDK’s freshness:

Concurrency model

  • All reads are thread-safe - guarded by AtomicReference for snapshot reads.
  • Background sync runs in a daemon thread - at most one at a time, guarded by a CAS counter.
  • SSE runs in a separate daemon thread - started by connectStream() (called by the auto-configuration).
The SDK does not pin a thread; reads from any @Async method, @RestController, or @Scheduled task are equally safe.