continue prost - #286
Conversation
|
@jokemanfire I appreciate you taking on this work very much. Thanks agian. |
There are some conflicts and API changes that need to be resolved and some code needs to be packaged to adapt to the current API. It's not easy to operate with the previous version of PR. I need to add some commit to complete this feature. I have communicated with the original author. |
dcf4304 to
781c816
Compare
|
@Tim-Zhang @justxuewei Local test all pass but i don't know how to install protoc in CI. |
21ebbd3 to
4a76b7b
Compare
a29312f to
5fadae0
Compare
|
Basically enough @Tim-Zhang @justxuewei just take a look . :) |
|
Nice work, thanks @jokemanfire! Could you cleanup your commits? It makes us easier to review and maintain.
Thanks! |
I have changed it. |
00fce61 to
735a10e
Compare
|
Once this feature gets merged, I prefer to bump a major version to 2 to avoid some compatibility issues, as it nearly changes the entire codegen engine. WDYT? @jokemanfire @Tim-Zhang |
This modification is indeed quite significant, and I agree. It depends on the maintainer's thoughts |
| let path: PathBuf = [out_dir.clone(), "mod.rs".to_string()].iter().collect(); | ||
| fs::write(path, "pub mod ttrpc;").unwrap(); | ||
|
|
||
| generate_ttrpc(&out_dir); |
There was a problem hiding this comment.
To get unified internal APIs which was defined in ttrpc.proto, how about keeping build script untouched?
I think we can try to avoid so many condition compiling sentences like #[cfg(not(feature = "prost"))] in code.
There was a problem hiding this comment.
right ,I think adding a transformation to the camel hump naming convention can reduce this conditional compilation code
|
I tried to minimize conditional compilation as much as possible @Tim-Zhang @justxuewei |
|
@Tim-Zhang Can you take some time to advance this feature? In the previous puncture, it was found that the prost library uses less memory during operation than the Rust Protobuf library |
There was a problem hiding this comment.
Several generator edge cases, size-limit regressions, and CI issues remain. The inline comments also include refactoring and idiomatic-Rust feedback focused on containing backend-specific behavior, reducing duplication, and avoiding unnecessary allocations and API divergence. Please address the inline findings before merge and add focused fixtures for imported types, multiple services with overlapping method names, and package-less schemas.
| let mut camel_case_name = String::with_capacity(name.len()); | ||
| for s in NameSpliter::new(name) { | ||
| let mut chs = s.chars(); | ||
| camel_case_name.extend(chs.next().unwrap().to_uppercase()); |
There was a problem hiding this comment.
Refactor/correctness: this custom name splitter can yield an empty segment after leading underscores and then panic at this unwrap; it also reimplements casing already handled by established Rust casing utilities and by normalized prost-build names. Prefer those normalized names or a well-tested casing helper.
Superseded by the inline review with additional refactoring feedback.
|
@jokemanfire I have left a few review comments, and btw please resolve the conflicts, thanks. |
thanks , I will take some time to resolve it. |
This commit refactors the ttrpc-codegen and the compiler, and merges the two crates into a single crate, named "codegen". The codegen uses prost crate, a protobuf compiler for Rust. Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
The ttrpc provides a "prost" feature to support the new version of codegen. An "example2" has been added to demonstrate how to use the codegen. Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
Install protoc when executing `make deps` of the ttrpc. Add codegen's check and build, and example2' build to the ci testing. Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
Fix all issues reported by cargo clippy to make ci testing pass. Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
merge from remote branch. ref: containerd#173 Co-authored-by: Xuewei Niu <niuxuewei.nxw@antgroup.com> Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
fix ci for protoc Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
because of the api change 1. fix the marco in prost 2. fix the test Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
fix rebase error. Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
skip build example2 in windows Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
while use protoc,rename the Code enum. Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
fix marco Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
Resolve Tim-Zhang's review on containerd#286 and adapt the prost backend to the master workspace. codegen (prost): - Use path-aware type_token() for method input/output types instead of format_ident!(), which panicked on qualified paths like super::google::protobuf::Empty. - Emit package-level imports once via finalize_package instead of per service, fixing E0252 on packages with multiple services. - Prefix per-method handler types with the service name so overlapping method names (Foo.Get / Bar.Get) no longer collide. - Make NameSpliter robust against empty segments to avoid panics on underscore-only / trailing-underscore names. - Refactor CodegenBuilder to owned PathBuf/Vec<PathBuf>, direct defaults, and build(self); drop the unrelated P: Default bound. - Add focused fixtures for imported types, overlapping method names, and package-less schemas. runtime / deps: - Align the prost family to 0.13 across ttrpc, prost-build, codegen, and example2 to avoid version drift. - Configure docs.rs with an explicit compatible feature set instead of all-features (prost and rustprotobuf are mutually exclusive). build / ci / docs: - Makefile: use $(OS) so the Windows branch is reachable. - bvt.yml: keep shell: bash on the multi-command Build step. - .gitignore: drop duplicate example2 rules. - README: document default-features = false for the prost feature. - build.rs: operate on the generated content in place (no clone). rebase onto master: - Adopt master's Cargo workspace; keep codegen and example2 as standalone workspace roots to avoid the ttrpc-codegen name collision. - Silence clippy::doc_overindented_list_items in prost-generated code. - Fix a stray brace in tests/run-examples.rs introduced during rebase. Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
There was a problem hiding this comment.
Pull request overview
This pull request continues the migration path toward supporting tokio-rs/prost alongside the existing rust-protobuf backend, adding a new standalone prost-based codegen crate plus a new example2 tree to exercise the prost workflow, and updating CI/build plumbing to install protoc and test both backends.
Changes:
- Add
prost+rustprotobufmutually-exclusive feature support in thettrpccrate, with conditional encode/decode paths across sync/async runtimes. - Introduce a new standalone
codegen/crate (prost-build based) and a newexample2/project that uses it. - Update CI and build scripts (including a new
install_protoc.sh) to ensureprotocis available and both backends build/test appropriately.
Reviewed changes
Copilot reviewed 54 out of 55 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| ttrpc-codegen/Makefile | Add local check/test targets for the legacy codegen crate. |
| compiler/Makefile | Add local check/test targets for the compiler crate. |
| tests/run-examples.rs | Run examples conditionally for rustprotobuf vs prost and add per-example working directory support. |
| src/ttrpc.proto | Change proto package to ttrpc (aligns with prost codegen expectations). |
| src/sync/utils.rs | Add prost-specific request/response helpers and macro variants. |
| src/sync/server.rs | Add prost decode/encode handling in sync server request path. |
| src/sync/mod.rs | Export utils as public module (macros/helpers used externally). |
| src/sync/client.rs | Add prost-specific oversize/status handling in sync client. |
| src/proto.rs | Add Codec impl for prost messages and gate protobuf stream codecs behind feature flags. |
| src/lib.rs | Re-export sync helpers and enforce mutual exclusivity of prost/rustprotobuf. |
| src/error.rs | Make Error -> Response and get_status work for both backends. |
| src/context.rs | Construct metadata KeyValue values compatibly for both backends. |
| src/asynchronous/utils.rs | Add prost variants of async handler/client macros and gate existing ones. |
| src/asynchronous/server.rs | Adjust async server response/status paths for prost message layout/size checks. |
| src/asynchronous/client.rs | Make async client request conversion/status handling work for both backends. |
| README.md | Document how to use the prost backend and its differences. |
| Makefile | Split CI checks/tests to run rustprotobuf and prost configurations (and skip prost where needed on Windows). |
| install_protoc.sh | Add helper to install protoc across GitHub Actions runner OSes. |
| example2/utils.rs | Add shared utilities for the prost-based example project. |
| example2/server.rs | Add sync prost example server. |
| example2/protocols/sync/mod.rs | Include generated sync prost protocol modules. |
| example2/protocols/protos/streaming.proto | Add streaming proto schema for example2. |
| example2/protocols/protos/oci.proto | Add OCI proto schema for example2. |
| example2/protocols/protos/health.proto | Add health proto schema for example2. |
| example2/protocols/protos/google/protobuf/test_empty.proto | Add test Empty message for example2 protos. |
| example2/protocols/protos/google/protobuf/empty.proto | Vendor protobuf well-known Empty type for example2 compilation. |
| example2/protocols/protos/google/protobuf/descriptor.proto | Vendor protobuf descriptor type for example2 compilation. |
| example2/protocols/protos/github.com/kata-containers/agent/pkg/types/types.proto | Vendor kata agent types proto used by example2. |
| example2/protocols/protos/github.com/gogo/protobuf/gogoproto/gogo.proto | Vendor gogo proto options used by example2 schemas. |
| example2/protocols/protos/agent.proto | Vendor kata agent service proto used by example2. |
| example2/protocols/mod.rs | Define example2 protocol module layout. |
| example2/protocols/hack/update-generated-proto.sh | Add script for updating/regenerating vendored protos + rust output. |
| example2/protocols/asynchronous/mod.rs | Include generated async prost protocol modules. |
| example2/Makefile | Add build/build-examples/deps targets (including protoc install). |
| example2/client.rs | Add sync prost example client. |
| example2/Cargo.toml | Define example2 crate dependencies and examples (prost + ttrpc prost feature). |
| example2/build.rs | Generate sync/async prost services via new codegen crate. |
| example2/async_stream_server.rs | Add async streaming server example for prost. |
| example2/async_stream_client.rs | Add async streaming client example for prost. |
| example2/async_server.rs | Add async unary server example for prost. |
| example2/async_client.rs | Add async unary client example for prost. |
| example/protocols/sync/mod.rs | Adjust example protocol module exports for legacy layout. |
| example/protocols/asynchronous/mod.rs | Adjust example async protocol module exports for legacy layout. |
| example/Cargo.toml | Ensure example explicitly enables rustprotobuf backend feature. |
| codegen/src/util.rs | Add identifier casing/type-path helper utilities for prost codegen. |
| codegen/src/svcgen.rs | Implement prost-build ServiceGenerator for ttrpc services/clients (sync+async+streaming). |
| codegen/src/lib.rs | Export the codegen API surface. |
| codegen/src/codegen.rs | Implement codegen builder + header injection using prost-build and fd_set introspection. |
| codegen/README.md | Document how to use the new prost-based codegen crate. |
| codegen/Makefile | Add build/test/check/deps targets for codegen crate. |
| codegen/Cargo.toml | Define new standalone ttrpc-codegen (prost-based) crate. |
| Cargo.toml | Add optional prost deps, define prost vs rustprotobuf features, and exclude new standalone crates from workspace. |
| build.rs | Generate ttrpc protos via protobuf-codegen or prost-build depending on selected backend, with prost enum variant rewriting. |
| .gitignore | Ignore generated protocol Rust files while keeping mod.rs tracked for both example trees. |
| .github/workflows/bvt.yml | Install protoc in CI and build example2 as part of the build job. |
Suppressed comments (2)
src/sync/utils.rs:182
- In the prost client macro,
mergeis called with an immutable slice.prost::Message::mergeneeds&mutinput (e.g.&mut &[u8]), otherwise this won’t compile.
src/asynchronous/utils.rs:317 - In the prost async client macro,
mergeis called with an immutable slice.prost::Message::mergerequires&mutinput (e.g.&mut &[u8]), otherwise it won’t compile.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 54 out of 55 changed files in this pull request and generated 2 comments.
Suppressed comments (10)
src/sync/utils.rs:113
- With the prost backend,
prost::Message::mergeexpects a mutableBuf(e.g.&mut &[u8]). Passing an immutable&[u8]won’t type-check, so this macro expansion will fail to compile under--features prost.
src/sync/utils.rs:182 - In the prost
client_request!macro,prost::Message::mergerequires a mutableBuf(e.g.&mut &[u8]). The currentmerge(&res.payload as &[u8])will not compile with prost 0.13.
src/asynchronous/utils.rs:317 - In the prost
async_client_request!macro,prost::Message::mergerequires a mutableBuf(e.g.&mut &[u8]). The currentmerge(&res.payload as &[u8])won’t type-check with prost 0.13.
tests/run-examples.rs:126 - In the prost test block, the sync
server/clientexample is commented out, so CI no longer exercises the basic sync example under the prost backend even thoughexample2provides it.
src/sync/client.rs:166 - For the prost backend, the oversize check currently only considers
req.payload.len(), but the encoded request size also includesservice,method,metadata, etc. This can bypass the max message size check with large metadata. Use the encoded size instead (via the existingCodec::size()implementation).
src/sync/utils.rs:58 - The prost
response_to_channelvariant doesn’t enforcecheck_oversizelike the rustprotobuf path does. That can send oversized responses and violate the library’s message size limits. Mirror the existing oversize handling before sending.
This issue also appears in the following locations of the same file:
- line 110
- line 179
compiler/Makefile:8
make -C compiler(as invoked by.github/workflows/bvt.yml) now defaults to running only thechecktarget, which means the build job no longer actually builds/tests this crate by default. Add an explicitalldefault target (or restore the previous include-based targets) so CI and localmakebehave as expected.
.PHONY: check
check:
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
ttrpc-codegen/Makefile:8
make -C ttrpc-codegen(as invoked by.github/workflows/bvt.yml) now defaults to running only thechecktarget, so the build job no longer builds/tests this crate by default. Add analldefault target somakecontinues to validate both linting and tests.
Makefile:3PROTOCis introduced but not used anywhere in the Makefile (no$(PROTOC)references). This adds confusion for maintainers; either wire it into the relevant targets or remove it.
PROTOC ?= $(shell which protoc 2>/dev/null || echo $(HOME)/protoc/bin/protoc)
all: debug test
src/error.rs:17
use crate::proto::{self, ...}importsproto::selfbut it’s never referenced, and the surrounding#[allow(unused_imports)]masks that. This can hide real unused-import issues; remove the unused import and the allow.
- error.rs: drop the unused `self` (proto module) import and the `#[allow(unused_imports)]` that masked it; Code/Response/Status are the only proto items referenced in this file. - sync/utils.rs: replace `#[allow(unused_imports)]` with explicit `#[cfg(not(feature = "prost"))]` gating for `Codec` and `check_oversize`, which are only used by the rustprotobuf backend (`Codec` provides the `encode()` trait method). Shared imports remain ungated. - README.md: fix "genereated" typo. - tests/run-examples.rs: remove a commented-out dead example2 call. Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
work continue with #173
Closes #258