//
// 先写入数据,然后再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

}
Beispiel #4
0
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())
		}
	}
}
Beispiel #5
0
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)
}
Beispiel #7
0
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)
}
Beispiel #8
0
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)
}
Beispiel #9
0
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
}
Beispiel #13
0
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)
}