consensus

package module
v1.13.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

README

Forge Consensus: Raft consensus building blocks for Go

Forge Consensus is the Raft consensus module for Forge, the Go backend framework. It holds a Raft implementation in Go with leader election, pre-vote, log replication and snapshots, plus the pieces a node is built from: log storage on BadgerDB, BoltDB or memory, gRPC, TCP, HTTP and in-process transports, peer discovery through static lists, DNS, Consul, etcd or Kubernetes, and in-memory and persistent state machines. A Forge extension sits on top, but it doesn't wire those pieces together yet, so read the status before you pick it for a distributed system.

Go CI Go Reference Apache 2.0

Documentation · Quick start · Status · Packages · The Forge extension · Configuration · FAQ

Quick start

You need Go 1.26 or later. Add Forge and the module:

go get github.com/xraph/forge@latest
go get github.com/xraph/forge/extensions/consensus@latest

This program builds a three-node Raft cluster in one process, using the in-process transport the module's own cluster tests run on. It waits for a leader, writes a key through it, and checks that every node has committed the entry:

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"time"

	"github.com/xraph/forge"
	"github.com/xraph/forge/extensions/consensus"
	"github.com/xraph/forge/extensions/consensus/raft"
	"github.com/xraph/forge/extensions/consensus/statemachine"
	"github.com/xraph/forge/extensions/consensus/storage"
	"github.com/xraph/forge/extensions/consensus/transport"
)

func main() {
	ctx := context.Background()
	logger := forge.NewNoopLogger()
	ids := []string{"node-1", "node-2", "node-3"}

	transports := map[string]*transport.LocalTransport{}
	nodes := map[string]*raft.Node{}
	machines := map[string]*statemachine.MemoryStateMachine{}

	// Build three nodes, each with its own log storage and state machine.
	for _, id := range ids {
		tr := transport.NewLocalTransport(transport.LocalTransportConfig{NodeID: id}, logger)
		st := storage.NewMemoryStorage(storage.MemoryStorageConfig{}, logger)
		sm := statemachine.NewMemoryStateMachine(statemachine.MemoryStateMachineConfig{}, logger)

		node, err := raft.NewNode(raft.Config{
			NodeID:             id,
			HeartbeatInterval:  100 * time.Millisecond,
			ElectionTimeoutMin: 300 * time.Millisecond,
			ElectionTimeoutMax: 600 * time.Millisecond,
		}, logger, sm, tr, st)
		if err != nil {
			log.Fatal(err)
		}

		if err := st.Start(ctx); err != nil {
			log.Fatal(err)
		}

		transports[id], nodes[id], machines[id] = tr, node, sm
	}

	// Connect every node to every other node, then start them.
	for _, id := range ids {
		for _, peer := range ids {
			if peer != id {
				transports[id].Connect(transports[peer])
				nodes[id].AddPeer(peer)
			}
		}
	}

	for _, id := range ids {
		if err := transports[id].Start(ctx); err != nil {
			log.Fatal(err)
		}

		if err := nodes[id].Start(ctx); err != nil {
			log.Fatal(err)
		}
	}

	// Wait for an election.
	leader := ""
	for leader == "" {
		time.Sleep(100 * time.Millisecond)

		for id, node := range nodes {
			if node.IsLeader() {
				leader = id
			}
		}
	}

	fmt.Println("leader:", leader)

	// Writes go to the leader and return once a majority has the entry.
	cmd, err := json.Marshal(consensus.Command{
		Type:    "set",
		Payload: map[string]any{"key": "greeting", "value": "hello"},
	})
	if err != nil {
		log.Fatal(err)
	}

	if err := nodes[leader].Propose(ctx, cmd); err != nil {
		log.Fatal(err)
	}

	value, err := machines[leader].Query(map[string]any{"type": "get", "key": "greeting"})
	fmt.Println("greeting:", value, err)

	// Followers learn the new commit index on the next heartbeat.
	time.Sleep(300 * time.Millisecond)

	for _, id := range ids {
		fmt.Println(id, "commit index:", nodes[id].GetCommitIndex())
	}
}

