// // shared by Put and Append. // func (ck *Clerk) PutAppend(key string, value string, op string) { ck.mu.Lock() defer ck.mu.Unlock() xid := nrand() putReq := &PutAppendArgs{} putRep := &PutAppendReply{} putReq.Xid = xid putReq.Value = value putReq.Op = op putReq.Key = key tries := 0 for { time.Sleep(100 * time.Millisecond) tries = tries + 1 glog.Infoln(" Loop count", tries) for index, _ := range ck.servers { glog.Infoln(ck.uuid, "PutAppend Calling server ", index, " for request ", putReq.Op) ret := call(ck.servers[index], "KVPaxos.PutAppend", putReq, putRep) if ret { //we got a response check if invalid response in which case try again if putRep.Err != OK { continue } return } else { glog.Warningln(ck.uuid, "RPC broke, retrying for a different server ", ck.servers) continue } } } }
func ping(conn net.Conn) error { select { case pingAtCh <- 1: glog.Infoln("Escort slave send ping!") default: // 没有收到上一次ping的pong,超时 glog.Warningln("Escort slave doesn't get pong!") return new(PingTimeOutErr) } pingcmd := new(Packet) pingcmd.Version = V1 pingcmd.Flags = FLAG_REQUEST pingcmd.Length = 0 pingcmd.Sequence = 0 data, err := pingcmd.Encode() _, err = conn.Write(data) if err != nil { glog.Errorf("[ERROR] %s", err.Error()) return err } return nil }
// // servers[] contains the ports of the set of // servers that will cooperate via Paxos to // form the fault-tolerant key/value service. // me is the index of the current server in servers[]. // func StartServer(servers []string, me int) *KVPaxos { // Go's RPC library to marshall/unmarshall. gob.Register(Op{}) kv := new(KVPaxos) kv.me = me kv.seenMap = make(map[int64]bool) kv.kvData = make(map[string]string) kv.toprocess = 1 rpcs := rpc.NewServer() rpcs.Register(kv) kv.px = paxos.Make(servers, me, rpcs) os.Remove(servers[me]) l, e := net.Listen("unix", servers[me]) if e != nil { glog.Fatal("listen error: ", e) } kv.l = l go func() { for kv.isdead() == false { conn, err := kv.l.Accept() if err == nil && kv.isdead() == false { go rpcs.ServeConn(conn) } else if err == nil { conn.Close() } if err != nil && kv.isdead() == false { glog.Warningln("KVPaxos(%v) accept: %v\n", me, err.Error()) kv.kill() } } }() return kv }
// // call() sends an RPC to the rpcname handler on server srv // with arguments args, waits for the reply, and leaves the // reply in reply. the reply argument should be a pointer // to a reply structure. // // the return value is true if the server responded, and false // if call() was not able to contact the server. in particular, // tplys contents are only valid if call() returned true. // // func call(srv string, name string, args interface{}, reply interface{}) bool { c, err := rpc.Dial("unix", srv) if err != nil { err1 := err.(*net.OpError) if err1.Err != syscall.ENOENT && err1.Err != syscall.ECONNREFUSED { glog.Warningln("paxos Dial() failed: %v\n", err1) } return false } defer c.Close() err = c.Call(name, args, reply) if err == nil { return true } glog.Infoln(err) return false }