示例#1
0
//
// 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
			}
		}
	}

}
示例#2
0
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
}
示例#3
0
//
// 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
}
示例#4
0
//
// 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
}