async def test_wrap_method_with_overriding_retry_deadline( utcnow, unused_sleep): fake_call = grpc_helpers_async.FakeUnaryUnaryCall(42) method = mock.Mock( spec=aio.UnaryUnaryMultiCallable, side_effect=([exceptions.InternalServerError(None)] * 4) + [fake_call], ) default_retry = retry_async.AsyncRetry() default_timeout = timeout.ExponentialTimeout(deadline=60) wrapped_method = gapic_v1.method_async.wrap_method(method, default_retry, default_timeout) # Overriding only the retry's deadline should also override the timeout's # deadline. result = await wrapped_method(retry=default_retry.with_deadline(30)) assert result == 42 timeout_args = [call[1]["timeout"] for call in method.call_args_list] assert timeout_args == [5.0, 10.0, 20.0, 26.0, 25.0] assert utcnow.call_count == ( 1 + 1 # Compute wait_for timeout in retry_async + 5 # First to set the deadline. + 5 # One for each min(timeout, maximum, (DEADLINE - NOW).seconds) )
def _timeout_from_retry_config(retry_params): """Creates a ExponentialTimeout object given a gapic retry configuration. Args: retry_params (dict): The retry parameter values, for example:: { "initial_retry_delay_millis": 1000, "retry_delay_multiplier": 2.5, "max_retry_delay_millis": 120000, "initial_rpc_timeout_millis": 120000, "rpc_timeout_multiplier": 1.0, "max_rpc_timeout_millis": 120000, "total_timeout_millis": 600000 } Returns: google.google-api-core.retry.ExponentialTimeout: The default time object for the method. """ return timeout.ExponentialTimeout( initial=(retry_params["initial_rpc_timeout_millis"] / _MILLIS_PER_SECOND), maximum=(retry_params["max_rpc_timeout_millis"] / _MILLIS_PER_SECOND), multiplier=retry_params["rpc_timeout_multiplier"], deadline=(retry_params["total_timeout_millis"] / _MILLIS_PER_SECOND), )
def test_with_timeout(self): original_timeout = timeout.ExponentialTimeout() timeout_ = original_timeout.with_deadline(42) assert original_timeout is not timeout_ assert timeout_._initial == timeout._DEFAULT_INITIAL_TIMEOUT assert timeout_._maximum == timeout._DEFAULT_MAXIMUM_TIMEOUT assert timeout_._multiplier == timeout._DEFAULT_TIMEOUT_MULTIPLIER assert timeout_._deadline == 42
def test_apply_passthrough(self): target = mock.Mock(spec=['__call__', '__name__'], __name__='target') timeout_ = timeout.ExponentialTimeout(42.0, 100, 2) wrapped = timeout_(target) wrapped(1, 2, meep='moop') target.assert_called_once_with(1, 2, meep='moop', timeout=42.0)
def test_apply_passthrough(self): target = mock.Mock(spec=["__call__", "__name__"], __name__="target") timeout_ = timeout.ExponentialTimeout(42.0, 100, 2) wrapped = timeout_(target) wrapped(1, 2, meep="moop") target.assert_called_once_with(1, 2, meep="moop", timeout=42.0)
def test_apply(self): target = mock.Mock(spec=['__call__', '__name__'], __name__='target') timeout_ = timeout.ExponentialTimeout(1, 10, 2) wrapped = timeout_(target) wrapped() target.assert_called_with(timeout=1) wrapped() target.assert_called_with(timeout=2) wrapped() target.assert_called_with(timeout=4)
def test_wrap_method_with_overriding_retry_deadline(utcnow, unused_sleep): method = mock.Mock( spec=['__call__'], side_effect=([exceptions.InternalServerError(None)] * 4) + [42]) default_retry = retry.Retry() default_timeout = timeout.ExponentialTimeout(deadline=60) wrapped_method = google.api_core.gapic_v1.method.wrap_method( method, default_retry, default_timeout) # Overriding only the retry's deadline should also override the timeout's # deadline. result = wrapped_method(retry=default_retry.with_deadline(30)) assert result == 42 timeout_args = [call[1]['timeout'] for call in method.call_args_list] assert timeout_args == [5.0, 10.0, 20.0, 26.0, 25.0] assert utcnow.call_count == ( 1 + # First to set the deadline. 5 + # One for each min(timeout, maximum, (DEADLINE - NOW).seconds) 5)
def _do_mutate_retryable_rows(self): """Mutate all the rows that are eligible for retry. A row is eligible for retry if it has not been tried or if it resulted in a transient error in a previous call. :rtype: list :return: The responses statuses, which is a list of :class:`~google.rpc.status_pb2.Status`. :raises: One of the following: * :exc:`~.table._BigtableRetryableError` if any row returned a transient error. * :exc:`RuntimeError` if the number of responses doesn't match the number of rows that were retried """ retryable_rows = [] index_into_all_rows = [] for index, status in enumerate(self.responses_statuses): if self._is_retryable(status): retryable_rows.append(self.rows[index]) index_into_all_rows.append(index) if not retryable_rows: # All mutations are either successful or non-retryable now. return self.responses_statuses mutate_rows_request = _mutate_rows_request( self.table_name, retryable_rows, app_profile_id=self.app_profile_id) data_client = self.client.table_data_client inner_api_calls = data_client._inner_api_calls if "mutate_rows" not in inner_api_calls: default_retry = (data_client._method_configs["MutateRows"].retry, ) if self.timeout is None: default_timeout = data_client._method_configs[ "MutateRows"].timeout else: default_timeout = timeout.ExponentialTimeout( deadline=self.timeout) data_client._inner_api_calls["mutate_rows"] = wrap_method( data_client.transport.mutate_rows, default_retry=default_retry, default_timeout=default_timeout, client_info=data_client._client_info, ) responses = data_client._inner_api_calls["mutate_rows"]( mutate_rows_request, retry=None) num_responses = 0 num_retryable_responses = 0 for response in responses: for entry in response.entries: num_responses += 1 index = index_into_all_rows[entry.index] self.responses_statuses[index] = entry.status if self._is_retryable(entry.status): num_retryable_responses += 1 if entry.status.code == 0: self.rows[index].clear() if len(retryable_rows) != num_responses: raise RuntimeError( "Unexpected number of responses", num_responses, "Expected", len(retryable_rows), ) if num_retryable_responses: raise _BigtableRetryableError return self.responses_statuses
def test_constructor_args(self): timeout_ = timeout.ExponentialTimeout(1, 2, 3, 4) assert timeout_._initial == 1 assert timeout_._maximum == 2 assert timeout_._multiplier == 3 assert timeout_._deadline == 4
def test_constructor(self): timeout_ = timeout.ExponentialTimeout() assert timeout_._initial == timeout._DEFAULT_INITIAL_TIMEOUT assert timeout_._maximum == timeout._DEFAULT_MAXIMUM_TIMEOUT assert timeout_._multiplier == timeout._DEFAULT_TIMEOUT_MULTIPLIER assert timeout_._deadline == timeout._DEFAULT_DEADLINE
def test___str__(self): timeout_ = timeout.ExponentialTimeout(1, 2, 3, 4) assert str(timeout_) == ( '<ExponentialTimeout initial=1.0, maximum=2.0, multiplier=3.0, ' 'deadline=4.0>')