FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Add ClientTransportFilter by joybestourous · Pull Request #10646 · grpc/grpc-java · GitHub

/ grpc-java Public

Add ClientTransportFilter - #10646

Merged
larry-safran merged 21 commits into
grpc:masterfrom
joybestourous:joy.bestourous/clienttransportfilter
Jan 3, 2024
Merged

Add ClientTransportFilter#10646
larry-safran merged 21 commits into
grpc:masterfrom
joybestourous:joy.bestourous/clienttransportfilter

Conversation

joybestourous commented Nov 3, 2023
edited
Loading

Copy link
Copy Markdown
Contributor

Problem
We're trying to add some stats on the number of connections opened, closed, and active on the client side for grpc-java. On the server side, ServerTransportFilter acts as a reasonable hook for this, but there doesn't seem to be anything comparable on the client side that I can find (if there is, please direct me to it!).

Closes #10647

Solution
Add a ClientTransportFilter. Similarly to ServerTransportFilter this will provide an observability hook and allows direct modification of the transport's attributes.
To wire this in, this PR also adds a filterTransport method to ManagedClientTransport.Listener which handles modifying the transport's attributes. This is called just before transportReady

joybestourous force-pushed the joy.bestourous/clienttransportfilter branch from dc9592d to a40996c Compare November 3, 2023 18:03
joybestourous changed the title Add ClientTransportFilter Add ClientTransportHook Nov 8, 2023
joybestourous marked this pull request as ready for review November 8, 2023 16:18
* to modify the channels or transport life-cycle event behavior, but they can be useful hooks
* for transport observability. Multiple filters may be registered to the client.
*/
@ExperimentalApi("https://gitub.com/grpc/grpc-java/issues/TODO")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Same as the other comment:

This should be a new ticket with "experimental API" label. Example: #10108.

I think it'd even make sense to use the same ticket to track both ClientTransportHook interface, and channel builder's addTransportHook().

@ejona86 - correct me if I'm wrong here

Co-authored-by: Sergii Tkachenko <hi@sergii.org>
larry-safran added the kokoro:force-run Add this label to a PR to tell Kokoro to re-run all tests. Not generally necessary label Nov 21, 2023
grpc-kokoro removed the kokoro:force-run Add this label to a PR to tell Kokoro to re-run all tests. Not generally necessary label Nov 21, 2023

Copy link
Copy Markdown
Contributor Author

👋 @ejona86 any update on this PR? is this still on track for v61 release?

ejona86 commented Dec 13, 2023
edited
Loading

Copy link
Copy Markdown
Member

