diff --git a/etcd.go b/etcd.go index a2d840cc8..4f1a4112b 100644 --- a/etcd.go +++ b/etcd.go @@ -13,6 +13,7 @@ import ( "github.com/coreos/go-raft" "io/ioutil" "log" + "net" "net/http" "os" "strings" @@ -89,6 +90,7 @@ const ( const ( ELECTIONTIMTOUT = 200 * time.Millisecond HEARTBEATTIMEOUT = 50 * time.Millisecond + HTTPTIMEOUT = time.Second ) //------------------------------------------------------------------------------ @@ -263,12 +265,22 @@ func createTransporter(st int) transporter { switch st { case HTTP: - t.client = nil + t.https = false + + tr := &http.Transport{ + Dial: dialTimeout, + } + + t.client = &http.Client{ + Transport: tr, + } return t case HTTPS: fallthrough case HTTPSANDVERIFY: + t.https = true + tlsCert, err := tls.LoadX509KeyPair(serverCertFile, serverKeyFile) if err != nil { @@ -280,6 +292,7 @@ func createTransporter(st int) transporter { Certificates: []tls.Certificate{tlsCert}, InsecureSkipVerify: true, }, + Dial: dialTimeout, DisableCompression: true, } @@ -291,6 +304,11 @@ func createTransporter(st int) transporter { return transporter{} } +// Dial with timeout +func dialTimeout(network, addr string) (net.Conn, error) { + return net.DialTimeout(network, addr, HTTPTIMEOUT) +} + // Start to listen and response raft command func startRaftTransport(port int, st int) { diff --git a/transporter.go b/transporter.go index 0eb6c5599..f49047372 100644 --- a/transporter.go +++ b/transporter.go @@ -12,10 +12,9 @@ import ( // Transporter layer for communication between raft nodes type transporter struct { - name string - // If https is used for server internal communcation, - // we will have a http client. Or it will be nil. client *http.Client + // https + https bool } // Sends AppendEntries RPCs to a peer when the server is the leader. @@ -104,22 +103,22 @@ func (t transporter) GetLeaderClientAddress() string { // Send server side POST request func (t transporter) Post(path string, body io.Reader) (*http.Response, error) { - if t.client != nil { + if t.https { resp, err := t.client.Post("https://"+path, "application/json", body) return resp, err } else { - resp, err := http.Post("http://"+path, "application/json", body) + resp, err := t.client.Post("http://"+path, "application/json", body) return resp, err } } // Send server side GET request func (t transporter) Get(path string) (*http.Response, error) { - if t.client != nil { + if t.https { resp, err := t.client.Get("https://" + path) return resp, err } else { - resp, err := http.Get("http://" + path) + resp, err := t.client.Get("http://" + path) return resp, err } }