Run it with go mod tidy && go run .:

leader: node-2
greeting: hello <nil>
node-1 commit index: 2
node-2 commit index: 2
node-3 commit index: 2

Entry 1 is the no-op every new leader writes, and entry 2 is your set. Calling Propose on a follower returns a not-leader error that names the current leader, which you can check with consensus.IsNotLeaderError.

Status

This module isn't ready to run a production cluster. Here's what we checked against the code as it is today, piece by piece, so you can decide which parts are worth building on:

Piece State
Leader election and log replication in raft Works on the in-process transport. Three nodes elect a leader, and a proposed entry commits on a majority
Applying entries on followers Followers advance their commit index but don't apply committed entries to their state machine, so reads from a follower stay empty. Read from the leader
consensus.NewExtension Validates config and registers services, but its storage, transport, discovery, state machine and Raft node are never created. See the Forge extension
Network transports, BadgerDB and BoltDB storage, discovery backends The code is here and compiles, but nothing in this repository runs a networked cluster on them yet
Cluster tests testing/ runs in-process clusters. TestLogReplication is skipped under -short, which is how CI runs it

Packages

You assemble a node from these packages yourself, the way the quick start does. Each one has a constructor that takes a config struct and a forge.Logger:

Package What's in it
raft raft.NewNode(config, logger, stateMachine, transport, storage), elections, replication, snapshots, Propose, AddPeer
storage NewMemoryStorage, NewBadgerStorage, NewBoltDBStorage, and a write-ahead log (NewWAL)
transport NewLocalTransport (in process), NewGRPCTransport, NewTCPTransport, NewHTTPTransport, TLS helpers and serializers
statemachine NewMemoryStateMachine (a key-value map with set, delete and increment) and NewPersistentStateMachine
discovery NewStaticDiscovery, NewDNSDiscovery, NewConsulDiscovery, NewEtcdDiscovery, NewKubernetesDiscovery
cluster Membership, quorum and topology tracking with cluster.NewManager
middleware Wrappers for Forge handlers that require leadership or quorum, enforce a read consistency level, or redirect writes to the leader
testing An in-process cluster harness and the cluster tests

From the root package you get the shared types (RaftNode, StateMachine, Storage, Transport, Command, LogEntry), the role and event constants, and the errors (ErrNotLeader, ErrNoQuorum and the rest, with IsNotLeaderError, IsNoQuorumError and IsRetryable). To plug in your own state machine, implement Apply, Snapshot, Restore and Query from consensus.StateMachine.

The Forge extension

app := forge.NewApp(forge.AppConfig{
	Name: "orders",
	Extensions: []forge.Extension{
		consensus.NewExtension(
			consensus.WithNodeID("node-1"),
			consensus.WithClusterID("orders"),
			consensus.WithBindAddress("0.0.0.0", 7000),
			consensus.WithPeers([]consensus.PeerConfig{
				{ID: "node-2", Address: "10.0.0.2", Port: 7000},
				{ID: "node-3", Address: "10.0.0.3", Port: 7000},
			}),
		),
	},
})

That compiles and starts, and here's what you get today. The extension loads and validates your config, then puts *consensus.Service (also named consensus and consensus:service), ClusterManager, RaftNode, StateMachine and a *consensus.LeadershipChecker in the container. Starting it only logs each component it would initialise. Nothing listens on the bind port, the node stays a follower, and so:

Call Result
Apply Always ErrNotLeader
Read Panics, because the state machine is nil
Health Returns storage not initialized, and the service's health loop logs that warning every health.check_interval
GetRaftNode, GetStateMachine, GetStorage, GetTransport nil, and so are the matching container entries
TransferLeadership, StepDown "not yet implemented" errors

