`MessageFieldView` boxes every present nested message on decode, while owned `MessageField` defaults to inline storage
Maintainers usually reply within 3 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 68/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- rust
- Domain
- backend, performance
Research direction
Start with MessageFieldViewV storage and the codegen logic that selects boxed storage for recursive owned fields, then compare the generated owned and view types. Run the small-unary benchmark in benches/rpc, especially BenchService/Unary with small_request(), to establish the allocation baseline. Done means nonrecursive present nested view fields avoid per-message boxing while recursive schemas retain the required boxed storage.
Written by the indexing model from the issue text.
Description
MessageFieldView<V> stores a set field as Option<Box<V>>, so decoding a view of a message allocates once for every nested message field that is present, however small the nested view is. The owned side made the opposite default: MessageField<T> is Inline<T> with recursive fields boxed automatically and box_type_in as the opt-out, and the ProtoBox docs note in passing that "view types are unaffected". So the zero-copy decode path, which is the one chosen for allocation-sensitive servers, pays a per-nested-message allocation that the owned path was redesigned to avoid.
Measured in connect-rust's small-unary gRPC benchmark (benches/rpc, BenchService/Unary with the ~300-byte small_request() payload: a BenchRequest holding a Payload with 15 scalar/string fields, a nested Metadata, two small maps, a packed repeated int32 and a repeated string), with a counting global allocator on the server: the request's decode_view makes 7 heap allocations, and 2 of them are MessageFieldView::set boxing the PayloadView (200 B) and the MetadataView (72 B). The other 5 are Vec growth in MapView::push (128 B then 256 B for a 4-entry map<string,string>, 128 B for a 2-entry one), RepeatedView<&str>::push (64 B) and extend_packed_int32 (20 B). For scale, the whole connect-rust request path around that decode (HTTP/2 framing, routing, response encoding) is about 20 allocations after connectrpc/connect-rust#296, so the view decode is a third of the framework-side total for this message shape.
The box exists to break the size recursion for self-referential messages, which is the same problem MessageField solves with a per-field storage parameter chosen by codegen (Inline by default, boxed where the codegen's cycle detection or a user option asks for it). Carrying that policy over, MessageFieldView<V, S = Inline<V>> with codegen emitting the boxed storage on exactly the fields where it already boxes the owned type, would make the common case allocation-free without changing what recursive schemas generate. The DefaultViewInstance / Deref behaviour is independent of where the value is stored.
The Vec-backed MapView / RepeatedView growth is a separate and smaller question (a first-push capacity larger than 1, or a small inline buffer, would remove most of it for short maps and lists); mentioning it here only because it is the rest of the same measurement.
- Dominant language
- Rust
- Stars
- 927
- Forks
- 119
- Avg merge
- 3d 6h
- Merged PRs (30d)
- 151
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from anthropics/buffa
-
codegen: `generate` does not check `CodeGenConfig::extern_paths`, so a direct caller's malformed proto name is kept and never matches a typePossibly taken @vladislav-miroshnikov claimed this 17 days ago. Openenhancement
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
anthropics/buffa#703 ·
Maintainers usually reply within 3 days
-
types: `AnyView` has none of `Any`'s type-URL helpersPossibly taken @farmer-data claimed this 16 days ago. Openenhancement
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
anthropics/buffa#643 ·
Maintainers usually reply within 3 days
-
docs: `DescriptorPool::files()` does not say that link-time inference is left out of the returned descriptorsPossibly taken @veljjanoski claimed this 16 days ago. Opendocumentation
Difficulty 1/5 Under an hour Newbie friendliness 78/100
anthropics/buffa#642 · 1 comment ·
Maintainers usually reply within 3 days
-
descriptor: an editions file whose edition the pool does not define links with the edition 2023 defaultsPossibly taken @saloni-garg claimed this 8 days ago. Openquestion
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
anthropics/buffa#634 ·
Maintainers usually reply within 3 days
-
codegen: the generated `TYPE_URL` doc names `Any::pack` / `Any::unpack_if`, not `pack_message` / `unpack_message`Possibly taken @veljjanoski claimed this 16 days ago. Opendocumentation
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
anthropics/buffa#621 · 1 comment ·
Maintainers usually reply within 3 days
All issues in anthropics/buffa
Similar issues
-
example
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
rust-lang-nursery/rust-cookbook#954 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 1-3 hours Newbie friendliness 70/100
OpenZeppelin/openzeppelin-relayer#967 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
src/runs.rs:1987: a missing --source-run-id now answers 400 "Source run ... does not exist", not 404Opennightly-audit
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
antithesishq/snouty#602 ·
Maintainers usually reply within 1 day