Sparkplug Primary Host STATE: Reject Old Offline Messages Before Broker Failover

A Sparkplug edge node can still reach its MQTT broker after the required Primary Host loses that broker connection. Broker reachability alone therefore cannot decide whether the edge should keep publishing there. Equally, reacting to every offline notification can make the edge abandon a usable connection after an older host session finally expires.

This review is scoped to Eclipse Sparkplug 3.0.0, dated November 16, 2022, and an edge configured to use a Primary Host. It is a protocol decision review, not a measurement of recovery time or a claim that an implementation buffers every sample.

Keep establishment and termination comparisons separate

The Sparkplug 3.0.0 specification defines two relevant gates:

  • Section 5.4: before birth publication, the configured host ID must match, online must be true, and the timestamp must be at least the previous STATE timestamp. With no prior STATE, treat the incoming message as latest and honor its online flag.
  • Section 5.5: for an established edge using a Primary Host, an offline timestamp at least as large as the previous online STATE timestamp requires disconnection. An older offline timestamp must not trigger disconnection. Publish NDEATH before intentional termination, then attempt the next configured server after a valid offline-triggered disconnect.

Notice the different comparison references: previous STATE for establishment, previous online STATE for this termination rule. Replacing both with an undocumented generic “last timestamp” variable makes the code harder to audit.

Make equality an explicit fixture

Use this small, proposed decision fixture with a matching configured host ID and an edge already publishing on one broker. The numbers are illustrative timestamp values, not captured event times:

previous online STATE timestamp: 200

incoming online=false, timestamp=100 -> do not disconnect for this message
incoming online=false, timestamp=200 -> terminate and attempt next server
incoming online=false, timestamp=201 -> terminate and attempt next server

Equality belongs in the termination path. A comparison implemented as only > would fail the middle case. Section 5.13 binds a host’s birth timestamp to its immediately preceding CONNECT Will timestamp; equal values are therefore meaningful. The host maintains STATE timestamps separately for each MQTT server. Sparkplug sections 5.5 and 5.13.

Three incoming offline STATE timestamps are compared with previous online timestamp 200: older 100 keeps the session, equal 200 and newer 201 trigger termination and next-server attempt.
Original scoped protocol-decision diagram; no MQTT execution or measured failover.

Original decision diagram. It depicts protocol comparisons, not measured failover timing or a complete client implementation.

Preserve the evidence used by the decision

For an implementation review, request a diagnostic record containing the configured Primary Host ID, incoming topic, broker connection identity, payload online value, payload timestamp, comparison reference and selected action. Keep the message’s receipt time separately. Otherwise a late-delivered older payload can look “new” in a log simply because the log line was just written.

Do not overwrite the comparison reference before recording it. A trace showing only the updated timestamp cannot demonstrate which two values caused the decision. Keep the established-session and startup branches distinguishable in the log, so an operator can tell whether a disconnect followed a qualifying host message, a transport loss or a local stop request.

These fields are a proposed observability design. The specification’s per-server timestamp obligation above is host-side; it is not permission to invent a universal edge-side global-watermark algorithm. Review how the selected edge implementation retains or resets its state across reconnects, configuration changes and restarts.

Exercise the two failure directions independently

In an isolated integration setup, first establish a valid host and edge session. Arrange an older host-offline notification after a newer host-online notification, while keeping the edge’s transport connection healthy. Confirm the exact received payload and comparison reference. A disconnect in this case should lead to investigation of the ordering check rather than an assumption that the broker failed.

Then exercise equal and newer offline timestamps separately. Capture NDEATH, connection termination, the attempted next server and the following readiness decision. Do not call the whole sequence successful merely because a connection attempt was logged. The next server may be unavailable or may not have a qualifying Primary Host state.

Add a wrong-host-ID case and a fresh-start case without timestamp history. The wrong host must not open this configured host’s readiness gate. A fresh start needs its own expected result; initializing a variable to an arbitrary “recent” value would hide the no-history behavior. Include an initially offline host as well as an initially online host.

Keep these tests off operational control topics until their scope is authorized. Record edge, host and broker versions, the server list and the exact payload sequence. Inspect the receiving application’s data quality separately from the routing decision: choosing another server does not establish zero loss, complete replay or uninterrupted current values.

No MQTT clients, brokers or failover sequence were executed for this article. The proposed evidence should establish which host-session notification caused the edge to leave, and whether a stale notification was correctly excluded, before anyone attributes the outcome to network quality.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *