Skip to content
This repository has been archived by the owner on Dec 8, 2021. It is now read-only.

Add LRO wrapper. #47

Merged
merged 7 commits into from
Nov 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ Metrics/MethodLength:
Metrics/PerceivedComplexity:
Max: 11

Metrics/BlockLength:
Max: 26

# Offense count: 2
Style/Documentation:
Exclude:
Expand All @@ -38,7 +41,7 @@ Style/Documentation:
# Offense count: 5
Style/StructInheritance:
Exclude:
- 'lib/google/gax.rb'
- 'lib/google/gax/settings.rb'

Style/NumericPredicate:
Enabled: false
1 change: 1 addition & 0 deletions google-gax.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Gem::Specification.new do |s|
s.add_dependency 'googleauth', '~> 0.5.1'
s.add_dependency 'grpc', '~> 1.0'
s.add_dependency 'googleapis-common-protos', '~> 1.3.1'
s.add_dependency 'google-protobuf', '~> 3.1.0'
s.add_dependency 'rly', '~> 0.2.3'

s.add_development_dependency 'codecov', '~> 0.1'
Expand Down
275 changes: 1 addition & 274 deletions lib/google/gax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

require 'google/gax/api_callable'
require 'google/gax/constants'
require 'google/gax/errors'
require 'google/gax/path_template'
require 'google/gax/settings'
Expand All @@ -36,279 +37,5 @@
module Google
# Gax defines Google API extensions
module Gax
# rubocop:disable Metrics/ParameterLists

# Encapsulates the call settings for an ApiCallable
# @!attribute [r] timeout
# @return [Numeric]
# @!attribute [r] retry_options
# @return [RetryOptions]
# @!attribute [r] page_descriptor
# @return [PageDescriptor]
# @!attribute [r] page_token
# @return [Object]
# @!attribute [r] bundle_descriptor
# @return [BundleDescriptor]
# @!attribute [r] kwargs
# @return [Hash]
class CallSettings
attr_reader :timeout, :retry_options, :page_descriptor, :page_token,
:bundler, :bundle_descriptor, :kwargs, :errors

# @param timeout [Numeric] The client-side timeout for API calls. This
# parameter is ignored for retrying calls.
# @param retry_options [RetryOptions] The configuration for retrying upon
# transient error. If set to nil, this call will not retry.
# @param page_descriptor [PageDescriptor] indicates the structure of page
# streaming to be performed. If set to nil, page streaming is not
# performed.
# @param page_token [Object] determines the page token used in the
# page streaming request. If there is no page_descriptor, this has no
# meaning.
# @param bundler orchestrates bundling. If nil, bundling is not
# performed.
# @param bundle_descriptor [BundleDescriptor] indicates the structure of
# the bundle. If nil, bundling is not performed.
# @param kwargs [Hash]
# Additional keyword argments to be passed to the API call.
# @param errors [Array<Exception>]
# Configures the exceptions to wrap with GaxError.
def initialize(timeout: 30, retry_options: nil, page_descriptor: nil,
page_token: nil, bundler: nil, bundle_descriptor: nil,
kwargs: {}, errors: [])
@timeout = timeout
@retry_options = retry_options
@page_descriptor = page_descriptor
@page_token = page_token
@bundler = bundler
@bundle_descriptor = bundle_descriptor
@kwargs = kwargs
@errors = errors
end

# @return true when it has retry codes.
def retry_codes?
@retry_options && @retry_options.retry_codes
end

# @return true when it has valid bundler configuration.
def bundler?
@bundler && @bundle_descriptor
end

# Creates a new CallSetting instance which is based on this but merged
# settings from options.
# @param options [CallOptions, nil] The overriding call settings.
# @return a new merged call settings.
def merge(options)
unless options
return CallSettings.new(timeout: @timeout,
retry_options: @retry_options,
page_descriptor: @page_descriptor,
page_token: @page_token,
bundler: @bundler,
bundle_descriptor: @bundle_descriptor,
kwargs: @kwargs,
errors: @errors)
end

timeout = if options.timeout == :OPTION_INHERIT
@timeout
else
options.timeout
end
retry_options = if options.retry_options == :OPTION_INHERIT
@retry_options
else
options.retry_options
end
page_token = if options.page_token == :OPTION_INHERIT
@page_token
else
options.page_token
end

kwargs = @kwargs.dup
kwargs.update(options.kwargs) if options.kwargs != :OPTION_INHERIT

CallSettings.new(timeout: timeout,
retry_options: retry_options,
page_descriptor: @page_descriptor,
page_token: page_token,
bundler: @bundler,
bundle_descriptor: @bundle_descriptor,
kwargs: kwargs,
errors: @errors)
end
end

private_constant :CallSettings

# Encapsulates the overridable settings for a particular API call
# @!attribute [r] timeout
# @return [Numeric, :OPTION_INHERIT]
# @!attribute [r] retry_options
# @return [RetryOptions, :OPTION_INHERIT]
# @!attribute [r] page_token
# @return [Object, :OPTION_INHERIT, :INITIAL_PAGE]
# @!attribute [r] kwargs
# @return [Hash, :OPTION_INHERIT]
class CallOptions
attr_reader :timeout, :retry_options, :page_token, :kwargs

# @param timeout [Numeric, :OPTION_INHERIT]
# The client-side timeout for API calls.
# @param retry_options [RetryOptions, :OPTION_INHERIT]
# The configuration for retrying upon transient error.
# If set to nil, this call will not retry.
# @param page_token [Object, :OPTION_INHERIT]
# If set and the call is configured for page streaming, page streaming
# is starting with this page_token.
# @param kwargs [Hash, :OPTION_INHERIT]
# Additional keyword argments to be passed to the API call.
def initialize(timeout: :OPTION_INHERIT,
retry_options: :OPTION_INHERIT,
page_token: :OPTION_INHERIT,
kwargs: :OPTION_INHERIT)
@timeout = timeout
@retry_options = retry_options
@page_token = page_token
@kwargs = kwargs
end
end

# Describes the structure of a page-streaming call.
class PageDescriptor < Struct.new(:request_page_token_field,
:response_page_token_field,
:resource_field)
end

# Per-call configurable settings for retrying upon transient failure.
class RetryOptions < Struct.new(:retry_codes, :backoff_settings)
# @!attribute retry_codes
# @return [Array<Grpc::Code>] a list of exceptions upon which
# a retry should be attempted.
# @!attribute backoff_settings
# @return [BackoffSettings] configuring the retry exponential
# backoff algorithm.
end

# Parameters to the exponential backoff algorithm for retrying.
class BackoffSettings < Struct.new(
:initial_retry_delay_millis,
:retry_delay_multiplier,
:max_retry_delay_millis,
:initial_rpc_timeout_millis,
:rpc_timeout_multiplier,
:max_rpc_timeout_millis,
:total_timeout_millis
)
# @!attribute initial_retry_delay_millis
# @return [Numeric] the initial delay time, in milliseconds,
# between the completion of the first failed request and the
# initiation of the first retrying request.
# @!attribute retry_delay_multiplier
# @return [Numeric] the multiplier by which to increase the
# delay time between the completion of failed requests, and
# the initiation of the subsequent retrying request.
# @!attribute max_retry_delay_millis
# @return [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.
# @!attribute initial_rpc_timeout_millis
# @return [Numeric] the initial timeout parameter to the request.
# @!attribute rpc_timeout_multiplier
# @return [Numeric] the multiplier by which to increase the
# timeout parameter between failed requests.
# @!attribute max_rpc_timeout_millis
# @return [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.
# @!attribute total_timeout_millis
# @return [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.
end

# Describes the structure of bundled call.
#
# request_discriminator_fields may include '.' as a separator, which is
# used to indicate object traversal. This allows fields in nested objects
# to be used to determine what requests to bundle.
class BundleDescriptor < Struct.new(:bundled_field,
:request_discriminator_fields,
:subresponse_field)
# @!attribute bundled_field
# @return [String] the repeated field in the request message
# that will have its elements aggregated by bundling.
# @!attribute request_discriminator_fields
# @return [Array<String>] a list of fields in the target
# request message class that are used to determine which
# messages should be bundled together.
# @!attribute subresponse_field
# @return [String] an optional field, when present it
# indicates the field in the response message that should be
# used to demultiplex the response into multiple response
# messages.
def initialize(bundled_field, request_discriminator_fields,
subresponse_field: nil)
super(bundled_field, request_discriminator_fields, subresponse_field)
end
end

# Holds values used to configure bundling.
#
# The xxx_threshold attributes are used to configure when the bundled
# request should be made.
class BundleOptions < Struct.new(:element_count_threshold,
:element_count_limit,
:request_byte_threshold,
:request_byte_limit,
:delay_threshold_millis)
# @!attribute element_count_threshold
# @return [Numeric] the bundled request will be sent once the
# count of outstanding elements in the repeated field
# reaches this value.
# @!attribute element_count_limit
# @return [Numeric] represents a hard limit on the number of
# elements in the repeated field of the bundle; if adding a
# request to a bundle would exceed this value, the bundle is
# sent and the new request is added to a fresh bundle. It is
# invalid for a single request to exceed this limit.
# @!attribute request_byte_threshold
# @return [Numeric] the bundled request will be sent once the
# count of bytes in the request reaches this value. Note
# that this value is pessimistically approximated by summing
# the bytesizes of the elements in the repeated field, and
# therefore may be an under-approximation.
# @!attribute request_byte_limit
# @return [Numeric] represents a hard limit on the size of the
# bundled request; if adding a request to a bundle would
# exceed this value, the bundle is sent and the new request
# is added to a fresh bundle. It is invalid for a single
# request to exceed this limit. Note that this value is
# pessimistically approximated by summing the bytesizes of
# the elements in the repeated field, with a buffer applied
# to correspond to the resulting under-approximation.
# @!attribute delay_threshold_millis
# @return [Numeric] the bundled request will be sent this
# amount of time after the first element in the bundle was
# added to it.
def initialize(element_count_threshold: 0,
element_count_limit: 0,
request_byte_threshold: 0,
request_byte_limit: 0,
delay_threshold_millis: 0)
super(
element_count_threshold,
element_count_limit,
request_byte_threshold,
request_byte_limit,
delay_threshold_millis)
end
end
end
end
3 changes: 0 additions & 3 deletions lib/google/gax/api_callable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@

module Google
module Gax
MILLIS_PER_SECOND = 1000.0

# A class to provide the Enumerable interface for page-streaming method.
# PagedEnumerable assumes that the API call returns a message for a page
# which holds a list of resources and the token to the next page.
Expand Down Expand Up @@ -341,7 +339,6 @@ def retryable(a_func, retry_options, kwargs)
result = nil
now = Time.now
deadline = now + total_timeout

loop do
begin
result = add_timeout_arg(a_func, timeout, kwargs).call(request)
Expand Down
2 changes: 1 addition & 1 deletion lib/google/gax/bundling.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def initialize(api_call,
# The number of bundled elements in the repeated field.
# @return [Numeric]
def element_count
@inputs.reduce(0) { |a, e| a + e.count }
@inputs.reduce(0) { |acc, elem| acc + elem.count }
end

# The size of the request in bytes of the bundled field elements.
Expand Down
34 changes: 34 additions & 0 deletions lib/google/gax/constants.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

module Google
module Gax
MILLIS_PER_SECOND = 1000.0
end
end
Loading