Skip to content

Commit 493be5d

Browse files
committed
rpc_util: add bytes pool for the parser
1 parent a6376c9 commit 493be5d

File tree

1 file changed

+37
-12
lines changed

1 file changed

+37
-12
lines changed

rpc_util.go

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -574,9 +574,7 @@ func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byt
574574
if int(length) > maxReceiveMessageSize {
575575
return 0, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", length, maxReceiveMessageSize)
576576
}
577-
// TODO(bradfitz,zhaoq): garbage. reuse buffer after proto decoding instead
578-
// of making it for each message:
579-
msg = make([]byte, int(length))
577+
msg = pool.Get(int(length))
580578
if _, err := p.r.Read(msg); err != nil {
581579
if err == io.EOF {
582580
err = io.ErrUnexpectedEOF
@@ -689,12 +687,12 @@ type payloadInfo struct {
689687
}
690688

691689
func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) ([]byte, error) {
692-
pf, d, err := p.recvMsg(maxReceiveMessageSize)
690+
pf, buf, err := p.recvMsg(maxReceiveMessageSize)
693691
if err != nil {
694692
return nil, err
695693
}
696694
if payInfo != nil {
697-
payInfo.wireLength = len(d)
695+
payInfo.wireLength = len(buf)
698696
}
699697

700698
if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil); st != nil {
@@ -706,10 +704,10 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei
706704
// To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor,
707705
// use this decompressor as the default.
708706
if dc != nil {
709-
d, err = dc.Do(bytes.NewReader(d))
710-
size = len(d)
707+
buf, err = dc.Do(bytes.NewReader(buf))
708+
size = len(buf)
711709
} else {
712-
d, size, err = decompress(compressor, d, maxReceiveMessageSize)
710+
buf, size, err = decompress(compressor, buf, maxReceiveMessageSize)
713711
}
714712
if err != nil {
715713
return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err)
@@ -720,7 +718,7 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei
720718
return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize)
721719
}
722720
}
723-
return d, nil
721+
return buf, nil
724722
}
725723

726724
// Using compressor, decompress d, returning data and size.
@@ -755,16 +753,18 @@ func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize
755753
// dc takes precedence over compressor.
756754
// TODO(dfawley): wrap the old compressor/decompressor using the new API?
757755
func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m interface{}, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) error {
758-
d, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor)
756+
buf, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor)
759757
if err != nil {
760758
return err
761759
}
762-
if err := c.Unmarshal(d, m); err != nil {
760+
if err := c.Unmarshal(buf, m); err != nil {
763761
return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message: %v", err)
764762
}
765763
if payInfo != nil {
766-
payInfo.uncompressedBytes = d
764+
payInfo.uncompressedBytes = make([]byte, len(buf))
765+
copy(payInfo.uncompressedBytes, buf)
767766
}
767+
pool.Put(&buf)
768768
return nil
769769
}
770770

@@ -914,3 +914,28 @@ const (
914914
)
915915

916916
const grpcUA = "grpc-go/" + Version
917+
918+
type bytesPool struct {
919+
sync.Pool
920+
}
921+
922+
func (p *bytesPool) Get(size int) []byte {
923+
bs := p.Pool.Get().(*[]byte)
924+
if cap(*bs) < size {
925+
*bs = make([]byte, size)
926+
}
927+
928+
return (*bs)[:size]
929+
}
930+
931+
func (p *bytesPool) Put(bs *[]byte) {
932+
p.Pool.Put(bs)
933+
}
934+
935+
var pool = bytesPool{
936+
sync.Pool{
937+
New: func() interface{} {
938+
return new([]byte)
939+
},
940+
},
941+
}

0 commit comments

Comments
 (0)