Title: Major refactoring of Timeout logic introduced incompatibility about RPC Timeout · Issue #654 · googleapis/python-api-core · GitHub
Open Graph Title: Major refactoring of Timeout logic introduced incompatibility about RPC Timeout · Issue #654 · googleapis/python-api-core
X Title: Major refactoring of Timeout logic introduced incompatibility about RPC Timeout · Issue #654 · googleapis/python-api-core
Description: Hello, I'm using the python-pubsub library and noticed that the timeout behavior is strange. After some investigation, I believe it is due to an incompatibility introduced by #462. The default retry and timeout settings in the python-pub...
Open Graph Description: Hello, I'm using the python-pubsub library and noticed that the timeout behavior is strange. After some investigation, I believe it is due to an incompatibility introduced by #462. The default retr...
X Description: Hello, I'm using the python-pubsub library and noticed that the timeout behavior is strange. After some investigation, I believe it is due to an incompatibility introduced by #462. The default ...
Opengraph URL: https://github.com/googleapis/python-api-core/issues/654
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Major refactoring of Timeout logic introduced incompatibility about RPC Timeout","articleBody":"Hello,\r\n\r\nI'm using the python-pubsub library and noticed that the timeout behavior is strange. After some investigation, I believe it is due to an incompatibility introduced by https://github.com/googleapis/python-api-core/pull/462.\r\n\r\nThe default retry and timeout settings in the python-pubsub library are as follows:\r\nhttps://github.com/googleapis/python-pubsub/blob/v2.21.1/google/pubsub_v1/services/publisher/transports/base.py#L166-L181\r\n```python\r\ndefault_retry=retries.Retry(\r\n initial=0.1,\r\n maximum=60.0,\r\n multiplier=4,\r\n predicate=retries.if_exception_type(\r\n core_exceptions.Aborted,\r\n core_exceptions.Cancelled,\r\n core_exceptions.DeadlineExceeded,\r\n core_exceptions.InternalServerError,\r\n core_exceptions.ResourceExhausted,\r\n core_exceptions.ServiceUnavailable,\r\n core_exceptions.Unknown,\r\n ),\r\n deadline=600.0,\r\n),\r\ndefault_timeout=60.0,\r\n```\r\n\r\nBefore #462 was introduced, `default_timeout=60.0` was interpreted as `default_timeout=ConstantTimeout(60)`.\r\nThis should be intended to set the RPC Timeout, i.e., the timeout for a single RPC call not including retries, to 60 seconds.\r\nHowever, after the introduction of #462, this line is now interpreted as `default_timeout=TimeToDeadlineTimeout(60)`.\r\nSince TimeToDeadlineTimeout determines the total timeout time across retries rather than determining the RPC Timeout, I don't believe that it can be used as a direct replacement for ConstantTimeout.\r\n\r\nThe strange behavior I mentioned at the beginning came from this: when the server did not respond in the first 60 seconds, the remaining timeout for RPC call was 0 seconds, and the gRPC client returned a 504 Deadline Exceeded on every retry.\r\n\r\nTimeToDeadlineTimeout by itself is useful, but given the original intent, I think it is necessary to specify the RPC Timeout as well as the total timeout.\r\n\r\nFinally, in my project, I implemented the following ClampMaxTimeout so that the RPC Timeout can be set while respecting the behavior of TimeToDeadlineTimeout.\r\n\r\n```python\r\nRPC_TIMEOUT_SECS = 60.0\r\nTOTAL_TIMEOUT_SECS = 600.0\r\n...\r\npublisher_options=pubsub_v1.types.PublisherOptions(\r\n timeout=compose(\r\n api_core.timeout.TimeToDeadlineTimeout(TOTAL_TIMEOUT_SECS),\r\n ClampMaxTimeout(RPC_TIMEOUT_SECS),\r\n ),\r\n ...\r\n...\r\nclass ClampMaxTimeout(object):\r\n def __init__(self, max_timeout: float):\r\n self._max_timeout = max_timeout\r\n\r\n def __call__(self, func: Callable) -\u003e Callable:\r\n @functools.wraps(func)\r\n def func_with_max_timeout(*args, **kwargs):\r\n if kwargs.get(\"timeout\") is not None:\r\n kwargs[\"timeout\"] = min(kwargs[\"timeout\"], self._max_timeout)\r\n else:\r\n kwargs[\"timeout\"] = self._max_timeout\r\n return func(*args, **kwargs)\r\n\r\n return func_with_max_timeout\r\n\r\n def __str__(self) -\u003e str:\r\n return \"\u003cClampMaxTimeout max_timeout={:.1f}\u003e\".format(self._max_timeout)\r\n\r\ndef compose(f: Callable, g: Callable) -\u003e Callable:\r\n return lambda x: f(g(x))\r\n```\r\n\r\nTo keep backward compatibility, I believe it is desirable to introduce a similar process in python-api-core.\r\n","author":{"url":"https://github.com/yoshizow","@type":"Person","name":"yoshizow"},"datePublished":"2024-05-10T06:52:13.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":3},"url":"https://github.com/654/python-api-core/issues/654"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:5a5278bb-0ca3-4f25-3d25-dbe6e289463f |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | A5B2:62240:184E2EF:2359047:6A4E554F |
| html-safe-nonce | a81cfe30baa145f9cecdd6238bdb217e852fc6493a0a545a410f534f7bd35647 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBNUIyOjYyMjQwOjE4NEUyRUY6MjM1OTA0Nzo2QTRFNTU0RiIsInZpc2l0b3JfaWQiOiIzMjc2MzczMjc5MDY1OTIwODQ3IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 643091f2c314c5732b38a147d1f5df9db8f1c3402bd18a390b948477ae6e4b34 |
| hovercard-subject-tag | issue:2289068997 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/googleapis/python-api-core/654/issue_layout |
| twitter:image | https://opengraph.githubassets.com/0addc65f7f14831b37dac8cdf66c55ce1b9c51fcd27ceaa5ef2944031fdd5f1a/googleapis/python-api-core/issues/654 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/0addc65f7f14831b37dac8cdf66c55ce1b9c51fcd27ceaa5ef2944031fdd5f1a/googleapis/python-api-core/issues/654 |
| og:image:alt | Hello, I'm using the python-pubsub library and noticed that the timeout behavior is strange. After some investigation, I believe it is due to an incompatibility introduced by #462. The default retr... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | yoshizow |
| hostname | github.com |
| expected-hostname | github.com |
| None | 030096ee0db095447bfe77409d33bfac127ca7128299c58deef27c52eaa1b1f0 |
| turbo-cache-control | no-preview |
| go-import | github.com/googleapis/python-api-core git https://github.com/googleapis/python-api-core.git |
| octolytics-dimension-user_id | 16785467 |
| octolytics-dimension-user_login | googleapis |
| octolytics-dimension-repository_id | 226992456 |
| octolytics-dimension-repository_nwo | googleapis/python-api-core |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 226992456 |
| octolytics-dimension-repository_network_root_nwo | googleapis/python-api-core |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | f344f1eab54fc7dfc02d0d018cda7e158c3db65c |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width