Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: Bidi uses metadata from start_rpc#205

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
busunkim96 wants to merge1 commit intomasterfrombidi-metadata

Conversation

@busunkim96
Copy link
Contributor

@busunkim96busunkim96 commentedJun 10, 2021
edited
Loading

Allow Bidi to use metadata from start_rpc when no other metadata
is provided.

This allowsclient_info on wrapped client methods will be passed through toBidiRpc.

Fixes#202 🦕

Not expected to impact Firestore, as metadata is explicitly passed:https://github.com/googleapis/python-firestore/blob/e57258c51e4b4aa664cc927454056412756fc7ac/google/cloud/firestore_v1/watch.py#L220-L226

Pub/Sub does not seem to passmetadata and may be impacted:https://github.com/googleapis/python-pubsub/blob/e907f6e05f59f64a3b08df3304e92ec960997be6/google/cloud/pubsub_v1/subscriber/_protocol/streaming_pull_manager.py#L523-L528

Allow Bidi to use metadata from start_rpc when no other metadatais provided.
@snippet-bot
Copy link

No region tags are edited in this PR.

This comment is generated bysnippet-bot.
If you find problems with this result, please file an issue at:
https://github.com/googleapis/repo-automation-bots/issues.
To update this comment, addsnippet-bot:force-run label or use the checkbox below:

  • Refresh this comment

@google-clagoogle-clabot added the cla: yesThis human has signed the Contributor License Agreement. labelJun 10, 2021
@busunkim96busunkim96 added the kokoro:force-runAdd this label to force Kokoro to re-run the tests. labelJun 10, 2021
@yoshi-kokoroyoshi-kokoro removed the kokoro:force-runAdd this label to force Kokoro to re-run the tests. labelJun 10, 2021
call=self._start_rpc(iter(request_generator),metadata=self._rpc_metadata)
# use metadata from self._start_rpc if no other metadata is specified
else:
call=self._start_rpc(iter(request_generator))

Choose a reason for hiding this comment

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

When I set up BidiRPC withLoggingV2Transport().tail_log_entries, that's the unwrapped method, not the wrapped method. Will this still get the metadata from the wrapped method?

Choose a reason for hiding this comment

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

also, I tried passing in LoggingServiceV2Client().tail_log_entries and it didn't seem to work.

I'm actually not sure how pubsub passes in the wrapped method successfully.
https://github.com/googleapis/python-pubsub/blob/e907f6e05f59f64a3b08df3304e92ec960997be6/google/cloud/pubsub_v1/subscriber/_protocol/streaming_pull_manager.py#L524

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

When I set up BidiRPC with LoggingV2Transport().tail_log_entries, that's the unwrapped method, not the wrapped method. Will this still get the metadata from the wrapped method?

I believe the wrapped one has to be passed in (the wrapper adds the metadata to the call)

also, I tried passing in LoggingServiceV2Client().tail_log_entries and it didn't seem to work.

I'm actually not sure how pubsub passes in the wrapped method successfully.

Hmm I'll go back and poke at what is actually expected to be passed in to Bidi.

Copy link
Contributor

@tseavertseaver left a comment

Choose a reason for hiding this comment

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

Overall, LGTM. I'll let@plamut comment on possible Pub/sub interactions.

@busunkim96
Copy link
ContributorAuthor

Looking at Firestore vs. Pub/Sub, I see Firestore is passing the method in thegRPC transport and Pub/Sub is passing the method in theGAPIC client.

