Sends a memcache request through the connection. NOTE: extras must be fix-sized values.
(
code opCode,
dataVersionId uint64, // aka CAS
key []byte, // may be nil
value []byte, // may be nil
extras ...interface{})
| 132 | // Sends a memcache request through the connection. NOTE: extras must be |
| 133 | // fix-sized values. |
| 134 | func (c *RawBinaryClient) sendRequest( |
| 135 | code opCode, |
| 136 | dataVersionId uint64, // aka CAS |
| 137 | key []byte, // may be nil |
| 138 | value []byte, // may be nil |
| 139 | extras ...interface{}) (err error) { |
| 140 | |
| 141 | if key != nil && len(key) > 255 { |
| 142 | return errors.New("Key too long") |
| 143 | } |
| 144 | if !c.validState { |
| 145 | // An error has occurred previously. It's not safe to continue sending. |
| 146 | return errors.New("Skipping due to previous error") |
| 147 | } |
| 148 | defer func() { |
| 149 | if err != nil { |
| 150 | c.validState = false |
| 151 | } |
| 152 | }() |
| 153 | |
| 154 | extrasBuffer := new(bytes.Buffer) |
| 155 | for _, extra := range extras { |
| 156 | err := binary.Write(extrasBuffer, binary.BigEndian, extra) |
| 157 | if err != nil { |
| 158 | return errors.Wrap(err, "Failed to write extra") |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | // NOTE: |
| 163 | // - memcache only supports a single dataType (0x0) |
| 164 | // - vbucket id is not used by the library since vbucket related op |
| 165 | // codes are unsupported |
| 166 | hdr := header{ |
| 167 | Magic: reqMagicByte, |
| 168 | OpCode: byte(code), |
| 169 | KeyLength: uint16(len(key)), |
| 170 | ExtrasLength: uint8(extrasBuffer.Len()), |
| 171 | TotalBodyLength: uint32(len(key) + len(value) + extrasBuffer.Len()), |
| 172 | DataVersionId: dataVersionId, |
| 173 | } |
| 174 | |
| 175 | var msgBuffer = make([]byte, headerLength+hdr.TotalBodyLength) |
| 176 | hdr.Serialize(msgBuffer) |
| 177 | var offset uint32 = headerLength |
| 178 | offset += uint32(copy(msgBuffer[offset:], extrasBuffer.Bytes())) |
| 179 | if key != nil { |
| 180 | offset += uint32(copy(msgBuffer[offset:], key)) |
| 181 | } |
| 182 | |
| 183 | if value != nil { |
| 184 | offset += uint32(copy(msgBuffer[offset:], value)) |
| 185 | } |
| 186 | if offset != headerLength+hdr.TotalBodyLength { |
| 187 | return errors.New("Failed to serialize message") |
| 188 | } |
| 189 | |
| 190 | bytesWritten, err := c.channel.Write(msgBuffer) |
| 191 | if err != nil { |