-
Notifications
You must be signed in to change notification settings - Fork 4.6k
encoding/proto: enable use cached size option #8569
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,17 +46,33 @@ func (c *codecV2) Marshal(v any) (data mem.BufferSlice, err error) { | |
| return nil, fmt.Errorf("proto: failed to marshal, message is %T, want proto.Message", v) | ||
| } | ||
|
|
||
| // Important: if we remove this Size call then we cannot use | ||
| // UseCachedSize in MarshalOptions below. | ||
| size := proto.Size(vv) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this seems to rely on a runtime behaviour of calling
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think if we don't call
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would this be cleaner?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The docstring of And that if that condition is not met, bad things might happen.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just want to flag an edge case that normally shouldn’t happen: if another part of the stack keeps a reference to the proto message and it’s shared across multiple Go routines, one routine might modify the message while another is marshaling it through this codec. In that situation, enabling That said, the issue I’m describing would still cause (other) problems even if
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've updated the comment: rs-unity@ec0c47e |
||
|
|
||
| // MarshalOptions with UseCachedSize allows reusing the result from the | ||
| // previous Size call. This is safe here because: | ||
| // | ||
| // 1. We just computed the size. | ||
| // 2. We assume the message is not being mutated concurrently. | ||
| // | ||
| // Important: If the proto.Size call above is removed, using UseCachedSize | ||
| // becomes unsafe and may lead to incorrect marshaling. | ||
| // | ||
| // For more details, see the doc of UseCachedSize: | ||
| // https://pkg.go.dev/google.golang.org/protobuf/proto#MarshalOptions | ||
| marshalOptions := proto.MarshalOptions{UseCachedSize: true} | ||
|
|
||
| if mem.IsBelowBufferPoolingThreshold(size) { | ||
| buf, err := proto.Marshal(vv) | ||
| buf, err := marshalOptions.Marshal(vv) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| data = append(data, mem.SliceBuffer(buf)) | ||
| } else { | ||
| pool := mem.DefaultBufferPool() | ||
| buf := pool.Get(size) | ||
| if _, err := (proto.MarshalOptions{}).MarshalAppend((*buf)[:0], vv); err != nil { | ||
| if _, err := marshalOptions.MarshalAppend((*buf)[:0], vv); err != nil { | ||
| pool.Put(buf) | ||
| return nil, err | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.