-
Notifications
You must be signed in to change notification settings - Fork 104
Opencensus Tracing: Start tracing bidi streaming callables. #636
Conversation
This depends on googleapis#633 and is extracted from googleapis#613. This introduces TracedBidiCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations. google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions.
e7ad7d5 to
00d216a
Compare
|
Rebased & ready for review |
Codecov Report
@@ Coverage Diff @@
## master #636 +/- ##
===========================================
+ Coverage 75.57% 75.8% +0.22%
- Complexity 1008 1011 +3
===========================================
Files 187 188 +1
Lines 4365 4410 +45
Branches 343 344 +1
===========================================
+ Hits 3299 3343 +44
Misses 911 911
- Partials 155 156 +1
Continue to review full report at Codecov.
|
# Conflicts: # gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallableFactory.java
vam-google
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with a bunch of comments. None of the comments makes me think that this PR can't be merged as is, so LGTM, but please check the comments and address them before submitting.
| @@ -0,0 +1,220 @@ | |||
| /* | |||
| * Copyright 2018 Google LLC | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2019
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| /** | ||
| * A wrapper callable that will wrap a callable chain in a trace. | ||
| * | ||
| * <p>This class is meant to be an internal implementation google-cloud-java clients only. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the mention of google-cloud-java from the doc. Gax should be generator-specific and should not really know about google-cloud-java. In @InternalApi it is kind of ok, since the whole gist of the annotation is to talk about "internal stuff", but it is not ok in the actual documentation of the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| @Override | ||
| public void cancel() { | ||
| cancellationCauseHolder.compareAndSet( | ||
| null, new CancellationException("Cancelled without cause")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't CancellationException("Cancelled without cause") == CancellationException() in essence? If yes, please remove the description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
|
||
| @Override | ||
| public void onResponse(ResponseT response) { | ||
| tracer.responseReceived(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the order of calls make any difference here (or can make any at least potentially in a corner case)? It seems logical to report response received (i.e. call tracer) as a last statement, so the reporting is done when everything is really done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does, we don't want to include the caller's callback in the trace
| public void onError(Throwable t) { | ||
| Throwable cancellationCause = cancellationCauseHolder.get(); | ||
| if (cancellationCause != null) { | ||
| tracer.operationCancelled(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would be the value of Throwable t here? Can it really be dropped? Won't it be same as cancellationCause? If no, why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is outdated, I switched to using the TracedResponseObserver from the server streaming PR
|
|
||
| @Override | ||
| public void send(RequestT request) { | ||
| tracer.requestSent(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks suspicious: requestSent() (past tense) is called before send() (the actual "sending" operation seems like).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense if you consider the message leaving the callers control as sent
|
|
||
| @Override | ||
| public void closeSend() { | ||
| innerStream.closeSend(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this (and the method above) call any tracer.<something>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that closing the input stream important enough to trace and the closeSendWithError is the equivalent of calling cancel() on the future from unary callable: we trace both on the completion
| } | ||
|
|
||
| private static class FakeClientStream implements ClientStream<String> { | ||
| private List<String> sent = Lists.newArrayList(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not use the guava's <CollectionType>.new<CollectionType>() methods (here and in the other places). This is what is said for this method in guava's documentation:
Note for Java 7 and later: this method is now unnecessary and should be treated as deprecated. Instead, use the `ArrayList#ArrayList()` constructor directly, taking advantage of the new "diamond" syntax
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| } | ||
|
|
||
| private static class FakeBidiCallable extends BidiStreamingCallable<String, String> { | ||
| RuntimeException syncError; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why aren't these fields declared private as well? They are part of a private class, please make them private (so we do not need to check the visibility of the class itself determine the actual visibility level of the fields).
Same applies to FakeBidiObserver and FakeStreamController. It could by stylistic thing, but FakeClientStream has its fields declared as private explicitly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| } | ||
| } | ||
|
|
||
| private static class FakeStreamController implements StreamController { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can some of these Fake* classes be replaced with mocks? This one seems like it can.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed this class, but left the others because the fakes were easier to deal with
| ApiTracer tracer, | ||
| ResponseObserver<ResponseT> innerObserver, | ||
| AtomicReference<Throwable> cancellationCauseHolder) { | ||
| this.tracer = tracer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems identical to the Server Streaming PR, but it does not have null pointer check. It is either the null check is redundant there or missing here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I switched to the ResponseObserver from the server streaming PR
# Conflicts: # gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcCallableFactory.java
|
Thanks for reviewing! |
This depends on #633 and is extracted from #613.
This introduces TracedBidiCallables that will create a trace and complete it. It is inserted as one of the outermost links in the callable chain to allow all other callables to contribute their annotations.
google-cloud-java that extend the chains (like cloud bigtable) will also use this class to trace their extensions.