mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
rpc: add buffering to the encode path.
This reduces the number of writes by 2 (1 client, 1 server) on each round trip. A simple test shows 24% higher throughput. R=rsc CC=golang-dev https://golang.org/cl/4279057
This commit is contained in:
parent
31a72d1a53
commit
a569725141
2 changed files with 31 additions and 16 deletions
|
|
@ -148,8 +148,12 @@ func (call *Call) done() {
|
||||||
|
|
||||||
// NewClient returns a new Client to handle requests to the
|
// NewClient returns a new Client to handle requests to the
|
||||||
// set of services at the other end of the connection.
|
// set of services at the other end of the connection.
|
||||||
|
// It adds a buffer to the write side of the connection so
|
||||||
|
// the header and payload are sent as a unit.
|
||||||
func NewClient(conn io.ReadWriteCloser) *Client {
|
func NewClient(conn io.ReadWriteCloser) *Client {
|
||||||
return NewClientWithCodec(&gobClientCodec{conn, gob.NewDecoder(conn), gob.NewEncoder(conn)})
|
encBuf := bufio.NewWriter(conn)
|
||||||
|
client := &gobClientCodec{conn, gob.NewDecoder(conn), gob.NewEncoder(encBuf), encBuf}
|
||||||
|
return NewClientWithCodec(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClientWithCodec is like NewClient but uses the specified
|
// NewClientWithCodec is like NewClient but uses the specified
|
||||||
|
|
@ -167,13 +171,17 @@ type gobClientCodec struct {
|
||||||
rwc io.ReadWriteCloser
|
rwc io.ReadWriteCloser
|
||||||
dec *gob.Decoder
|
dec *gob.Decoder
|
||||||
enc *gob.Encoder
|
enc *gob.Encoder
|
||||||
|
encBuf *bufio.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gobClientCodec) WriteRequest(r *Request, body interface{}) os.Error {
|
func (c *gobClientCodec) WriteRequest(r *Request, body interface{}) (err os.Error) {
|
||||||
if err := c.enc.Encode(r); err != nil {
|
if err = c.enc.Encode(r); err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
return c.enc.Encode(body)
|
if err = c.enc.Encode(body); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return c.encBuf.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gobClientCodec) ReadResponseHeader(r *Response) os.Error {
|
func (c *gobClientCodec) ReadResponseHeader(r *Response) os.Error {
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@
|
||||||
package rpc
|
package rpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"gob"
|
"gob"
|
||||||
"http"
|
"http"
|
||||||
"log"
|
"log"
|
||||||
|
|
@ -339,6 +340,7 @@ type gobServerCodec struct {
|
||||||
rwc io.ReadWriteCloser
|
rwc io.ReadWriteCloser
|
||||||
dec *gob.Decoder
|
dec *gob.Decoder
|
||||||
enc *gob.Encoder
|
enc *gob.Encoder
|
||||||
|
encBuf *bufio.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gobServerCodec) ReadRequestHeader(r *Request) os.Error {
|
func (c *gobServerCodec) ReadRequestHeader(r *Request) os.Error {
|
||||||
|
|
@ -349,11 +351,14 @@ func (c *gobServerCodec) ReadRequestBody(body interface{}) os.Error {
|
||||||
return c.dec.Decode(body)
|
return c.dec.Decode(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gobServerCodec) WriteResponse(r *Response, body interface{}) os.Error {
|
func (c *gobServerCodec) WriteResponse(r *Response, body interface{}) (err os.Error) {
|
||||||
if err := c.enc.Encode(r); err != nil {
|
if err = c.enc.Encode(r); err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
return c.enc.Encode(body)
|
if err = c.enc.Encode(body); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return c.encBuf.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gobServerCodec) Close() os.Error {
|
func (c *gobServerCodec) Close() os.Error {
|
||||||
|
|
@ -367,7 +372,9 @@ func (c *gobServerCodec) Close() os.Error {
|
||||||
// ServeConn uses the gob wire format (see package gob) on the
|
// ServeConn uses the gob wire format (see package gob) on the
|
||||||
// connection. To use an alternate codec, use ServeCodec.
|
// connection. To use an alternate codec, use ServeCodec.
|
||||||
func (server *Server) ServeConn(conn io.ReadWriteCloser) {
|
func (server *Server) ServeConn(conn io.ReadWriteCloser) {
|
||||||
server.ServeCodec(&gobServerCodec{conn, gob.NewDecoder(conn), gob.NewEncoder(conn)})
|
buf := bufio.NewWriter(conn)
|
||||||
|
srv := &gobServerCodec{conn, gob.NewDecoder(conn), gob.NewEncoder(buf), buf}
|
||||||
|
server.ServeCodec(srv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeCodec is like ServeConn but uses the specified codec to
|
// ServeCodec is like ServeConn but uses the specified codec to
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue