Skip to content

Introduce BraveRpcService #6115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 20, 2025
Merged

Introduce BraveRpcService #6115

merged 12 commits into from
May 20, 2025

Conversation

jrhee17
Copy link
Contributor

@jrhee17 jrhee17 commented Feb 20, 2025

Motivation:

The motivation for this PR is better described in #6084

The changeset in this PR attempts to:

  • Expose ArmeriaHttpServerParser and ArmeriaRpcServerParser
    • By doing so, users can choose what information must be extracted from BraveService or BraveRpcService. This can provide more flexibility on whether to use only BraveService, only BraveRpcService, or both BraveService and BraveRpcService
  • Introduce BraveRpcService which allows users to perform sampling or request/response parsing based on RpcRequest

Modifications:

  • Added BraveRpcService. By default, armeria-specific tags/annotations recorded by BraveRpcService is the same as BraveService
  • Exposed ArmeriaHttpServerParser and ArmeriaRpcServerParser to allow users to easily construct a RpcTracing or HttpTracing

Result:

  • Users may use RpcRequest, RpcResponse to apply sampling/tags/annotations

@jrhee17 jrhee17 added this to the 1.33.0 milestone Feb 20, 2025
@jrhee17 jrhee17 force-pushed the feat/brave-rpc branch 2 times, most recently from 1c0572c to c53cb0a Compare February 21, 2025 05:39
@jrhee17 jrhee17 marked this pull request as ready for review February 21, 2025 08:07
* Decorates an {@link RpcService} to trace inbound {@link RpcRequest}s using
* <a href="https://github.com/openzipkin/brave">Brave</a>.
*/
public final class BraveRpcService extends SimpleDecoratingRpcService {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question) Is it possible to share the common logic with BraveService by adding AbstractBraveService and extending it, as you did in AbstractMetricCollectingClient?

super(delegate);
}

