You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
These capabilities are intentionally outside the base KinopioHub::kinopiohub target and only exist when KINOPIO_BUILD_LEAF_RUNTIME=ON.
Current Behavior
Connection
Construction is non-blocking.
Use connected(timeout) when you need to wait for readiness.
Automatic reconnect uses nats.c reconnect options and callbacks.
servers, noEcho, timeout, pingInterval, maxPingOut, maxReconnectAttempts, and reconnectTimeWait are mapped to the underlying nats.c connection options.
Multi-server selection supports three effective modes:
ordered, random, latency.
If serverSelectionMode is unset and noRandomize is also unset, the effective default is latency.
If serverSelectionMode is unset and noRandomize is explicitly set, true maps to ordered and false maps to random.
ordered preserves the configured input order for initial connect and explicit reconnect().
random shuffles candidates once at the start of each connection cycle, then keeps that order stable inside the cycle.
latency probes every configured candidate before initial connect and explicit reconnect(), preferring healthy servers with lower RTT and falling back to the original input order if all probes fail.
When latency mode is active with more than one candidate, the hub also runs periodic background probes and may hot-switch to a better server when the measured gain is at least 30 ms.
A successful hot-switch rebuilds logical subscriptions, services, and value tracking on the replacement connection before draining the previous one.
Successful hot-switches do not intentionally transition the hub back through disconnected.
Optional Local Leaf Runtime
This capability is opt-in and only exists when the project is built with KINOPIO_BUILD_LEAF_RUNTIME=ON.
The public entry point is kinopio/leaf.hpp plus the KinopioHub::kinopiohub_leaf target.
startLeafNode() resolves nats-server in this order: explicit binary path, newest cached version under defaultCacheDirectory(), then automatic download of the latest stable official release when downloads are allowed.
Downloaded nats-server binaries are cached by version so later launches can stay local.
The runtime writes an isolated config file, log file, PID file, state file, and generated TLS files inside its runtime directory.
LeafRuntimeSnapshot::localReady tracks whether the local process and monitoring endpoint are up.
LeafRuntimeSnapshot::bridgeReady tracks whether at least one upstream leaf remote is connected.
An unreachable upstream backbone does not block local startup or local nats:// client traffic through the leaf runtime.
The current implementation expects host tools for lifecycle work: curl, openssl, and tar on macOS/Linux or PowerShell archive extraction on Windows.
Optional Auto Leaf Coordination
This capability is also opt-in and currently ships through kinopio/leaf.hpp plus the KinopioHub::kinopiohub_leaf target.
The high-level entry point is startAutoLeaf(const AutoLeafOptions&).
The coordination state model is:
discovering, following-leader, leader-missing-grace, electing, starting-leaf, leader, stopped.
Nodes coordinate per discovery namespace and reuse a stable node identity via AutoLeafOptions::nodeId or a persisted node-id file.
Elections prefer higher backbone quality scores. By default the score is derived from live probes of configured upstream leaf remotes; ties are broken deterministically by node id.
The current leader is sticky while healthy. A recovered former leader follows the active leader instead of immediately preempting it, which suppresses rapid flip-flops.
Winning election starts the local leaf runtime and publishes leader metadata through AutoLeafSnapshot and the discovery manifest file.
The first transport for discovery is IPv4 UDP broadcast; host firewalls and network policy can therefore affect visibility.
If you want other hosts or runtimes to consume the discovered leader URL directly, you should set a routable advertiseHost and a compatible leafRuntime.leafListenHost.
A custom codec replaces the default serializer and deserializer through KinopioOptions::codec.
Subscription And Service Execution
sub() uses callbacks and returns a move-only SubscriptionHandle.
serve() uses callbacks and returns a move-only ServiceHandle.
User callbacks run on background delivery threads supplied by the transport layer.
During the replay window of a hot-switch, an external publish can briefly reach both the old and new transport subscriptions, which may duplicate callback delivery.
Listener and subscription cancellation are idempotent.
Request / Reply Error Shape
Transport failures such as timeout, disconnect, and no responders throw typed C++ exceptions.
If a service handler throws, the reply payload is a structured error object:
{ "error": true, "message": "..." }
req() returns that payload as data. It does not automatically convert handler failures into local exceptions.
Currently Not Supported
Capability
Current status
ws:// / wss:// transport
not supported
Browser runtime behavior
not supported
Browser-side background switching to a local leaf
not supported
Dynamic property access like hub.chat.messages
not supported
Async-iterator style subscriptions
not supported
Public serializeData() / deserializeData() helpers
not exposed
Public offStateChange()
not exposed
Public Scope.dispose()
not exposed
Operational Notes
Default example and integration-test server:
nats://demo.nats.io:4222
Override examples with KINOPIO_NATS_URL for a single server or KINOPIO_NATS_URLS for a comma-separated multi-server list.
The optional leaf runtime examples are only built with KINOPIO_BUILD_LEAF_RUNTIME=ON. leaf_runtime.cpp accepts KINOPIO_LEAF_UPSTREAM_URLS; auto_leaf.cpp accepts KINOPIO_AUTO_LEAF_NAMESPACE, KINOPIO_AUTO_LEAF_DISCOVERY_PORT, KINOPIO_AUTO_LEAF_ADVERTISE_HOST, and KINOPIO_LEAF_UPSTREAM_URLS.
Override integration tests with:
KINOPIO_NATS_URL
The core SDK targets modern macOS and Linux builds through CMake. The optional leaf runtime and auto coordination layer also carry a first-round Windows code path, but this repository still does not claim browser-host parity or browser-side background failover behavior.