mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #7068 from heyitsanthony/fix-v2-health
v2http: submit QGET in health endpoint if no progress
This commit is contained in:
commit
12d930b40f
@ -312,6 +312,29 @@ func TestCtlV2AuthWithCommonName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCtlV2ClusterHealth(t *testing.T) {
|
||||||
|
defer testutil.AfterTest(t)
|
||||||
|
epc := setupEtcdctlTest(t, &configNoTLS, true)
|
||||||
|
defer func() {
|
||||||
|
if err := epc.Close(); err != nil {
|
||||||
|
t.Fatalf("error closing etcd processes (%v)", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// has quorum
|
||||||
|
if err := etcdctlClusterHealth(epc, "cluster is healthy"); err != nil {
|
||||||
|
t.Fatalf("cluster-health expected to be healthy (%v)", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// cut quorum
|
||||||
|
epc.procs[0].Stop()
|
||||||
|
epc.procs[1].Stop()
|
||||||
|
if err := etcdctlClusterHealth(epc, "cluster is unhealthy"); err != nil {
|
||||||
|
t.Fatalf("cluster-health expected to be unhealthy (%v)", err)
|
||||||
|
}
|
||||||
|
epc.procs[0], epc.procs[1] = nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
func etcdctlPrefixArgs(clus *etcdProcessCluster) []string {
|
func etcdctlPrefixArgs(clus *etcdProcessCluster) []string {
|
||||||
endpoints := ""
|
endpoints := ""
|
||||||
if proxies := clus.proxies(); len(proxies) != 0 {
|
if proxies := clus.proxies(); len(proxies) != 0 {
|
||||||
@ -330,6 +353,11 @@ func etcdctlPrefixArgs(clus *etcdProcessCluster) []string {
|
|||||||
return cmdArgs
|
return cmdArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func etcdctlClusterHealth(clus *etcdProcessCluster, val string) error {
|
||||||
|
cmdArgs := append(etcdctlPrefixArgs(clus), "cluster-health")
|
||||||
|
return spawnWithExpect(cmdArgs, val)
|
||||||
|
}
|
||||||
|
|
||||||
func etcdctlSet(clus *etcdProcessCluster, key, value string) error {
|
func etcdctlSet(clus *etcdProcessCluster, key, value string) error {
|
||||||
cmdArgs := append(etcdctlPrefixArgs(clus), "set", key, value)
|
cmdArgs := append(etcdctlPrefixArgs(clus), "set", key, value)
|
||||||
return spawnWithExpect(cmdArgs, value)
|
return spawnWithExpect(cmdArgs, value)
|
||||||
|
@ -346,33 +346,24 @@ func serveVars(w http.ResponseWriter, r *http.Request) {
|
|||||||
fmt.Fprintf(w, "\n}\n")
|
fmt.Fprintf(w, "\n}\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: change etcdserver to raft interface when we have it.
|
|
||||||
// add test for healthHandler when we have the interface ready.
|
|
||||||
func healthHandler(server *etcdserver.EtcdServer) http.HandlerFunc {
|
func healthHandler(server *etcdserver.EtcdServer) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if !allowMethod(w, r.Method, "GET") {
|
if !allowMethod(w, r.Method, "GET") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if uint64(server.Leader()) == raft.None {
|
if uint64(server.Leader()) == raft.None {
|
||||||
http.Error(w, `{"health": "false"}`, http.StatusServiceUnavailable)
|
http.Error(w, `{"health": "false"}`, http.StatusServiceUnavailable)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||||
// wait for raft's progress
|
defer cancel()
|
||||||
index := server.Index()
|
if _, err := server.Do(ctx, etcdserverpb.Request{Method: "QGET"}); err != nil {
|
||||||
for i := 0; i < 3; i++ {
|
|
||||||
time.Sleep(250 * time.Millisecond)
|
|
||||||
if server.Index() > index {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
w.Write([]byte(`{"health": "true"}`))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
http.Error(w, `{"health": "false"}`, http.StatusServiceUnavailable)
|
http.Error(w, `{"health": "false"}`, http.StatusServiceUnavailable)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte(`{"health": "true"}`))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func versionHandler(c api.Cluster, fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
|
func versionHandler(c api.Cluster, fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user