Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement new Codec that uses mem.BufferSlice instead of []byte #7356

Merged
merged 100 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
12bf91d
Implement new Codec that uses [][]byte instead of []byte
PapaCharlie Apr 10, 2024
5575dbc
Disable full materialization if the BufferSlice only has one buffer i…
PapaCharlie Apr 10, 2024
3807e4b
Fix tests
PapaCharlie Apr 11, 2024
d9f1aa7
Add copyright
PapaCharlie Apr 11, 2024
abb4993
Complete migration by reading off wire in *Buffers
PapaCharlie Apr 15, 2024
eb442ed
More fixes
PapaCharlie Apr 15, 2024
3578382
transport package mostly fixed!
PapaCharlie Apr 16, 2024
cf49cd1
Nuke `BufferProvider` interface
PapaCharlie Apr 16, 2024
28f5651
Move to new `mem` package, wire in the BufferPool all the way down to…
PapaCharlie Apr 17, 2024
842d3fc
Complete!
PapaCharlie Apr 18, 2024
d3863ec
Address vet
PapaCharlie Apr 18, 2024
1ba7894
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie Apr 18, 2024
b4b467f
Always fully materialize the buffers for the binlog
PapaCharlie Apr 18, 2024
466a0ce
First pass at attempting getting the leakcheck package at checking bu…
PapaCharlie Apr 18, 2024
afcd86a
Implement buffer leak check
PapaCharlie Apr 18, 2024
710ee3d
More frees
PapaCharlie Apr 18, 2024
80eab7c
Make referencing a buffer actually create a copy
PapaCharlie Apr 29, 2024
af0a194
Clear unread buffers on stream close
PapaCharlie May 2, 2024
e9deef0
Add ref in SendMsg
PapaCharlie May 2, 2024
74ffdf4
Fix retries
PapaCharlie May 3, 2024
527b644
Fix the retries?
PapaCharlie May 3, 2024
5a1e22e
Drain stream to pass test
PapaCharlie May 3, 2024
13efcff
Cleanups
PapaCharlie May 9, 2024
3e7f3d4
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie May 9, 2024
ab24c18
Remove dial
PapaCharlie May 14, 2024
af4644b
Disable goroutine leak check, but never disable buffer leak check
PapaCharlie May 28, 2024
df282ce
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie May 29, 2024
3ef511e
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie May 30, 2024
017b72f
Add docs and address comments
PapaCharlie Jun 20, 2024
978d448
Getting closer
PapaCharlie Jun 20, 2024
9be25eb
Disable leakcheck
PapaCharlie Jun 26, 2024
23975fc
Add TODO on leakcheck
PapaCharlie Jun 26, 2024
25adf8a
Address comments
PapaCharlie Jun 26, 2024
9962795
Address more comments
PapaCharlie Jun 26, 2024
5ee8565
Clean up buffers when initial call succeeds
PapaCharlie Jul 1, 2024
c5ed951
More touchups
PapaCharlie Jul 1, 2024
a2a6add
Address comments
PapaCharlie Jul 20, 2024
b6894dd
Allow specific tests to skip leakcheck
PapaCharlie Jul 22, 2024
37f1c30
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie Jul 22, 2024
9a877dd
Add ForceCodecV2 option
PapaCharlie Jul 22, 2024
be4d4ab
Introduce `mem` package
PapaCharlie Jul 22, 2024
5624e37
Address comments
PapaCharlie Jul 23, 2024
169406f
add a few unit tests for Buffer; fix docstring for NopBufferPool
easwars Jul 23, 2024
c029ea2
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie Jul 23, 2024
0889be4
Make BufferSlice.Reader take reference
PapaCharlie Jul 23, 2024
dace88f
Minor tweaks to BufferSlice.Reader
PapaCharlie Jul 23, 2024
14c288c
Improve test
PapaCharlie Jul 24, 2024
ae308d4
more tests and minor touchups
easwars Jul 25, 2024
01ac2c6
fix a bug in BufferSlice.Reader
easwars Jul 25, 2024
1261d3e
add prefix to test names to match type
easwars Jul 25, 2024
50bda24
handle review comments
easwars Jul 26, 2024
4d0eaa5
handle more review comments from dfawley
easwars Jul 26, 2024
f6f8b48
Merge remote-tracking branch 'upstream/master' into pc/mem
PapaCharlie Aug 1, 2024
5aa0784
Address comments
PapaCharlie Aug 1, 2024
284c19c
Merge branch 'pc/mem' into pc/newcodec
PapaCharlie Aug 1, 2024
0d79099
Update after rebase on pc/mem
PapaCharlie Aug 1, 2024
2ee31ca
Rename test
PapaCharlie Aug 1, 2024
c2d9987
Merge branch 'pc/mem' into pc/newcodec
PapaCharlie Aug 1, 2024
3a8cac5
Rename to onFree
PapaCharlie Aug 1, 2024
462e031
Merge branch 'pc/mem' into pc/newcodec
PapaCharlie Aug 1, 2024
30f191b
Fix mem test
PapaCharlie Aug 1, 2024
aaca195
Change to MaterializeToBuffer
PapaCharlie Aug 1, 2024
89ca8a9
Merge branch 'pc/mem' into pc/newcodec
PapaCharlie Aug 1, 2024
84c5817
Fix vet failure
PapaCharlie Aug 1, 2024
87df011
Unbreak uint cast
PapaCharlie Aug 1, 2024
e6c6731
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie Aug 5, 2024
5cbb1d7
Reuse `Buffer` instances
PapaCharlie Aug 6, 2024
6e2146e
Fix `prepareMsg`
PapaCharlie Aug 6, 2024
152db3d
Make `BufferPool.Put` take a `*[]byte`
PapaCharlie Aug 6, 2024
981a5dc
Hack hack hack!
PapaCharlie Aug 6, 2024
8c40132
Implement flate.Reader to prevent wrapping
PapaCharlie Aug 6, 2024
5074715
Refactor splitting
PapaCharlie Aug 6, 2024
aa33829
Run it with tags instead
PapaCharlie Aug 9, 2024
19cc6b3
More touchups, tests are passing
PapaCharlie Aug 9, 2024
2efbe0d
Make leaks informational instead of failures
PapaCharlie Aug 9, 2024
35f35e4
Enable test failures with tag
PapaCharlie Aug 10, 2024
606b9f2
Split more stuff
PapaCharlie Aug 10, 2024
5672329
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie Aug 10, 2024
8898f13
First pass at object reduction
PapaCharlie Aug 12, 2024
4949fc4
Getting closer
PapaCharlie Aug 12, 2024
d4b487a
Pool ref counters
PapaCharlie Aug 12, 2024
4b0c81e
More fixes
PapaCharlie Aug 13, 2024
44376be
No-copy BufferSlice
PapaCharlie Aug 13, 2024
ebffde3
Finish up the job!
PapaCharlie Aug 13, 2024
b82bf1f
Fix compile error on default tag
PapaCharlie Aug 13, 2024
c87426e
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie Aug 13, 2024
83d0322
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie Aug 14, 2024
87a408c
Remove tags
PapaCharlie Aug 14, 2024
aaa3f16
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie Aug 14, 2024
6c38c43
Fix leakcheck
PapaCharlie Aug 14, 2024
189e620
Fix grpchttp2
PapaCharlie Aug 14, 2024
d557400
Fix vet
PapaCharlie Aug 14, 2024
a7fb1d6
Fix tests
PapaCharlie Aug 14, 2024
299260c
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie Aug 20, 2024
6ad4793
Address Doug's comments
PapaCharlie Aug 20, 2024
dab5e1e
rerun tests
PapaCharlie Aug 20, 2024
7ff751b
Add coments
PapaCharlie Aug 20, 2024
bcb1b41
Fix grammar
PapaCharlie Aug 20, 2024
04691be
Fix test
PapaCharlie Aug 21, 2024
27f2187
Merge remote-tracking branch 'upstream/master' into pc/newcodec
PapaCharlie Aug 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions benchmark/benchmain/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import (
"google.golang.org/grpc/internal"
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/mem"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/test/bufconn"

Expand Down Expand Up @@ -347,10 +348,10 @@ func makeClients(bf stats.Features) ([]testgrpc.BenchmarkServiceClient, func())
}
switch bf.RecvBufferPool {
case recvBufferPoolNil:
// Do nothing.
opts = append(opts, experimental.WithBufferPool(mem.NopBufferPool{}))
sopts = append(sopts, experimental.BufferPool(mem.NopBufferPool{}))
case recvBufferPoolSimple:
opts = append(opts, experimental.WithRecvBufferPool(grpc.NewSharedBufferPool()))
sopts = append(sopts, experimental.RecvBufferPool(grpc.NewSharedBufferPool()))
// Do nothing as buffering is enabled by default.
default:
logger.Fatalf("Unknown shared recv buffer pool type: %v", bf.RecvBufferPool)
}
Expand Down
75 changes: 68 additions & 7 deletions codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,79 @@
import (
"google.golang.org/grpc/encoding"
_ "google.golang.org/grpc/encoding/proto" // to register the Codec for "proto"
"google.golang.org/grpc/mem"
)

// baseCodec contains the functionality of both Codec and encoding.Codec, but
// omits the name/string, which vary between the two and are not needed for
// anything besides the registry in the encoding package.
// baseCodec captures the new encoding.CodecV2 interface without the Name
// function, allowing it to be implemented by older Codec and encoding.Codec
// implementations. The omitted Name function is only needed for the register in
// the encoding package and is not part of the core functionality.
type baseCodec interface {
Marshal(v any) ([]byte, error)
Unmarshal(data []byte, v any) error
Marshal(v any) (mem.BufferSlice, error)
Unmarshal(data mem.BufferSlice, v any) error
}

// getCodec returns an encoding.CodecV2 for the codec of the given name (if
// registered). Initially checks the V2 registry with encoding.GetCodecV2 and
// returns the V2 codec if it is registered. Otherwise, it checks the V1 registry
// with encoding.GetCodec and if it is registered wraps it with newCodecV1Bridge
// to turn it into an encoding.CodecV2. Returns nil otherwise.
func getCodec(name string) encoding.CodecV2 {
codecV2 := encoding.GetCodecV2(name)
if codecV2 != nil {
return codecV2
}

codecV1 := encoding.GetCodec(name)
if codecV1 != nil {
return newCodecV1Bridge(codecV1)

Check warning on line 49 in codec.go

View check run for this annotation

Codecov / codecov/patch

codec.go#L49

Added line #L49 was not covered by tests
}

return nil
}

