Receive a memcache response from the connection. The status, dataVersionId (aka CAS), key and value are returned, while the extra values are stored in the arguments. NOTE: extras must be pointers to fix-sized values.
(
expectedCode opCode,
extras ...interface{})
| 203 | // values are stored in the arguments. NOTE: extras must be pointers to |
| 204 | // fix-sized values. |
| 205 | func (c *RawBinaryClient) receiveResponse( |
| 206 | expectedCode opCode, |
| 207 | extras ...interface{}) ( |
| 208 | status ResponseStatus, |
| 209 | dataVersionId uint64, |
| 210 | key []byte, // is nil when key length is zero |
| 211 | value []byte, // is nil when the value length is zero |
| 212 | err error) { |
| 213 | |
| 214 | if !c.validState { |
| 215 | // An error has occurred previously. It's not safe to continue sending. |
| 216 | err = errors.New("Skipping due to previous error") |
| 217 | return |
| 218 | } |
| 219 | defer func() { |
| 220 | if err != nil { |
| 221 | c.validState = false |
| 222 | } |
| 223 | }() |
| 224 | |
| 225 | // Process the header fields |
| 226 | hdr := header{} |
| 227 | var hdrBytes = make([]byte, headerLength) |
| 228 | hdrBytesRead, err := io.ReadFull(c.channel, hdrBytes) |
| 229 | if err != nil { |
| 230 | err = errors.Wrap(err, "Failed to read header") |
| 231 | return |
| 232 | } |
| 233 | if hdrBytesRead != headerLength { |
| 234 | err = errors.Newf("Failed to read header: got %d bytes, expected %d", |
| 235 | hdrBytesRead, headerLength) |
| 236 | return |
| 237 | } |
| 238 | hdr.Deserialize(hdrBytes) |
| 239 | if hdr.Magic != respMagicByte { |
| 240 | err = errors.Newf("Invalid response magic byte: %d", hdr.Magic) |
| 241 | return |
| 242 | } |
| 243 | if hdr.OpCode != byte(expectedCode) { |
| 244 | err = errors.Newf("Invalid response op code: %d", hdr.OpCode) |
| 245 | return |
| 246 | } |
| 247 | if hdr.DataType != 0 { |
| 248 | err = errors.Newf("Invalid data type: %d", hdr.DataType) |
| 249 | return |
| 250 | } |
| 251 | |
| 252 | valueLength := int(hdr.TotalBodyLength) |
| 253 | valueLength -= (int(hdr.KeyLength) + int(hdr.ExtrasLength)) |
| 254 | if valueLength < 0 { |
| 255 | err = errors.Newf("Invalid response header. Wrong payload size.") |
| 256 | return |
| 257 | } |
| 258 | |
| 259 | status = ResponseStatus(hdr.VBucketIdOrStatus) |
| 260 | dataVersionId = hdr.DataVersionId |
| 261 | |
| 262 | if hdr.ExtrasLength == 0 { |