support consistent get

This commit is contained in:
Xiang Li 2013-09-15 16:42:34 -04:00
parent 2d7c1be164
commit a3545a7ffa
2 changed files with 32 additions and 21 deletions

View File

@ -185,13 +185,12 @@ func DeleteHttpHandler(w http.ResponseWriter, req *http.Request) error {
// Dispatch the command to leader
func dispatch(c Command, w http.ResponseWriter, req *http.Request, etcd bool) error {
if r.State() == raft.Leader {
if body, err := r.Do(c); err != nil {
return err
} else {
if body == nil {
return etcdErr.NewError(etcdErr.EcodeRaftInternal, "Empty result from raft")
return etcdErr.NewError(300, "Empty result from raft")
} else {
body, _ := body.([]byte)
w.WriteHeader(http.StatusOK)
@ -204,28 +203,14 @@ func dispatch(c Command, w http.ResponseWriter, req *http.Request, etcd bool) er
leader := r.Leader()
// current no leader
if leader == "" {
return etcdErr.NewError(etcdErr.EcodeRaftInternal, "")
return etcdErr.NewError(300, "")
}
// tell the client where is the leader
path := req.URL.Path
redirect(leader, etcd, w, req)
var url string
if etcd {
etcdAddr, _ := nameToEtcdURL(leader)
url = etcdAddr + path
} else {
raftAddr, _ := nameToRaftURL(leader)
url = raftAddr + path
}
debugf("Redirect to %s", url)
http.Redirect(w, req, url, http.StatusTemporaryRedirect)
return nil
}
return etcdErr.NewError(etcdErr.EcodeRaftInternal, "")
return etcdErr.NewError(300, "")
}
//--------------------------------------
@ -282,7 +267,7 @@ func GetHttpHandler(w http.ResponseWriter, req *http.Request) error {
recursive := req.FormValue("recursive")
if req.FormValue("wait") == "true" {
if req.FormValue("wait") == "true" { // watch
command := &WatchCommand{
Key: key,
}
@ -305,7 +290,16 @@ func GetHttpHandler(w http.ResponseWriter, req *http.Request) error {
event, err = command.Apply(r.Server)
} else {
} else { //get
if req.FormValue("consistent") == "true" {
if r.State() != raft.Leader {
leader := r.Leader()
redirect(leader, true, w, req)
return nil
}
}
command := &GetCommand{
Key: key,
}

17
util.go
View File

@ -65,6 +65,23 @@ func startWebInterface() {
// HTTP Utilities
//--------------------------------------
func redirect(node string, etcd bool, w http.ResponseWriter, req *http.Request) {
var url string
path := req.URL.Path
if etcd {
etcdAddr, _ := nameToEtcdURL(node)
url = etcdAddr + path
} else {
raftAddr, _ := nameToRaftURL(node)
url = raftAddr + path
}
debugf("Redirect to %s", url)
http.Redirect(w, req, url, http.StatusTemporaryRedirect)
}
func decodeJsonRequest(req *http.Request, data interface{}) error {
decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&data); err != nil && err != io.EOF {