github.com/marineam/etcd@v0.1.2-0.20130821182615-9b7109b46686/transporter.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "crypto/tls" 6 "encoding/json" 7 "fmt" 8 "github.com/coreos/go-raft" 9 "io" 10 "net" 11 "net/http" 12 ) 13 14 // Transporter layer for communication between raft nodes 15 type transporter struct { 16 client *http.Client 17 } 18 19 // Create transporter using by raft server 20 // Create http or https transporter based on 21 // whether the user give the server cert and key 22 func newTransporter(scheme string, tlsConf tls.Config) transporter { 23 t := transporter{} 24 25 tr := &http.Transport{ 26 Dial: dialTimeout, 27 } 28 29 if scheme == "https" { 30 tr.TLSClientConfig = &tlsConf 31 tr.DisableCompression = true 32 } 33 34 t.client = &http.Client{Transport: tr} 35 36 return t 37 } 38 39 // Dial with timeout 40 func dialTimeout(network, addr string) (net.Conn, error) { 41 return net.DialTimeout(network, addr, HTTPTimeout) 42 } 43 44 // Sends AppendEntries RPCs to a peer when the server is the leader. 45 func (t transporter) SendAppendEntriesRequest(server *raft.Server, peer *raft.Peer, req *raft.AppendEntriesRequest) *raft.AppendEntriesResponse { 46 var aersp *raft.AppendEntriesResponse 47 var b bytes.Buffer 48 json.NewEncoder(&b).Encode(req) 49 50 u, _ := nameToRaftURL(peer.Name) 51 debugf("Send LogEntries to %s ", u) 52 53 resp, err := t.Post(fmt.Sprintf("%s/log/append", u), &b) 54 55 if err != nil { 56 debugf("Cannot send AppendEntriesRequest to %s: %s", u, err) 57 } 58 59 if resp != nil { 60 defer resp.Body.Close() 61 aersp = &raft.AppendEntriesResponse{} 62 if err := json.NewDecoder(resp.Body).Decode(&aersp); err == nil || err == io.EOF { 63 return aersp 64 } 65 66 } 67 68 return aersp 69 } 70 71 // Sends RequestVote RPCs to a peer when the server is the candidate. 72 func (t transporter) SendVoteRequest(server *raft.Server, peer *raft.Peer, req *raft.RequestVoteRequest) *raft.RequestVoteResponse { 73 var rvrsp *raft.RequestVoteResponse 74 var b bytes.Buffer 75 json.NewEncoder(&b).Encode(req) 76 77 u, _ := nameToRaftURL(peer.Name) 78 debugf("Send Vote to %s", u) 79 80 resp, err := t.Post(fmt.Sprintf("%s/vote", u), &b) 81 82 if err != nil { 83 debugf("Cannot send VoteRequest to %s : %s", u, err) 84 } 85 86 if resp != nil { 87 defer resp.Body.Close() 88 rvrsp := &raft.RequestVoteResponse{} 89 if err := json.NewDecoder(resp.Body).Decode(&rvrsp); err == nil || err == io.EOF { 90 return rvrsp 91 } 92 93 } 94 return rvrsp 95 } 96 97 // Sends SnapshotRequest RPCs to a peer when the server is the candidate. 98 func (t transporter) SendSnapshotRequest(server *raft.Server, peer *raft.Peer, req *raft.SnapshotRequest) *raft.SnapshotResponse { 99 var aersp *raft.SnapshotResponse 100 var b bytes.Buffer 101 json.NewEncoder(&b).Encode(req) 102 103 u, _ := nameToRaftURL(peer.Name) 104 debugf("Send Snapshot to %s [Last Term: %d, LastIndex %d]", u, 105 req.LastTerm, req.LastIndex) 106 107 resp, err := t.Post(fmt.Sprintf("%s/snapshot", u), &b) 108 109 if err != nil { 110 debugf("Cannot send SendSnapshotRequest to %s : %s", u, err) 111 } 112 113 if resp != nil { 114 defer resp.Body.Close() 115 aersp = &raft.SnapshotResponse{} 116 if err = json.NewDecoder(resp.Body).Decode(&aersp); err == nil || err == io.EOF { 117 118 return aersp 119 } 120 } 121 122 return aersp 123 } 124 125 // Sends SnapshotRecoveryRequest RPCs to a peer when the server is the candidate. 126 func (t transporter) SendSnapshotRecoveryRequest(server *raft.Server, peer *raft.Peer, req *raft.SnapshotRecoveryRequest) *raft.SnapshotRecoveryResponse { 127 var aersp *raft.SnapshotRecoveryResponse 128 var b bytes.Buffer 129 json.NewEncoder(&b).Encode(req) 130 131 u, _ := nameToRaftURL(peer.Name) 132 debugf("Send SnapshotRecovery to %s [Last Term: %d, LastIndex %d]", u, 133 req.LastTerm, req.LastIndex) 134 135 resp, err := t.Post(fmt.Sprintf("%s/snapshotRecovery", u), &b) 136 137 if err != nil { 138 debugf("Cannot send SendSnapshotRecoveryRequest to %s : %s", u, err) 139 } 140 141 if resp != nil { 142 defer resp.Body.Close() 143 aersp = &raft.SnapshotRecoveryResponse{} 144 if err = json.NewDecoder(resp.Body).Decode(&aersp); err == nil || err == io.EOF { 145 return aersp 146 } 147 } 148 149 return aersp 150 } 151 152 // Send server side POST request 153 func (t transporter) Post(path string, body io.Reader) (*http.Response, error) { 154 return t.client.Post(path, "application/json", body) 155 } 156 157 // Send server side GET request 158 func (t transporter) Get(path string) (*http.Response, error) { 159 return t.client.Get(path) 160 }