One more thing to watch: with advanced.enable_auto_snapshot on (the default), the service takes a snapshot every raft.snapshot_interval (30 minutes by default) and that call panics on the nil state machine, which takes the process down. If you add the extension anyway, set advanced.enable_auto_snapshot: false. The admin API under admin_api isn't implemented either; turning it on only writes a log line.

Configuration

The extension reads extensions.consensus from your config, falling back to consensus. Options you pass in code override the file.

extensions:
  consensus:
    node_id: node-1
    cluster_id: orders
    bind_addr: 0.0.0.0
    bind_port: 7000
    peers:
      - {id: node-2, address: 10.0.0.2, port: 7000}
      - {id: node-3, address: 10.0.0.3, port: 7000}
    raft:
      heartbeat_interval: 1s
      election_timeout_min: 5s
      election_timeout_max: 10s
    transport:
      type: grpc          # grpc or tcp
    storage:
      type: badger        # badger, boltdb, pebble or postgres
      path: ./data/consensus
    discovery:
      type: static        # static, dns, consul, etcd or kubernetes
    advanced:
      enable_auto_snapshot: false

Validation runs when the extension registers. If any of these rules fail, your app won't start:

Rule Default
node_id is set empty, so you must set it
cluster_id is set default
bind_port is between 1 and 65535 7000
raft.heartbeat_interval < raft.election_timeout_min < raft.election_timeout_max 1s, 5s, 10s
transport.type is grpc or tcp grpc
transport.max_message_size is positive 4MB
discovery.type is static, dns, consul, etcd or kubernetes static
storage.type is badger, boltdb, pebble or postgres, and storage.path is set badger, ./data/consensus
security.cert_file and key_file are set when enable_tls is on, and ca_file when enable_mtls is on TLS off

The options are WithNodeID, WithClusterID, WithBindAddress, WithPeers, WithTransportType, WithDiscoveryType, WithStorageType, WithStoragePath, WithTLS, WithMTLS, WithConfig and WithRequireConfig. The config also has election, health, observability, resilience, admin_api, events and advanced sections. Their full key list and defaults are in internal/config.go and on the configuration page. Today the extension acts on a handful of them: health.enabled and health.check_interval drive its health loop, observability.metrics.enabled and collection_interval drive metrics collection, and advanced.enable_auto_snapshot with raft.snapshot_interval drives the snapshot loop. events.enabled is on by default. It adds events to the extension's dependencies and publishes start and stop events when an event bus is in the container.

Documentation

Topic Where
What the module covers Features
Every config key Configuration
Exported functions and types Functions, pkg.go.dev
The Raft algorithm In Search of an Understandable Consensus Algorithm
Extensions in general Forge extension system

FAQ

Is there a Raft implementation in Go I can embed in a Forge service?

There is one in raft, and the quick start shows a three-node cluster electing a leader and committing an entry. Check the status table first: follower state machines don't apply entries yet, and the networked transports haven't been run as a cluster here.

How does leader election work?

Nodes start as followers with a randomised election timeout between election_timeout_min and election_timeout_max. A follower that hears no heartbeat in that window becomes a candidate, runs a pre-vote if it's on, then asks its peers for votes, and the node with a majority becomes leader and sends heartbeats every heartbeat_interval.

Can I use this for distributed locks or leader-only jobs?

Not through the extension yet, because IsLeader stays false. With your own raft.Node, IsLeader() and GetLeader() tell you which node should run a leader-only job.

Which storage backends are there?

In memory, BadgerDB and BoltDB, plus a write-ahead log. The config validator also accepts pebble and postgres, but there's no implementation for either in this module.

Contributing

The module is its own Go module inside the Forge repository. Test it from its directory, without -short if you want the cluster tests:

cd extensions/consensus
GOWORK=off go test -race ./...
GOWORK=off go test -count=1 -run TestLogReplication -v ./testing/
GOWORK=off golangci-lint run ./...

AGENTS.md has the full build, lint and release rules for the repository, and CONTRIBUTING.md has the contribution guidelines.

License

Forge Consensus is part of Forge and is available under the Apache License 2.0.

Documentation

Index

Constants

View Source
const (
	// ServiceKey is the DI key for the consensus service.
	ServiceKey = "consensus"
	// ServiceKeyLegacy is the legacy DI key for the consensus service.
	ServiceKeyLegacy = "consensus:service"

	// ClusterManagerKey is the DI key for the cluster manager.
	ClusterManagerKey = "consensus:cluster"
	// RaftNodeKey is the DI key for the Raft node.
	RaftNodeKey = "consensus:raft"
	// StateMachineKey is the DI key for the state machine.
	StateMachineKey = "consensus:statemachine"
	// LeadershipCheckerKey is the DI key for the leadership checker.
	LeadershipCheckerKey = "consensus:leadership"
)

DI container keys for consensus extension services.

View Source
const (
	RoleFollower  = internal.RoleFollower
	RoleCandidate = internal.RoleCandidate
	RoleLeader    = internal.RoleLeader
)

Constants - Node Roles.

View Source
const (
	StatusActive    = internal.StatusActive
	StatusInactive  = internal.StatusInactive
	StatusSuspected = internal.StatusSuspected
	StatusFailed    = internal.StatusFailed
)

Constants - Node Status.

View Source
const (
	EntryNormal  = internal.EntryNormal
	EntryConfig  = internal.EntryConfig
	EntryBarrier = internal.EntryBarrier
	EntryNoop    = internal.EntryNoop
)

Constants - Entry Types.

View Source
const (
	MessageTypeAppendEntries   = internal.MessageTypeAppendEntries
	MessageTypeRequestVote     = internal.MessageTypeRequestVote
	MessageTypeInstallSnapshot = internal.MessageTypeInstallSnapshot
	MessageTypeHeartbeat       = internal.MessageTypeHeartbeat
)

Constants - Message Types.

View Source
const (
	NodeChangeTypeAdded   = internal.NodeChangeTypeAdded
	NodeChangeTypeRemoved = internal.NodeChangeTypeRemoved
	NodeChangeTypeUpdated = internal.NodeChangeTypeUpdated
)

Constants - Node Change Types.

View Source
const (
	BatchOpSet    = internal.BatchOpSet
	BatchOpDelete = internal.BatchOpDelete
)

Constants - Batch Op Types.

View Source
const (
	ConsensusEventNodeStarted       = internal.ConsensusEventNodeStarted
	ConsensusEventNodeStopped       = internal.ConsensusEventNodeStopped
	ConsensusEventNodeJoined        = internal.ConsensusEventNodeJoined
	ConsensusEventNodeLeft          = internal.ConsensusEventNodeLeft
	ConsensusEventNodeFailed        = internal.ConsensusEventNodeFailed
	ConsensusEventNodeRecovered     = internal.ConsensusEventNodeRecovered
	ConsensusEventLeaderElected     = internal.ConsensusEventLeaderElected
	ConsensusEventLeaderStepDown    = internal.ConsensusEventLeaderStepDown
	ConsensusEventLeaderTransfer    = internal.ConsensusEventLeaderTransfer
	ConsensusEventLeaderLost        = internal.ConsensusEventLeaderLost
	ConsensusEventRoleChanged       = internal.ConsensusEventRoleChanged
	ConsensusEventBecameFollower    = internal.ConsensusEventBecameFollower
	ConsensusEventBecameCandidate   = internal.ConsensusEventBecameCandidate
	ConsensusEventBecameLeader      = internal.ConsensusEventBecameLeader
	ConsensusEventClusterFormed     = internal.ConsensusEventClusterFormed
	ConsensusEventClusterUpdated    = internal.ConsensusEventClusterUpdated
	ConsensusEventQuorumAchieved    = internal.ConsensusEventQuorumAchieved
	ConsensusEventQuorumLost        = internal.ConsensusEventQuorumLost
	ConsensusEventMembershipChanged = internal.ConsensusEventMembershipChanged
	ConsensusEventLogAppended       = internal.ConsensusEventLogAppended
	ConsensusEventLogCommitted      = internal.ConsensusEventLogCommitted
	ConsensusEventLogCompacted      = internal.ConsensusEventLogCompacted
	ConsensusEventLogTruncated      = internal.ConsensusEventLogTruncated
	ConsensusEventSnapshotStarted   = internal.ConsensusEventSnapshotStarted
	ConsensusEventSnapshotCompleted = internal.ConsensusEventSnapshotCompleted
	ConsensusEventSnapshotFailed    = internal.ConsensusEventSnapshotFailed
	ConsensusEventSnapshotRestored  = internal.ConsensusEventSnapshotRestored
	ConsensusEventHealthy           = internal.ConsensusEventHealthy
	ConsensusEventUnhealthy         = internal.ConsensusEventUnhealthy
	ConsensusEventDegraded          = internal.ConsensusEventDegraded
	ConsensusEventRecovering        = internal.ConsensusEventRecovering
	ConsensusEventConfigUpdated     = internal.ConsensusEventConfigUpdated
	ConsensusEventConfigReloaded    = internal.ConsensusEventConfigReloaded
)

Constants - Event Types.

Variables

View Source
var (
	ErrNotLeader            = internal.ErrNotLeader
	ErrNoLeader             = internal.ErrNoLeader
	ErrNotStarted           = internal.ErrNotStarted
	ErrAlreadyStarted       = internal.ErrAlreadyStarted
	ErrNodeNotFound         = internal.ErrNodeNotFound
	ErrClusterNotFound      = internal.ErrClusterNotFound
	ErrStorageUnavailable   = internal.ErrStorageUnavailable
	ErrTransportUnavailable = internal.ErrTransportUnavailable
	ErrDiscoveryUnavailable = internal.ErrDiscoveryUnavailable
	ErrNoQuorum             = internal.ErrNoQuorum
	ErrInvalidTerm          = internal.ErrInvalidTerm
	ErrStaleTerm            = internal.ErrStaleTerm
	ErrLogInconsistent      = internal.ErrLogInconsistent
	ErrSnapshotFailed       = internal.ErrSnapshotFailed
	ErrCompactionFailed     = internal.ErrCompactionFailed
	ErrElectionTimeout      = internal.ErrElectionTimeout
	ErrInvalidPeer          = internal.ErrInvalidPeer
	ErrPeerExists           = internal.ErrPeerExists
	ErrPeerNotFound         = internal.ErrPeerNotFound
	ErrInsufficientPeers    = internal.ErrInsufficientPeers
	ErrInvalidConfig        = internal.ErrInvalidConfig
)

Error exports.

View Source
var (
	NewNotLeaderError = internal.NewNotLeaderError
	NewNoLeaderError  = internal.NewNoLeaderError
	NewTimeoutError   = internal.NewTimeoutError
	NewNoQuorumError  = internal.NewNoQuorumError
	NewStaleTermError = internal.NewStaleTermError
	IsNotLeaderError  = internal.IsNotLeaderError
	IsNoLeaderError   = internal.IsNoLeaderError
	IsNoQuorumError   = internal.IsNoQuorumError
	IsStaleTermError  = internal.IsStaleTermError
	IsRetryable       = internal.IsRetryable
	IsFatal           = internal.IsFatal
)

Error helper functions.

View Source
var (
	DefaultConfig     = internal.DefaultConfig
	WithNodeID        = internal.WithNodeID
	WithClusterID     = internal.WithClusterID
	WithBindAddress   = internal.WithBindAddress
	WithPeers         = internal.WithPeers
	WithTransportType = internal.WithTransportType
	WithDiscoveryType = internal.WithDiscoveryType
	WithStorageType   = internal.WithStorageType
	WithStoragePath   = internal.WithStoragePath
	WithTLS           = internal.WithTLS
	WithMTLS          = internal.WithMTLS
	WithConfig        = internal.WithConfig
	WithRequireConfig = internal.WithRequireConfig
)

