Browse Source

rafthttp: print out log when clusterID mismatch instead of exiting

We have heard from several users that they do not expect a clusterID
mismatch to kill the cluster.
Xiang Li 10 years ago
parent
commit
0d3d4c5b01
4 changed files with 17 additions and 14 deletions
  1. 9 7
      rafthttp/http.go
  2. 3 6
      rafthttp/pipeline.go
  3. 0 1
      rafthttp/pipeline_test.go
  4. 5 0
      rafthttp/stream.go

+ 9 - 7
rafthttp/http.go

@@ -126,6 +126,15 @@ func (h *streamHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
+	wcid := h.cid.String()
+	w.Header().Set("X-Etcd-Cluster-ID", wcid)
+
+	if gcid := r.Header.Get("X-Etcd-Cluster-ID"); gcid != wcid {
+		log.Printf("rafthttp: streaming request ignored due to cluster ID mismatch got %s want %s", gcid, wcid)
+		http.Error(w, "clusterID mismatch", http.StatusPreconditionFailed)
+		return
+	}
+
 	w.Header().Add("X-Server-Version", version.Version)
 
 	var t streamType
@@ -162,13 +171,6 @@ func (h *streamHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	wcid := h.cid.String()
-	if gcid := r.Header.Get("X-Etcd-Cluster-ID"); gcid != wcid {
-		log.Printf("rafthttp: streaming request ignored due to cluster ID mismatch got %s want %s", gcid, wcid)
-		http.Error(w, "clusterID mismatch", http.StatusPreconditionFailed)
-		return
-	}
-
 	wto := h.id.String()
 	if gto := r.Header.Get("X-Raft-To"); gto != wto {
 		log.Printf("rafthttp: streaming request ignored due to ID mismatch got %s want %s", gto, wto)

+ 3 - 6
rafthttp/pipeline.go

@@ -148,12 +148,9 @@ func (p *pipeline) post(data []byte) error {
 
 	switch resp.StatusCode {
 	case http.StatusPreconditionFailed:
-		err := fmt.Errorf("conflicting cluster ID with the target cluster (%s != %s)", resp.Header.Get("X-Etcd-Cluster-ID"), p.cid)
-		select {
-		case p.errorc <- err:
-		default:
-		}
-		return nil
+		log.Printf("rafthttp: request sent was ignored due to cluster ID mismatch (remote[%s]:%s, local:%s)",
+			uu.Host, resp.Header.Get("X-Etcd-Cluster-ID"), p.cid)
+		return fmt.Errorf("cluster ID mismatch")
 	case http.StatusForbidden:
 		err := fmt.Errorf("the member has been permanently removed from the cluster")
 		select {

+ 0 - 1
rafthttp/pipeline_test.go

@@ -165,7 +165,6 @@ func TestPipelinePostErrorc(t *testing.T) {
 		err  error
 	}{
 		{"http://localhost:2380", http.StatusForbidden, nil},
-		{"http://localhost:2380", http.StatusPreconditionFailed, nil},
 	}
 	for i, tt := range tests {
 		picker := mustNewURLPicker(t, []string{tt.u})

+ 5 - 0
rafthttp/stream.go

@@ -424,6 +424,11 @@ func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) {
 	case http.StatusNotFound:
 		resp.Body.Close()
 		return nil, fmt.Errorf("local member has not been added to the peer list of member %s", cr.to)
+	case http.StatusPreconditionFailed:
+		resp.Body.Close()
+		log.Printf("rafthttp: request sent was ignored due to cluster ID mismatch (remote[%s]:%s, local:%s)",
+			uu.Host, resp.Header.Get("X-Etcd-Cluster-ID"), cr.cid)
+		return nil, fmt.Errorf("cluster ID mismatch")
 	default:
 		resp.Body.Close()
 		return nil, fmt.Errorf("unhandled http status %d", resp.StatusCode)