func (parse *TextProtocolParse) release(conn *common.Conn, doClose bool) { if doClose { go conn.Close() } else { go parse.pool.Release(conn) } }
func (pool *ConnectionPool) release(i int, conn *common.Conn) { select { case pool.pools[i] <- conn: default: conn.Close() } }
// fillPacket fill the send packet and write the packet to buffer. func (parse *BinaryPorotolParse) fillPacket(p *packet, conn *common.Conn) (err error) { var header []byte = make([]byte, headerLen) var i int // fill request header header[i] = p.magic i += magicLen header[i] = p.opcode i += opcodeLen binary.BigEndian.PutUint16(header[i:i+keyLen], p.keyLength) i += keyLen header[i] = p.extrasLength i += extrasLen header[i] = p.dataType i += dataTypeLen binary.BigEndian.PutUint16(header[i:i+statusLen], p.statusOrVbucket) i += statusLen binary.BigEndian.PutUint32(header[i:i+totalBodyLen], p.totalBodyLength) i += totalBodyLen binary.BigEndian.PutUint32(header[i:i+opaqueLen], p.opaque) i += opaqueLen binary.BigEndian.PutUint64(header[i:i+casLen], p.cas) // write content to buffer _, err = conn.WriteToBuffer(header) _, err = conn.WriteToBuffer(p.extras) _, err = conn.WriteToBuffer(p.key) _, err = conn.WriteToBuffer(p.value) return }
func (parse *BinaryPorotolParse) requestAndResponse(conn *common.Conn, reqPacket *packet) (resPacket *packet, err error) { if err = parse.fillPacket(reqPacket, conn); err != nil { parse.release(conn, true) return } if err = conn.Flush(); err != nil { parse.release(conn, true) return } if resPacket, err = parse.parsePacket(conn); err != nil { parse.release(conn, true) return } else { err = parse.checkError(resPacket.statusOrVbucket) parse.release(conn, false) } return }
// parsePacket parse the response packet from serer. func (parse *BinaryPorotolParse) parsePacket(conn *common.Conn) (p *packet, err error) { var header []byte = make([]byte, headerLen) var i, n int // read response header if n, err = conn.Read(header); err != nil { return } else if n != headerLen { err = errors.New("Memcached : Unknow error") return } // parse response header p = &packet{} p.magic = header[i] i += magicLen p.opcode = header[i] i += opcodeLen p.keyLength = binary.BigEndian.Uint16(header[i : i+keyLen]) i += keyLen p.extrasLength = header[i] i += extrasLen p.dataType = header[i] i += dataTypeLen p.statusOrVbucket = binary.BigEndian.Uint16(header[i : i+statusLen]) i += statusLen p.totalBodyLength = binary.BigEndian.Uint32(header[i : i+totalBodyLen]) i += totalBodyLen p.opaque = binary.BigEndian.Uint32(header[i : i+opaqueLen]) i += opaqueLen p.cas = binary.BigEndian.Uint64(header[i : i+casLen]) // read extras from response if exist if p.extrasLength > 0 { p.extras = make([]byte, p.extrasLength) if n, err = conn.Read(p.extras); err != nil { return } else if n != int(p.extrasLength) { err = errors.New("Memcached : Unknow error") return } } // read key from response if exist if p.keyLength > 0 { p.key = make([]byte, p.keyLength) if n, err = conn.Read(p.key); err != nil { return } else if n != int(p.keyLength) { err = errors.New("Memcached : Unknow error") return } } // read value from response if exist valueLength := int(p.totalBodyLength) - int(p.keyLength) - int(p.extrasLength) if valueLength > 0 { p.value = make([]byte, valueLength) if n, err = conn.Read(p.value); err != nil { return } else if n != valueLength { err = errors.New("Memcached : Unknow error") return } } return }