// // 先写入数据,然后再Flush Transport // func (p *TBufferedFramedTransport) FlushBuffer(force bool) error { size := p.Buffer.Len() // 1. 将p.buf的大小以BigEndian模式写入: buf中 buf := p.LenghW[:4] binary.BigEndian.PutUint32(buf, uint32(size)) // log.Printf("----> Frame Size: %d, %v\n", size, buf) // 然后transport中先写入: 长度信息 _, err := p.Writer.Write(buf) if err != nil { return thrift.NewTTransportExceptionFromError(err) } // 2. 然后继续写入p.buf中的数据 if size > 0 { var n int64 if n, err = p.Buffer.WriteTo(p.Writer); err != nil { log.ErrorErrorf(err, "Error Flushing Expect Write: %d, but %d\n", size, n) return thrift.NewTTransportExceptionFromError(err) } } p.nbuffered++ // Buffer重新开始处理数据 p.Buffer.Reset() // Flush Buffer return p.FlushTransport(force) }
func (p *TBufferedFramedTransport) Read(buf []byte) (l int, err error) { // 1. 首先读取Frame Header if p.FrameSize == 0 { p.FrameSize, err = p.readFrameHeader() if err != nil { return } } // 2. 异常处理 if p.FrameSize < len(buf) { frameSize := p.FrameSize tmp := make([]byte, p.FrameSize) l, err = p.Read(tmp) copy(buf, tmp) if err == nil { err = thrift.NewTTransportExceptionFromError( fmt.Errorf("Not enough frame size %d to read %d bytes", frameSize, len(buf))) return } } // 3. 读取剩下的数据 got, err := p.Reader.Read(buf) p.FrameSize = p.FrameSize - got //sanity check if p.FrameSize < 0 { return 0, thrift.NewTTransportException(thrift.UNKNOWN_TRANSPORT_EXCEPTION, "Negative frame size") } return got, thrift.NewTTransportExceptionFromError(err) }
// 读取Frame的完整的数据,包含 func (p *TBufferedFramedTransport) ReadFrame() (frame []byte, err error) { if p.FrameSize != 0 { err = thrift.NewTTransportExceptionFromError( fmt.Errorf("Unexpected frame size: %d", p.FrameSize)) return nil, err } var frameSize int // Reader来自transport, 中间被封装了多长 frameSize, err = p.readFrameHeader() if err != nil { err1, ok := err.(thrift.TTransportException) if ok { err = thrift.NewTTransportException(err1.TypeId(), fmt.Sprintf("Frame Header Read Error: %s", err1.Error())) } else { err = thrift.NewTTransportExceptionFromError( fmt.Errorf("Frame Header Read Error: %s", err.Error())) } return } bytes := getSlice(frameSize, frameSize) // 什么时候会出现? // 1. 如果tcp package比较大,则容易出现package的一部分先到,另一部分随后再到 // 2. 在同一个机器上的两个进程之间出现的概率低(Time Delay小); 跨机器访问,出现概率高 var l int l, err = io.ReadFull(p.Reader, bytes) // l, err = p.Reader.Read(bytes) if l != frameSize { log.Warnf(Red("<==== ReadFrame frame size: %d, Got: %d"), frameSize, l) } if err != nil { err1, ok := err.(thrift.TTransportException) if ok { err = thrift.NewTTransportException(err1.TypeId(), fmt.Sprintf("Frame Data Read Error: %s", err1.Error())) } else { err = thrift.NewTTransportExceptionFromError( fmt.Errorf("Frame Data Read Error: %s", err.Error())) } return nil, err } return bytes, nil }
func Benchmark_CallEchoService(b *testing.B) { socket, err := thrift.NewTSocketTimeout(net.JoinHostPort("127.0.0.1", "8080"), TIMEOUT) if err != nil { t.Fatal("Unable to new client socket", err) } transport := thrift.NewTFramedTransport(socket) var protocol thrift.TProtocol = thrift.NewTBinaryProtocolTransport(transport) protocol = thrift.NewTMultiplexedProtocol(protocol, "EchoService") client := rpc.NewEchoServiceClientProtocol(transport, protocol, protocol) err = transport.Open() if err != nil { t.Fatal("Unable to open client socket", err) } defer transport.Close() for i := 0; i < b.N; i++ { //use b.N for looping _, err2 := client.Echo(currentTimeMillis(), "hello world") if err2 != nil { exception := thrift.NewTTransportExceptionFromError(err2) t.Fatal("test TestCallEchoService failed", exception.TypeId(), exception.Err()) } } }
func (t *natsTransport) Open() error { t.closed = make(chan struct{}) t.writeBuffer = bytes.NewBuffer(make([]byte, 0, maxMessageSize)) reader, writer := io.Pipe() timeoutReader := newTimeoutReader(reader) timeoutReader.SetTimeout(t.readTimeout) t.reader = timeoutReader t.writer = writer sub, err := t.conn.Subscribe(t.listenTo, func(msg *nats.Msg) { if msg.Reply == disconnect { // Remote client is disconnecting. t.writer.Close() return } t.writer.Write(msg.Data) }) if err != nil { return thrift.NewTTransportExceptionFromError(err) } t.conn.Flush() // Ensure subscription is processed before moving on. t.sub = sub if t.heartbeatInterval > 0 { go t.startHeartbeat() } return nil }
func (p *TUnixDomain) Read(buf []byte) (int, error) { if !p.IsOpen() { return 0, thrift.NewTTransportException(thrift.NOT_OPEN, "Connection not open") } p.pushDeadline(true, false) n, err := p.conn.Read(buf) return n, thrift.NewTTransportExceptionFromError(err) }
func (t *natsTransport) Flush() error { data := t.writeBuffer.Bytes() if len(data) == 0 { return nil } err := t.conn.Publish(t.replyTo, data) t.writeBuffer.Reset() return thrift.NewTTransportExceptionFromError(err) }
func (t *natsTransport) Write(p []byte) (int, error) { remaining := maxMessageSize - t.writeBuffer.Len() if remaining < len(p) { t.writeBuffer.Write(p[0:remaining]) if err := t.Flush(); err != nil { return 0, thrift.NewTTransportExceptionFromError(err) } return t.Write(p[remaining:]) } return t.writeBuffer.Write(p) }
func (this *TUnixSocket) Accept() (thrift.TTransport, error) { if this.interrupted { return nil, errors.New("Transport Interrupted") } if this.listener == nil { return nil, thrift.NewTTransportException(thrift.NOT_OPEN, "No underlying server socket") } conn, err := this.listener.Accept() if err != nil { return nil, thrift.NewTTransportExceptionFromError(err) } return thrift.NewTSocketFromConnTimeout(conn, this.clientTimeout), nil }
func (p *TServerUnixDomain) Accept() (thrift.TTransport, error) { p.mu.RLock() interrupted := p.interrupted p.mu.RUnlock() if interrupted { return nil, errors.New("Transport Interrupted") } if p.listener == nil { return nil, thrift.NewTTransportException(thrift.NOT_OPEN, "No underlying server socket") } conn, err := p.listener.Accept() if err != nil { return nil, thrift.NewTTransportExceptionFromError(err) } return thrift.NewTSocketFromConnTimeout(conn, p.clientTimeout), nil }
func (p *TBufferedFramedTransport) ReadByte() (c byte, err error) { if p.FrameSize == 0 { p.FrameSize, err = p.readFrameHeader() if err != nil { return } } if p.FrameSize < 1 { return 0, thrift.NewTTransportExceptionFromError( fmt.Errorf("Not enough frame size %d to read %d bytes", p.FrameSize, 1)) } c, err = p.Reader.ReadByte() if err == nil { p.FrameSize-- } return }
func (t *natsTransport) Open() error { sub, err := t.conn.Subscribe(t.listenTo, func(msg *nats.Msg) { if msg.Reply == disconnect { // Remote client is disconnecting. t.writer.Close() return } t.writer.Write(msg.Data) }) if err != nil { return thrift.NewTTransportExceptionFromError(err) } t.conn.Flush() // Ensure subscription is processed before moving on. t.sub = sub if t.heartbeatInterval > 0 { go t.startHeartbeat() } return nil }
func (t *natsTransport) Read(p []byte) (int, error) { n, err := t.reader.Read(p) return n, thrift.NewTTransportExceptionFromError(err) }
"time" "git.apache.org/thrift.git/lib/go/thrift" ) type timeout struct{} func (t timeout) Error() string { return "timeout" } func (t timeout) Timeout() bool { return true } var errTimeout = thrift.NewTTransportExceptionFromError(timeout{}) type timeoutReader struct { buff *bufio.Reader timeout time.Duration ch <-chan error } func newTimeoutReader(r io.Reader) *timeoutReader { return &timeoutReader{buff: bufio.NewReader(r), timeout: -1} } func (r *timeoutReader) SetTimeout(t time.Duration) time.Duration { prev := r.timeout r.timeout = t return prev
func (p *TBufferedFramedTransport) Write(buf []byte) (int, error) { // 直接写入Buffer n, err := p.Buffer.Write(buf) return n, thrift.NewTTransportExceptionFromError(err) }