Skip to content

Commit de1c628

Browse files
author
Dmitriy Matrenichev
committed
fix: copy data from big frame msg
🤦 I forgot to actually copy data from the frame on `len(payload) > bufferPoolingThreshold`. Also add test to ensure that this works correctly. Signed-off-by: Dmitriy Matrenichev <[email protected]>
1 parent ef47ec7 commit de1c628

File tree

4 files changed

+59
-20
lines changed

4 files changed

+59
-20
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ require (
2020
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect
2121
gopkg.in/yaml.v3 v3.0.1 // indirect
2222
)
23+
24+
retract v0.5.0

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
1919
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
2020
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
2121
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
22-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
23-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
2422
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc=
2523
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
2624
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=

proxy/codec.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ func (c *rawCodec) Marshal(v any) (data mem.BufferSlice, err error) {
5757
} else {
5858
pool := mem.DefaultBufferPool()
5959
buf := pool.Get(len(f.payload))
60+
copy(*buf, f.payload)
61+
6062
data = append(data, mem.NewBuffer(buf, pool))
6163
}
6264

proxy/codec_test.go

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,73 @@
11
package proxy_test
22

33
import (
4+
"bytes"
5+
"strings"
46
"testing"
57

68
"github.com/stretchr/testify/require"
79
"google.golang.org/grpc/mem"
810

911
"github.com/siderolabs/grpc-proxy/proxy"
12+
talos_testproto "github.com/siderolabs/grpc-proxy/testservice"
1013
)
1114

1215
func TestCodec_ReadYourWrites(t *testing.T) {
13-
framePtr := proxy.NewFrame(nil)
14-
data := []byte{0xDE, 0xAD, 0xBE, 0xEF}
15-
codec := proxy.Codec()
16+
d := []byte{0xDE, 0xAD, 0xBE, 0xEF}
1617

17-
buffer := mem.Copy(data, mem.DefaultBufferPool())
18-
defer buffer.Free()
18+
for key, val := range map[string][]byte{
19+
"short message": d,
20+
"long message": bytes.Repeat(d, 3072),
21+
} {
22+
t.Run(key, func(t *testing.T) {
23+
framePtr := proxy.NewFrame(nil)
24+
codec := proxy.Codec()
1925

20-
require.NoError(t, codec.Unmarshal(mem.BufferSlice{buffer}, framePtr), "unmarshalling must go ok")
21-
out, err := codec.Marshal(framePtr)
22-
require.NoError(t, err, "no marshal error")
23-
require.Equal(t, data, out.Materialize(), "output and data must be the same")
26+
buffer := mem.Copy(val, mem.DefaultBufferPool())
27+
defer func() { buffer.Free() }()
2428

25-
out.Free()
26-
buffer.Free()
27-
buffer = mem.Copy([]byte{0x55}, mem.DefaultBufferPool())
29+
require.NoError(t, codec.Unmarshal(mem.BufferSlice{buffer}, framePtr), "unmarshalling must go ok")
30+
out, err := codec.Marshal(framePtr)
31+
require.NoError(t, err, "no marshal error")
32+
require.Equal(t, val, out.Materialize(), "output and data must be the same")
2833

29-
// reuse
30-
require.NoError(t, codec.Unmarshal(mem.BufferSlice{buffer}, framePtr), "unmarshalling must go ok")
31-
out, err = codec.Marshal(framePtr)
32-
require.NoError(t, err, "no marshal error")
33-
require.Equal(t, []byte{0x55}, out.Materialize(), "output and data must be the same")
34+
out.Free()
35+
buffer.Free()
36+
buffer = mem.Copy([]byte{0x55}, mem.DefaultBufferPool())
3437

35-
out.Free()
38+
// reuse
39+
require.NoError(t, codec.Unmarshal(mem.BufferSlice{buffer}, framePtr), "unmarshalling must go ok")
40+
out, err = codec.Marshal(framePtr)
41+
require.NoError(t, err, "no marshal error")
42+
require.Equal(t, []byte{0x55}, out.Materialize(), "output and data must be the same")
43+
44+
out.Free()
45+
})
46+
}
47+
}
48+
49+
func TestCodecUsualMessage(t *testing.T) {
50+
const msg = "short message"
51+
52+
for key, val := range map[string]string{
53+
"short message": "edbca",
54+
"long message": strings.Repeat(msg, 3072),
55+
} {
56+
t.Run(key, func(t *testing.T) {
57+
msg := &talos_testproto.PingRequest{Value: val}
58+
59+
codec := proxy.Codec()
60+
61+
out, err := codec.Marshal(msg)
62+
require.NoError(t, err, "no marshal error")
63+
64+
defer out.Free()
65+
66+
var dst talos_testproto.PingRequest
67+
68+
require.NoError(t, codec.Unmarshal(out, &dst), "unmarshalling must go ok")
69+
require.NotZero(t, dst.Value, "output must not be zero")
70+
require.Equal(t, msg.Value, dst.Value, "output and data must be the same")
71+
})
72+
}
3673
}

0 commit comments

Comments
 (0)