Config functions.

Functions

func NewExtension

func NewExtension(opts ...internal.ConfigOption) forge.Extension

NewExtension creates a new consensus extension with functional options.

func NewExtensionWithConfig

func NewExtensionWithConfig(config Config) forge.Extension

NewExtensionWithConfig creates a new consensus extension with a complete config.

Types

type AdminAPIConfig

type AdminAPIConfig = internal.AdminAPIConfig

Config exports.

type AdvancedConfig

type AdvancedConfig = internal.AdvancedConfig

Config exports.

type AppendEntriesRequest

type AppendEntriesRequest = internal.AppendEntriesRequest

Type exports.

type AppendEntriesResponse

type AppendEntriesResponse = internal.AppendEntriesResponse

Type exports.

type BadgerOptions

type BadgerOptions = internal.BadgerOptions

Config exports.

type BatchOp

type BatchOp = internal.BatchOp

Type exports.

type BatchOpType

type BatchOpType = internal.BatchOpType

Type exports.

type BoltOptions

type BoltOptions = internal.BoltOptions

Config exports.

type ClusterInfo

type ClusterInfo = internal.ClusterInfo

Type exports.

type ClusterManager

type ClusterManager = internal.ClusterManager

Type exports.

type Command

type Command = internal.Command

Type exports.

type Config

type Config = internal.Config

Config exports.

type ConfigOption

type ConfigOption = internal.ConfigOption

Config exports.

type ConsensusEvent

type ConsensusEvent = internal.ConsensusEvent

Event exports.

type ConsensusEventType

type ConsensusEventType = internal.ConsensusEventType

Event exports.

type ConsensusService

type ConsensusService = internal.ConsensusService

Type exports.

type ConsensusStats

type ConsensusStats = internal.ConsensusStats

Type exports.

type Discovery

type Discovery = internal.Discovery

Type exports.

type DiscoveryConfig

type DiscoveryConfig = internal.DiscoveryConfig

Config exports.

type ElectionConfig

type ElectionConfig = internal.ElectionConfig

Config exports.

type EntryType

type EntryType = internal.EntryType

Type exports.

type EventsConfig

type EventsConfig = internal.EventsConfig

Config exports.

type Extension

type Extension struct {
	*forge.BaseExtension
	// contains filtered or unexported fields
}

Extension implements forge.Extension for distributed consensus.

func (*Extension) Apply

func (e *Extension) Apply(ctx context.Context, cmd Command) error

Apply applies a command to the consensus system.

func (*Extension) Dependencies

func (e *Extension) Dependencies() []string

Dependencies returns extension dependencies.

func (*Extension) GetClusterInfo

func (e *Extension) GetClusterInfo() ClusterInfo

GetClusterInfo returns cluster information.

func (*Extension) GetLeader

func (e *Extension) GetLeader() string

GetLeader returns the current leader node ID.

func (*Extension) GetRole

func (e *Extension) GetRole() NodeRole

GetRole returns the current node role.

func (*Extension) GetStats

func (e *Extension) GetStats() ConsensusStats

GetStats returns consensus statistics.

func (*Extension) Health

func (e *Extension) Health(ctx context.Context) error

Health checks the health of the consensus system.

func (*Extension) IsLeader

func (e *Extension) IsLeader() bool

IsLeader returns true if this node is the leader.

func (*Extension) Metrics

func (e *Extension) Metrics() map[string]any

Metrics returns observable metrics (implements ObservableExtension).

func (*Extension) Read

func (e *Extension) Read(ctx context.Context, query any) (any, error)

Read performs a consistent read operation.

func (*Extension) Register

func (e *Extension) Register(app forge.App) error

Register registers the extension with the app.

func (*Extension) Reload

func (e *Extension) Reload(ctx context.Context) error

Reload reloads the extension configuration (implements HotReloadableExtension).

func (*Extension) Service

func (e *Extension) Service() *Service

Service returns the consensus service (for advanced usage).

func (*Extension) Start

func (e *Extension) Start(ctx context.Context) error

Start starts the consensus extension.

func (*Extension) Stop

func (e *Extension) Stop(ctx context.Context) error

Stop stops the consensus extension.

type HealthCheck

type HealthCheck = internal.HealthCheck

Type exports.

type HealthConfig

type HealthConfig = internal.HealthConfig

Config exports.

type HealthStatus

type HealthStatus = internal.HealthStatus

Type exports.

type HealthStatusEvent

type HealthStatusEvent = internal.HealthStatusEvent

Event exports.

type InstallSnapshotRequest

type InstallSnapshotRequest = internal.InstallSnapshotRequest

Type exports.

type InstallSnapshotResponse

type InstallSnapshotResponse = internal.InstallSnapshotResponse

Type exports.

type KeyValue

type KeyValue = internal.KeyValue

Type exports.

type LeaderElectedEvent

type LeaderElectedEvent = internal.LeaderElectedEvent

Event exports.

type LeadershipChecker

type LeadershipChecker struct {
	// contains filtered or unexported fields
}

LeadershipChecker provides middleware support for checking leadership.

func NewLeadershipChecker

func NewLeadershipChecker(service ConsensusService) *LeadershipChecker

NewLeadershipChecker creates a new leadership checker.

func (*LeadershipChecker) GetLeader

func (lc *LeadershipChecker) GetLeader() string

GetLeader returns the current leader node ID.

func (*LeadershipChecker) IsLeader

func (lc *LeadershipChecker) IsLeader() bool

IsLeader returns true if this node is the leader.

func (*LeadershipChecker) RequireLeader

func (lc *LeadershipChecker) RequireLeader() error

RequireLeader returns an error if this node is not the leader.

func (*LeadershipChecker) RequireQuorum

func (lc *LeadershipChecker) RequireQuorum() error

RequireQuorum returns an error if there is no quorum.

type LogEntry

type LogEntry = internal.LogEntry

Type exports.

type LoggingConfig

type LoggingConfig = internal.LoggingConfig

Config exports.

type MembershipChangedEvent

type MembershipChangedEvent = internal.MembershipChangedEvent

Event exports.

type Message

type Message = internal.Message

Type exports.

type MessageType

type MessageType = internal.MessageType

Type exports.

type MetricsConfig

type MetricsConfig = internal.MetricsConfig

Config exports.

type NodeChangeEvent

type NodeChangeEvent = internal.NodeChangeEvent

Type exports.

type NodeChangeType

type NodeChangeType = internal.NodeChangeType

Type exports.

type NodeInfo

type NodeInfo = internal.NodeInfo

Type exports.

type NodeRole

type NodeRole = internal.NodeRole

Type exports.

type NodeStatus

type NodeStatus = internal.NodeStatus

Type exports.

type ObservabilityConfig

type ObservabilityConfig = internal.ObservabilityConfig

Config exports.

type PeerConfig

type PeerConfig = internal.PeerConfig

Config exports.

type QuorumStatusEvent

type QuorumStatusEvent = internal.QuorumStatusEvent

Event exports.

type RaftConfig

type RaftConfig = internal.RaftConfig

Config exports.

type RaftNode

type RaftNode = internal.RaftNode

Type exports.

type RaftStats

type RaftStats = internal.RaftStats

Type exports.

type RequestVoteRequest

type RequestVoteRequest = internal.RequestVoteRequest

Type exports.

type RequestVoteResponse

type RequestVoteResponse = internal.RequestVoteResponse

Type exports.

type ResilienceConfig

type ResilienceConfig = internal.ResilienceConfig

Config exports.

type RoleChangedEvent

type RoleChangedEvent = internal.RoleChangedEvent

Event exports.

