diff --git a/shared/main.go b/shared/main.go index 67b70cfe..b59b1151 100644 --- a/shared/main.go +++ b/shared/main.go @@ -133,6 +133,95 @@ func StartNode(ServerID uint64, serverconfigs []*autoconfig.ConfigServer, gdb *g return ss } +func StartNodeEx(ServerID uint64, serverconfigs []*autoconfig.ConfigServer, gdb *gorm.DB) *SharedState { + + // addr := "localhost" + + // addr = fmt.Sprintf("%s:%d", addr, port) + + // https://github.com/golang/go/issues/17393 + if runtime.GOOS == "darwin" { + signal.Ignore(syscall.Signal(0xd)) + } + initialMembers := make(map[uint64]string) + + // when joining a new node which is not an initial members, the initialMembers + // map should be empty. + // when restarting a node that is not a member of the initial nodes, you can + // leave the initialMembers to be empty. we still populate the initialMembers + // here for simplicity. + + for _, v := range serverconfigs { + // key is the ReplicaID, ReplicaID is not allowed to be 0 + // value is the raft address + + initialMembers[v.ReplicaId] = fmt.Sprintf("%s:%d", v.Host, v.Port-2000) + } + + // for simplicity, in this example program, addresses of all those 3 initial + // raft members are hard coded. when address is not specified on the command + // line, we assume the node being launched is an initial raft member. + + var nodeAddr = initialMembers[ServerID] + + fmt.Fprintf(os.Stdout, "node address: %s\n", nodeAddr) + // change the log verbosity + logger.GetLogger("raft").SetLevel(logger.ERROR) + logger.GetLogger("rsm").SetLevel(logger.WARNING) + logger.GetLogger("transport").SetLevel(logger.WARNING) + logger.GetLogger("grpc").SetLevel(logger.WARNING) + // config for raft node + // See GoDoc for all available options + rc := config.Config{ + // ShardID and ReplicaID of the raft node + ReplicaID: uint64(ServerID), + ShardID: shardID, + + ElectionRTT: 10, + + HeartbeatRTT: 1, + CheckQuorum: true, + + SnapshotEntries: 10, + + CompactionOverhead: 5, + } + datadir := filepath.Join( + "shared-state", + fmt.Sprintf("node%d", ServerID)) + + nhc := config.NodeHostConfig{ + + WALDir: datadir, + // NodeHostDir is where everything else is stored. + NodeHostDir: datadir, + // RTTMillisecond is the average round trip time between NodeHosts (usually + // on two machines/vms), it is in millisecond. Such RTT includes the + // processing delays caused by NodeHosts, not just the network delay between + // two NodeHost instances. + RTTMillisecond: 200, + // RaftAddress is used to identify the NodeHost instance + RaftAddress: nodeAddr, + } + nh, err := dragonboat.NewNodeHost(nhc) + if err != nil { + panic(err) + } + + if err := nh.StartReplica(initialMembers, true, NewFsStateMachine, rc); err != nil { + fmt.Fprintf(os.Stderr, "failed to add cluster, %v\n", err) + os.Exit(1) + } + + ss := &SharedState{ + shardID: shardID, + replicaID: ServerID, + nh: nh, + } + + return ss +} + // func JoinCluster(ServerID string, LeaderAddress string, RaftBind string, gdb *gorm.DB) *StateCluster { // fsm := StartNode(ServerID, RaftBind, gdb) diff --git a/shared/main_test.go b/shared/main_test.go index 0e1b77de..10ad0958 100644 --- a/shared/main_test.go +++ b/shared/main_test.go @@ -5,3 +5,15 @@ import "testing" func TestMain(t *testing.T) { test1() } + +func TestNodeA(t *testing.T) { + test1() +} + +func TestNodeB(t *testing.T) { + test1() +} + +func TestNodeC(t *testing.T) { + test1() +}