Sorry I went silent on this. I had been hoping to sneak it into 1.60 but then issues with the release cropped up that ended up taking a lot of my time. (I actually didn't see your comment two days ago either...)

We discussed in our API review and the general verdict was "make it a filter like on server-side." Having it just be a hook caused a whole slew of naming/identity/purpose crises that are all solved by mirroring the existing server-side API. Before my time evaporated I was going to actually make the necessary plumbing change...

The listener could receive and return Attributes, just like is done on server-side. In OkHttpClientTransport, BinderTransport, InProcessTransport, CronetClientTransport look to be pretty easy to support (some places attributes would no longer be final; that's okay). NettyClientHandler could pass the Attributes through ClientTransportLifecycleManager.nofiyReady() and update the attributes on return.

But I think that would be inherently racy, in a way not present on server-side. transportReady() is when the client can start sending RPCs on the transport, so we'd need to synchronize the attribute update. On server-side, the server's transport thread can update the attributes before processing any RPCs from the connection.

So instead of adding Attributes to transportReady(), let's add a new method to ManagedClientTransport.Listener just to do this filtering. It can be called just before transportReady(). With a default implementation that just echos back the same attributes, I hope there's not even many tests that have to be updated.

ejona86 commented Dec 13, 2023

Copy link
Copy Markdown
Member

(FYI, the branch cut for 1.61 is a week earlier than normal, or maybe a bit more. So it is coming up soon. I'd be fine backporting this to the release, even though it is technically a feature, if we can do so at least a week before the release. If there's any bugs, seem they should only impact you and not destabilize others.)

Copy link
Copy Markdown
Contributor Author

Sorry I went silent on this. I had been hoping to sneak it into 1.60 but then issues with the release cropped up that ended up taking a lot of my time. (I actually didn't see your comment two days ago either...)

We discussed in our API review and the general verdict was "make it a filter like on server-side." Having it just be a hook caused a whole slew of naming/identity/purpose crises that are all solved by mirroring the existing server-side API. Before my time evaporated I was going to actually make the necessary plumbing change...

The listener could receive and return Attributes, just like is done on server-side. In OkHttpClientTransport, BinderTransport, InProcessTransport, CronetClientTransport look to be pretty easy to support (some places attributes would no longer be final; that's okay). NettyClientHandler could pass the Attributes through ClientTransportLifecycleManager.nofiyReady() and update the attributes on return.

But I think that would be inherently racy, in a way not present on server-side. transportReady() is when the client can start sending RPCs on the transport, so we'd need to synchronize the attribute update. On server-side, the server's transport thread can update the attributes before processing any RPCs from the connection.

So instead of adding Attributes to transportReady(), let's add a new method to ManagedClientTransport.Listener just to do this filtering. It can be called just before transportReady(). With a default implementation that just echos back the same attributes, I hope there's not even many tests that have to be updated.

Thanks for getting back to me! I addressed these suggestions, ptal and let me know if i understood you correctly. As for backporting this to 1.61, I think we're fine with waiting for 1.62 if you folks are at all worried about the risk. Thanks again!

joybestourous changed the title Add ClientTransportHook Add ClientTransportFilter Dec 18, 2023

ejona86 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

This looks good to me, other than some nits.

ejona86 added the kokoro:run Add this label to a PR to tell Kokoro the code is safe and tests can be run label Dec 18, 2023
ejona86 added this to the 1.61 milestone Dec 18, 2023
grpc-kokoro removed the kokoro:run Add this label to a PR to tell Kokoro the code is safe and tests can be run label Dec 18, 2023
ejona86 requested a review from larry-safran December 18, 2023 22:50
Co-authored-by: Eric Anderson <ejona@google.com>
sergiitk added the kokoro:run Add this label to a PR to tell Kokoro the code is safe and tests can be run label Dec 26, 2023
grpc-kokoro removed the kokoro:run Add this label to a PR to tell Kokoro the code is safe and tests can be run label Dec 26, 2023
sergiitk added the kokoro:run Add this label to a PR to tell Kokoro the code is safe and tests can be run label Dec 26, 2023
grpc-kokoro removed the kokoro:run Add this label to a PR to tell Kokoro the code is safe and tests can be run label Dec 26, 2023

Copy link
Copy Markdown
Member
/tmpfs/src/github/grpc-java/cronet/src/main/java/io/grpc/cronet/CronetClientTransport.java:172: error: cannot assign a value to final variable attrs
        attrs = CronetClientTransport.this.listener.filterTransport(attrs);
        ^

larry-safran commented Dec 26, 2023 via email

Copy link
Copy Markdown
Contributor

larry-safran added the kokoro:force-run Add this label to a PR to tell Kokoro to re-run all tests. Not generally necessary label Dec 28, 2023
grpc-kokoro removed the kokoro:force-run Add this label to a PR to tell Kokoro to re-run all tests. Not generally necessary label Dec 28, 2023

Copy link
Copy Markdown
Contributor

@joybestourous The builds failed because of CronetClientTransportTest. That test uses a mock for clientTransportListener which by default returns null for all of the methods. You will need to put a when clause into setUp() so that clientTransportListener.filterTransport(attr) just returns its argument.

For example:

when(clientTransportListener.filterTransport(any()).thenAnswer(i -> i.getArguments()[0])

ejona86 added the kokoro:run Add this label to a PR to tell Kokoro the code is safe and tests can be run label Jan 3, 2024
grpc-kokoro removed the kokoro:run Add this label to a PR to tell Kokoro the code is safe and tests can be run label Jan 3, 2024
larry-safran merged commit 91d15ce into grpc:master Jan 3, 2024

Copy link
Copy Markdown
Contributor Author

@joybestourous The builds failed because of CronetClientTransportTest. That test uses a mock for clientTransportListener which by default returns null for all of the methods. You will need to put a when clause into setUp() so that clientTransportListener.filterTransport(attr) just returns its argument.

For example:

when(clientTransportListener.filterTransport(any()).thenAnswer(i -> i.getArguments()[0])

Thanks for bringing this to completion 🙏 sorry I missed these errors my android setup was not working properly.

larry-safran commented Jan 3, 2024 via email

Copy link
Copy Markdown
Contributor

ejona86 commented Jan 11, 2024

Copy link
Copy Markdown
Member

#10805 is suspicious, and shouldn't be necessary. I feel like there's no harm happening at present with making the field volatile, but the fact TSAN is finding issues makes clear something is happening that we don't expect. So we aren't going to backport this into the 1.61 release. We'll probably try to remove the volatile before 1.62, but even if we don't, at that point it will have seen enough testing that we are then more confident it won't cause an issue.

Copy link
Copy Markdown
Contributor Author

#10805 is suspicious, and shouldn't be necessary. I feel like there's no harm happening at present with making the field volatile, but the fact TSAN is finding issues makes clear something is happening that we don't expect. So we aren't going to backport this into the 1.61 release. We'll probably try to remove the volatile before 1.62, but even if we don't, at that point it will have seen enough testing that we are then more confident it won't cause an issue.

Oh hm that's super surprising / suspicious. Makes complete sense to put this in 1.62. Thanks for the heads up!

github-actions Bot locked as resolved and limited conversation to collaborators Apr 12, 2024
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Client-side transport hooks

5 participants


Back | FazBrowse Home | New Git URL