Implement Interceptor API - #8
Open
sauravzg wants to merge 8 commits into
Open
Conversation
This was referenced Jan 13, 2026
Owner
Author
|
This PR is part of a stack of 13 bookmarks:
Created with jj-stack |
This was referenced Jan 13, 2026
Open
Open
sauravzg
force-pushed
the
codec_handlers
branch
from
January 21, 2026 22:19
cbe817b to
9a0a210
Compare
sauravzg
force-pushed
the
interceptor_api
branch
2 times, most recently
from
January 21, 2026 22:24
24c761b to
7fd3354
Compare
sauravzg
force-pushed
the
codec_handlers
branch
from
January 21, 2026 22:24
9a0a210 to
27a4a31
Compare
These traits are supposed to provide abstractions over standard references and protobuf views and muts to eliminate hard dependency on protobuf The biggest challenge in the message module is to solve the long-standing difficulty of reborrowing mutable message views. The Problem: Reborrowing GATs When working with Generic Associated Types (GATs) for mutable views (e.g., type Mut<'a>), we frequently need to "reborrow" a view to pass it to a child function without consuming the original. However, traditional approaches fail here: 1. Foreign Types: We cannot add a .reborrow() method directly to protobuf::Mut as it is a foreign type. 2. HRTB Hell: Defining a separate Reborrow trait and requiring for<'a> T::Mut<'a>: Reborrow leads to complex Higher-Ranked Trait Bound errors (e.g., "implementation is not general enough") that are extremely difficult to satisfy in Rust's current type system. The Solution: Static Operator Pattern We bypass these issues by moving the reborrowing logic into the provider trait itself as a static operator. * Introduced AsMut::reborrow_view<'a, 'b>(view: &'b mut Self::Mut<'a>) -> Self::Mut<'b>. * This bundles the reborrowing logic with the type definition, avoiding the need for extra traits or complex HRTB bounds on the view type itself. Changes: * as_mut.rs: Defined AsMut with the reborrow_view static operator. Implemented it for protobuf::Message and added tests verifying that views can be reborrowed and mutated without consuming the original. * as_view.rs: Defined AsView for immutable views.
…terns This change introduces an initial implementation of the stream API, designed to mimic the API surface of Google's internal C++ versions. Key Highlights: * **API Mimicry**: This implementation mimics the API but does not reflect the true implementation of the internal C++ versions. It is currently functionally incomplete, particularly regarding context management between the producer and the writer. * **Dynamic Traits**: We have chosen to use `dyn` traits to allow for simpler injection of functors. This implementation is currently sufficient to enable experimental development against this form of API. We plan to improve functionality and performance in future iterations.
Introduce the public API traits for server-side gRPC methods (`UnaryMethod`, `ClientStreamingMethod`, `ServerStreamingMethod`, `BidiStreamingMethod`). These traits are designed to be the primary interface for codegen. Currently, the API utilizes Google's internal StreamAPIs (e.g., `PushStream`). We plan to eventually support Tonic-like APIs and adapt the implementation later; this step is primarily to unblock server-side implementation progress. Note on design: - The public API is scoped to access request and response messages only. - Modifications to headers and trailers are intended to be handled via "interceptor" APIs, following the Java gRPC model. - Contextual information is expected to be accessed via a read-only local context.
…c API This change introduces data objects for the internal generic API. We introduce separate objects for Unary and Streaming (e.g., `UnaryRequest` vs `StreamingRequest`, `UnaryResponseWriter` vs `StreamingResponseWriter`) as unifying reference and owned APIs proved difficult. The input side (`UnaryRequest`, `StreamingRequest`) is straightforward, providing access to metadata and the message/stream. The output side (`StreamingResponseWriter`) is slightly nuanced, offering a "staged builder" like API: 1. `send_initial_metadata(metadata)` transitions to a `BodyWriter`. 2. The `BodyWriter` allows writing the actual stream and sending trailers. A unit test (`test_interceptor_composition`) is added to demonstrate how a writer can be intercepted, which is more nuanced than intercepting the read input stream. UnaryMethod ByteStream Handler Unary stuff Refactor message traits call changes Change hander call options(might probably be deleted) since call options shouldn't contain metadata.
…r handling all types of gRPC methods on the server side, along with adapters for specific method types. Key changes: - Introduce `StreamingMethodHandler` trait to provide a common interface for method execution. - Add `UnaryMethodAdapter`, `ServerStreamingAdapter`, `ClientStreamingAdapter`, and `BidiStreamingAdapter` to bridge specific method traits to the unified handler. Note that `ServerStreamingHandler` (via `ServerStreamingAdapter`) is currently not "zero-cost". It uses a `tokio::sync::oneshot` channel to retrieve the request before sending it to the application handler. This approach was adopted to avoid complex lifetime issues encountered with inline stream writer chaining without interior mutability. Optimization of this path is deferred to future work. Migrate to V2 API
ser changes
This change introduces the `Interceptor` trait and associated infrastructure for intercepting gRPC calls on the server side. The new `interceptor` module includes: - `Interceptor` trait: The core abstraction with `intercept_unary` and `intercept_streaming` methods. - `InterceptorExt` trait: Provides a `chain` combinator for composing multiple interceptors. - `InterceptedMethodHandler`: Wraps a `MethodHandler` with an `Interceptor`, allowing interception logic to wrap the inner handler execution. - `ChainedInterceptor`: Implements the composition of two interceptors. The design supports both generic operations (e.g., logging, metrics) and type-specific inspection (via message downcasting). Add ByteStream Interceptor
sauravzg
force-pushed
the
codec_handlers
branch
from
February 24, 2026 16:53
27a4a31 to
889c1d6
Compare
sauravzg
force-pushed
the
interceptor_api
branch
from
February 24, 2026 16:53
7fd3354 to
6b29331
Compare
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.