Skip to content
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 google-c2p resolver. #25215

Merged
merged 2 commits into from
Jan 26, 2021
Merged

Implement google-c2p resolver. #25215

merged 2 commits into from
Jan 26, 2021

Conversation

markdroth
Copy link
Member

As part of this, I've changed the Resolver API such that the base class no longer takes ownership of the WorkSerializer or ResultHandler. That will require internal changes, so I'll put together a cherry-pick for that once we're happy with this PR.

I don't really have a good way to test the C2P resolver, but I'm hoping that you can put together an interop test that will cover it.

@markdroth markdroth added the release notes: no Indicates if PR should not be in release notes label Jan 20, 2021
@markdroth markdroth requested a review from apolcyn January 20, 2021 18:59
void* arg, grpc_error* error) {
auto* self = static_cast<MetadataQuery*>(arg);
self->MaybeCallOnDone(error);
grpc_http_response_destroy(&self->response_);
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like a potentially use-after-free since we are destroying response_ here, but in MaybeCallDone we just potentially passed it to a closure scheduled on the work serializer.

Any reason to not destroy response_ in the MetadataQuery's dtor?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch! And yes, that's exactly the right fix. Done.

if (on_done_called_.CompareExchangeStrong(
&expected, true, MemoryOrder::RELAXED, MemoryOrder::RELAXED)) {
// Hop back into WorkSerializer.
Ref().release(); // Ref held by callback.
Copy link
Contributor

Choose a reason for hiding this comment

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

If I'm correct, we need to ref error here, since it's only current ref is the OnHttpRequestDone closure, which may finish before the work serializer closure runs?

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, I should have reffed it in the caller, because this function should take ownership of it, as per https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md#ownership-rules.

Fixed.

},
DEBUG_LOCATION);
} else {
GRPC_ERROR_UNREF(error);
Copy link
Contributor

Choose a reason for hiding this comment

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

related to above comment, isn't error's only ref held by the OnHttpRequestDone closure, so unreff'ing here is too much?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think the above fix covers this as well.


void GoogleCloud2ProdResolver::ZoneQueryDone(std::string zone) {
zone_query_.reset();
zone_ = std::move(zone);
Copy link
Contributor

Choose a reason for hiding this comment

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

since in case of error we will be filling in zone_ with the empty string, does TD understand an empty string zone?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. I've changed the code to not set the locality at all if zone_ is the empty string.

Copy link
Member Author

@markdroth markdroth left a comment

Choose a reason for hiding this comment

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

Thanks for the review!

void* arg, grpc_error* error) {
auto* self = static_cast<MetadataQuery*>(arg);
self->MaybeCallOnDone(error);
grpc_http_response_destroy(&self->response_);
Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch! And yes, that's exactly the right fix. Done.

if (on_done_called_.CompareExchangeStrong(
&expected, true, MemoryOrder::RELAXED, MemoryOrder::RELAXED)) {
// Hop back into WorkSerializer.
Ref().release(); // Ref held by callback.
Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, I should have reffed it in the caller, because this function should take ownership of it, as per https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md#ownership-rules.

Fixed.

},
DEBUG_LOCATION);
} else {
GRPC_ERROR_UNREF(error);
Copy link
Member Author

Choose a reason for hiding this comment

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

I think the above fix covers this as well.


void GoogleCloud2ProdResolver::ZoneQueryDone(std::string zone) {
zone_query_.reset();
zone_ = std::move(zone);
Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. I've changed the code to not set the locality at all if zone_ is the empty string.

Copy link
Contributor

@apolcyn apolcyn left a comment

Choose a reason for hiding this comment

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

LGTM

@markdroth
Copy link
Member Author

The test failures both look like infrastructure issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition/Needs Internal Changes release notes: no Indicates if PR should not be in release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants