-
Notifications
You must be signed in to change notification settings - Fork 90
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
AsyncIO Integration [Part 1] #26
Conversation
997a7b5
to
0f9b66f
Compare
@busunkim96 PTAL. |
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.
LGTM. At some point the docs will need to be updated to include the new classes (https://github.com/googleapis/python-api-core/tree/master/docs). Does it make more sense to do that now or to wait for other parts to be added?
tests/asyncio/test_retry_async.py
Outdated
@@ -0,0 +1,397 @@ | |||
# Copyright 2017 Google LLC |
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.
# Copyright 2017 Google LLC | |
# Copyright 2020 Google LLC |
@busunkim96 I will add doc in a separate PR. It might be better to update the doc for all new classes once. |
4589485
to
97fa36c
Compare
@busunkim96 PTAL at the doc gen code. After checking the doc generation code, I found you are using Sphinx so it actually is easy to add docs alone the code. So, I will try to add docs templates with code in following PRs. |
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.
Tests look great, just had some nits to pick.
Args: | ||
target(Callable): The function to call and retry. This must be a | ||
nullary function - apply arguments with `functools.partial`. | ||
predicate (Callable[Exception]): A callable used to determine if an |
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.
Maybe a name other than 'predicate' would be more helpful. I like the lisp convention of naming predicates with a -p tail; maybe is_retryable_p
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 function signature is mimicking the sync version, so we have consistent naming between two versions. I can change if you feel strongly.
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.
Not too strongly, especially if we're trying to preserve a convention.
google/api_core/retry_async.py
Outdated
Returns: | ||
AsyncRetry: A new retry instance with the given deadline. | ||
""" | ||
return AsyncRetry( |
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.
It might be worthwhile to add a replace
method to AsyncRetry
that takes optional parameters corresponding to the constructor params and returns a new AsyncRetry
with the passed in overrides applied.
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 think the original designer of this class try to use the builder pattern. Naming each one with_*
makes the application code more meaningful semantically. WDYT?
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'm fine preserving the interfaces, but it seems like a lot of boilerplate for a common, straightforward desire: given an object, return a copy with specific fields updated. I think having a replace method that gets called by the with_deadline
and with_predicate
methods is still a net win.
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.
Switched to use a common _replace
method. Thanks for the suggestion.
assert retry._initial == 1.0 | ||
assert retry._multiplier == 2.5 | ||
assert retry._maximum == 120.0 | ||
assert retry._deadline == 600.0 | ||
assert timeout._initial == 120.0 | ||
assert timeout._multiplier == 1.0 | ||
assert timeout._maximum == 120.0 |
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.
Why not define an __eq__
method to handle all this boilerplate? The retry error predicate would still need to be tested by hand, but it would clean this bit up.
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.
Can you explain more about this comment? Do you mean an __eq__
method to compare a retry/timeout object and parsed JSON object?
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.
@software-dov Thanks for the detailed review. I definitely learned today. PTALA.
Args: | ||
target(Callable): The function to call and retry. This must be a | ||
nullary function - apply arguments with `functools.partial`. | ||
predicate (Callable[Exception]): A callable used to determine if an |
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 function signature is mimicking the sync version, so we have consistent naming between two versions. I can change if you feel strongly.
google/api_core/retry_async.py
Outdated
Returns: | ||
AsyncRetry: A new retry instance with the given deadline. | ||
""" | ||
return AsyncRetry( |
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 think the original designer of this class try to use the builder pattern. Naming each one with_*
makes the application code more meaningful semantically. WDYT?
BTW, I don't have the permission to merge PRs (and I don't have the full context of the release process). So, if there is any blocker, please let me know, no rush. |
@lidizheng There's nothing blocking the release since the changes are additive. Let's release this next week. Thanks for all your work on this and @software-dov thank you for the thorough review. 😁 |
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.
LGTM. One minor issue, no need to repost if you don't think it's worth the hassle.
google/api_core/retry_async.py
Outdated
Returns: | ||
AsyncRetry: A new retry instance with the given deadline. | ||
""" | ||
return AsyncRetry( |
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'm fine preserving the interfaces, but it seems like a lot of boilerplate for a common, straightforward desire: given an object, return a copy with specific fields updated. I think having a replace method that gets called by the with_deadline
and with_predicate
methods is still a net win.
This change includes: * Nox configuration support for AsynciO unit tests * No pre release gRPC Python required * AsyncIO retry module * AsyncIO config parsing module * Exception parsing patch * Corresponding unit test cases
Children PR of #26. This PR includes AsyncIO version of: * Polling future * Page iterator The AsyncIO version of polling future still uses the same mechanism as the sync version. The AsyncIO polling future tries to update its own state whenever the application want to access information or perform actions. For page iterator, it has similar interface design as sync version. But instead of fulfilling normal generator protocol, it is based on the async generator. Related #23
🤖 I have created a release \*beep\* \*boop\* --- ## [1.18.0](https://www.github.com/googleapis/python-api-core/compare/v1.17.0...v1.18.0) (2020-06-04) ### Features * [CBT-6 helper] Exposing Retry._deadline as a property ([#20](https://www.github.com/googleapis/python-api-core/issues/20)) ([7be1e59](https://www.github.com/googleapis/python-api-core/commit/7be1e59e9d75c112f346d2b76dce3dd60e3584a1)) * add client_encryped_cert_source to ClientOptions ([#31](https://www.github.com/googleapis/python-api-core/issues/31)) ([e4eaec0](https://www.github.com/googleapis/python-api-core/commit/e4eaec0ff255114138d3715280f86d34d861a6fa)) * AsyncIO Integration [Part 2] ([#28](https://www.github.com/googleapis/python-api-core/issues/28)) ([dd9b2f3](https://www.github.com/googleapis/python-api-core/commit/dd9b2f38a70e85952cc05552ec8070cdf29ddbb4)), closes [#23](https://www.github.com/googleapis/python-api-core/issues/23) * First batch of AIO integration ([#26](https://www.github.com/googleapis/python-api-core/issues/26)) ([a82f289](https://www.github.com/googleapis/python-api-core/commit/a82f2892b8f219b82e120e6ed9f4070869c28be7)) * third batch of AsyncIO integration ([#29](https://www.github.com/googleapis/python-api-core/issues/29)) ([7d8d580](https://www.github.com/googleapis/python-api-core/commit/7d8d58075a92e93662747d36a2d55b5e9f0943e1)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please).
Since the PR in microgenerator is pretty stable, the existing set of AsyncIO features should be sufficient to support generated code. I plan to split the AsyncIO integration into 3 parts (please let me know if anything I can do to help review): utility modules, LRO related modules, grpc helpers modules.
This PR contains following changes:
Related #23