Add a simple `StreamMessageAndWriter` for a dedicated event loop
See original GitHub issueA DefaultStreamMessage is a thread-safe StreamMessageAndWriter for multiple producder.
Some technics are used for concurrency such as:
MpscChunkedArrayQueuehttps://github.com/line/armeria/blob/f0252bd457cc5e4fd3e70382debfb8cbadd74bbb/core/src/main/java/com/linecorp/armeria/common/stream/DefaultStreamMessage.java#L106- Some volatile fields https://github.com/line/armeria/blob/f0252bd457cc5e4fd3e70382debfb8cbadd74bbb/core/src/main/java/com/linecorp/armeria/common/stream/DefaultStreamMessage.java#L89-L97
- CAS operations https://github.com/line/armeria/blob/f0252bd457cc5e4fd3e70382debfb8cbadd74bbb/core/src/main/java/com/linecorp/armeria/common/stream/DefaultStreamMessage.java#L478
In some cases, we can write and read elements in a single event loop.
For example, the HttpObjects for DecodedHttpRequest and DecodedHttpResponse are always written in an event loop with channelRead event.
https://github.com/line/armeria/blob/002e24970fb71cbf7bb27697f95367499a19588c/core/src/main/java/com/linecorp/armeria/client/Http1ResponseDecoder.java#L185
https://github.com/line/armeria/blob/6f93315ba003f167788d5f4f1c6d7464387444bc/core/src/main/java/com/linecorp/armeria/server/Http1RequestDecoder.java#L248
Furthermore, we don’t directly expose the DecodedHttpRequest and DecodedHttpResponse for gRPC services and clients. It also is subscribed by the event loop which is used for writing.
https://github.com/line/armeria/blob/207c5e038f59802dca769936a50e219a5fe308ea/grpc/src/main/java/com/linecorp/armeria/server/grpc/ArmeriaServerCall.java#L645-L649
It would be efficient to add a non-thread-safe version of StreamMessageAndWriter and use it for handling encoding and decoding HTTP layer for gRPC service and client.
Issue Analytics
- State:
- Created 2 years ago
- Comments:10 (10 by maintainers)

Top Related StackOverflow Question
That is true for HTTP protocol and REST. A HttpRequest and Response is directly exposed to users with
HttpServiceandWebClient. Users can subscribe to thePublisherwith their ownSubscriber. Some thread safety is required for thePublisher.However, We don’t expose our
HttpRequestto users for gRPC services.ArmeriaServerCallsubscribes toHttpRequestwithctx.eventLoop()for decoding gRPC framesStreamObserverThough a service is RPC, a
HttpRequestis exposed to users by decorators. But users can not subscribe to thePublisherdirectly because Armeria’sStreamMessageshould be subscribed only once. I think the stream duplicator could take care of the safety for decorators.Agreed. We don’t need to use
MpscChunkedArrayQueuefor decoded request and response.Prepration: Extract the media type defined in
GrpcSerializationProvidertoMediaTypesuch asMediaType.GRPC,MediaType.GRPC_JSONand so on. It is also convenient to add a utility for gRPC media type -mediaType.isGrpc(). https://github.com/line/armeria/blob/9e601afd504a4cb31f6e811cb66b9c535dd026d3/grpc/src/main/java/com/linecorp/armeria/internal/common/grpc/GrpcSerializationFormatProvider.java#L35-L41Predicate:
armeria-grpcshould be added as a dependency. We can statically know withClass.forName("c.l.a.g.GrpcService").StreamMessageifreq.contentType().isGrpc()returns true.subscribeStreamMessageDuplicatormust be used for subscribing to a stream from outside ofService. The following Javadoc would help you learn the mechanism. https://github.com/line/armeria/blob/87602a8d52bb94c8bfdec28f48687d3ee4100192/core/src/main/java/com/linecorp/armeria/common/stream/StreamMessageDuplicator.java#L29-L43abortabort()with in the event loop inDecodedHttpRequest. https://github.com/line/armeria/blob/dbfc1cdbbacb7c15d8128b5b40972de28a82930e/core/src/main/java/com/linecorp/armeria/server/DecodedHttpRequest.java#L48