Conversation
- grpcurl list doesn't work for undertow (sadly)
…propagation - **Refactor to fully reactive I/O:** Removed the blocking `GrpcHandler` (which relied on `InputStream.readNBytes`) and promoted `UnifiedGrpcBridge` to the primary `Route.Handler`. - **Zero-copy ByteBuffer pipeline:** Migrated `GrpcDeframer` and `GrpcRequestBridge` to consume `Flow.Subscriber<ByteBuffer>` instead of `byte[]`. This allows Netty, Undertow, and Jetty to pipe native socket buffers directly into the gRPC state machine without intermediate array allocations. - **Backpressure integration:** Wired gRPC's `ClientCallStreamObserver.setOnReadyHandler` directly to Jooby's `Flow.Subscription`, ensuring the server only demands more data when the internal gRPC buffers are ready. - **Context propagation:** Added parsing and propagation of the `grpc-timeout` header into gRPC `CallOptions` (deadlines). - **Metadata propagation:** Added HTTP header to gRPC `Metadata` mapping via `ClientInterceptors`, including base64 decoding for `-bin` suffixed headers. - **Server Reflection upgrade:** Swapped the deprecated `v1alpha` reflection service for the stable `ProtoReflectionServiceV1`. - **Testing:** Added comprehensive unit tests for `GrpcDeframer` fragmentation/coalescing logic and `GrpcRequestBridge` backpressure state handling.
This commit removes the gRPC module's tight coupling to Jooby's core request lifecycle (`Context` and `Sender`) and introduces a clean, zero-dependency Service Provider Interface (SPI). This prevents gRPC specifics (like HTTP/2 trailers and framing) from polluting the standard HTTP/1.1 pipeline. Core changes: - Add `GrpcExchange` and `GrpcProcessor` SPI to `jooby-core`. - Refactor `UnifiedGrpcBridge` to act as a pure protocol bridge using Java `Flow` and `ByteBuffer`, entirely isolated from web core classes. - Fix circular dependencies in the reactive `GrpcRequestBridge`. Server Implementations: - Jetty: Implement `JettyGrpcExchange` and `JettyGrpcInputBridge`. Fixed early commit issues by eagerly registering `TrailersSupplier`. - Netty: Implement `NettyGrpcExchange` and `NettyGrpcInputBridge`. Map trailing headers natively via `LastHttpContent` and properly intercept HTTP/2 pipeline streams. - Undertow: Implement `UndertowGrpcExchange`, `UndertowGrpcInputBridge`, and remove hardcoded gRPC checks from standard `UndertowHandler`. Fixed XNIO non-blocking event loop stalls using `wakeupReads()` and implemented manual, synchronous `StreamSinkChannel` flushing to prevent bidirectional deadlocks. All three servers now handle reactive backpressure natively and achieve 100% compliance with strict HTTP/2 clients like `grpcurl`.
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.
This feature introduces first-class, native gRPC support to Jooby. It allows developers to run standard REST APIs and gRPC services side-by-side on the exact same port, sharing the same underlying HTTP/2 web server (Netty, Undertow, or Jetty) without sacrificing performance or specification compliance.
Key Features
FlowAPI. The bridge natively translates gRPC'sStreamObserverbackpressure to the underlying socket demand.ProtoReflectionService, making it instantly compatible with tools likegrpcurland Postman.Example Usage
Adding a gRPC service is as simple as installing the new
GrpcModuleand passing in your generatedBindableServiceimplementations: