func readResponseHeader(r *bufio.Reader) (binprot.ResponseHeader, error) { resHeader, err := binprot.ReadResponseHeader(r) if err != nil { return binprot.ResponseHeader{}, err } if err := binprot.DecodeError(resHeader); err != nil { binprot.PutResponseHeader(resHeader) return resHeader, err } binprot.PutResponseHeader(resHeader) return resHeader, nil }
func simpleCmdLocal(rw *bufio.ReadWriter) error { if err := rw.Flush(); err != nil { return err } resHeader, err := binprot.ReadResponseHeader(rw) if err != nil { return err } defer binprot.PutResponseHeader(resHeader) err = binprot.DecodeError(resHeader) if err != nil { n, ioerr := rw.Discard(int(resHeader.TotalBodyLength)) metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) if ioerr != nil { return ioerr } return err } // Read in the message bytes from the body n, err := rw.Discard(int(resHeader.TotalBodyLength)) metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) return err }
func simpleCmdLocal(rw *bufio.ReadWriter, flush bool) error { if flush { if err := rw.Flush(); err != nil { return err } } resHeader, err := binprot.ReadResponseHeader(rw) if err != nil { return err } n, ioerr := rw.Discard(int(resHeader.TotalBodyLength)) metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) if ioerr != nil { binprot.PutResponseHeader(resHeader) return ioerr } binprot.PutResponseHeader(resHeader) return binprot.DecodeError(resHeader) }
func getLocal(rw *bufio.ReadWriter, readExp bool) (data []byte, flags, exp uint32, err error) { if err := rw.Flush(); err != nil { return nil, 0, 0, err } resHeader, err := binprot.ReadResponseHeader(rw) if err != nil { return nil, 0, 0, err } defer binprot.PutResponseHeader(resHeader) err = binprot.DecodeError(resHeader) if err != nil { n, ioerr := rw.Discard(int(resHeader.TotalBodyLength)) metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) if ioerr != nil { return nil, 0, 0, ioerr } return nil, 0, 0, err } var serverFlags uint32 binary.Read(rw, binary.BigEndian, &serverFlags) metrics.IncCounterBy(common.MetricBytesReadLocal, 4) var serverExp uint32 if readExp { binary.Read(rw, binary.BigEndian, &serverExp) metrics.IncCounterBy(common.MetricBytesReadLocal, 4) } // total body - key - extra dataLen := resHeader.TotalBodyLength - uint32(resHeader.KeyLength) - uint32(resHeader.ExtraLength) buf := make([]byte, dataLen) // Read in value n, err := io.ReadAtLeast(rw, buf, int(dataLen)) metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) if err != nil { return nil, 0, 0, err } return buf, serverFlags, serverExp, nil }
func getMetadataCommon(rw *bufio.ReadWriter) (metadata, error) { if err := rw.Flush(); err != nil { return emptyMeta, err } resHeader, err := binprot.ReadResponseHeader(rw) if err != nil { return emptyMeta, err } defer binprot.PutResponseHeader(resHeader) err = binprot.DecodeError(resHeader) if err != nil { // read in the message "Not found" after a miss n, ioerr := rw.Discard(int(resHeader.TotalBodyLength)) metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) if ioerr != nil { return emptyMeta, ioerr } return emptyMeta, err } // we currently do nothing with the flags //buf := make([]byte, 4) //n, err := io.ReadAtLeast(rw, buf, 4) //metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) //if err != nil { // return emptyMeta, err //} //serverFlags := binary.BigEndian.Uint32(buf) // instead of reading and parsing flags, just discard rw.Discard(4) metrics.IncCounterBy(common.MetricBytesReadLocal, 4) metaData, err := readMetadata(rw) if err != nil { return emptyMeta, err } return metaData, nil }
func getLocalIntoBuf(rw *bufio.Reader, metaData metadata, tokenBuf, dataBuf []byte, chunkNum, totalDataLength int) (opcodeNoop bool, err error) { resHeader, err := binprot.ReadResponseHeader(rw) if err != nil { return false, err } defer binprot.PutResponseHeader(resHeader) // it feels a bit dirty knowing about batch gets here, but it's the most logical place to put // a check for an opcode that signals the end of a batch get or GAT. This code is a bit too big // to copy-paste in multiple places. if resHeader.Opcode == binprot.OpcodeNoop { return true, nil } err = binprot.DecodeError(resHeader) if err != nil { // read in the message "Not found" after a miss n, ioerr := rw.Discard(int(resHeader.TotalBodyLength)) metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) if ioerr != nil { return false, ioerr } return false, err } // we currently do nothing with the flags //buf := make([]byte, 4) //n, err := io.ReadAtLeast(rw, buf, 4) //metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) //if err != nil { // return emptyMeta, err //} //serverFlags := binary.BigEndian.Uint32(buf) // instead of reading and parsing flags, just discard rw.Discard(4) metrics.IncCounterBy(common.MetricBytesReadLocal, 4) // Read in token if requested if tokenBuf != nil { n, err := io.ReadAtLeast(rw, tokenBuf, tokenSize) metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) if err != nil { return false, err } } // indices for slicing, end exclusive start, end := chunkSliceIndices(int(metaData.ChunkSize), chunkNum, int(metaData.Length)) // read data directly into buf chunkBuf := dataBuf[start:end] // Read in value n, err := io.ReadAtLeast(rw, chunkBuf, len(chunkBuf)) metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) if err != nil { return false, err } // consume padding at end of chunk if needed if len(chunkBuf) < totalDataLength { n, ioerr := rw.Discard(totalDataLength - len(chunkBuf)) metrics.IncCounterBy(common.MetricBytesReadLocal, uint64(n)) if ioerr != nil { return false, ioerr } } return false, nil }