// // servers[] contains the ports of the set of // servers that will cooperate via Paxos to // form the fault-tolerant shardmaster service. // me is the index of the current server in servers[]. // func StartServer(servers []*labrpc.ClientEnd, me int, persister *raft.Persister) *ShardMaster { sm := new(ShardMaster) sm.me = me sm.configs = make([]Config, 1) sm.configs[0].Groups = map[int][]string{} gob.Register(Op{}) sm.applyCh = make(chan raft.ApplyMsg) sm.rf = raft.Make(servers, me, persister, sm.applyCh) // Your code here. return sm }
// // servers[] contains the ports of the set of // servers that will cooperate via Raft to // form the fault-tolerant key/value service. // me is the index of the current server in servers[]. // the k/v server should store snapshots with persister.SaveSnapshot(), // and Raft should save its state (including log) with persister.SaveRaftState(). // the k/v server should snapshot when Raft's saved state exceeds maxraftstate bytes, // in order to allow Raft to garbage-collect its log. if maxraftstate is -1, // you don't need to snapshot. // StartKVServer() must return quickly, so it should start goroutines // for any long-running work. // func StartKVServer(servers []*labrpc.ClientEnd, me int, persister *raft.Persister, maxraftstate int) *RaftKV { // call gob.Register on structures you want // Go's RPC library to marshall/unmarshall. gob.Register(Op{}) kv := new(RaftKV) kv.me = me kv.maxraftstate = maxraftstate // Your initialization code here. kv.applyCh = make(chan raft.ApplyMsg) kv.rf = raft.Make(servers, me, persister, kv.applyCh) return kv }
// // servers[] contains the ports of the servers in this group. // // me is the index of the current server in servers[]. // // the k/v server should store snapshots with // persister.SaveSnapshot(), and Raft should save its state (including // log) with persister.SaveRaftState(). // // the k/v server should snapshot when Raft's saved state exceeds // maxraftstate bytes, in order to allow Raft to garbage-collect its // log. if maxraftstate is -1, you don't need to snapshot. // // gid is this group's GID, for interacting with the shardmaster. // // pass masters[] to shardmaster.MakeClerk() so you can send // RPCs to the shardmaster. // // make_end(servername) turns a server name from a // Config.Groups[gid][i] into a labrpc.ClientEnd on which you can // send RPCs. You'll need this to send RPCs to other groups. // // look at client.go for examples of how to use masters[] // and make_end() to send RPCs to the group owning a specific shard. // // StartServer() must return quickly, so it should start goroutines // for any long-running work. // func StartServer(servers []*labrpc.ClientEnd, me int, persister *raft.Persister, maxraftstate int, gid int, masters []*labrpc.ClientEnd, make_end func(string) *labrpc.ClientEnd) *ShardKV { // call gob.Register on structures you want // Go's RPC library to marshall/unmarshall. gob.Register(Op{}) kv := new(ShardKV) kv.me = me kv.maxraftstate = maxraftstate kv.make_end = make_end kv.gid = gid kv.masters = masters // Your initialization code here. // Use something like this to talk to the shardmaster: // kv.mck = shardmaster.MakeClerk(kv.masters) kv.applyCh = make(chan raft.ApplyMsg) kv.rf = raft.Make(servers, me, persister, kv.applyCh) return kv }
// // servers[] contains the ports of the set of // servers that will cooperate via Raft to // form the fault-tolerant key/value service. // me is the index of the current server in servers[]. // the k/v server should store snapshots with persister.SaveSnapshot(), // and Raft should save its state (including log) with persister.SaveRaftState(). // the k/v server should snapshot when Raft's saved state exceeds maxraftstate bytes, // in order to allow Raft to garbage-collect its log. if maxraftstate is -1, // you don't need to snapshot. // StartKVServer() must return quickly, so it should start goroutines // for any long-running work. // func StartKVServer(servers []*labrpc.ClientEnd, me int, persister *raft.Persister, maxraftstate int) *RaftKV { // call gob.Register on structures you want // Go's RPC library to marshall/unmarshall. gob.Register(Op{}) kv := new(RaftKV) kv.me = me kv.maxraftstate = maxraftstate // Your initialization code here. kv.db = make(map[string]string) kv.ack = make(map[int64]int) kv.result = make(map[int]chan Op) kv.applyCh = make(chan raft.ApplyMsg, 100) kv.rf = raft.Make(servers, me, persister, kv.applyCh) go func() { for { msg := <-kv.applyCh if msg.UseSnapshot { var LastIncludedIndex int var LastIncludedTerm int r := bytes.NewBuffer(msg.Snapshot) d := gob.NewDecoder(r) kv.mu.Lock() d.Decode(&LastIncludedIndex) d.Decode(&LastIncludedTerm) kv.db = make(map[string]string) kv.ack = make(map[int64]int) d.Decode(&kv.db) d.Decode(&kv.ack) kv.mu.Unlock() } else { op := msg.Command.(Op) kv.mu.Lock() if !kv.CheckDup(op.Id, op.ReqId) { kv.Apply(op) } ch, ok := kv.result[msg.Index] if ok { select { case <-kv.result[msg.Index]: default: } ch <- op } else { kv.result[msg.Index] = make(chan Op, 1) } //need snapshot if maxraftstate != -1 && kv.rf.GetPerisistSize() > maxraftstate { w := new(bytes.Buffer) e := gob.NewEncoder(w) e.Encode(kv.db) e.Encode(kv.ack) data := w.Bytes() go kv.rf.StartSnapshot(data, msg.Index) } kv.mu.Unlock() } } }() return kv }