I wonder if that contributed to the behavior difference between the two that requiresthis workaround? (Also see:googleapis/python-pubsub#93 (comment) and#30)

@jameslynnwu For it "not working" whenLoggingServiceV2Client().tail_log_entries was passed did it hang, error, or something else?

@jameslynnwu
Copy link

Great find!
When I pass inLoggingServiceV2Client().tail_log_entries, it doesn't respond and the request does not seem to be initiated.

However, if I use the same workaround, it works.

# Does not respond. Request doesn't seem to be initiatedclient = LoggingServiceV2Client()self.tail_stub = bidi.BidiRpc(client.logging.tail_log_entries)# Worksclient = LoggingServiceV2Client()self.tail_stub = bidi.BidiRpc(client.logging.transport.tail_log_entries)# Worksclient = LoggingServiceV2Client()client.transport._prefetch_first_result_ = Falseself.tail_stub = bidi.BidiRpc(client.logging.tail_log_entries)

@plamut
Copy link
Contributor

plamut commentedJun 16, 2021
edited
Loading

The Pub/Sub client passes thestreaming_pull() method when creating aBidi instance. This method comes from the auto-generated client andinvokes the wrapped transport method.

The subscriber client does not pass any metadata on its own toResumableBidiRpc, it just leaves it up to the (generated) transport to do thewrapping, which setsclient_info on requests, among other things.


As for the changes in this PR - since no metadata is passed toBidiRpc, the default valueNone is used for it.

Before the PR,BidiRpc.open() called the following (sendingNone for metadata:

call=self._start_rpc(iter(request_generator),metadata=self._rpc_metadata)

With the changes in this PR, however, that changes:

ifself._rpc_metadata:call=self._start_rpc(iter(request_generator),metadata=self._rpc_metadata)# use metadata from self._start_rpc if no other metadata is specifiedelse:call=self._start_rpc(iter(request_generator))

Since metadata isNone, this code now effectively becomes the following:

call=self._start_rpc(iter(request_generator))

No explicitNone metadata is passed in, thus the generatedstreaming_pull() method now usesits own default, which is an empty tuple.

When the (wrapped) method is eventually called, thefollowing logic in_GapicCallable determines the metadata:

ifself._metadataisnotNone:metadata=kwargs.get("metadata", [])# Due to the nature of invocation, None should be treated the same# as not specified.ifmetadataisNone:metadata= []metadata=list(metadata)    ...

If I traced this correctly, there should be no difference between passingNone and an empty tuple as a kwarg. Both get transformed to an empty list, and the original metadata from the method wrapping time is not modified.

Does this answer the question?


As for passing in a wrapped vs. un-wrapepd method - the regression caused by a Firestore fix back then seems to only affect the wrapped methods, yes, as the key changelives in in the_StreamingResponseIterator (the latter wraps the stream errors, and only comes into play with the wrapped methods).

We had to introduce a flag that changes how_StreamingResponseIterator behaves, as Firestore's fix can break Pub/Sub. :)
(and Logging, if I understood@jameslynnwu correctly).

@jameslynnwu
Copy link

One more thing to note, though we probably not want to address all of this at once.

Passing in theclient.logging.tail_log_entries vsclient.logging.transport.tail_log_entries changes what is passed into theshould_recover method ofResumableBidiRPC from either agrpc.Call or agoogle.api_core.exceptions.GoogleAPICallError to agrpc.Call, respectively.

If we can ensure that onlyclient.logging.tail_log_entries is passed it that would makeshould_recover more predictable. Alternatively, we should update the code to always pass the same result intoshould_recover regardless of ifclient.logging.tail_log_entries orclient.logging.transport.tail_log_entries is passed in.

Also, it's interesting thatshould_recover is called twice from callbacks and from exception.

@busunkim96
Copy link
ContributorAuthor

@plamut Thank you for the detailed analysis. 🙏

I'm OOO the rest of the week so I'll come back and look at this next week.

@busunkim96
Copy link
ContributorAuthor

As@plamut explained above, this PR is a no-op, if you pass the wrapped method the metadata will get added (which is why Pub/Sub doesn't passmetadata explicitly tostart_rpc).

I had a bit of trouble tracing this through but was able to confirm the expected headers in the gRPC logs:

export GRPC_TRACE=allexport GRPC_VERBOSITY=debug
I0625 21:17:38.217348925 2619277 chttp2_transport.cc:1363]   HTTP:0:HDR:CLI: :scheme: httpsI0625 21:17:38.217356118 2619277 chttp2_transport.cc:1363]   HTTP:0:HDR:CLI: :method: POSTI0625 21:17:38.217363271 2619277 chttp2_transport.cc:1363]   HTTP:0:HDR:CLI: :authority: pubsub.googleapis.com:443I0625 21:17:38.217370411 2619277 chttp2_transport.cc:1363]   HTTP:0:HDR:CLI: :path: /google.pubsub.v1.Subscriber/StreamingPullI0625 21:17:38.217377702 2619277 chttp2_transport.cc:1363]   HTTP:0:HDR:CLI: x-goog-api-client: gl-python/3.8.3 grpc/1.38.0 gax/1.30.0 gccl/2.5.0

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@jameslynnwujameslynnwujameslynnwu left review comments

@software-dovsoftware-dovAwaiting requested review from software-dov

@plamutplamutAwaiting requested review from plamut

+1 more reviewer

@tseavertseavertseaver left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

cla: yesThis human has signed the Contributor License Agreement.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

client_info fromstart_rpc arg should be used when creatingBidiRpc

5 participants

@busunkim96@jameslynnwu@plamut@tseaver@yoshi-kokoro

[8]ページ先頭

©2009-2025 Movatter.jp