Skip to content

Commit 95cde20

Browse files
committed
fix: resolve the issue where rpc timeout of 0 is used when timeout expires
1 parent 9182916 commit 95cde20

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

google/api_core/timeout.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ def __call__(self, func):
102102
def func_with_timeout(*args, **kwargs):
103103
"""Wrapped function that adds timeout."""
104104

105-
remaining_timeout = self._timeout
106-
if remaining_timeout is not None:
105+
if self._timeout is not None:
107106
# All calculations are in seconds
108107
now_timestamp = self._clock().timestamp()
109108

@@ -114,8 +113,20 @@ def func_with_timeout(*args, **kwargs):
114113
now_timestamp = first_attempt_timestamp
115114

116115
time_since_first_attempt = now_timestamp - first_attempt_timestamp
117-
# Avoid setting negative timeout
118-
kwargs["timeout"] = max(0, self._timeout - time_since_first_attempt)
116+
remaining_timeout = self._timeout - time_since_first_attempt
117+
118+
# Although the `deadline` parameter in `google.api_core.retry.Retry`
119+
# is deprecated, and should be treated the same as the `timeout`,
120+
# it is still possible for `deadline` argument in google.api_core.retry.Retry
121+
# to be larger than the `timeout`.
122+
# Avoid setting negative timeout or timeout less than 5 seconds when the `timeout`
123+
# has expired.
124+
# See https://github.com/googleapis/python-api-core/issues/654
125+
# Revert back to the original timeout when this happens
126+
if remaining_timeout < 5:
127+
remaining_timeout = self._timeout
128+
129+
kwargs["timeout"] = remaining_timeout
119130

120131
return func(*args, **kwargs)
121132

tests/unit/test_timeout.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ def _clock():
8282
wrapped()
8383
target.assert_called_with(timeout=41.0)
8484
wrapped()
85-
target.assert_called_with(timeout=3.0)
85+
target.assert_called_with(timeout=42.0)
8686
wrapped()
87-
target.assert_called_with(timeout=0.0)
87+
target.assert_called_with(timeout=42.0)
8888
wrapped()
89-
target.assert_called_with(timeout=0.0)
89+
target.assert_called_with(timeout=42.0)
9090

9191
def test_apply_no_timeout(self):
9292
target = mock.Mock(spec=["__call__", "__name__"], __name__="target")

0 commit comments

Comments
 (0)