-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
PubSub: Making thread.Policy.on_exception
more robust.
#4444
Conversation
thread.Policy.on_exception
more robust.thread.Policy.on_exception
more robust.
4244392
to
ae0b073
Compare
code = exception.grpc_status_code | ||
else: | ||
code = getattr(exception, 'code', None) | ||
if callable(code): |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
details = 'Bad thing happened. Time out, go sit in the corner.' | ||
exc_state = grpc._channel._RPCState( | ||
(), None, trailing, status_code, details) | ||
exc = grpc._channel._Rendezvous(exc_state, None, None, None) |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
It's because this happens during streaming. |
if getattr(exception, 'code', lambda: None)() == deadline_exceeded: | ||
if isinstance(exception, exceptions.GoogleAPICallError): | ||
code = exception.grpc_status_code | ||
else: |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
|
||
# If this is in the list of idempotent exceptions DEADLINE_EXCEEDED, | ||
# then we want to retry. That entails just returning None. | ||
if code in _IDEMPOTENT_RETRY_CODES: |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
- Adding special handling for API core exceptions - Retrying on both types of idempotent error - Also doing a "drive-by" hygiene fix changing a global from `logger` to `_LOGGER` Towards googleapis#4234.
Also removing the `logger` -> `_LOGGER` change to make the PR easier to review.
ae0b073
to
30a949f
Compare
So I have updated and have a better understanding thanks to chats with @jonparrott and @lukesneeringer.
I'm still not sure why I would like to continue that exploration but still merge this PR. SGTY @jonparrott and @lukesneeringer? |
@@ -65,6 +66,10 @@ class BasePolicy(object): | |||
""" | |||
|
|||
_managed_ack_ids = None | |||
_IDEMPOTENT_RETRIES = ( |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
if getattr(exception, 'code', lambda: None)() == deadline_exceeded: | ||
# If this is in the list of idempotent exceptions, then we want to | ||
# retry. That entails just returning None. | ||
if isinstance(exception, self._IDEMPOTENT_RETRIES): |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Well I was able to reproduce Traceback (most recent call last):
File "${HOME}/.pyenv/versions/3.6.3/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "${HOME}/.pyenv/versions/3.6.3/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File ".../google/cloud/pubsub_v1/subscriber/_consumer.py", line 249, in _blocking_consume
self._policy.on_exception(exc)
File ".../google/cloud/pubsub_v1/subscriber/policy/thread.py", line 162, in on_exception
self._future.set_exception(exception)
File ".../google/cloud/pubsub_v1/futures.py", line 159, in set_exception
raise RuntimeError('set_exception can only be called once.')
RuntimeError: set_exception can only be called once. on my very first run with the hack from google.cloud.pubsub_v1.subscriber.policy import base
# Monkey-patch to intentionally miss errors.
base.BasePolicy._RETRYABLE_STREAM_ERRORS = () |
NOTE: I am NOT comfortable with this as a fix, it seems WAAAAAY too bolted on.
I'm surprised the retry strategy doesn't come into play hereThere should a less hard-coded way to map to the idempotent retry codesThe method should have a straightforward way to determine the gRPC status code from the exceptionRuntimeError: set_exception can only be called once
occurs if I don't filter out theUNAVAILABLE
(e.g.). This seems like a bug in a different code path than is covered here.logger
to_LOGGER
Towards #4234.