func (d *Dispatcher) SetHeartbeatTick(num int) {
	d.cfg.HeartbeatTick = num
}
SetHeartbeatTick set the number of Node.Tick invocations that must pass between
heartbeats. That is, a leader sends heartbeat messages to maintain its
leadership every HeartbeatTick ticks.
This function must be called before call node.Start().
package casbinraft
import (
	"context"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"log"
	"math"
	"net"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"sync/atomic"
	"time"
	"github.com/casbin/casbin/v3"
	"github.com/coreos/etcd/etcdserver/stats"
	"github.com/coreos/etcd/pkg/transport"
	"github.com/coreos/etcd/pkg/types"
	"github.com/coreos/etcd/raft"
	"github.com/coreos/etcd/raft/raftpb"
	"github.com/coreos/etcd/rafthttp"
	"github.com/coreos/etcd/snap"
	"github.com/coreos/etcd/wal"
	"github.com/coreos/etcd/wal/walpb"
	"github.com/pkg/errors"
)
const (
	defaultSnapshotCount uint64 = 10000
	defaultHeartBeatTick int    = 1
	defaultElectionTick  int    = 10
)
type Dispatcher struct {
	id         uint64
	isJoin     bool
	ctx        context.Context
	engine     *Engine
	store      *raft.MemoryStorage
	cfg        *raft.Config
	raft       raft.Node
	membership *Cluster
	ticker     *time.Ticker
	done       chan struct{}
	snapdir     string
	snapshotter *snap.Snapshotter
	confState     *raftpb.ConfState
	snapshotIndex uint64
	appliedIndex  uint64
	snapCount     uint64
	transport  *rafthttp.Transport
	httpServer *http.Server
	waldir     string
	wal        *wal.WAL
	enableTLS bool
	keyFile   string
	certFile  string
	caFile    string
}
func NewDispatcher(id uint64, peers map[uint64]string, join ...bool) *Dispatcher {
	isJoin := false
	if len(join) > 0 {
		isJoin = join[0]
	}
	store := raft.NewMemoryStorage()
	membership := NewCluster(peers)
	d := &Dispatcher{
		id:     id,
		ctx:    context.TODO(),
		isJoin: isJoin,
		store:  store,
		cfg: &raft.Config{
			ID:              id,
			ElectionTick:    defaultElectionTick,
			HeartbeatTick:   defaultHeartBeatTick,
			Storage:         store,
			MaxSizePerMsg:   math.MaxUint16,
			MaxInflightMsgs: 256,
		},
		membership: membership,
		ticker:     time.NewTicker(100 * time.Millisecond),
		done:       make(chan struct{}),
		snapdir:    fmt.Sprintf("casbin-%d-snap", id),
		snapCount:  defaultSnapshotCount,
		waldir:     fmt.Sprintf("casbin-%d", id),
	}
	return d
}
func (d *Dispatcher) SetEnforcer(enforcer interface{}) error {
	value, ok := enforcer.(*casbin.Enforcer)
	if !ok {
		return errors.New("type of parameter should be *casbin.Enforcer")
	}
	d.engine = newEngine(value)
	return nil
}
func (d *Dispatcher) SetSnapshotCount(count uint64) {
	d.snapCount = count
}
func (d *Dispatcher) SetSnapDirName(name string) {
	d.snapdir = name
}
func (d *Dispatcher) SetWalDirName(name string) {
	d.waldir = name
}