// start i'th server in gi'th group func (cfg *config) StartServer(gi int, i int) { cfg.mu.Lock() gg := cfg.groups[gi] // a fresh set of outgoing ClientEnd names // to talk to other servers in this group. gg.endnames[i] = make([]string, cfg.n) for j := 0; j < cfg.n; j++ { gg.endnames[i][j] = randstring(20) } // and the connections to other servers in this group. ends := make([]*labrpc.ClientEnd, cfg.n) for j := 0; j < cfg.n; j++ { ends[j] = cfg.net.MakeEnd(gg.endnames[i][j]) cfg.net.Connect(gg.endnames[i][j], cfg.servername(gg.gid, j)) cfg.net.Enable(gg.endnames[i][j], true) } // ends to talk to shardmaster service mends := make([]*labrpc.ClientEnd, cfg.nmasters) gg.mendnames[i] = make([]string, cfg.nmasters) for j := 0; j < cfg.nmasters; j++ { gg.mendnames[i][j] = randstring(20) mends[j] = cfg.net.MakeEnd(gg.mendnames[i][j]) cfg.net.Connect(gg.mendnames[i][j], cfg.mastername(j)) cfg.net.Enable(gg.mendnames[i][j], true) } // a fresh persister, so old instance doesn't overwrite // new instance's persisted state. // give the fresh persister a copy of the old persister's // state, so that the spec is that we pass StartKVServer() // the last persisted state. if gg.saved[i] != nil { gg.saved[i] = gg.saved[i].Copy() } else { gg.saved[i] = raft.MakePersister() } cfg.mu.Unlock() gg.servers[i] = StartServer(ends, i, gg.saved[i], cfg.maxraftstate, gg.gid, mends, func(servername string) *labrpc.ClientEnd { name := randstring(20) end := cfg.net.MakeEnd(name) cfg.net.Connect(name, servername) cfg.net.Enable(name, true) return end }) kvsvc := labrpc.MakeService(gg.servers[i]) rfsvc := labrpc.MakeService(gg.servers[i].rf) srv := labrpc.MakeServer() srv.AddService(kvsvc) srv.AddService(rfsvc) cfg.net.AddServer(cfg.servername(gg.gid, i), srv) }
func (cfg *config) StartMasterServer(i int) { // ClientEnds to talk to other master replicas. ends := make([]*labrpc.ClientEnd, cfg.nmasters) for j := 0; j < cfg.nmasters; j++ { endname := randstring(20) ends[j] = cfg.net.MakeEnd(endname) cfg.net.Connect(endname, cfg.mastername(j)) cfg.net.Enable(endname, true) } p := raft.MakePersister() cfg.masterservers[i] = shardmaster.StartServer(ends, i, p) msvc := labrpc.MakeService(cfg.masterservers[i]) rfsvc := labrpc.MakeService(cfg.masterservers[i].Raft()) srv := labrpc.MakeServer() srv.AddService(msvc) srv.AddService(rfsvc) cfg.net.AddServer(cfg.mastername(i), srv) }
// If restart servers, first call ShutdownServer func (cfg *config) StartServer(i int) { cfg.mu.Lock() // a fresh set of outgoing ClientEnd names. cfg.endnames[i] = make([]string, cfg.n) for j := 0; j < cfg.n; j++ { cfg.endnames[i][j] = randstring(20) } // a fresh set of ClientEnds. ends := make([]*labrpc.ClientEnd, cfg.n) for j := 0; j < cfg.n; j++ { ends[j] = cfg.net.MakeEnd(cfg.endnames[i][j]) cfg.net.Connect(cfg.endnames[i][j], j) } // a fresh persister, so old instance doesn't overwrite // new instance's persisted state. // give the fresh persister a copy of the old persister's // state, so that the spec is that we pass StartKVServer() // the last persisted state. if cfg.saved[i] != nil { cfg.saved[i] = cfg.saved[i].Copy() } else { cfg.saved[i] = raft.MakePersister() } cfg.mu.Unlock() cfg.kvservers[i] = StartKVServer(ends, i, cfg.saved[i], cfg.maxraftstate) kvsvc := labrpc.MakeService(cfg.kvservers[i]) rfsvc := labrpc.MakeService(cfg.kvservers[i].rf) srv := labrpc.MakeServer() srv.AddService(kvsvc) srv.AddService(rfsvc) cfg.net.AddServer(i, srv) }
// // start or re-start a Raft. // if one already exists, "kill" it first. // allocate new outgoing port file names, and a new // state persister, to isolate previous instance of // this server. since we cannot really kill it. // func (cfg *config) start1(i int) { cfg.crash1(i) // a fresh set of outgoing ClientEnd names. // so that old crashed instance's ClientEnds can't send. cfg.endnames[i] = make([]string, cfg.n) for j := 0; j < cfg.n; j++ { cfg.endnames[i][j] = randstring(20) } // a fresh set of ClientEnds. ends := make([]*labrpc.ClientEnd, cfg.n) for j := 0; j < cfg.n; j++ { ends[j] = cfg.net.MakeEnd(cfg.endnames[i][j]) cfg.net.Connect(cfg.endnames[i][j], j) } cfg.mu.Lock() // a fresh persister, so old instance doesn't overwrite // new instance's persisted state. // but copy old persister's content so that we always // pass Make() the last persisted state. if cfg.saved[i] != nil { cfg.saved[i] = cfg.saved[i].Copy() } else { cfg.saved[i] = MakePersister() } cfg.mu.Unlock() // listen to messages from Raft indicating newly committed messages. applyCh := make(chan ApplyMsg) go func() { for m := range applyCh { err_msg := "" if m.UseSnapshot { // ignore the snapshot } else if v, ok := (m.Command).(int); ok { cfg.mu.Lock() for j := 0; j < len(cfg.logs); j++ { if old, oldok := cfg.logs[j][m.Index]; oldok && old != v { // some server has already committed a different value for this entry! err_msg = fmt.Sprintf("commit index=%v server=%v %v != server=%v %v", m.Index, i, m.Command, j, old) } } _, prevok := cfg.logs[i][m.Index-1] cfg.logs[i][m.Index] = v cfg.mu.Unlock() if m.Index > 1 && prevok == false { err_msg = fmt.Sprintf("server %v apply out of order %v", i, m.Index) } } else { err_msg = fmt.Sprintf("committed command %v is not an int", m.Command) } if err_msg != "" { log.Fatalf("apply error: %v\n", err_msg) cfg.applyErr[i] = err_msg // keep reading after error so that Raft doesn't block // holding locks... } } }() rf := Make(ends, i, cfg.saved[i], applyCh) cfg.mu.Lock() cfg.rafts[i] = rf cfg.mu.Unlock() svc := labrpc.MakeService(rf) srv := labrpc.MakeServer() srv.AddService(svc) cfg.net.AddServer(i, srv) }