Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a document? #21

Open
aelous opened this issue Mar 2, 2020 · 3 comments
Open

Is there a document? #21

aelous opened this issue Mar 2, 2020 · 3 comments
Labels

Comments

@aelous
Copy link

aelous commented Mar 2, 2020

No description provided.

@aelous aelous changed the title Is there are document? Is there a document? Mar 2, 2020
@mervinkid
Copy link
Collaborator

Hi, @aelous
Thanks for your feedback.
Unfortunately, this library does not provide formal documentation at this time.
But I can tell you how to use this library simply by replying to the issue.

@aelous
Copy link
Author

aelous commented Mar 3, 2020

OK,thx

@mervinkid
Copy link
Collaborator

mervinkid commented Mar 3, 2020

Hi @aelous ,
This library is an implementation of multi-raft allows multiple raft group instance in single raft server instance.
It used by ChubaoFS which hosted by the Cloud Native Computing Foundation (CNCF) as a sandbox project.

The following demos shows how to use this library.

package main

import (
	"fmt"

	"github.com/pkg/errors"
	"github.com/tiglabs/raft"
	"github.com/tiglabs/raft/proto"
	"github.com/tiglabs/raft/storage/wal"
)

// Constants
const (
	nodeID          uint64 = 1      // ID of current node
	electionTickSec int    = 5      // Seconds of election tick
	heartbeatPort   string = "2019" // port used to process heartbeat
	replicatePort   string = "2020" // port used to process replication
	raftGroupID     uint64 = 1
)

// Errors
var (
	ErrNodeNotExists     = errors.New("node not exists")
	ErrUnknownSocketType = errors.New("unknown socket type")
)

// Implementation of interface 'github.com/tiglabs/raft/Resolver'.
type resolver struct {
	nodeMap map[uint64]string // node ID -> node address
}

// NodeAddress called by raft and used to resolve address of specified node ID.
func (r *resolver) NodeAddress(nodeID uint64, stype raft.SocketType) (addr string, err error) {
	var address string
	var found bool
	if address, found = r.nodeMap[nodeID]; !found {
		return "", ErrNodeNotExists
	}
	switch stype {
	case raft.HeartBeat:
		return fmt.Sprintf("%s:%s", address, heartbeatPort), nil
	case raft.Replicate:
		return fmt.Sprintf("%s:%s", address, replicatePort), nil
	default:
		return "", ErrUnknownSocketType
	}
}

func newResolver() *resolver {
	return &resolver{
		nodeMap: make(map[uint64]string),
	}
}

// Implementation of interface 'github.com/tiglabs/raft/StateMachine'
type stateMachine struct {
}

func (*stateMachine) Apply(command []byte, index uint64) (interface{}, error) {
	// invoked when apply a raft log.
	panic("implement me")
}

func (*stateMachine) ApplyMemberChange(confChange *proto.ConfChange, index uint64) (interface{}, error) {
	// invoked when raft member changed.
	panic("implement me")
}

func (*stateMachine) Snapshot() (proto.Snapshot, error) {
	// invoked when some node need a snapshot to recover.
	panic("implement me")
}

func (*stateMachine) ApplySnapshot(peers []proto.Peer, iter proto.SnapIterator) error {
	// invoked when current node applying snapshot.
	panic("implement me")
}

func (*stateMachine) HandleFatalEvent(err *raft.FatalError) {
	// invoked when some error occurred.
	panic("implement me")
}

func (*stateMachine) HandleLeaderChange(leader uint64) {
	// invoked when leader of raft group changed.
	panic("implement me")
}

func main() {

	var err error

	// configuration for raft instance
	var config = raft.DefaultConfig()
	config.NodeID = nodeID                     // setup node ID
	config.ElectionTick = electionTickSec      // setup election tick
	config.LeaseCheck = true                   // use the lease mechanism
	config.HeartbeatAddr = ":" + heartbeatPort // setup heartbeat port
	config.ReplicateAddr = ":" + replicatePort // setup replicate port
	config.Resolver = newResolver()            // setup address resolver

	// init and start raft server instance
	var raftServer *raft.RaftServer
	if raftServer, err = raft.NewRaftServer(config); err != nil {
		panic(err) // start fail
	}

	// setup and create a raft group instance from raft server instance
	var raftConfig = &raft.RaftConfig{
		ID:           raftGroupID,
		Term:         0,                     // term of this raft group which need be managed by yourself
		Peers:        make([]proto.Peer, 0), // peers of this raft group members
		StateMachine: &stateMachine{},       // setup implementation instance for event handle
	}
	// setup WAL storage for raft this raft group instance
	var path = fmt.Sprintf("/tmp/raft/%d", raftGroupID)
	if raftConfig.Storage, err = wal.NewStorage(path, &wal.Config{}); err != nil {
		panic(err) // init storage fail
	}
	if err = raftServer.CreateRaft(raftConfig); err != nil {
		panic(err) // start raft group instance fail
	}

	// submit a log to raft group 1 if current node is leader.
	if raftServer.IsLeader(raftGroupID) {
		// submit
		var future = raftServer.Submit(raftGroupID, []byte("hello raft"))
		// wait for result
		var resp interface{}
		if resp, err = future.Response(); err != nil {
			panic(err) // responded an error
		}
		fmt.Printf("response: %v\n", resp)
	}

	// get committed index ID of raft group '1'
	var committedIndex = raftServer.CommittedIndex(raftGroupID)
	fmt.Printf("committed index: %v\n", committedIndex)

	// stop raft group '1'
	if err = raftServer.RemoveRaft(raftGroupID); err != nil {
		panic(err) // stop raft group instance fail
	}

	// stop raft server instance
	raftServer.Stop()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants