simpleraft

package module
v0.0.0-...-14b6e79 Latest Latest
Warning

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

Go to latest
Published: Jan 14, 2025 License: Apache-2.0 Imports: 13 Imported by: 0

README

go-libp2p-simple-raft

A simple raft wrapper for libp2p.

Motivation: I wanted to experiment and have a simple wrapper to work with raft and libp2p, hence why this.

Usage
import (
    "github.com/mudler/go-libp2p-simple-raft"
)

// Structure nodes have to agree on
type raftState struct {
    Value int
}

ctx := context.Background()

// start a libp2p node (not done here)

// NewSimpleRaft needs a libp2p host, a state to calculate consensus on, and a channel to listen for new peers that are discovered
w, err := simpleraft.NewSimpleRaft(ctx, h, &raftState{Value: 3}, peerChan)
if err != nil {
    fmt.Println(err)
}

// Make sure states are syncronized
err = w.WaitForSync(ctx)
if err != nil {
    fmt.Println(err)
}

// Check if we are leaders and update state
if !w.IsLeader() {
    // we are not leaders, we can only read the state and/or know who is the leader
    state, err:= w.GetState()
    address, serverID := w.GetLeaderID()
    return
}

// verify we are leaders
if err := w.VerifyLeader(); err != nil {
    fmt.Println("error", err)
}

// try to write the state
nUpdates := 0
for {
    if nUpdates >= 1000 {
        break
    }

    newState := &raftState{nUpdates * 2}

    // CommitState() blocks until the state has been
    // agreed upon by everyone
    agreedState, err := w.CommitState(newState)
    if err != nil {
        fmt.Println(err)
        continue
    }
    if agreedState == nil {
        fmt.Println("agreedState is nil: commited on a non-leader?")
        continue
    }
    agreedRaftState := agreedState.(*raftState)
    nUpdates++

    if nUpdates%200 == 0 {
        fmt.Printf("Performed %d updates. Current state value: %d\n",
            nUpdates, agreedRaftState.Value)
    }
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type SimpleRaft

type SimpleRaft struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func NewSimpleRaft

func NewSimpleRaft(ctx context.Context, h host.Host, state consensus.State, peerChan chan peer.AddrInfo) (*SimpleRaft, error)

func (*SimpleRaft) CommitState

func (rw *SimpleRaft) CommitState(state consensus.State) (consensus.State, error)

func (*SimpleRaft) GetLeader

func (rw *SimpleRaft) GetLeader() (peer.AddrInfo, error)

func (*SimpleRaft) GetLeaderID

func (rw *SimpleRaft) GetLeaderID() (leaderAddress hraft.ServerAddress, serverID hraft.ServerID)

func (*SimpleRaft) GetPeers

func (rw *SimpleRaft) GetPeers() []peer.AddrInfo

func (*SimpleRaft) GetState

func (rw *SimpleRaft) GetState() (consensus.State, error)

func (*SimpleRaft) IsLeader

func (rw *SimpleRaft) IsLeader() bool

func (*SimpleRaft) VerifyLeader

func (rw *SimpleRaft) VerifyLeader() error

func (*SimpleRaft) WaitForLeader

func (rw *SimpleRaft) WaitForLeader(ctx context.Context) (string, error)

WaitForLeader holds until Raft says we have a leader. Returns if ctx is canceled.

func (*SimpleRaft) WaitForSync

func (rw *SimpleRaft) WaitForSync(ctx context.Context) error

WaitForSync waits for a leader and for the state to be up to date, then returns.

func (*SimpleRaft) WaitForUpdates

func (rw *SimpleRaft) WaitForUpdates(ctx context.Context) error

WaitForUpdates holds until Raft has synced to the last index in the log

func (*SimpleRaft) WaitForVoter

func (rw *SimpleRaft) WaitForVoter(ctx context.Context) error

Jump to

Keyboard shortcuts

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