O serve0(ServiceRequestContext ctx, I req, BI braveReq, Span span) throws Exception {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This abstraction is slightly different from what I had in mind.
Instead of enforcing the subclass to call serve0() after preprocessing, should we handle all processes in AbstractBraveService but delegate the domain-specific part to the subclasses?

What do you think of this direction?

abstract class AbstractBraveService<BI extends brave.Request, BO extends brave.Response, ...>

    abstract BI braveRequest(ServiceRequestContext ctx, I req);

    abstract BO braveResponse(ServiceRequestContext ctx, RequestLog log, BI braveReq);

    abstract Span handleReceive(BI braveReq);

    abstract void handleSend(BO response, Span span);

    @Override
    public final O serve(ServiceRequestContext ctx, I req) throws Exception {
        if (!ctx.config().transientServiceOptions().contains(TransientServiceOption.WITH_TRACING)) {
            return unwrap().serve(ctx, req);
        }
        final BI braveReq = braveRequest(ctx, req);
        final Span span = handleReceive(braveReq);
        ...
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I understood the intention was to open the possibility to support more request types. Updated

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, IIRC, there was some duplicate code and there were functions for which subclasses had to call parent methods when implementing them.
My proposal is to allow implementations to focus only on domain-specific parts, without such constraints.

Copy link
Contributor

@ikhoon ikhoon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @jrhee17! 🙇‍♂️🙇‍♂️

Copy link
Contributor

@minwoox minwoox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some questions, but basically looks good. 👍

Comment on lines 75 to 78
abstract Tracer tracer();

abstract RequestContextCurrentTraceContext currentTraceContext();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracer and currentTraceContext are only used in AbstractBraverService, so how about passing them through the constructor instead?

@@ -41,53 +52,25 @@
* <li>address.local</li>
* </ul>
*/
final class ArmeriaHttpServerParser implements HttpRequestParser, HttpResponseParser {
public final class ArmeriaHttpServerParser {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Global comment: Could you add @UnstableApi?

@Nullable
@Override
public String errorCode() {
return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Is returning null okay?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if there is a way to reliably fetch an error code for thrift (or is there even a concept of error codes in thrift?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't aware of that either. Let's fix this later if it becomes an issue.

@Nullable
@Override
public Throwable error() {
final Object content = log.responseContent();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we use log.responseCause?

Comment on lines 2 to 4
* Copyright 2025 LINE Corporation
*
* LINE Corporation licenses this file to you under the Apache License,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Time to update the template?

Suggested change
* Copyright 2025 LINE Corporation
*
* LINE Corporation licenses this file to you under the Apache License,
* Copyright 2025 LY Corporation
*
* LY Corporation licenses this file to you under the Apache License,

Comment on lines 46 to 52
abstract BI braveRequest(ServiceRequestContext ctx);

abstract BO braveResponse(ServiceRequestContext ctx, RequestLog log, BI braveReq);

abstract Span handleReceive(BI braveReq);

abstract void handleSend(BO response, Span span);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we move these abstract methods down so they are grouped?

@@ -41,53 +52,25 @@
* <li>address.local</li>
* </ul>
*/
final class ArmeriaHttpServerParser implements HttpRequestParser, HttpResponseParser {
public final class ArmeriaHttpServerParser {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just BraveServerParsers? Any better names? 🤔

* <li>address.local</li>
* </ul>
*/
public final class ArmeriaRpcServerParser {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • @UnstableApi
  • How about merging this class into ArmeriaHttpServerParser and provide all factory methods there? e.g. BraveServerParsers.rpcRequestParser()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about merging this class into ArmeriaHttpServerParser and provide all factory methods there?

I was assuming that most users will be interested in Http related integrations only.
Do you prefer that libs.brave6.instrumentation.rpc is included with the api scope instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about merging this class into ArmeriaHttpServerParser and provide all factory methods there? e.g. BraveServerParsers.rpcRequestParser()

Just merged the class and added the dependency since it seems you prefer this way.

Comment on lines 2 to 4
* Copyright 2019 LINE Corporation
*
* LINE Corporation licenses this file to you under the Apache License,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2025 and LY

* Decorates an {@link RpcService} to trace inbound {@link RpcRequest}s using
* <a href="https://github.com/openzipkin/brave">Brave</a>.
*/
public final class BraveRpcService extends AbstractBraveService<RpcServerRequest, RpcServerResponse,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@UnstableApi?

jrhee17 and others added 3 commits April 10, 2025 11:36
…rmeriaHttpServerParser.java

Co-authored-by: Trustin Lee <trustin@linecorp.com>
…rmeriaRpcServerParser.java

Co-authored-by: Trustin Lee <trustin@linecorp.com>
Copy link

codecov bot commented Apr 10, 2025

Codecov Report

Attention: Patch coverage is 92.66055% with 8 lines in your changes missing coverage. Please review.

Project coverage is 74.62%. Comparing base (8150425) to head (23843d7).
Report is 78 commits behind head on main.

Files with missing lines Patch % Lines
.../server/brave/RpcServiceRequestContextAdapter.java 80.76% 3 Missing and 2 partials ⚠️
...corp/armeria/server/brave/ArmeriaServerParser.java 84.61% 0 Missing and 2 partials ⚠️
...orp/armeria/server/brave/AbstractBraveService.java 95.45% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #6115      +/-   ##
============================================
+ Coverage     74.46%   74.62%   +0.15%     
- Complexity    22234    22493     +259     
============================================
  Files          1963     1976      +13     
  Lines         82437    83062     +625     
  Branches      10764    10800      +36     
============================================
+ Hits          61385    61983     +598     
- Misses        15918    15929      +11     
- Partials       5134     5150      +16     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions bot added the Stale label May 11, 2025
@jrhee17
Copy link
Contributor Author

jrhee17 commented May 12, 2025

Let me go ahead and merge this next week (5/19) unless anyone has further comments

@github-actions github-actions bot removed the Stale label May 13, 2025
@jrhee17
Copy link
Contributor Author

jrhee17 commented May 20, 2025

Let me go ahead and merge this PR.

@jrhee17 jrhee17 merged commit 2bc4f17 into line:main May 20, 2025
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants