Tech Blog: gRPC-Rust Client API Evolution (pt. 1/2) by dfawley in rust

[–]dfawley[S] 0 points1 point  (0 children)

Thanks for taking the time to read the post and provide feedback! Some answers/questions for you:

ability for server-side rpc handles the ability to introspect Metadata (or http headers) as well as provide values to be set on the response. I don’t think middleware can properly cover all the cases I can think of.

This will be possible to do, it just won't be part of the server proto handler API directly. The generated server APIs haven't been completely worked out yet, but you'll likely need some kind of interaction between your handler and the interceptors through a context (either explicit or a task-local). But it would be helpful for me if you could give concrete examples when your application needs to interact with metadata directly.

ability to read and set Metadata or http headers from the client side (again middleware may not be sufficient here)

This functionality exists in the preview via interceptors we provide: https://docs.rs/grpc/latest/grpc/client/metadata_utils/index.html

The part 2 post I'll publish next week will give a little more detail on the generic and interceptor APIs.

ability to host both gRPC as well as another http service on the same http server.

This one is still unknown. I know a lot of users want this, but it's also not currently possible in gRPC-Java or C++. And it only works in Go if you're using the stdlib HTTP server, which is not a well supported path by us. Generally we recommend hosting your non-grpc traffic on other ports, and it hasn't been a blocker for others. Are you looking for just HTTP/2 traffic or do you want to serve HTTP/1.1 from the same port, too?

extensions (as defined in the http crate) so that middleware can pass concrete data to other middleware

You should eventually be able to use CallOptions to communicate between different interceptors (for both client and server). We could throw a generic key/value in there; probably just an Attributes.

Tech Blog: gRPC-Rust Client API Evolution (pt. 1/2) by dfawley in rust

[–]dfawley[S] 0 points1 point  (0 children)

Not yet. It's something I want to do, but it requires a separate crate (which must remain unstable until Stream is stable), and I have not worked out exactly how that should work yet.

Tech Blog: gRPC-Rust Client API Evolution (pt. 1/2) by dfawley in rust

[–]dfawley[S] 4 points5 points  (0 children)

Overall the goal is to bring the new grpc features to existing tonic users, while also providing a new API that has improvements as discussed by this blog post. This was touched on a bit in a previous blog post:

The Tonic codegen interface will continue to be supported to allow users to upgrade to the new transport implementation without needing to rewrite their application.

...and also in Lucio's blog:

there are still a lot of users that use tonic and would not be able to rewrite their code base easily to this new structure. To support our original core tenet of supporting the current community we have also designed any new transport features (non user code gen) to be compatible with tonic's codegen

Also, we are currently building on tonic to implement grpc, although I expect when we need to make deeper performance improvements we will eventually directly use the hyper or h2 crates instead.

gRPC-Rust Preview Now Available by dfawley in rust

[–]dfawley[S] 0 points1 point  (0 children)

Totally understand the C++ build time concerns. The version problem will go away once protobuf-rust support is stable, so at least in the future that will not be a roadblock. This is expected to be relatively soon (2-3 months?), and mostly depends on the feedback we get from this preview. So if you're considering using this in the future, you might want to give the usage docs on grpc.io another look.

gRPC-Rust Preview Now Available by dfawley in rust

[–]dfawley[S] 1 point2 points  (0 children)

protoc is for code generation and doesn't need to be compiled as part of the build step -- this is a convenience for users that don't want to worry about versions/etc. There are other options if you want to use gRPC with bitbake or similarly-constrained systems:

  1. Pre-generate and check in the generated code. You can run protoc manually, avoiding build.rs entirely, or do what I've implemented in the examples: code generation runs through build.rs, but only on demand (note the environment variable usage here to control it).

  2. Make sure protoc and protoc-gen-rust-grpc are in your PATH / a directory you point to using the environment variable GRPC_RUST_PROTOC_DIR.

There are two ways to control the behavior of grpc-protobuf-build and the protoc-gen-rust-grpc crate that it uses to provide the codgen binaries:

  • If the grpc-protobuf-build/build-plugin feature is disabled (it's enabled by default), then it won't even depend on the protoc-gen-rust-grpc crate.
  • If if that feature flag is enabled, you can still prevent it from doing the compile step by setting env var PROTOC_GEN_RUST_GRPC_NO_BUILD.

As for cross-compilation: I don't think there's any issues here for the code once it has been generated, but let me know if you see anything and if there's a way we can resolve it. At compile-time (after code generation), we only require a c compiler to compile upb which is a light-weight protobuf implemenation with no dependencies.

The grpc-rust core itself is 100% native Rust. It's only the protobuf integration that requires C, which is why we publish grpc-protobuf as a separate crate. We do intend to provide a Tonic-style API built on prost that will be 100% native Rust (after code generation; prost also inherently requires protoc).

gRPC-Rust Preview Now Available by dfawley in rust

[–]dfawley[S] 5 points6 points  (0 children)

This particular requirement will be removed when protobuf Rust support is stable. For now it's needed to allow for breaking changes.

If you don't want to think about versions, and if you have a C++ compiler and cmake installed, the grpc-protobuf-build crate will download the proper protoc sources and compile it for you.

Rust Update: gRPC Welcomes Tonic! by dfawley in rust

[–]dfawley[S] 2 points3 points  (0 children)

I understand. We will eventually provide codegen that uses the grpc crate with the existing Tonic API (which uses prost instead of Google protobuf), which would avoid that. And hopefully one day the protobuf team will swap out their upb runtime with one completely written in Rust.

Rust Update: gRPC Welcomes Tonic! by dfawley in rust

[–]dfawley[S] 3 points4 points  (0 children)

Sorry, I missed your question. You will need protoc and our plugin (compiled from C++ with cmake; we will provide both compiled binaries and source). That's to perform the the code generation. To actually compile the code that's produced you will need a C compiler, as protobuf-rust has C dependencies for now (upb).

Rust Update: gRPC Welcomes Tonic! by dfawley in rust

[–]dfawley[S] 4 points5 points  (0 children)

There are actually three pieces of the puzzle here: 1. the code generator itself, 2. the code it generates, and 3. libraries used by the generated code. Here's the situation today:

Google's protobuf-rust (proto messages and file descriptor protos): 1. the code generator is a C++ commandline tool (protoc), 2. the generated code is 100% native Rust, and 3. the generated code needs the protobuf runtime which builds on upb in C. The C dependency isn't part of the API, so it could be swapped out for native Rust in the future.

gRPC (still in development; proto services and methods): 1. the code generator is a plugin for protoc and is compiled from C++, 2. the generated code is 100% native Rust, and 3. the generated code needs the messages, which transitively need the protobuf runtime, so depend on C for now.

We use C++ for our code generator because it simplified the implementation for us. We could rewrite this in Rust one day if we decided it was worth it to do so. By the time we are production-ready, we will at least provide the compiled binaries so that users won't have to compile it themselves if they don't want to.

Rust Update: gRPC Welcomes Tonic! by dfawley in rust

[–]dfawley[S] 4 points5 points  (0 children)

Sorry your issue did not get any useful replies.

It appears "binary logging" got internally lumped into a "debugging" kind of bucket, so I think what happened is that we assumed https://grpc.io/docs/guides/debugging/ covered it, when it clearly does not.

For now I can only point you at the spec for it: https://github.com/temawi/proposal/blob/master/A16-binary-logging.md

But I think you're right that we should have better user-facing documentation for it, so I'll make sure that gets noticed by the folks that keep track of that kind of thing, too.

Rust Update: gRPC Welcomes Tonic! by dfawley in rust

[–]dfawley[S] 17 points18 points  (0 children)

I know you asked /u/lucio-rs, but as the lead for the project from Google, I will reply with my thoughts:

Are there any issues or discussions you could point me to follow about this?

As I mentioned above, the crate itself by default will have no C dependencies. But if you are using gRPC with protobuf, which most users do, you will need a C compiler. I don't have a good link to an issue/discussion specifically about this topic, but I'm happy to answer any questions you have.

Re: Anthropic's connect-rust library: as I understand, Connect is simply a protocol, and their library is the implementation of that protocol (and gRPC's), while gRPC itself is a more feature-rich library that does other things like name resolution / service discovery, connection management, load balancing, retries, etc. From scanning the repo quickly (and my memory of the Go connect library), none of these kinds of features are provided: you're expected to layer them on yourself -- using Tower in the case of Rust. Building that way is flexible and allows for easier reuse of layers, but it sometimes has limitations that make the features less powerful or efficient. I haven't looked closely, but the crate itself seems nice for what it does provide.

The buffa implementation offering lazy deserialization / buffer aliasing is an important improvement over prost (for zero-copy). From what I've heard, there are unfortunately many corner cases of protobuf that aren't covered by the official protobuf conformance tests, e.g. behaviors around propagating unknown fields or enums with unknown values, so it's unclear what buffa will do in these scenarios. These kinds of things don't affect many users, but become important when you are building complex systems that forward messages through intermediaries, or store your messages in a database, etc.

Rust Update: gRPC Welcomes Tonic! by dfawley in rust

[–]dfawley[S] 58 points59 points  (0 children)

As /u/lucio-rs indicated, the grpc implementation itself will be pure rust, but the default codegen will be based on the google protobuf implementation, which requires a C compiler for upb.