@@ -108,82 +108,53 @@ func (host *Host) releaseConn(conn net.Conn) {
108
108
}
109
109
}
110
110
111
- func (host * Host ) execute (req * mc.Request ) (resp * mc.Response , delta time.Duration , err error ) {
112
- now := time .Now ()
111
+ func (host * Host ) executeWithTimeout (req * mc.Request , timeout time.Duration ) (resp * mc.Response , err error ) {
113
112
conn , err := host .getConn ()
114
113
if err != nil {
115
114
return
116
115
}
116
+ conn .SetDeadline (time .Now ().Add (timeout ))
117
+
118
+ var reason string
119
+
120
+ defer func () {
121
+ if err != nil {
122
+ logger .Errorf ("error occurred on %s, reason: %s, err: %s" , host .Addr , reason , err .Error ())
123
+ if resp != nil {
124
+ resp .CleanBuffer ()
125
+ }
126
+ conn .Close ()
127
+ } else {
128
+ host .releaseConn (conn )
129
+ }
130
+ }()
117
131
118
132
err = req .Write (conn )
119
133
if err != nil {
120
- logger .Infof ("%s write request failed: %v" , host .Addr , err )
121
- conn .Close ()
134
+ reason = "write request failed"
122
135
return
123
136
}
124
137
125
138
resp = new (mc.Response )
126
139
if req .NoReply {
127
- host .releaseConn (conn )
128
140
resp .Status = "STORED"
129
- delta = time .Since (now )
130
141
return
131
142
}
132
143
133
144
reader := bufio .NewReader (conn )
134
145
if err = resp .Read (reader ); err != nil {
135
- logger .Infof ("%s read response failed: %v" , host .Addr , err )
136
- conn .Close ()
137
- return nil , 0 , err
146
+ reason = "read response failed"
147
+ return nil , err
138
148
}
139
149
140
150
if err = req .Check (resp ); err != nil {
141
- logger .Infof ("%s unexpected response %s %v %v" ,
142
- host .Addr , req , resp , err )
143
- conn .Close ()
144
- return nil , 0 , err
151
+ reason = fmt .Sprintf ("unexpected response %v %v" ,
152
+ req , resp )
153
+ return nil , err
145
154
}
146
-
147
- host .releaseConn (conn )
148
- delta = time .Since (now )
149
155
return
150
156
}
151
157
152
- func (host * Host ) executeWithTimeout (req * mc.Request , timeout time.Duration ) (resp * mc.Response , err error ) {
153
- var tmpErr error
154
- var tmpResp * mc.Response
155
- done := make (chan bool )
156
- isTimeout := make (chan bool , 1 )
157
-
158
- go func () {
159
- var delta time.Duration
160
- tmpResp , delta , tmpErr = host .execute (req )
161
- select {
162
- case done <- true :
163
- case <- isTimeout :
164
- logger .Infof ("request %v to host %s return after timeout, use %d ms" ,
165
- req , host .Addr , delta / 1e6 )
166
- if tmpResp != nil {
167
- tmpResp .CleanBuffer ()
168
- }
169
- }
170
- }()
171
-
172
- timer := time .NewTimer (timeout )
173
- defer timer .Stop ()
174
-
175
- select {
176
- case <- done :
177
- resp = tmpResp
178
- err = tmpErr
179
- case <- timer .C :
180
- isTimeout <- true
181
- err = fmt .Errorf ("request %v timeout" , req )
182
- logger .Infof ("request %v to host %s timeout" , req , host .Addr )
183
- }
184
- return resp , err
185
- }
186
-
187
158
func (host * Host ) Len () int {
188
159
return 0
189
160
}
@@ -210,7 +181,7 @@ func (host *Host) Get(key string) (*mc.Item, error) {
210
181
211
182
func (host * Host ) GetMulti (keys []string ) (map [string ]* mc.Item , error ) {
212
183
req := & mc.Request {Cmd : "get" , Keys : keys }
213
- resp , _ , err := host .execute (req )
184
+ resp , err := host .executeWithTimeout (req , time . Duration ( proxyConf . ReadTimeoutMs ) * time . Millisecond )
214
185
if err != nil {
215
186
return nil , err
216
187
}
@@ -221,7 +192,7 @@ func (host *Host) Append(key string, value []byte) (bool, error) {
221
192
flag := 0
222
193
item := newItem (flag , value )
223
194
req := & mc.Request {Cmd : "append" , Keys : []string {key }, Item : item }
224
- resp , _ , err := host .execute (req )
195
+ resp , err := host .executeWithTimeout (req , time . Duration ( proxyConf . ReadTimeoutMs ) * time . Millisecond )
225
196
item .Free ()
226
197
if err == nil {
227
198
return resp .Status == "STORED" , nil
@@ -234,7 +205,7 @@ func (host *Host) Incr(key string, value int) (int, error) {
234
205
flag := 0
235
206
item := newItem (flag , []byte (strconv .Itoa (value )))
236
207
req := & mc.Request {Cmd : "incr" , Keys : []string {key }, Item : item }
237
- resp , _ , err := host .execute (req )
208
+ resp , err := host .executeWithTimeout (req , time . Duration ( proxyConf . ReadTimeoutMs ) * time . Millisecond )
238
209
item .Free ()
239
210
if err != nil {
240
211
return 0 , err
@@ -244,7 +215,7 @@ func (host *Host) Incr(key string, value int) (int, error) {
244
215
245
216
func (host * Host ) Delete (key string ) (bool , error ) {
246
217
req := & mc.Request {Cmd : "delete" , Keys : []string {key }}
247
- resp , _ , err := host .execute (req )
218
+ resp , err := host .executeWithTimeout (req , time . Duration ( proxyConf . ReadTimeoutMs ) * time . Millisecond )
248
219
if err == nil {
249
220
return resp .Status == "DELETED" , nil
250
221
} else {
0 commit comments