var _ baseCodec = Codec(nil)
var _ baseCodec = encoding.Codec(nil)
func newCodecV0Bridge(c Codec) baseCodec {
return codecV0Bridge{codec: c}

Check warning on line 56 in codec.go

View check run for this annotation

Codecov / codecov/patch

codec.go#L55-L56

Added lines #L55 - L56 were not covered by tests
}

func newCodecV1Bridge(c encoding.Codec) encoding.CodecV2 {
return codecV1Bridge{
codecV0Bridge: codecV0Bridge{codec: c},
name: c.Name(),
}
}

var _ baseCodec = codecV0Bridge{}

type codecV0Bridge struct {
codec interface {
Marshal(v any) ([]byte, error)
Unmarshal(data []byte, v any) error
}
}

func (c codecV0Bridge) Marshal(v any) (mem.BufferSlice, error) {
data, err := c.codec.Marshal(v)
if err != nil {
return nil, err
}
return mem.BufferSlice{mem.NewBuffer(data, nil)}, nil
easwars marked this conversation as resolved.
Show resolved Hide resolved
}

func (c codecV0Bridge) Unmarshal(data mem.BufferSlice, v any) (err error) {
return c.codec.Unmarshal(data.Materialize(), v)
}

var _ encoding.CodecV2 = codecV1Bridge{}

type codecV1Bridge struct {
codecV0Bridge
name string
}

func (c codecV1Bridge) Name() string {
return c.name
}

// Codec defines the interface gRPC uses to encode and decode messages.
// Note that implementations of this interface must be thread safe;
Expand Down
27 changes: 5 additions & 22 deletions dialoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"google.golang.org/grpc/internal/binarylog"
"google.golang.org/grpc/internal/transport"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/mem"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/stats"
)
Expand Down Expand Up @@ -60,7 +61,7 @@
internal.WithBinaryLogger = withBinaryLogger
internal.JoinDialOptions = newJoinDialOption
internal.DisableGlobalDialOptions = newDisableGlobalDialOptions
internal.WithRecvBufferPool = withRecvBufferPool
internal.WithBufferPool = withBufferPool
}

// dialOptions configure a Dial call. dialOptions are set by the DialOption
Expand Down Expand Up @@ -92,7 +93,6 @@
defaultServiceConfigRawJSON *string
resolvers []resolver.Builder
idleTimeout time.Duration
recvBufferPool SharedBufferPool
defaultScheme string
maxCallAttempts int
}
Expand Down Expand Up @@ -677,11 +677,11 @@
WriteBufferSize: defaultWriteBufSize,
UseProxy: true,
UserAgent: grpcUA,
BufferPool: mem.DefaultBufferPool(),
},
bs: internalbackoff.DefaultExponential,
healthCheckFunc: internal.HealthCheckFunc,
idleTimeout: 30 * time.Minute,
recvBufferPool: nopBufferPool{},
defaultScheme: "dns",
maxCallAttempts: defaultMaxCallAttempts,
}
Expand Down Expand Up @@ -758,25 +758,8 @@
})
}

// WithRecvBufferPool returns a DialOption that configures the ClientConn
// 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.NewSharedBufferPool.
//
// Note: The shared buffer pool feature will not be active if any of the following
// options are used: WithStatsHandler, EnableTracing, or binary logging. In such
// cases, the shared buffer pool will be ignored.
//
// Deprecated: use experimental.WithRecvBufferPool instead. Will be deleted in
// v1.60.0 or later.
func WithRecvBufferPool(bufferPool SharedBufferPool) DialOption {
return withRecvBufferPool(bufferPool)
}

func withRecvBufferPool(bufferPool SharedBufferPool) DialOption {
func withBufferPool(bufferPool mem.BufferPool) DialOption {

Check warning on line 761 in dialoptions.go

View check run for this annotation

Codecov / codecov/patch

dialoptions.go#L761

Added line #L761 was not covered by tests
return newFuncDialOption(func(o *dialOptions) {
o.recvBufferPool = bufferPool
o.copts.BufferPool = bufferPool

Check warning on line 763 in dialoptions.go

View check run for this annotation

Codecov / codecov/patch

dialoptions.go#L763

Added line #L763 was not covered by tests
})
}
77 changes: 77 additions & 0 deletions encoding/encoding_v2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
*
* Copyright 2017 gRPC authors.
PapaCharlie marked this conversation as resolved.
Show resolved Hide resolved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package encoding

import (
"strings"

"google.golang.org/grpc/mem"
)

// CodecV2 defines the interface gRPC uses to encode and decode messages. Note
// that implementations of this interface must be thread safe; a CodecV2's
// methods can be called from concurrent goroutines.
type CodecV2 interface {
// Marshal returns the wire format of v.
PapaCharlie marked this conversation as resolved.
Show resolved Hide resolved
Marshal(v any) (out mem.BufferSlice, err error)
// Unmarshal parses the wire format into v.
PapaCharlie marked this conversation as resolved.
Show resolved Hide resolved
Unmarshal(data mem.BufferSlice, v any) error
// Name returns the name of the Codec implementation. The returned string
// will be used as part of content type in transmission. The result must be
// static; the result cannot change between calls.
Name() string
}

var registeredV2Codecs = make(map[string]CodecV2)
dfawley marked this conversation as resolved.
Show resolved Hide resolved

// RegisterCodecV2 registers the provided CodecV2 for use with all gRPC clients and
// servers.
//
// The CodecV2 will be stored and looked up by result of its Name() method, which
// should match the content-subtype of the encoding handled by the CodecV2. This
// is case-insensitive, and is stored and looked up as lowercase. If the
// result of calling Name() is an empty string, RegisterCodecV2 will panic. See
// Content-Type on
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
// more details.
//
// If both a Codec and CodecV2 are registered with the same name, the CodecV2
// will be used.
//
// NOTE: this function must only be called during initialization time (i.e. in
// an init() function), and is not thread-safe. If multiple Codecs are
// registered with the same name, the one registered last will take effect.
func RegisterCodecV2(codec CodecV2) {
if codec == nil {
panic("cannot register a nil CodecV2")

Check warning on line 62 in encoding/encoding_v2.go

View check run for this annotation

Codecov / codecov/patch

encoding/encoding_v2.go#L62

Added line #L62 was not covered by tests
}
if codec.Name() == "" {
panic("cannot register CodecV2 with empty string result for Name()")

Check warning on line 65 in encoding/encoding_v2.go

View check run for this annotation

Codecov / codecov/patch

encoding/encoding_v2.go#L65

Added line #L65 was not covered by tests
}
contentSubtype := strings.ToLower(codec.Name())
registeredV2Codecs[contentSubtype] = codec
}

// GetCodecV2 gets a registered CodecV2 by content-subtype, or nil if no CodecV2 is
// registered for the content-subtype.
//
// The content-subtype is expected to be lowercase.
func GetCodecV2(contentSubtype string) CodecV2 {
return registeredV2Codecs[contentSubtype]
}
72 changes: 72 additions & 0 deletions encoding/proto/proto_v2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package proto

import (
"fmt"

"google.golang.org/grpc/encoding"
"google.golang.org/grpc/mem"
"google.golang.org/protobuf/proto"
)

func init() {
encoding.RegisterCodecV2(&codecV2{})
}

// codec is a CodecV2 implementation with protobuf. It is the default codec for
// gRPC.
type codecV2 struct{}

var _ encoding.CodecV2 = (*codecV2)(nil)

func (c *codecV2) Marshal(v any) (mem.BufferSlice, error) {
vv := messageV2Of(v)
if vv == nil {
return nil, fmt.Errorf("proto: failed to marshal, message is %T, want proto.Message", v)

Check warning on line 42 in encoding/proto/proto_v2.go

View check run for this annotation

Codecov / codecov/patch

encoding/proto/proto_v2.go#L42

Added line #L42 was not covered by tests
}

pool := mem.DefaultBufferPool()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use the buffer pool configured on the channel, instead of the default buffer pool, right?

To be able to do that though, we need some way for the codec to know which pool to use (based on which channel is making the request). One options is to register a factory with the encoding package instead of registering the codec itself, and when building an instance of the codec using the factory, we can pass in the configured buffer pool.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we previously had a conversation on this. If the user really wants to have the specific pool that's used by the channel, they can provide a custom codec when initializing the client/server and make sure that that custom codec reuses the same BufferPool provided with exeperimental.BufferPool

buf := pool.Get(proto.Size(vv))
if _, err := (proto.MarshalOptions{}).MarshalAppend(buf[:0], vv); err != nil {
pool.Put(buf)
return nil, err

Check warning on line 49 in encoding/proto/proto_v2.go

View check run for this annotation

Codecov / codecov/patch

encoding/proto/proto_v2.go#L48-L49

Added lines #L48 - L49 were not covered by tests
}
return mem.BufferSlice{mem.NewBuffer(buf, pool.Put)}, nil
}

func (c *codecV2) Unmarshal(data mem.BufferSlice, v any) (err error) {
vv := messageV2Of(v)
if vv == nil {
return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v)

Check warning on line 57 in encoding/proto/proto_v2.go

View check run for this annotation

Codecov / codecov/patch

encoding/proto/proto_v2.go#L57

Added line #L57 was not covered by tests
}

defer data.Free()

buf := data.LazyMaterialize(mem.DefaultBufferPool())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar concern for the read path.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

defer buf.Free()
// TODO: Upgrade proto.Unmarshal to support mem.BufferSlice. Right now, it's not
// really possible without a major overhaul of the proto package, but the
// vtprotobuf library may be able to support this.
return proto.Unmarshal(buf.ReadOnlyData(), vv)
}

func (c *codecV2) Name() string {
return Name
}
55 changes: 27 additions & 28 deletions experimental/experimental.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,38 +28,37 @@
import (
"google.golang.org/grpc"
"google.golang.org/grpc/internal"
"google.golang.org/grpc/mem"
)

// WithRecvBufferPool returns a grpc.DialOption that configures the use of
// bufferPool for parsing incoming messages on a grpc.ClientConn. Depending on
// the application's workload, this could result in reduced memory allocation.
// WithBufferPool returns a grpc.DialOption that configures the use of bufferPool
// for parsing incoming messages on a grpc.ClientConn, and for temporary buffers
// when marshaling outgoing messages. By default, mem.DefaultBufferPool is used,
// and this option only exists to provide alternative buffer pool implementations
easwars marked this conversation as resolved.
Show resolved Hide resolved
// to the client, such as more optimized size allocations etc. However, the
// default buffer pool is already tuned to account for many different use-cases.
//
// If you are unsure about how to implement a memory pool but want to utilize
// one, begin with grpc.NewSharedBufferPool.
//
// Note: The shared buffer pool feature will not be active if any of the
// following options are used: WithStatsHandler, EnableTracing, or binary
// logging. In such cases, the shared buffer pool will be ignored.
//
// Note: It is not recommended to use the shared buffer pool when compression is
// enabled.
func WithRecvBufferPool(bufferPool grpc.SharedBufferPool) grpc.DialOption {
return internal.WithRecvBufferPool.(func(grpc.SharedBufferPool) grpc.DialOption)(bufferPool)
// Note: The following options will interfere with the buffer pool because they
// require a fully materialized buffer instead of a sequence of buffers:
// EnableTracing, and binary logging. In such cases, materializing the buffer
// will generate a lot of garbage, reducing the overall benefit from using a
// pool.
func WithBufferPool(bufferPool mem.BufferPool) grpc.DialOption {
return internal.WithBufferPool.(func(mem.BufferPool) grpc.DialOption)(bufferPool)

Check warning on line 47 in experimental/experimental.go

View check run for this annotation

Codecov / codecov/patch

experimental/experimental.go#L46-L47

Added lines #L46 - L47 were not covered by tests
}

// RecvBufferPool returns a grpc.ServerOption that configures the server 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.NewSharedBufferPool.
//
// Note: The shared buffer pool feature will not be active if any of the
// following options are used: StatsHandler, EnableTracing, or binary logging.
// In such cases, the shared buffer pool will be ignored.
// BufferPool returns a grpc.ServerOption that configures the server to use the
// provided buffer pool for parsing incoming messages and for temporary buffers
// when marshaling outgoing messages. By default, mem.DefaultBufferPool is used,
// and this option only exists to provide alternative buffer pool implementations
// to the server, such as more optimized size allocations etc. However, the
// default buffer pool is already tuned to account for many different use-cases.
//
// Note: It is not recommended to use the shared buffer pool when compression is
// enabled.
func RecvBufferPool(bufferPool grpc.SharedBufferPool) grpc.ServerOption {
return internal.RecvBufferPool.(func(grpc.SharedBufferPool) grpc.ServerOption)(bufferPool)
// Note: The following options will interfere with the buffer pool because they
// require a fully materialized buffer instead of a sequence of buffers:
// EnableTracing, and binary logging. In such cases, materializing the buffer
// will generate a lot of garbage, reducing the overall benefit from using a
// pool.
func BufferPool(bufferPool mem.BufferPool) grpc.ServerOption {
return internal.BufferPool.(func(mem.BufferPool) grpc.ServerOption)(bufferPool)

Check warning on line 63 in experimental/experimental.go

View check run for this annotation

Codecov / codecov/patch

experimental/experimental.go#L62-L63

Added lines #L62 - L63 were not covered by tests
}
Loading
Loading