type SecurityConfig

type SecurityConfig = internal.SecurityConfig

Config exports.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service implements internal.ConsensusService.

func NewConsensusService

func NewConsensusService(config internal.Config, logger forge.Logger, metrics forge.Metrics) (*Service, error)

NewConsensusService creates a new consensus service.

func (*Service) AddNode

func (s *Service) AddNode(ctx context.Context, nodeID, address string, port int) error

AddNode adds a node to the cluster.

func (*Service) Apply

func (s *Service) Apply(ctx context.Context, cmd Command) error

Apply applies a command to the state machine.

func (*Service) GetClusterInfo

func (s *Service) GetClusterInfo() ClusterInfo

GetClusterInfo returns cluster information.

func (*Service) GetClusterManager

func (s *Service) GetClusterManager() ClusterManager

GetClusterManager returns the cluster manager.

func (*Service) GetDiscovery

func (s *Service) GetDiscovery() Discovery

GetDiscovery returns the discovery service.

func (*Service) GetHealthStatus

func (s *Service) GetHealthStatus(ctx context.Context) HealthStatus

GetHealthStatus returns detailed health status.

func (*Service) GetLeader

func (s *Service) GetLeader() string

GetLeader returns the current leader node ID.

func (*Service) GetRaftNode

func (s *Service) GetRaftNode() RaftNode

GetRaftNode returns the Raft node.

func (*Service) GetRole

func (s *Service) GetRole() NodeRole

GetRole returns the current role of this node.

func (*Service) GetStateMachine

func (s *Service) GetStateMachine() StateMachine

GetStateMachine returns the state machine.

func (*Service) GetStats

func (s *Service) GetStats() internal.ConsensusStats

GetStats returns consensus statistics.

func (*Service) GetStorage

func (s *Service) GetStorage() Storage

GetStorage returns the storage backend.

func (*Service) GetTerm

func (s *Service) GetTerm() uint64

GetTerm returns the current term.

func (*Service) GetTransport

func (s *Service) GetTransport() Transport

GetTransport returns the transport.

func (*Service) HealthCheck

func (s *Service) HealthCheck(ctx context.Context) error

HealthCheck performs a health check.

func (*Service) IsLeader

func (s *Service) IsLeader() bool

IsLeader returns true if this node is the leader.

func (*Service) Read

func (s *Service) Read(ctx context.Context, query any) (any, error)

Read performs a consistent read operation.

func (*Service) RemoveNode

func (s *Service) RemoveNode(ctx context.Context, nodeID string) error

RemoveNode removes a node from the cluster.

func (*Service) Snapshot

func (s *Service) Snapshot(ctx context.Context) error

Snapshot creates a snapshot.

func (*Service) Start

func (s *Service) Start(ctx context.Context) error

Start starts the consensus service.

func (*Service) StepDown

func (s *Service) StepDown(ctx context.Context) error

StepDown causes the leader to step down.

func (*Service) Stop

func (s *Service) Stop(ctx context.Context) error

Stop stops the consensus service.

func (*Service) TransferLeadership

func (s *Service) TransferLeadership(ctx context.Context, targetNodeID string) error

TransferLeadership transfers leadership to another node.

func (*Service) UpdateConfig

func (s *Service) UpdateConfig(ctx context.Context, config Config) error

UpdateConfig updates the configuration.

type Snapshot

type Snapshot = internal.Snapshot

Type exports.

type SnapshotEvent

type SnapshotEvent = internal.SnapshotEvent

Event exports.

type StateMachine

type StateMachine = internal.StateMachine

Type exports.

type Storage

type Storage = internal.Storage

Type exports.

type StorageConfig

type StorageConfig = internal.StorageConfig

Config exports.

type TracingConfig

type TracingConfig = internal.TracingConfig

Config exports.

type Transport

type Transport = internal.Transport

Type exports.

type TransportConfig

type TransportConfig = internal.TransportConfig

Config exports.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL