-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: upgrade Codec implementations and usages to Codec2
This is breaking change, that (potentially) should lower the memory usage on our gRPC layer. Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
- Loading branch information
Showing
9 changed files
with
76 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,77 +1,79 @@ | ||
// Copyright 2024 Siderolabs. All Rights Reserved. | ||
// See LICENSE for licensing terms. | ||
|
||
package proxy | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"google.golang.org/grpc/encoding" | ||
"google.golang.org/protobuf/proto" | ||
gproto "google.golang.org/grpc/encoding/proto" | ||
"google.golang.org/grpc/mem" | ||
) | ||
|
||
// Codec returns a proxying [encoding.Coder] with the default protobuf codec as parent. | ||
// Codec returns a proxying [encoding.CodecV2] with the default protobuf codec as parent. | ||
// | ||
// See CodecWithParent. | ||
func Codec() encoding.Codec { | ||
return CodecWithParent(&protoCodec{}) | ||
// See [CodecWithParent]. | ||
func Codec() encoding.CodecV2 { | ||
if c := encoding.GetCodecV2(gproto.Name); c != nil { | ||
return CodecWithParent(c) | ||
} | ||
|
||
panic(errors.New(`no codec named "proto" found`)) | ||
} | ||
|
||
// CodecWithParent returns a proxying [encoding.Codec] with a user provided codec as parent. | ||
// CodecWithParent returns a proxying [encoding.CodecV2] with a user provided codec as parent. | ||
// | ||
// This codec is *crucial* to the functioning of the proxy. It allows the proxy server to be oblivious | ||
// to the schema of the forwarded messages. It basically treats a gRPC message frame as raw bytes. | ||
// However, if the server handler, or the client caller are not proxy-internal functions it will fall back | ||
// to trying to decode the message using a fallback codec. | ||
func CodecWithParent(fallback encoding.Codec) encoding.Codec { | ||
return &rawCodec{fallback} | ||
func CodecWithParent(fallback encoding.CodecV2) encoding.CodecV2 { | ||
return &rawCodec{parentCodec: fallback} | ||
} | ||
|
||
type rawCodec struct { | ||
parentCodec encoding.Codec | ||
parentCodec encoding.CodecV2 | ||
} | ||
|
||
type frame struct { | ||
payload []byte | ||
} | ||
|
||
// NewFrame constructs a frame for raw codec. | ||
func NewFrame(payload []byte) interface{} { | ||
func NewFrame(payload []byte) any { | ||
return &frame{payload: payload} | ||
} | ||
|
||
func (c *rawCodec) Marshal(v interface{}) ([]byte, error) { | ||
out, ok := v.(*frame) | ||
func (c *rawCodec) Marshal(v any) (data mem.BufferSlice, err error) { | ||
f, ok := v.(*frame) | ||
if !ok { | ||
return c.parentCodec.Marshal(v) | ||
} | ||
|
||
return out.payload, nil | ||
if mem.IsBelowBufferPoolingThreshold(len(f.payload)) { | ||
data = append(data, mem.SliceBuffer(f.payload)) | ||
} else { | ||
pool := mem.DefaultBufferPool() | ||
buf := pool.Get(len(f.payload)) | ||
data = append(data, mem.NewBuffer(buf, pool)) | ||
} | ||
|
||
return data, nil | ||
} | ||
|
||
func (c *rawCodec) Unmarshal(data []byte, v interface{}) error { | ||
func (c *rawCodec) Unmarshal(data mem.BufferSlice, v any) error { | ||
dst, ok := v.(*frame) | ||
if !ok { | ||
return c.parentCodec.Unmarshal(data, v) | ||
} | ||
|
||
dst.payload = data | ||
dst.payload = data.Materialize() | ||
|
||
return nil | ||
} | ||
|
||
func (c *rawCodec) Name() string { | ||
return fmt.Sprintf("proxy>%s", c.parentCodec.Name()) | ||
} | ||
|
||
// protoCodec is a Codec implementation with protobuf. It is the default rawCodec for gRPC. | ||
type protoCodec struct{} | ||
|
||
func (protoCodec) Marshal(v interface{}) ([]byte, error) { | ||
return proto.Marshal(v.(proto.Message)) //nolint:forcetypeassert | ||
} | ||
|
||
func (protoCodec) Unmarshal(data []byte, v interface{}) error { | ||
return proto.Unmarshal(data, v.(proto.Message)) //nolint:forcetypeassert | ||
} | ||
|
||
func (protoCodec) Name() string { | ||
return "proto" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters