Skip to content

Commit 7a38243

Browse files
authored
fix: support 'retry' for ops built from HTTP/gRPC responses (googleapis#115)
Closes googleapis#87.
1 parent b394c08 commit 7a38243

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

google/api_core/operation.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,19 +192,24 @@ def cancelled(self):
192192
)
193193

194194

195-
def _refresh_http(api_request, operation_name):
195+
def _refresh_http(api_request, operation_name, retry=None):
196196
"""Refresh an operation using a JSON/HTTP client.
197197
198198
Args:
199199
api_request (Callable): A callable used to make an API request. This
200200
should generally be
201201
:meth:`google.cloud._http.Connection.api_request`.
202202
operation_name (str): The name of the operation.
203+
retry (google.api_core.retry.Retry): (Optional) retry policy
203204
204205
Returns:
205206
google.longrunning.operations_pb2.Operation: The operation.
206207
"""
207208
path = "operations/{}".format(operation_name)
209+
210+
if retry is not None:
211+
api_request = retry(api_request)
212+
208213
api_response = api_request(method="GET", path=path)
209214
return json_format.ParseDict(api_response, operations_pb2.Operation())
210215

@@ -249,19 +254,25 @@ def from_http_json(operation, api_request, result_type, **kwargs):
249254
return Operation(operation_proto, refresh, cancel, result_type, **kwargs)
250255

251256

252-
def _refresh_grpc(operations_stub, operation_name):
257+
def _refresh_grpc(operations_stub, operation_name, retry=None):
253258
"""Refresh an operation using a gRPC client.
254259
255260
Args:
256261
operations_stub (google.longrunning.operations_pb2.OperationsStub):
257262
The gRPC operations stub.
258263
operation_name (str): The name of the operation.
264+
retry (google.api_core.retry.Retry): (Optional) retry policy
259265
260266
Returns:
261267
google.longrunning.operations_pb2.Operation: The operation.
262268
"""
263269
request_pb = operations_pb2.GetOperationRequest(name=operation_name)
264-
return operations_stub.GetOperation(request_pb)
270+
271+
rpc = operations_stub.GetOperation
272+
if retry is not None:
273+
rpc = retry(rpc)
274+
275+
return rpc(request_pb)
265276

266277

267278
def _cancel_grpc(operations_stub, operation_name):

tests/unit/test_operation.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,17 +177,39 @@ def test_unexpected_result():
177177

178178

179179
def test__refresh_http():
180-
api_request = mock.Mock(return_value={"name": TEST_OPERATION_NAME, "done": True})
180+
json_response = {"name": TEST_OPERATION_NAME, "done": True}
181+
api_request = mock.Mock(return_value=json_response)
181182

182183
result = operation._refresh_http(api_request, TEST_OPERATION_NAME)
183184

185+
assert isinstance(result, operations_pb2.Operation)
184186
assert result.name == TEST_OPERATION_NAME
185187
assert result.done is True
188+
186189
api_request.assert_called_once_with(
187190
method="GET", path="operations/{}".format(TEST_OPERATION_NAME)
188191
)
189192

190193

194+
def test__refresh_http_w_retry():
195+
json_response = {"name": TEST_OPERATION_NAME, "done": True}
196+
api_request = mock.Mock()
197+
retry = mock.Mock()
198+
retry.return_value.return_value = json_response
199+
200+
result = operation._refresh_http(api_request, TEST_OPERATION_NAME, retry=retry)
201+
202+
assert isinstance(result, operations_pb2.Operation)
203+
assert result.name == TEST_OPERATION_NAME
204+
assert result.done is True
205+
206+
api_request.assert_not_called()
207+
retry.assert_called_once_with(api_request)
208+
retry.return_value.assert_called_once_with(
209+
method="GET", path="operations/{}".format(TEST_OPERATION_NAME)
210+
)
211+
212+
191213
def test__cancel_http():
192214
api_request = mock.Mock()
193215

@@ -224,6 +246,21 @@ def test__refresh_grpc():
224246
operations_stub.GetOperation.assert_called_once_with(expected_request)
225247

226248

249+
def test__refresh_grpc_w_retry():
250+
operations_stub = mock.Mock(spec=["GetOperation"])
251+
expected_result = make_operation_proto(done=True)
252+
retry = mock.Mock()
253+
retry.return_value.return_value = expected_result
254+
255+
result = operation._refresh_grpc(operations_stub, TEST_OPERATION_NAME, retry=retry)
256+
257+
assert result == expected_result
258+
expected_request = operations_pb2.GetOperationRequest(name=TEST_OPERATION_NAME)
259+
operations_stub.GetOperation.assert_not_called()
260+
retry.assert_called_once_with(operations_stub.GetOperation)
261+
retry.return_value.assert_called_once_with(expected_request)
262+
263+
227264
def test__cancel_grpc():
228265
operations_stub = mock.Mock(spec=["CancelOperation"])
229266

0 commit comments

Comments
 (0)