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 // Dispatch the command to leader
func dispatch(c Command, w http.ResponseWriter, req *http.Request, etcd bool) error { func dispatch(c Command, w http.ResponseWriter, req *http.Request, etcd bool) error {
if r.State() == raft.Leader { if r.State() == raft.Leader {
if body, err := r.Do(c); err != nil { if body, err := r.Do(c); err != nil {
return err return err
} else { } else {
if body == nil { if body == nil {
return etcdErr.NewError(etcdErr.EcodeRaftInternal, "Empty result from raft") return etcdErr.NewError(300, "Empty result from raft")
} else { } else {
body, _ := body.([]byte) body, _ := body.([]byte)
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
@ -204,28 +203,14 @@ func dispatch(c Command, w http.ResponseWriter, req *http.Request, etcd bool) er
leader := r.Leader() leader := r.Leader()
// current no leader // current no leader
if leader == "" { if leader == "" {
return etcdErr.NewError(etcdErr.EcodeRaftInternal, "") return etcdErr.NewError(300, "")
} }
// tell the client where is the leader redirect(leader, etcd, w, req)
path := req.URL.Path
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 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") recursive := req.FormValue("recursive")
if req.FormValue("wait") == "true" { if req.FormValue("wait") == "true" { // watch
command := &WatchCommand{ command := &WatchCommand{
Key: key, Key: key,
} }
@ -305,7 +290,16 @@ func GetHttpHandler(w http.ResponseWriter, req *http.Request) error {
event, err = command.Apply(r.Server) 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{ command := &GetCommand{
Key: key, Key: key,
} }

17
util.go
View File

@ -65,6 +65,23 @@ func startWebInterface() {
// HTTP Utilities // 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 { func decodeJsonRequest(req *http.Request, data interface{}) error {
decoder := json.NewDecoder(req.Body) decoder := json.NewDecoder(req.Body)
if err := decoder.Decode(&data); err != nil && err != io.EOF { if err := decoder.Decode(&data); err != nil && err != io.EOF {