func (p *TFramedTransport) Flush() error { size := p.writeBuffer.Len() buf := []byte{0, 0, 0, 0} binary.BigEndian.PutUint32(buf, uint32(size)) _, err := p.transport.Write(buf) if err != nil { return thrift.NewTTransportExceptionFromOsError(err) } if size > 0 { n, err := p.writeBuffer.WriteTo(p.transport) if err != nil { println("Error while flushing write buffer of size ", size, " to transport, only wrote ", n, " bytes: ", err.Error()) return thrift.NewTTransportExceptionFromOsError(err) } } err = p.transport.Flush() return thrift.NewTTransportExceptionFromOsError(err) }
func (p *TFramedTransport) Read(buf []byte) (int, error) { if p.readBuffer.Len() > 0 { got, err := p.readBuffer.Read(buf) if got > 0 { return got, thrift.NewTTransportExceptionFromOsError(err) } } // Read another frame of data f, e := p.readFrame() if e != nil { return f, e } if f == 0 { // no more to read right now return 0, nil } got, err := p.readBuffer.Read(buf) return got, thrift.NewTTransportExceptionFromOsError(err) }
func (ce *CassandraCommand) doExecute(outConn Connection, timeout time.Duration) (outPackets <-chan *CommandPacket) { inCh := make(chan *CommandPacket) go func() { defer close(inCh) log.Print("CassandraCommand:Execute executing ", ce.name) // get transport and protocol for the inbound connection inTrans := NewCommandPacketTTransport(inCh) inProt := ce.protocolFactory.GetProtocol(inTrans) // get transport and protocol for the upstream connection outTrans := outConn.Transport() outProt := outConn.ProtocolFactory().GetProtocol(outTrans) // write our inbound command header to the upstream connection headProtExc := outProt.WriteMessageBegin(ce.name, ce.typeId, ce.seqId) // respond to errors from writing the command header if headProtExc != nil { // headProtExc is a thrift.TTException log.Print("CassandraCommand:Execute error sending header to upsteram server: ", headProtExc) ce.writeError(inProt, headProtExc) return } if ce.argsProc != nil && ce.argsProc.GotArgs() { // if we already read the args and processed it, write the processed args to the upstream server writeExc := ce.writeArgsMessage(outProt) outProt.WriteMessageEnd() if writeExc != nil { log.Print("CassandraCommand:Execute error writing processed args: ", writeExc) ce.writeError(inProt, writeExc) return } } else { // otherwise just write all inbound packets to the upstream server for pkt := range ce.inPackets { if pkt.Error() != nil { // if we got an error, then bail log.Print("CassandraCommand:Execute error reading data from client: ", pkt.Error()) ce.writeError(inProt, thrift.NewTProtocolExceptionFromOsError(pkt.Error())) return } // pass on our inbound input to the upstream server wnWritten, wErr := outTrans.Write(pkt.Bytes()) if wErr != nil { log.Print("CassandraCommand:Execute error writing ", wnWritten, " bytes to upstream server: ", wErr) ce.writeError(inProt, thrift.NewTTransportExceptionFromOsError(wErr)) return } } } outTrans.Flush() // get rid of the command // start reading a connection, block until it's ready oName, oTypId, oSeqId, oErr := outProt.ReadMessageBegin() // respond to errors from reading the command header if oErr != nil { log.Print("CassandraCommand:Execute error reading response header from upstream server: ", oErr) ce.writeError(inProt, oErr) return } // write our header received from the upstream to the inbound connection iErr := inProt.WriteMessageBegin(oName, oTypId, oSeqId) if iErr != nil { // received an error writing response header, try and send an error log.Print("CassandraCommand:Execute error writing response header to client: ", iErr) ce.writeError(inProt, iErr) return } // read all data from the upstream server, streaming them to the inbound connection // note: at this point we kind of have our asses hanging out: we can not successfully send error header should we encounter // an error reading, as we've already written the header. we'll still send an error just in case for pkt := range TTransportReadGen(outTrans, "upstreamResp") { if pkt.Error() != nil { log.Print("CassandraCommand:Execute error writing response data to client: ", pkt.Error()) ce.writeError(inProt, thrift.NewTProtocolExceptionFromOsError(pkt.Error())) return } _, writeErr := inProt.Transport().Write(pkt.Bytes()) // this will ultimately translate into inCh <-pkt if writeErr != nil { log.Print("CassandraCommand:Execute error writing back to client protocol: ", writeErr) } } }() return inCh }
func (p *TFramedTransport) Write(buf []byte) (int, error) { n, err := p.writeBuffer.Write(buf) return n, thrift.NewTTransportExceptionFromOsError(err) }