IsNonVoting vs IsObserver in Dragonboat: Understanding Node Configuration Differences
IsNonVoting and IsObserver represent the identical node configuration in Dragonboat, with IsObserver serving as a deprecated alias that automatically maps to IsNonVoting during configuration validation.
In the Dragonboat Raft library (lni/dragonboat), the config.Config struct provides two boolean fields that control whether a replica participates in log replication without voting power. Understanding the relationship between these fields ensures your cluster configuration remains compatible with future library versions while maintaining correct consensus behavior.
What Are IsNonVoting and IsObserver in Dragonboat?
Both IsNonVoting and IsObserver configure a Raft replica that receives log entries from the leader but does not participate in leader elections and is excluded from quorum calculations. These nodes stay synchronized with the cluster state without affecting availability requirements.
In config/config.go, the Config struct defines these fields:
type Config struct {
ReplicaID uint64
RaftAddress string
IsNonVoting bool // Official field
IsObserver bool // Deprecated alias
// ... other fields
}
Key Differences Between IsNonVoting and IsObserver
While functionally equivalent at runtime, the fields differ in their support status and internal handling.
Current Status and Deprecation
IsNonVoting is the officially supported, documented configuration option marked as production-ready. IsObserver is a deprecated legacy name retained only for backward compatibility. According to the Dragonboat CHANGELOG, the terminology was updated to align with the Raft paper's description of "non-voting members" (section 4.2.1).
Configuration Validation Mapping
The distinction effectively disappears during configuration validation. In config/config.go, the Validate() method explicitly maps the deprecated field to the current one:
// config/config.go lines 173-186
func (c *Config) Validate() error {
// ... other validation logic ...
if c.IsObserver {
c.IsNonVoting = true // Observer is just an alias
}
// ... remainder of validation ...
}
This means setting IsObserver: true results in IsNonVoting being set to true internally, producing identical runtime behavior.
Practical Implementation: Configuring Non-Voting Nodes
When implementing non-voting replicas in your Dragonboat deployment, use the current APIs and configuration fields to ensure future compatibility.
Using IsNonVoting (Recommended)
Configure the node at startup by setting IsNonVoting in the replica configuration:
cfg := dragonboat.Config{
ReplicaID: 2,
RaftAddress: "10.0.0.2:63001",
IsNonVoting: true, // Official field
// IsObserver: true, // Deprecated - do not use
}
err := nh.StartReplica(shardID, replicaID, stateMachineFactory, cfg)
if err != nil {
// handle error
}
Using RequestAddNonVoting API
For dynamic cluster membership changes, use the RequestAddNonVoting method on NodeHost:
// Request addition of non-voting replica
rs, err := nh.RequestAddNonVoting(
shardID, // cluster shard ID
replicaID, // unique replica ID
"10.0.0.2:63001", // Raft address
0, // configChangeIndex (0 = auto)
10*time.Second, // timeout
)
if err != nil {
// handle request error
}
// Wait for completion
if err := rs.Completed().Err; err != nil {
// handle completion error
}
This API is defined in nodehost.go (lines 1170-1186) and provides the preferred mechanism for adding non-voting members without requiring configuration file changes.
Legacy IsObserver Usage (Deprecated)
While existing code using IsObserver continues to function, the field will eventually be removed:
// Legacy code - still works but not recommended
cfg := dragonboat.Config{
ReplicaID: 2,
RaftAddress: "10.0.0.2:63001",
IsObserver: true, // Maps to IsNonVoting during validation
}
The Dragonboat CHANGELOG explicitly warns that IsObserver is deprecated in favor of IsNonVoting.
Summary
- IsNonVoting and IsObserver are functionally identical – both configure replicas that receive log entries without voting rights or quorum membership.
- IsNonVoting is the current, supported field located in
config.Configand marked as production-ready. - IsObserver is a deprecated alias that
config.Config.Validate()automatically maps toIsNonVotingfor backward compatibility. - Use
RequestAddNonVotingfor dynamic membership changes and setIsNonVoting: truein configuration structs for new deployments.
Frequently Asked Questions
What is the difference between IsNonVoting and IsObserver in Dragonboat?
There is no functional difference. IsObserver is a deprecated alias for IsNonVoting. When config.Config.Validate() runs, it sets IsNonVoting = true if IsObserver is true, making them behave identically at runtime. Use IsNonVoting for all new code.
Is IsObserver still supported in Dragonboat?
Yes, but only for backward compatibility. The field still works because the validation logic in config/config.go maps it to IsNonVoting, but it is marked as deprecated in the CHANGELOG and will be removed in a future release. Migrate existing code to use IsNonVoting to avoid breaking changes.
How do I add a non-voting node to a Dragonboat cluster?
Use the NodeHost.RequestAddNonVoting method, which handles the membership change protocol. Provide the shard ID, replica ID, Raft address, and timeout. Alternatively, start a replica with IsNonVoting: true in the Config struct passed to StartReplica, then use the standard membership change APIs to add it to the cluster view.
Can a non-voting node be promoted to a voting member?
Yes. A non-voting replica can be promoted to a full voting member using the membership change APIs such as RequestAddReplica. Because the node already has the complete log from participating in replication, promotion requires only a configuration change to grant it voting rights rather than a full state transfer.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →