Skip to content

Commit

Permalink
rpc_util: introduce simple pool implementation for new user
Browse files Browse the repository at this point in the history
  • Loading branch information
hueypark committed Mar 15, 2023
1 parent 086dd28 commit d6c1d97
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 32 deletions.
34 changes: 2 additions & 32 deletions benchmark/benchmain/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,8 @@ func makeClient(bf stats.Features) (testgrpc.BenchmarkServiceClient, func()) {
case sharedRecvBufferPoolNil:
// Do nothing.
case sharedRecvBufferPoolSimple:
opts = append(opts, grpc.WithSharedRecvBufferPool(newSimpleSharedRecvBufferPool()))
sopts = append(sopts, grpc.SharedRecvBufferPool(newSimpleSharedRecvBufferPool()))
opts = append(opts, grpc.WithSharedRecvBufferPool(grpc.NewSimpleSharedBufferPool()))
sopts = append(sopts, grpc.SharedRecvBufferPool(grpc.NewSimpleSharedBufferPool()))
default:
logger.Fatalf("Unknown shared recv buffer pool type: %v", bf.SharedRecvBufferPool)
}
Expand Down Expand Up @@ -915,33 +915,3 @@ type nopDecompressor struct{}

func (nopDecompressor) Do(r io.Reader) ([]byte, error) { return io.ReadAll(r) }
func (nopDecompressor) Type() string { return compModeNop }

// simpleSharedRecvBufferPool is a simple implementation of sharedRecvBufferPool.
type simpleSharedRecvBufferPool struct {
sync.Pool
}

func newSimpleSharedRecvBufferPool() *simpleSharedRecvBufferPool {
return &simpleSharedRecvBufferPool{
Pool: sync.Pool{
New: func() interface{} {
bs := make([]byte, 0)
return &bs
},
},
}
}

func (p *simpleSharedRecvBufferPool) Get(size int) []byte {
bs := p.Pool.Get().(*[]byte)
if cap(*bs) < size {
*bs = make([]byte, size)
return *bs
}

return (*bs)[:size]
}

func (p *simpleSharedRecvBufferPool) Put(bs *[]byte) {
p.Pool.Put(bs)
}
3 changes: 3 additions & 0 deletions dialoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,9 @@ func WithResolvers(rs ...resolver.Builder) DialOption {
// to use the provided shared buffer pool for parsing incoming messages. Depending
// on the application's workload, this could result in reduced memory allocation.
//
// If you are unsure about how to implement a memory pool but want to utilize one,
// begin with grpc.NewSimpleSharedBufferPool.
//
// # Experimental
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
Expand Down
3 changes: 3 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,9 @@ func NumStreamWorkers(numServerWorkers uint32) ServerOption {
// to use the provided shared buffer pool for parsing incoming messages. Depending
// on the application's workload, this could result in reduced memory allocation.
//
// If you are unsure about how to implement a memory pool but want to utilize one,
// begin with grpc.NewSimpleSharedBufferPool.
//
// # Experimental
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
Expand Down
33 changes: 33 additions & 0 deletions shared_buffer_pool.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,40 @@
package grpc

import "sync"

// SharedBufferPool is a pool of buffers that can be shared.
type SharedBufferPool interface {
Get(length int) []byte
Put(*[]byte)
}

// NewSimpleSharedBufferPool creates a new SimpleSharedBufferPool.
func NewSimpleSharedBufferPool() SharedBufferPool {
return &simpleSharedBufferPool{
Pool: sync.Pool{
New: func() interface{} {
bs := make([]byte, 0)
return &bs
},
},
}
}

// simpleSharedBufferPool is a simple implementation of SharedBufferPool.
type simpleSharedBufferPool struct {
sync.Pool
}

func (p *simpleSharedBufferPool) Get(size int) []byte {
bs := p.Pool.Get().(*[]byte)
if cap(*bs) < size {
*bs = make([]byte, size)
return *bs
}

return (*bs)[:size]
}

func (p *simpleSharedBufferPool) Put(bs *[]byte) {
p.Pool.Put(bs)
}

0 comments on commit d6c1d97

Please sign in to comment.