Module: Google::Gax

Defined in:
lib/google/gax.rb,
lib/google/gax/grpc.rb,
lib/google/gax/util.rb,
lib/google/gax/errors.rb,
lib/google/gax/version.rb,
lib/google/gax/bundling.rb,
lib/google/gax/settings.rb,
lib/google/gax/constants.rb,
lib/google/gax/operation.rb,
lib/google/gax/api_callable.rb,
lib/google/gax/path_template.rb

Overview

Gax defines Google API extensions

Defined Under Namespace

Modules: Grpc Classes: AbortedError, AlreadyExistsError, BackoffSettings, BundleDescriptor, BundleOptions, CallOptions, CanceledError, DataLossError, DeadlineExceededError, Event, Executor, FailedPreconditionError, GaxError, InternalError, InvalidArgumentError, NotFoundError, Operation, OutOfRangeError, PageDescriptor, PagedEnumerable, PathLex, PathParse, PathTemplate, PermissionDeniedError, ResourceExhaustedError, RetryError, RetryOptions, Segment, Task, Timer, UnauthenticatedError, UnavailableError, UnimplementedError, UnknownError

Constant Summary collapse

VERSION_MATCHER =

Regex used by gapic to find version files and directories.

/
    ([vV]\d+) # Major version eg: v1
    ([pP]\d+)? # Point release eg: p2
    (([aA]lpha|[bB]eta)\d*)? # Release level eg: alpha3
/x
VERSION =
'1.8.1'.freeze
MILLIS_PER_SECOND =
1000.0

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#backoff_settingsBackoffSettings

Returns configuring the retry exponential backoff algorithm.

Returns:

  • (BackoffSettings)

    configuring the retry exponential backoff algorithm.



# File 'lib/google/gax/settings.rb', line 192

#initial_retry_delay_millisNumeric

Returns the initial delay time, in milliseconds, between the completion of the first failed request and the initiation of the first retrying request.

Returns:

  • (Numeric)

    the initial delay time, in milliseconds, between the completion of the first failed request and the initiation of the first retrying request.



# File 'lib/google/gax/settings.rb', line 210

#initial_rpc_timeout_millisNumeric

Returns the initial timeout parameter to the request.

Returns:

  • (Numeric)

    the initial timeout parameter to the request.



# File 'lib/google/gax/settings.rb', line 210

#max_retry_delay_millisNumeric

Returns the maximum delay time, in milliseconds, between requests. When this value is reached, retry_delay_multiplier will no longer be used to increase delay time.

Returns:

  • (Numeric)

    the maximum delay time, in milliseconds, between requests. When this value is reached, retry_delay_multiplier will no longer be used to increase delay time.



# File 'lib/google/gax/settings.rb', line 210

#max_rpc_timeout_millisNumeric

Returns the maximum timeout parameter, in milliseconds, for a request. When this value is reached, rpc_timeout_multiplier will no longer be used to increase the timeout.

Returns:

  • (Numeric)

    the maximum timeout parameter, in milliseconds, for a request. When this value is reached, rpc_timeout_multiplier will no longer be used to increase the timeout.



# File 'lib/google/gax/settings.rb', line 210

#retry_codesArray<Grpc::Code>

Returns a list of exceptions upon which a retry should be attempted.

Returns:

  • (Array<Grpc::Code>)

    a list of exceptions upon which a retry should be attempted.



# File 'lib/google/gax/settings.rb', line 192

#retry_delay_multiplierNumeric

Returns the multiplier by which to increase the delay time between the completion of failed requests, and the initiation of the subsequent retrying request.

Returns:

  • (Numeric)

    the multiplier by which to increase the delay time between the completion of failed requests, and the initiation of the subsequent retrying request.



# File 'lib/google/gax/settings.rb', line 210

#rpc_timeout_multiplierNumeric

Returns the multiplier by which to increase the timeout parameter between failed requests.

Returns:

  • (Numeric)

    the multiplier by which to increase the timeout parameter between failed requests.



# File 'lib/google/gax/settings.rb', line 210

#total_timeout_millisNumeric

Returns the total time, in milliseconds, starting from when the initial request is sent, after which an error will be returned, regardless of the retrying attempts made meanwhile.

Returns:

  • (Numeric)

    the total time, in milliseconds, starting from when the initial request is sent, after which an error will be returned, regardless of the retrying attempts made meanwhile.



# File 'lib/google/gax/settings.rb', line 210

Class Method Details

.compute_bundle_id(obj, discriminator_fields) ⇒ Array<Object>

Computes a bundle id from the discriminator fields of ‘obj`.

discriminator_fields may include ‘.’ as a separator, which is used to indicate object traversal. This is meant to allow fields in the computed bundle_id. the return is an array computed by going through the discriminator fields in order and obtaining the str(value) object field (or nested object field) if any discriminator field cannot be found, ValueError is raised.

Parameters:

  • obj (Object)

    an object.

  • discriminator_fields (Array<String>)

    a list of discriminator fields in the order to be to be used in the id.

Returns:

  • (Array<Object>)

    array of objects computed as described above.



72
73
74
75
76
77
78
# File 'lib/google/gax/bundling.rb', line 72

def compute_bundle_id(obj, discriminator_fields)
  result = []
  discriminator_fields.each do |field|
    result.push(str_dotted_access(obj, field))
  end
  result
end

.construct_settings(service_name, client_config, config_overrides, retry_names, timeout, bundle_descriptors: {}, page_descriptors: {}, metadata: {}, kwargs: {}, errors: []) ⇒ CallSettings?

Constructs a dictionary mapping method names to CallSettings.

The client_config parameter is parsed from a client configuration JSON file of the form:

{
  "interfaces": {
    "google.fake.v1.ServiceName": {
      "retry_codes": {
        "idempotent": ["UNAVAILABLE", "DEADLINE_EXCEEDED"],
        "non_idempotent": []
      },
      "retry_params": {
        "default": {
          "initial_retry_delay_millis": 100,
          "retry_delay_multiplier": 1.2,
          "max_retry_delay_millis": 1000,
          "initial_rpc_timeout_millis": 2000,
          "rpc_timeout_multiplier": 1.5,
          "max_rpc_timeout_millis": 30000,
          "total_timeout_millis": 45000
        }
      },
      "methods": {
        "CreateFoo": {
          "retry_codes_name": "idempotent",
          "retry_params_name": "default"
        },
        "Publish": {
          "retry_codes_name": "non_idempotent",
          "retry_params_name": "default",
          "bundling": {
            "element_count_threshold": 40,
            "element_count_limit": 200,
            "request_byte_threshold": 90000,
            "request_byte_limit": 100000,
            "delay_threshold_millis": 100
          }
        }
      }
    }
  }
}

Parameters:

  • service_name (String)

    The fully-qualified name of this service, used as a key into the client config file (in the example above, this value should be ‘google.fake.v1.ServiceName’).

  • client_config (Hash)

    A hash parsed from the standard API client config file.

  • config_overrides (Hash)

    A hash in the same structure of client_config to override the settings.

  • retry_names (Hash)

    A hash mapping the string names used in the standard API client config file to API response status codes.

  • timeout (Numeric)

    The timeout parameter for all API calls in this dictionary.

  • bundle_descriptors (Hash{String => BundleDescriptor}) (defaults to: {})

    A dictionary of method names to BundleDescriptor objects for methods that are bundling-enabled.

  • page_descriptors (Hash{String => PageDescriptor}) (defaults to: {})

    A dictionary of method names to PageDescriptor objects for methods that are page streaming-enabled.

  • metadata (Hash) (defaults to: {})

    Header params to be passed to the API call.

  • kwargs (Hash) (defaults to: {})

    Deprecated, same as metadata and if present will be merged with metadata

  • errors (Array<Exception>) (defaults to: [])

    Configures the exceptions to wrap with GaxError.

Returns:

  • (CallSettings, nil)

    A CallSettings, or nil if the service is not found in the config.



488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/google/gax/settings.rb', line 488

def construct_settings(service_name, client_config, config_overrides,
                       retry_names, timeout, bundle_descriptors: {},
                       page_descriptors: {}, metadata: {}, kwargs: {},
                       errors: [])
  defaults = {}

  .merge!(kwargs) if kwargs.is_a?(Hash) && .is_a?(Hash)

  service_config = client_config.fetch('interfaces', {})[service_name]
  return nil unless service_config

  overrides = config_overrides.fetch('interfaces', {})[service_name] || {}

  service_config['methods'].each_pair do |method_name, method_config|
    snake_name = upper_camel_to_lower_underscore(method_name)

    overriding_method =
      overrides.fetch('methods', {}).fetch(method_name, {})

    bundling_config = method_config.fetch('bundling', nil)
    if overriding_method && overriding_method.key?('bundling')
      bundling_config = overriding_method['bundling']
    end
    bundle_descriptor = bundle_descriptors[snake_name]

    defaults[snake_name] = CallSettings.new(
      timeout: calc_method_timeout(
        timeout, method_config, overriding_method
      ),
      retry_options: merge_retry_options(
        construct_retry(method_config,
                        service_config['retry_codes'],
                        service_config['retry_params'],
                        retry_names),
        construct_retry(overriding_method,
                        overrides['retry_codes'],
                        overrides['retry_params'],
                        retry_names)
      ),
      page_descriptor: page_descriptors[snake_name],
      bundler: construct_bundling(bundling_config, bundle_descriptor),
      bundle_descriptor: bundle_descriptor,
      metadata: ,
      errors: errors
    )
  end

  defaults
end

.create_api_call(func, settings, params_extractor: nil, exception_transformer: nil) ⇒ Proc

Converts an rpc call into an API call governed by the settings.

In typical usage, func will be a proc used to make an rpc request. This will mostly likely be a bound method from a request stub used to make an rpc call.

The result is created by applying a series of function decorators defined in this module to func. settings is used to determine which function decorators to apply.

The result is another proc which for most values of settings has the same signature as the original. Only when settings configures bundling does the signature change.

Parameters:

  • func (Proc)

    used to make a bare rpc call

  • settings (CallSettings)

    provides the settings for this call

  • params_extractor (Proc) (defaults to: nil)

    extracts routing header params from the request

  • exception_transformer (Proc) (defaults to: nil)

    if an API exception occurs this transformer is given the original exception for custom processing instead of raising the error directly

Returns:

  • (Proc)

    a bound method on a request stub used to make an rpc call

Raises:

  • (StandardError)

    if settings has incompatible values, e.g, if bundling and page_streaming are both configured



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/google/gax/api_callable.rb', line 227

def create_api_call(func, settings, params_extractor: nil,
                    exception_transformer: nil)
  api_caller = proc do |api_call, request, _settings, block|
    api_call.call(request, block)
  end

  if settings.page_descriptor
    if settings.bundler?
      raise 'ApiCallable has incompatible settings: ' \
          'bundling and page streaming'
    end
    page_descriptor = settings.page_descriptor
    api_caller = page_streamable(page_descriptor.request_page_token_field,
                                 page_descriptor.response_page_token_field,
                                 page_descriptor.resource_field)
  elsif settings.bundler?
    api_caller = bundleable(settings.bundle_descriptor)
  end

  proc do |request, options = nil, &block|
    this_settings = settings.merge(options)
    if params_extractor
      params = params_extractor.call(request)
      this_settings = with_routing_header(this_settings, params)
    end
    api_call = if this_settings.retry_codes?
                 retryable(func, this_settings.retry_options,
                           this_settings.)
               else
                 add_timeout_arg(func, this_settings.timeout,
                                 this_settings.)
               end
    begin
      api_caller.call(api_call, request, this_settings, block)
    rescue *settings.errors => e
      error_class = Google::Gax.from_error(e)
      error = error_class.new('RPC failed')
      raise error if exception_transformer.nil?
      exception_transformer.call error
    rescue StandardError => error
      raise error if exception_transformer.nil?
      exception_transformer.call error
    end
  end
end

.from_error(error) ⇒ Object



74
75
76
77
78
79
80
# File 'lib/google/gax/errors.rb', line 74

def from_error(error)
  if error.respond_to? :code
    grpc_error_class_for error.code
  else
    GaxError
  end
end

.grpc_error_class_for(grpc_error_code) ⇒ Object



138
139
140
141
142
143
144
145
146
147
# File 'lib/google/gax/errors.rb', line 138

def self.grpc_error_class_for(grpc_error_code)
  # The gRPC status code 0 is for a successful response.
  # So there is no error subclass for a 0 status code, use current class.
  [GaxError, CanceledError, UnknownError, InvalidArgumentError,
   DeadlineExceededError, NotFoundError, AlreadyExistsError,
   PermissionDeniedError, ResourceExhaustedError, FailedPreconditionError,
   AbortedError, OutOfRangeError, UnimplementedError, InternalError,
   UnavailableError, DataLossError,
   UnauthenticatedError][grpc_error_code] || GaxError
end

.str_dotted_access(obj, name) ⇒ String?

Helper function for #compute_bundle_id. Used to retrieve a nested field signified by name where dots in name indicate nested objects.

Parameters:

  • obj (Object)

    an object.

  • name (String)

    a name for a field in the object.

Returns:

  • (String, nil)

    value of named attribute. Can be nil.



51
52
53
54
55
56
57
# File 'lib/google/gax/bundling.rb', line 51

def str_dotted_access(obj, name)
  name.split('.').each do |part|
    obj = obj[part]
    break if obj.nil?
  end
  obj.nil? ? nil : obj.to_s
end

.time_to_timestamp(time) ⇒ Google::Protobuf::Timestamp

Utility for converting a Ruby Time instance to a Google::Protobuf::Timestamp.

Parameters:

  • time (Time)

    The Time to be converted.

Returns:

  • (Google::Protobuf::Timestamp)

    The converted Google::Protobuf::Timestamp.



180
181
182
# File 'lib/google/gax/util.rb', line 180

def time_to_timestamp(time)
  Google::Protobuf::Timestamp.new(seconds: time.to_i, nanos: time.nsec)
end

.timestamp_to_time(timestamp) ⇒ Time

Utility for converting a Google::Protobuf::Timestamp instance to a Ruby time.

Parameters:

  • timestamp (Google::Protobuf::Timestamp)

    The timestamp to be converted.

Returns:

  • (Time)

    The converted Time.



169
170
171
# File 'lib/google/gax/util.rb', line 169

def timestamp_to_time(timestamp)
  Time.at(timestamp.nanos * 10**-9 + timestamp.seconds)
end

.to_proto(hash, message_class) ⇒ Object

Creates an instance of a protobuf message from a hash that may include nested hashes. ‘google/protobuf` allows for the instantiation of protobuf messages using hashes but does not allow for nested hashes to instantiate nested submessages.

Parameters:

  • hash (Hash || Class)

    The hash to be converted into a proto message. If an instance of the proto message class is given, it is returned unchanged.

  • message_class (Class)

    The corresponding protobuf message class of the given hash.

Returns:

  • (Object)

    An instance of the given message class.



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/google/gax/util.rb', line 54

def to_proto(hash, message_class)
  return hash if hash.is_a? message_class

  # Sanity check: input must be a Hash
  unless hash.is_a? Hash
    raise ArgumentError.new(
      "Value #{hash} must be a Hash or a #{message_class.name}"
    )
  end
  hash = coerce_submessages(hash, message_class)
  message_class.new(hash)
end