@@ -14,7 +14,10 @@ import (
14
14
const Name = "proto"
15
15
16
16
func init () {
17
- encoding .RegisterCodecV2 (& cortexCodec {})
17
+ encoding .RegisterCodecV2 (& cortexCodec {
18
+ noOpBufferPool : mem.NopBufferPool {},
19
+ defaultBufferPool : mem .DefaultBufferPool (),
20
+ })
18
21
}
19
22
20
23
type ReleasableMessage interface {
@@ -25,7 +28,10 @@ type GogoProtoMessage interface {
25
28
MarshalToSizedBuffer (dAtA []byte ) (int , error )
26
29
}
27
30
28
- type cortexCodec struct {}
31
+ type cortexCodec struct {
32
+ noOpBufferPool mem.BufferPool
33
+ defaultBufferPool mem.BufferPool
34
+ }
29
35
30
36
func (c cortexCodec ) Name () string {
31
37
return Name
@@ -64,7 +70,7 @@ func (c *cortexCodec) Marshal(v any) (data mem.BufferSlice, err error) {
64
70
65
71
data = append (data , buf )
66
72
} else {
67
- pool := mem . DefaultBufferPool ()
73
+ pool := c . defaultBufferPool
68
74
buf := pool .Get (size )
69
75
70
76
// If v implements MarshalToSizedBuffer we should use it as it is more optimized
@@ -94,10 +100,17 @@ func (c *cortexCodec) Unmarshal(data mem.BufferSlice, v any) error {
94
100
return fmt .Errorf ("failed to unmarshal, message is %T, want proto.Message" , v )
95
101
}
96
102
97
- // To be in the safe side, we will never automatically release the buffer used to Unmarshal the message automatically.
98
- // This should simulate the same behavior of grpc v1.65.0 and before.
99
- buf := data .MaterializeToBuffer (mem .DefaultBufferPool ())
103
+ // To be safe, we avoid automatically releasing the buffer used to unmarshal the message.
104
+ // Additionally, we avoid using a pooled byte slice unless the message implements ReleasableMessage.
105
+ // This mimics the behavior of gRPC versions 1.65.0 and earlier.
106
+ rm , ok := v .(ReleasableMessage )
107
+ bufferPool := c .defaultBufferPool
108
+
109
+ if ! ok {
110
+ bufferPool = c .noOpBufferPool
111
+ }
100
112
113
+ buf := data .MaterializeToBuffer (bufferPool )
101
114
err := proto .Unmarshal (buf .ReadOnlyData (), vv )
102
115
103
116
if err != nil {
@@ -106,8 +119,8 @@ func (c *cortexCodec) Unmarshal(data mem.BufferSlice, v any) error {
106
119
}
107
120
108
121
// If v implements ReleasableMessage interface, we add the buff to be freed later when the request is no longer being used
109
- if fm , ok := v .( ReleasableMessage ); ok {
110
- fm .RegisterBuffer (buf )
122
+ if rm != nil {
123
+ rm .RegisterBuffer (buf )
111
124
}
112
125
113
126
return err
0 commit comments