Skip to content

Instrumentation of Google Http Client#914

Merged
randomanderson merged 7 commits into
masterfrom
landerson/google-http-client
Jul 17, 2019
Merged

Instrumentation of Google Http Client#914
randomanderson merged 7 commits into
masterfrom
landerson/google-http-client

Conversation

@randomanderson
Copy link
Copy Markdown
Contributor

Instruments Google Http Client.

Support for both synchronous and asynchronous requests

@randomanderson randomanderson requested a review from a team as a code owner July 12, 2019 20:17
Copy link
Copy Markdown
Contributor

@tylerbenson tylerbenson left a comment

Choose a reason for hiding this comment

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

Great job on your first integration!
I think the async instrumentation still needs some work. I can help out if you need.


public static class GoogleHttpClientAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void methodEnter(@Advice.This final HttpRequest request) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since this is sync advice, I suggest returning the opened Scope the end of this method, then in the OnMethodExit, you can declare a @Advice.Enter method parameter reference that scope directly (and close it there). This way you don't need to use the contextStore.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Google does things different than other http clients in that there's no callback.
Paraphasing the code:

execute() { // do stuff }

Future executeAsync(Executor executor) {
   return executor.submit( this::execute);
}

The method advice around execute() happens in both modes, synchronous and asynchronous. And, in both modes, the span ends when execute returns.

The difference is whether the span starts on execute()-enter (synchronous case) or whether the span was started before execute()-enter (async case).

I'm using the contextStore to track the span that was created in the async method so that the same span can be populated when execute() is called

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the summary. I was expecting a bit more from the framework in terms of async support. The status quo is certainly underwhelming.

Looking at the code, since the primary distinction is that it schedules the same work on a different thread instead of running directly, I can see a good argument that we should just start the span when the request is made, not when it gets scheduled. What do you think?


@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void methodExit(
@Advice.This final HttpRequest request, @Advice.Thrown final Throwable throwable) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't understand how this advice is "async". It seems to wrap the method called, but not handle the callback or such.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

See above comment. In the normal case, methodExit of executeAsync() does nothing (execute() finishes the span). The only time methodExit needs to do something is if an exception was thrown when submitting to the executor: it finishes the span because execute() will never be called.

request.setThrowExceptionOnExecuteError(throwExceptionOnError)

HttpResponse response = executeRequest(request)
callback?.call()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This callback should be executed inside the async callback, not here...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There isn't a callback. Google's HttpClient returns a basic Future that you can call get() on. From the user's perspective, they only know the request is finished when get() returns.

Copy link
Copy Markdown
Contributor

@tylerbenson tylerbenson left a comment

Choose a reason for hiding this comment

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

I think this is good. In the future we should reevaluate how to allocate the "queuing time" vs "network time".

import com.google.api.client.http.HttpRequest
import com.google.api.client.http.HttpResponse

class GoogleHttpClientAsyncTest extends AbstractGoogleHttpClientTest {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is more of a stylistic thing, but I would have probably put these two options as nested classes of the parent class. Fine to leave as is though.


public static class GoogleHttpClientAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void methodEnter(@Advice.This final HttpRequest request) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the summary. I was expecting a bit more from the framework in terms of async support. The status quo is certainly underwhelming.

Looking at the code, since the primary distinction is that it schedules the same work on a different thread instead of running directly, I can see a good argument that we should just start the span when the request is made, not when it gets scheduled. What do you think?

@tylerbenson tylerbenson added this to the 0.31.0 milestone Jul 17, 2019
@tylerbenson tylerbenson added the inst: others All other instrumentations label Jul 17, 2019
@randomanderson randomanderson merged commit 0f9b28d into master Jul 17, 2019
@randomanderson randomanderson deleted the landerson/google-http-client branch July 17, 2019 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

inst: others All other instrumentations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants