Skip to content

getAttributes() always empty if called from SimpleForwardingClientCall #4118

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

Closed
maseev opened this issue Feb 23, 2018 · 7 comments
Closed

getAttributes() always empty if called from SimpleForwardingClientCall #4118

maseev opened this issue Feb 23, 2018 · 7 comments

Comments

@maseev
Copy link

maseev commented Feb 23, 2018

What version of gRPC are you using?

1.10.0

What did you expect to see?

Let's say we have the following client interceptor which is attached to our channel:

class LoggingClientInterceptor implements ClientInterceptor {

  private static final Logger log = LoggerFactory.getLogger(LoggingClientInterceptor.class);

  @Override
  public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
      CallOptions callOptions, Channel next) {
    return new SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
      @Override
      public void start(Listener<RespT> responseListener, Metadata headers) {
        log.info("grpc request; method: {}, attributes: {}", method.getFullMethodName(),
            getAttributes());

        super.start(responseListener, headers);
      }
    };
  }
}

When calling the getAttributes() method I expected to see a set of attributes which contains at least the information about the server to which the client is going to make a request to. Unfortunately, getAttributes() method always empty.

@maseev maseev changed the title getAttributes() is always empty if called from SimpleForwardingClientCall getAttributes() always returns an empty collection if called from SimpleForwardingClientCall Feb 23, 2018
@dapengzhang0
Copy link
Member

You seems to call getAttributes() too early that the call is not completely started. The safest timing to call getAttributes() is after the ClientCall.Listener receives anything, say after ClientCall.Listener::onHeader() is called.

@maseev
Copy link
Author

maseev commented Feb 24, 2018

Yes, you're right. According to the javadoc, the getAttributes() method may only be called after ClientCall.Listener.onHeaders(io.grpc.Metadata) or ClientCall.Listener.onClose(io.grpc.Status, io.grpc.Metadata). Unfortunately, it doesn't work either. Here's the updated version of the client interceptor:

class LoggingClientInterceptor implements ClientInterceptor {

  private static final Logger log = LoggerFactory.getLogger(LoggingClientInterceptor.class);

  @Override
  public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
      CallOptions callOptions, Channel next) {
    return new SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
      @Override
      public void start(Listener<RespT> responseListener, Metadata headers) {
        final SimpleForwardingClientCallListener<RespT> listener =
            new SimpleForwardingClientCallListener<RespT>(responseListener) {
              @Override
              public void onMessage(RespT response) {
                log.debug("grpc response; method: {}, attributes: {}, response: {}",
                    method.getFullMethodName(), getAttributes(), response);
                super.onMessage(response);
              }
            };

        super.start(listener, headers);
      }

      @Override
      public void sendMessage(ReqT request) {
        log.debug("grpc request; method: {}, request: {}", method.getFullMethodName(), request);
        super.sendMessage(request);
      }
    };
  }
}

And again, I get the empty set of attributes when I call getAttributes().
If I understand correctly (according to my logs), the default "lifecycle" of the client call with the attached listener looks like the following:

ClientCall::start
ClientCall::sendMessage
ClientCall.Listener::onReady
ClientCall.Listener::onHeaders
ClientCall.Listener::onMessage
ClientCall.Listener::onClose

So, it should be pretty safe to call the getAttributes() method from the ClientCall.Listener::onMessage, according to the documentation. Maybe I'm missing something.

@maseev maseev changed the title getAttributes() always returns an empty collection if called from SimpleForwardingClientCall getAttributes() always empty if called from SimpleForwardingClientCall Feb 26, 2018
@dapengzhang0
Copy link
Member

@maseev , what attribute are you expecting? What transport are you using: Netty, OkHttp, or InProcess?

@maseev
Copy link
Author

maseev commented Feb 27, 2018

@dapengzhang0 I'm expecting an attribute which contains the information about the server to which the client is going to send a request. I'm using the Netty transport.

@zpencer
Copy link
Contributor

zpencer commented Feb 27, 2018

Do you happen to be using plaintext?

@dapengzhang0
Copy link
Member

dapengzhang0 commented Feb 27, 2018

+1

Do you happen to be using plaintext?

@maseev, your updated interceptor will work correctly. But if you are using plaintext, no attributes will be added by the grpc library. If you are using Netty transport with TLS, two attributes may be added:
Grpc.TRANSPORT_ATTR_SSL_SESSION and Grpc.TRANSPORT_ATTR_REMOTE_ADDR

@maseev
Copy link
Author

maseev commented Feb 28, 2018

Oh, I didn't know that. I do use plaintext actually. I guess that explains everything. Thank you for your help @zpencer @dapengzhang0.

@maseev maseev closed this as completed Feb 28, 2018
@lock lock bot locked as resolved and limited conversation to collaborators Sep 28, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants