func (b *Broker) setupRaft() (err error) {
	defer func() {
		if b.raft == nil && b.raftStore != nil {
			if err := b.raftStore.Close(); err != nil {
				log.Error.Printf("leader/%d: close raft store error: %s", b.config.ID, err)
			}
		}
	}()
	b.fsm, err = fsm.New(b.tracer, fsm.NodeID(b.config.ID))
	if err != nil {
		return err
	}
	trans, err := raft.NewTCPTransport(b.config.RaftAddr,
		nil,
		3,
		10*time.Second,
		nil,
	)
	if err != nil {
		return err
	}
	b.raftTransport = trans
	b.config.RaftConfig.LocalID = raft.ServerID(fmt.Sprintf("%d", b.config.ID))
	b.config.RaftConfig.StartAsLeader = b.config.StartAsLeader
	var logStore raft.LogStore
	var stable raft.StableStore
	var snap raft.SnapshotStore
	if b.config.DevMode {
		store := raft.NewInmemStore()
		b.raftInmem = store
		stable = store
		logStore = store
		snap = raft.NewInmemSnapshotStore()
	} else {
		path := filepath.Join(b.config.DataDir, raftState)
		if err := ensurePath(path, true); err != nil {
			return err
		}
		store, err := raftboltdb.NewBoltStore(filepath.Join(path, "raft.db"))
		if err != nil {
			return err
		}
		b.raftStore = store
		stable = store
		cacheStore, err := raft.NewLogCache(raftLogCacheSize, store)
		if err != nil {
			return err
		}
		logStore = cacheStore
		snapshots, err := raft.NewFileSnapshotStore(path, snapshotsRetained, nil)
		if err != nil {
			return err
		}
		snap = snapshots
	}
	if b.config.Bootstrap || b.config.DevMode {
		hasState, err := raft.HasExistingState(logStore, stable, snap)
		if err != nil {
			return err
		}
		if !hasState {
			configuration := raft.Configuration{
				Servers: []raft.Server{
					raft.Server{
						ID:      b.config.RaftConfig.LocalID,
						Address: trans.LocalAddr(),
					},
				},
			}
			if err := raft.BootstrapCluster(b.config.RaftConfig, logStore, stable, snap, trans, configuration); err != nil {
				return err
			}
		}
	}
	raftNotifyCh := make(chan bool, 1)
	b.config.RaftConfig.NotifyCh = raftNotifyCh
	b.raftNotifyCh = raftNotifyCh
	b.raft, err = raft.NewRaft(b.config.RaftConfig, b.fsm, logStore, stable, snap, trans)
	return err
}
setupRaft is used to setup and initialize Raft.
package jocko
import (
	"fmt"
	"math/rand"
	"path/filepath"
	"sync"
	"time"
	"github.com/hashicorp/raft"
	raftboltdb "github.com/hashicorp/raft-boltdb"
	"github.com/hashicorp/serf/serf"
	"github.com/travisjeffery/jocko/jocko/fsm"
	"github.com/travisjeffery/jocko/jocko/metadata"
	"github.com/travisjeffery/jocko/jocko/structs"
	"github.com/travisjeffery/jocko/log"
	"github.com/travisjeffery/jocko/protocol"
)
const (
	barrierWriteTimeout = 2 * time.Minute
)