-
Notifications
You must be signed in to change notification settings - Fork 4k
Implement missing authority API for HandlerRegistry #2709
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
Implement missing authority API for HandlerRegistry #2709
Conversation
|
Thanks for your pull request. The automated tests will run as soon as one of the admins verifies this change is ok for us to run on our infrastructure. |
|
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed, please reply here (e.g.
|
|
@ejona86 I've implemented this PR per your recommendations on IRC. |
ejona86
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.
Looks pretty good. Only small changes necessary.
It could use two tests or so.
| @GuardedBy("this") | ||
| private Set<InProcessStream> streams = new HashSet<InProcessStream>(); | ||
| @GuardedBy("this") | ||
| private String authority; |
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.
Make this final, and no need for the @GuardedBy then. (See comment below about the setter)
| public void setAuthority(String string) { | ||
| // TODO(ejona): Do something with this? Could be useful for testing, but can we "validate" | ||
| // it? | ||
| authority = string; |
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 set only impacts this one stream. So add another field for the authority to the stream. You can initialize it from the transport's value.
| private String getOrUpdateAuthority(AsciiString authority) { | ||
| if (authority == null) { | ||
| return ""; | ||
| } else if (lastKnownAuthority == null || !lastKnownAuthority.equals(authority)) { |
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.
If you invert the equals check you can avoid the null check. !authority.equals(lastKnownAuthority)
| } | ||
|
|
||
| @Override | ||
| public String getAuthority() { |
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.
Given that HandlerRegistry is the only thing that is using the value from getAuthority() currently, and it is @Nullable, I would still feel better by defaulting to null. Here and in NettyServerHandler.
It's something we can change in the future though. We'll probably deal with it when we expose getAuthority() on ServerCall. At that point we may make it non-null where empty string is explicitly called out in the API.
|
I signed it! |
|
CLAs look good, thanks! |
| private Set<InProcessStream> streams = new HashSet<InProcessStream>(); | ||
|
|
||
| public InProcessTransport(String name) { | ||
| public InProcessTransport(String name, String authority) { |
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 would be API breaking.
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.
No, it isn't. InProcessTransport itself is package-private.
| public void setAuthority(String string) { | ||
| // TODO(ejona): Do something with this? Could be useful for testing, but can we "validate" | ||
| // it? | ||
| InProcessStream.this.authority = string; |
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 would not be thread safe
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.
InProcessStream.this.authority is now volatile. Setting and reading references are atomic in Java. Strings are immutable. This should be thread safe now, right?
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.
Actually, it was fine as it was before (without volatile). setAuthority "May only be called before start."
|
@ejona86 @carl-mastrangelo Test cases added and feedback addressed. |
|
I can't reproduce the |
|
Jenkins, okay to test. |
|
okay to test |
| lastKnownAuthority = authority; | ||
| } | ||
|
|
||
| // AsciiString.toString() is internally cached, so subsequent calls will not |
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 not efficient enough. If the client changes the authority every request and the server doesn't read from it, it will unnecessarily convert it. Why not do the conversion when getAuthority is called?
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.
getAuthority() is always called.
This is plenty efficient enough. It doesn't hinder the common case at all.
Most clients, by far, won't change the authority every request. And even if they do change constantly, then any optimization here would probably be in the noise.
I'd rather get to a point we can call good enough for now and any future optimization for edge cases gets included with the HPACK tricks we're planning.
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 talked with Carl. He showed me that getAuthority() isn't always called, since it is only called when the immutable lookup fails. But we also agreed that it will 99% of the time always be the same authority. And we also believe that the HPACK table will even make it the same AsciiString instance. So Carl is now okay with this. He would still like to have our nice HPACK stuff, but that's orthogonal and future work.
|
Thank you for implementing this! I'm sorry that I didn't do it initially, but I'm glad you were able to. |
HandlerRegistry.lookupMethod(String methodName, String authority)is never never invoked with a non-null authority string. Per the discussion on the mailing list, I implemented this method.https://groups.google.com/forum/#!topic/grpc-io/1RPka9CKAvE