google-gax 0.1.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/google/gax.rb +61 -54
- data/lib/google/gax/api_callable.rb +77 -44
- data/lib/google/gax/errors.rb +14 -8
- data/lib/google/gax/grpc.rb +15 -12
- data/lib/google/gax/path_template.rb +4 -2
- data/lib/google/gax/settings.rb +88 -62
- data/lib/google/gax/version.rb +1 -1
- data/spec/google/gax/api_callable_spec.rb +59 -10
- data/spec/google/gax/path_template_spec.rb +2 -1
- data/spec/google/gax/settings_spec.rb +80 -10
- metadata +3 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df878307196d3628c155d4de6d3b333524b93937
|
4
|
+
data.tar.gz: bd5b46d05109352ad29de368998e36efe1bfcd8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18285c95727f2da714caf8c9ad7d8a99cb7d50bfeb2322045dbc4f4bf4f1b549441d7f0b8e035ab9d708fd820ebc9252260ec17165a90fb36d681f7fecc1e007
|
7
|
+
data.tar.gz: 50b8a13d7f050e099146eba2f1d11f77e123c5fa64923d731d3707ff2f539e70d71a9f6dea790143990fa47e05b801e8501cd5d3ca0b51f4291e07368e15ab7a
|
data/lib/google/gax.rb
CHANGED
@@ -36,6 +36,8 @@ require 'google/gax/version'
|
|
36
36
|
|
37
37
|
module Google
|
38
38
|
module Gax
|
39
|
+
# rubocop:disable Metrics/ParameterLists
|
40
|
+
|
39
41
|
# Encapsulates the call settings for an ApiCallable
|
40
42
|
# @!attribute [r] timeout
|
41
43
|
# @return [Numeric]
|
@@ -43,29 +45,34 @@ module Google
|
|
43
45
|
# @return [RetryOptions]
|
44
46
|
# @!attribute [r] page_descriptor
|
45
47
|
# @return [PageDescriptor]
|
48
|
+
# @!attribute [r] page_token
|
49
|
+
# @return [Object]
|
46
50
|
# @!attribute [r] bundle_descriptor
|
47
51
|
# @return [BundleDescriptor]
|
48
52
|
class CallSettings
|
49
|
-
attr_reader :timeout, :retry_options, :page_descriptor, :
|
50
|
-
:bundle_descriptor
|
53
|
+
attr_reader :timeout, :retry_options, :page_descriptor, :page_token,
|
54
|
+
:bundler, :bundle_descriptor
|
51
55
|
|
52
56
|
# @param timeout [Numeric] The client-side timeout for API calls. This
|
53
57
|
# parameter is ignored for retrying calls.
|
54
58
|
# @param retry_options [RetryOptions] The configuration for retrying upon
|
55
|
-
# transient error. If set to
|
59
|
+
# transient error. If set to nil, this call will not retry.
|
56
60
|
# @param page_descriptor [PageDescriptor] indicates the structure of page
|
57
|
-
# streaming to be performed. If set to
|
61
|
+
# streaming to be performed. If set to nil, page streaming is not
|
58
62
|
# performed.
|
59
|
-
# @param
|
63
|
+
# @param page_token [Object] determines the page token used in the
|
64
|
+
# page streaming request. If there is no page_descriptor, this has no
|
65
|
+
# meaning.
|
66
|
+
# @param bundler orchestrates bundling. If nil, bundling is not
|
60
67
|
# performed.
|
61
68
|
# @param bundle_descriptor [BundleDescriptor] indicates the structure of
|
62
|
-
# the bundle. If
|
63
|
-
def initialize(
|
64
|
-
|
65
|
-
bundler: nil, bundle_descriptor: nil)
|
69
|
+
# the bundle. If nil, bundling is not performed.
|
70
|
+
def initialize(timeout: 30, retry_options: nil, page_descriptor: nil,
|
71
|
+
page_token: nil, bundler: nil, bundle_descriptor: nil)
|
66
72
|
@timeout = timeout
|
67
73
|
@retry_options = retry_options
|
68
74
|
@page_descriptor = page_descriptor
|
75
|
+
@page_token = page_token
|
69
76
|
@bundler = bundler
|
70
77
|
@bundle_descriptor = bundle_descriptor
|
71
78
|
end
|
@@ -86,12 +93,12 @@ module Google
|
|
86
93
|
# @return a new merged call settings.
|
87
94
|
def merge(options)
|
88
95
|
unless options
|
89
|
-
return CallSettings.new(
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
96
|
+
return CallSettings.new(timeout: @timeout,
|
97
|
+
retry_options: @retry_options,
|
98
|
+
page_descriptor: @page_descriptor,
|
99
|
+
page_token: @page_token,
|
100
|
+
bundler: @bundler,
|
101
|
+
bundle_descriptor: @bundle_descriptor)
|
95
102
|
end
|
96
103
|
|
97
104
|
timeout = if options.timeout == :OPTION_INHERIT
|
@@ -104,14 +111,18 @@ module Google
|
|
104
111
|
else
|
105
112
|
options.retry_options
|
106
113
|
end
|
107
|
-
|
114
|
+
page_token = if options.page_token == :OPTION_INHERIT
|
115
|
+
@page_token
|
116
|
+
else
|
117
|
+
options.page_token
|
118
|
+
end
|
108
119
|
|
109
|
-
CallSettings.new(
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
120
|
+
CallSettings.new(timeout: timeout,
|
121
|
+
retry_options: retry_options,
|
122
|
+
page_descriptor: @page_descriptor,
|
123
|
+
page_token: page_token,
|
124
|
+
bundler: @bundler,
|
125
|
+
bundle_descriptor: @bundle_descriptor)
|
115
126
|
end
|
116
127
|
end
|
117
128
|
|
@@ -120,34 +131,32 @@ module Google
|
|
120
131
|
# @return [Numeric, :OPTION_INHERIT]
|
121
132
|
# @!attribute [r] retry_options
|
122
133
|
# @return [RetryOptions, :OPTION_INHERIT]
|
123
|
-
# @!attribute [r]
|
124
|
-
# @return [
|
134
|
+
# @!attribute [r] page_token
|
135
|
+
# @return [Object, :OPTION_INHERIT, :INITIAL_PAGE]
|
125
136
|
class CallOptions
|
126
|
-
attr_reader :timeout, :retry_options, :
|
137
|
+
attr_reader :timeout, :retry_options, :page_token
|
127
138
|
|
128
139
|
# @param timeout [Numeric, :OPTION_INHERIT]
|
129
140
|
# The client-side timeout for API calls.
|
130
141
|
# @param retry_options [RetryOptions, :OPTION_INHERIT]
|
131
142
|
# The configuration for retrying upon transient error.
|
132
143
|
# If set to nil, this call will not retry.
|
133
|
-
# @param
|
144
|
+
# @param page_token [Object, :OPTION_INHERIT]
|
134
145
|
# If set and the call is configured for page streaming, page streaming
|
135
|
-
# is
|
136
|
-
def initialize(
|
137
|
-
|
138
|
-
|
139
|
-
is_page_streaming: :OPTION_INHERIT)
|
146
|
+
# is starting with this page_token.
|
147
|
+
def initialize(timeout: :OPTION_INHERIT,
|
148
|
+
retry_options: :OPTION_INHERIT,
|
149
|
+
page_token: :OPTION_INHERIT)
|
140
150
|
@timeout = timeout
|
141
151
|
@retry_options = retry_options
|
142
|
-
@
|
152
|
+
@page_token = page_token
|
143
153
|
end
|
144
154
|
end
|
145
155
|
|
146
156
|
# Describes the structure of a page-streaming call.
|
147
|
-
class PageDescriptor < Struct.new(
|
148
|
-
|
149
|
-
|
150
|
-
:resource_field)
|
157
|
+
class PageDescriptor < Struct.new(:request_page_token_field,
|
158
|
+
:response_page_token_field,
|
159
|
+
:resource_field)
|
151
160
|
end
|
152
161
|
|
153
162
|
# Per-call configurable settings for retrying upon transient failure.
|
@@ -168,7 +177,8 @@ module Google
|
|
168
177
|
:initial_rpc_timeout_millis,
|
169
178
|
:rpc_timeout_multiplier,
|
170
179
|
:max_rpc_timeout_millis,
|
171
|
-
:total_timeout_millis
|
180
|
+
:total_timeout_millis
|
181
|
+
)
|
172
182
|
# @!attribute initial_retry_delay_millis
|
173
183
|
# @return [Numeric] the initial delay time, in milliseconds,
|
174
184
|
# between the completion of the first failed request and the
|
@@ -204,13 +214,12 @@ module Google
|
|
204
214
|
# request_discriminator_fields may include '.' as a separator, which is
|
205
215
|
# used to indicate object traversal. This allows fields in nested objects
|
206
216
|
# to be used to determine what requests to bundle.
|
207
|
-
class BundleDescriptor < Struct.new(
|
208
|
-
|
209
|
-
|
210
|
-
:subresponse_field)
|
217
|
+
class BundleDescriptor < Struct.new(:bundled_field,
|
218
|
+
:request_discriminator_fields,
|
219
|
+
:subresponse_field)
|
211
220
|
# @!attribute bundled_field
|
212
221
|
# @return [String] the repeated field in the request message
|
213
|
-
# that will have its elements aggregated by bundling
|
222
|
+
# that will have its elements aggregated by bundling.
|
214
223
|
# @!attribute request_discriminator_fields
|
215
224
|
# @return [Array<String>] a list of fields in the target
|
216
225
|
# request message class that are used to determine which
|
@@ -230,12 +239,11 @@ module Google
|
|
230
239
|
#
|
231
240
|
# The xxx_threshold attributes are used to configure when the bundled
|
232
241
|
# request should be made.
|
233
|
-
class BundleOptions < Struct.new(
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
:delay_threshold)
|
242
|
+
class BundleOptions < Struct.new(:element_count_threshold,
|
243
|
+
:element_count_limit,
|
244
|
+
:request_byte_threshold,
|
245
|
+
:request_byte_limit,
|
246
|
+
:delay_threshold)
|
239
247
|
# @!attribute element_count_threshold
|
240
248
|
# @return [Numeric] the bundled request will be sent once the
|
241
249
|
# count of outstanding elements in the repeated field
|
@@ -265,12 +273,11 @@ module Google
|
|
265
273
|
# @return [Numeric] the bundled request will be sent this
|
266
274
|
# amount of time after the first element in the bundle was
|
267
275
|
# added to it.
|
268
|
-
def initialize(
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
delay_threshold: 0)
|
276
|
+
def initialize(element_count_threshold: 0,
|
277
|
+
element_count_limit: 0,
|
278
|
+
request_byte_threshold: 0,
|
279
|
+
request_byte_limit: 0,
|
280
|
+
delay_threshold: 0)
|
274
281
|
super(
|
275
282
|
element_count_threshold,
|
276
283
|
element_count_limit,
|
@@ -33,6 +33,7 @@ require 'google/gax/errors'
|
|
33
33
|
require 'google/gax/grpc'
|
34
34
|
|
35
35
|
# rubocop:disable Metrics/ModuleLength
|
36
|
+
|
36
37
|
module Google
|
37
38
|
module Gax
|
38
39
|
MILLIS_PER_SECOND = 1000.0
|
@@ -44,14 +45,37 @@ module Google
|
|
44
45
|
# PagedEnumerable provides the enumerations over the resource data,
|
45
46
|
# and also provides the enumerations over the pages themselves.
|
46
47
|
#
|
48
|
+
# Example 1: normal iteration over resources.
|
49
|
+
# paged_enumerable.each { |resource| puts resource }
|
50
|
+
#
|
51
|
+
# Example 2: per-page iteration.
|
52
|
+
# paged_enumerable.each_page { |page| puts page }
|
53
|
+
#
|
54
|
+
# Example 3: Enumerable over pages.
|
55
|
+
# pages = paged_enumerable.enum_for(:each_page).to_a
|
56
|
+
#
|
57
|
+
# Example 4: more exact operations over pages.
|
58
|
+
# while some_condition()
|
59
|
+
# page = paged_enumerable.page
|
60
|
+
# do_something(page)
|
61
|
+
# break if paged_enumerable.next_page?
|
62
|
+
# paged_enumerable.next_page
|
63
|
+
# end
|
64
|
+
#
|
47
65
|
# @attribute [r] page
|
48
66
|
# @return [Page] The current page object.
|
67
|
+
# @attribute [r] response
|
68
|
+
# @return [Object] The current response object.
|
69
|
+
# @attribute [r] page_token
|
70
|
+
# @return [Object] The page token to be used for the next API call.
|
49
71
|
class PagedEnumerable
|
50
72
|
# A class to represent a page in a PagedEnumerable. This also implements
|
51
73
|
# Enumerable, so it can iterate over the resource elements.
|
52
74
|
#
|
53
75
|
# @attribute [r] response
|
54
|
-
# @return [Object]
|
76
|
+
# @return [Object] the actual response object.
|
77
|
+
# @attribute [r] next_page_token
|
78
|
+
# @return [Object] the page token to be used for the next API call.
|
55
79
|
class Page
|
56
80
|
include Enumerable
|
57
81
|
attr_reader :response
|
@@ -112,14 +136,17 @@ module Google
|
|
112
136
|
end
|
113
137
|
|
114
138
|
# Initiate the streaming with the requests and keywords.
|
139
|
+
# @param page_token [Object]
|
140
|
+
# The page token for the first page to be streamed, or nil.
|
115
141
|
# @param request [Object]
|
116
142
|
# The initial request object.
|
117
143
|
# @param kwargs [Hash]
|
118
144
|
# Other keyword arguments to be passed to a_func.
|
119
145
|
# @return [PagedEnumerable]
|
120
146
|
# returning self for further uses.
|
121
|
-
def start(request, **kwargs)
|
147
|
+
def start(page_token, request, **kwargs)
|
122
148
|
@request = request
|
149
|
+
@request[@request_page_token_field] = page_token if page_token
|
123
150
|
@kwargs = kwargs
|
124
151
|
@page = @page.dup_with(@func.call(@request, **@kwargs))
|
125
152
|
self
|
@@ -143,9 +170,9 @@ module Google
|
|
143
170
|
|
144
171
|
# Iterate over the pages.
|
145
172
|
# @yield [Page] Gives the pages in the stream.
|
146
|
-
# @raise [
|
173
|
+
# @raise [GaxError] if it's not started yet.
|
147
174
|
def each_page
|
148
|
-
raise 'not started!' unless started?
|
175
|
+
raise GaxError, 'not started!' unless started?
|
149
176
|
yield @page
|
150
177
|
loop do
|
151
178
|
break unless next_page?
|
@@ -165,6 +192,14 @@ module Google
|
|
165
192
|
@request[@request_page_token_field] = @page.next_page_token
|
166
193
|
@page = @page.dup_with(@func.call(@request, **@kwargs))
|
167
194
|
end
|
195
|
+
|
196
|
+
def response
|
197
|
+
@page.response
|
198
|
+
end
|
199
|
+
|
200
|
+
def page_token
|
201
|
+
@page.next_page_token
|
202
|
+
end
|
168
203
|
end
|
169
204
|
|
170
205
|
# rubocop:disable Metrics/AbcSize
|
@@ -190,9 +225,9 @@ module Google
|
|
190
225
|
# e.g, if bundling and page_streaming are both configured
|
191
226
|
def create_api_call(func, settings)
|
192
227
|
api_call = if settings.retry_codes?
|
193
|
-
|
228
|
+
retryable(func, settings.retry_options)
|
194
229
|
else
|
195
|
-
|
230
|
+
add_timeout_arg(func, settings.timeout)
|
196
231
|
end
|
197
232
|
|
198
233
|
if settings.page_descriptor
|
@@ -200,18 +235,20 @@ module Google
|
|
200
235
|
raise 'ApiCallable has incompatible settings: ' \
|
201
236
|
'bundling and page streaming'
|
202
237
|
end
|
203
|
-
return
|
238
|
+
return page_streamable(
|
204
239
|
api_call,
|
205
240
|
settings.page_descriptor.request_page_token_field,
|
206
241
|
settings.page_descriptor.response_page_token_field,
|
207
|
-
settings.page_descriptor.resource_field
|
242
|
+
settings.page_descriptor.resource_field,
|
243
|
+
settings.page_token
|
244
|
+
)
|
208
245
|
end
|
209
246
|
if settings.bundler?
|
210
|
-
return
|
211
|
-
|
247
|
+
return bundleable(api_call, settings.bundle_descriptor,
|
248
|
+
settings.bundler)
|
212
249
|
end
|
213
250
|
|
214
|
-
|
251
|
+
catch_errors(api_call)
|
215
252
|
end
|
216
253
|
|
217
254
|
# Updates a_func to wrap exceptions with GaxError
|
@@ -219,16 +256,12 @@ module Google
|
|
219
256
|
# @param a_func [Proc]
|
220
257
|
# @param errors [Array<Exception>] Configures the exceptions to wrap.
|
221
258
|
# @return [Proc] A proc that will wrap certain exceptions with GaxError
|
222
|
-
def
|
259
|
+
def catch_errors(a_func, errors: Grpc::API_ERRORS)
|
223
260
|
proc do |request, **kwargs|
|
224
261
|
begin
|
225
262
|
a_func.call(request, **kwargs)
|
226
|
-
rescue
|
227
|
-
|
228
|
-
raise GaxError.new('RPC failed', cause: err)
|
229
|
-
else
|
230
|
-
raise err
|
231
|
-
end
|
263
|
+
rescue *errors
|
264
|
+
raise GaxError, 'RPC failed'
|
232
265
|
end
|
233
266
|
end
|
234
267
|
end
|
@@ -248,11 +281,10 @@ module Google
|
|
248
281
|
# @param bundler orchestrates bundling.
|
249
282
|
# @return [Proc] A proc takes the API call's request and returns
|
250
283
|
# an Event object.
|
251
|
-
def
|
284
|
+
def bundleable(a_func, desc, bundler)
|
252
285
|
proc do |request|
|
253
|
-
the_id = bundling.compute_bundle_id(
|
254
|
-
|
255
|
-
desc.request_discriminator_fields)
|
286
|
+
the_id = bundling.compute_bundle_id(request,
|
287
|
+
desc.request_discriminator_fields)
|
256
288
|
return bundler.schedule(a_func, the_id, desc, request)
|
257
289
|
end
|
258
290
|
end
|
@@ -265,17 +297,21 @@ module Google
|
|
265
297
|
# @param response_page_token_field [String] The field of the next
|
266
298
|
# page token in the response.
|
267
299
|
# @param resource_field [String] The field to be streamed.
|
300
|
+
# @param page_token [Object] The page_token for the first page to be
|
301
|
+
# streamed, or nil.
|
268
302
|
# @return [Proc] A proc that returns an iterable over the specified field.
|
269
|
-
def
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
303
|
+
def page_streamable(a_func,
|
304
|
+
request_page_token_field,
|
305
|
+
response_page_token_field,
|
306
|
+
resource_field,
|
307
|
+
page_token)
|
274
308
|
enumerable = PagedEnumerable.new(a_func,
|
275
309
|
request_page_token_field,
|
276
310
|
response_page_token_field,
|
277
311
|
resource_field)
|
278
|
-
|
312
|
+
proc do |request, **kwargs|
|
313
|
+
enumerable.start(page_token, request, **kwargs)
|
314
|
+
end
|
279
315
|
end
|
280
316
|
|
281
317
|
# rubocop:disable Metrics/MethodLength
|
@@ -288,7 +324,7 @@ module Google
|
|
288
324
|
# upon which the proc should retry, and the parameters to the
|
289
325
|
# exponential backoff retry algorithm.
|
290
326
|
# @return [Proc] A proc that will retry on exception.
|
291
|
-
def
|
327
|
+
def retryable(a_func, retry_options)
|
292
328
|
delay_mult = retry_options.backoff_settings.retry_delay_multiplier
|
293
329
|
max_delay = (retry_options.backoff_settings.max_retry_delay_millis /
|
294
330
|
MILLIS_PER_SECOND)
|
@@ -302,32 +338,29 @@ module Google
|
|
302
338
|
delay = retry_options.backoff_settings.initial_retry_delay_millis
|
303
339
|
timeout = (retry_options.backoff_settings.initial_rpc_timeout_millis /
|
304
340
|
MILLIS_PER_SECOND)
|
305
|
-
exc = nil
|
306
341
|
result = nil
|
307
342
|
now = Time.now
|
308
343
|
deadline = now + total_timeout
|
309
344
|
|
310
|
-
|
345
|
+
loop do
|
311
346
|
begin
|
312
|
-
|
313
|
-
result = _add_timeout_arg(a_func, timeout).call(request, **kwargs)
|
347
|
+
result = add_timeout_arg(a_func, timeout).call(request, **kwargs)
|
314
348
|
break
|
315
349
|
rescue => exception
|
316
350
|
unless exception.respond_to?(:code) &&
|
317
351
|
retry_options.retry_codes.include?(exception.code)
|
318
|
-
raise RetryError
|
319
|
-
|
320
|
-
cause: exception)
|
352
|
+
raise RetryError, 'Exception occurred in retry method that ' \
|
353
|
+
'was not classified as transient'
|
321
354
|
end
|
322
|
-
exc = RetryError.new('Retry total timeout exceeded with exception',
|
323
|
-
cause: exception)
|
324
355
|
sleep(rand(delay) / MILLIS_PER_SECOND)
|
325
356
|
now = Time.now
|
326
357
|
delay = [delay * delay_mult, max_delay].min
|
327
358
|
timeout = [timeout * timeout_mult, max_timeout, deadline - now].min
|
359
|
+
if now >= deadline
|
360
|
+
raise RetryError, 'Retry total timeout exceeded with exception'
|
361
|
+
end
|
328
362
|
end
|
329
363
|
end
|
330
|
-
raise exc unless exc.nil?
|
331
364
|
result
|
332
365
|
end
|
333
366
|
end
|
@@ -341,16 +374,16 @@ module Google
|
|
341
374
|
# @param timeout [Numeric] to be added to the original proc as it
|
342
375
|
# final positional arg.
|
343
376
|
# @return [Proc] the original proc updated to the timeout arg
|
344
|
-
def
|
377
|
+
def add_timeout_arg(a_func, timeout)
|
345
378
|
proc do |request, **kwargs|
|
346
379
|
kwargs[:timeout] = timeout
|
347
380
|
a_func.call(request, **kwargs)
|
348
381
|
end
|
349
382
|
end
|
350
383
|
|
351
|
-
module_function :create_api_call, :
|
352
|
-
:
|
353
|
-
private_class_method :
|
354
|
-
:
|
384
|
+
module_function :create_api_call, :catch_errors, :bundleable,
|
385
|
+
:page_streamable, :retryable, :add_timeout_arg
|
386
|
+
private_class_method :catch_errors, :bundleable, :page_streamable,
|
387
|
+
:retryable, :add_timeout_arg
|
355
388
|
end
|
356
389
|
end
|
data/lib/google/gax/errors.rb
CHANGED
@@ -27,20 +27,26 @@
|
|
27
27
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
28
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
29
|
|
30
|
+
require 'English'
|
31
|
+
|
30
32
|
module Google
|
31
33
|
module Gax
|
32
34
|
# Common base class for exceptions raised by GAX.
|
33
35
|
class GaxError < StandardError
|
34
|
-
attr_reader :cause
|
35
|
-
|
36
36
|
# @param msg [String] describes the error that occurred.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
def initialize(msg, cause:nil)
|
41
|
-
msg = "GaxError #{msg}, caused by #{cause}" if cause
|
37
|
+
def initialize(msg)
|
38
|
+
msg = "GaxError #{msg}"
|
39
|
+
msg += ", caused by #{$ERROR_INFO}" if $ERROR_INFO
|
42
40
|
super(msg)
|
43
|
-
@cause =
|
41
|
+
@cause = $ERROR_INFO
|
42
|
+
end
|
43
|
+
|
44
|
+
# cause is a new method introduced in 2.1.0, bring this
|
45
|
+
# method if it does not exist.
|
46
|
+
unless respond_to?(:cause)
|
47
|
+
define_method(:cause) do
|
48
|
+
@cause
|
49
|
+
end
|
44
50
|
end
|
45
51
|
end
|
46
52
|
|
data/lib/google/gax/grpc.rb
CHANGED
@@ -34,9 +34,11 @@ module Google
|
|
34
34
|
module Gax
|
35
35
|
# Grpc adapts the gRPC surface
|
36
36
|
module Grpc
|
37
|
-
STATUS_CODE_NAMES =
|
38
|
-
|
39
|
-
|
37
|
+
STATUS_CODE_NAMES = Hash[
|
38
|
+
GRPC::Core::StatusCodes.constants.map do |sym|
|
39
|
+
[sym.to_s, GRPC::Core::StatusCodes.const_get(sym)]
|
40
|
+
end
|
41
|
+
].freeze
|
40
42
|
|
41
43
|
API_ERRORS = [GRPC::BadStatus, GRPC::Cancelled].freeze
|
42
44
|
|
@@ -48,20 +50,21 @@ module Google
|
|
48
50
|
#
|
49
51
|
# @param port [Fixnum] The port on which to connect to the remote host.
|
50
52
|
#
|
51
|
-
# @param chan_creds [
|
52
|
-
#
|
53
|
-
#
|
53
|
+
# @param chan_creds [Grpc::Core::ChannelCredentials]
|
54
|
+
# A ChannelCredentials object for use with an SSL-enabled Channel.
|
55
|
+
# If nil, credentials are pulled from a default location.
|
54
56
|
#
|
55
|
-
# @param channel [Object]
|
56
|
-
#
|
57
|
+
# @param channel [Object]
|
58
|
+
# A Channel object through which to make calls. If nil, a secure
|
59
|
+
# channel is constructed.
|
57
60
|
#
|
58
61
|
# @param updater_proc [Proc]
|
59
|
-
#
|
60
|
-
#
|
62
|
+
# A function that transforms the metadata for requests, e.g., to give
|
63
|
+
# OAuth credentials.
|
61
64
|
#
|
62
65
|
# @param scopes [Array<String>]
|
63
|
-
#
|
64
|
-
#
|
66
|
+
# The OAuth scopes for this service. This parameter is ignored if
|
67
|
+
# a custom metadata_transformer is supplied.
|
65
68
|
#
|
66
69
|
# @yield [address, creds]
|
67
70
|
# the generated gRPC method to create a stub.
|
@@ -216,7 +216,8 @@ module Google
|
|
216
216
|
i += size
|
217
217
|
elsif segment.literal != that[i]
|
218
218
|
throw ArgumentError.new(
|
219
|
-
"mismatched literal: '#{segment.literal}' != '#{that[i]}'"
|
219
|
+
"mismatched literal: '#{segment.literal}' != '#{that[i]}'"
|
220
|
+
)
|
220
221
|
else
|
221
222
|
i += 1
|
222
223
|
end
|
@@ -226,7 +227,8 @@ module Google
|
|
226
227
|
end
|
227
228
|
if i != that.size || i != segment_count
|
228
229
|
throw ArgumentError.new(
|
229
|
-
"match error: could not instantiate a path template from #{path}"
|
230
|
+
"match error: could not instantiate a path template from #{path}"
|
231
|
+
)
|
230
232
|
end
|
231
233
|
bindings
|
232
234
|
end
|
data/lib/google/gax/settings.rb
CHANGED
@@ -31,32 +31,23 @@ module Google
|
|
31
31
|
module Gax
|
32
32
|
# Helper for #construct_settings
|
33
33
|
#
|
34
|
-
# @param
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# @param method_retry_override [BundleOptions, :OPTION_INHERIT, nil]
|
38
|
-
# If set to :OPTION_INHERIT, the retry settings are derived from
|
39
|
-
# method config. Otherwise, this parameter overrides
|
40
|
-
# +method_config+.
|
41
|
-
|
34
|
+
# @param bundle_config A Hash specifying a bundle parameters, the value for
|
35
|
+
# 'bundling' field in a method config (See ``construct_settings()`` for
|
36
|
+
# information on this config.)
|
42
37
|
# @param bundle_descriptor [BundleDescriptor] A BundleDescriptor
|
43
38
|
# object describing the structure of bundling for this
|
44
39
|
# method. If not set, this method will not bundle.
|
45
40
|
# @return An Executor that configures bundling, or nil if this
|
46
41
|
# method should not bundle.
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
options =
|
52
|
-
method_config['bundling'].each_pair do |key, value|
|
53
|
-
options[key.intern] = value
|
54
|
-
end
|
55
|
-
# TODO: comment-out when bundling is supported.
|
56
|
-
# Executor.new(options)
|
57
|
-
elsif method_bundling_override
|
58
|
-
# Executor.new(method_bundling_override)
|
42
|
+
def construct_bundling(bundle_config, bundle_descriptor)
|
43
|
+
if bundle_config && bundle_descriptor
|
44
|
+
options = BundleOptions.new
|
45
|
+
bundle_config.each_pair do |key, value|
|
46
|
+
options[key.intern] = value
|
59
47
|
end
|
48
|
+
# TODO: comment-out when bundling is supported.
|
49
|
+
# Executor.new(options)
|
50
|
+
nil
|
60
51
|
end
|
61
52
|
end
|
62
53
|
|
@@ -65,11 +56,7 @@ module Google
|
|
65
56
|
# @param method_config [Hash] A dictionary representing a single
|
66
57
|
# +methods+ entry of the standard API client config file. (See
|
67
58
|
# #construct_settings for information on this yaml.)
|
68
|
-
# @param
|
69
|
-
# If set to :OPTION_INHERIT, the retry settings are derived from
|
70
|
-
# method config. Otherwise, this parameter overrides
|
71
|
-
# +method_config+.
|
72
|
-
# @param retry_codes_def [Hash] A dictionary parsed from the
|
59
|
+
# @param retry_codes [Hash] A dictionary parsed from the
|
73
60
|
# +retry_codes_def+ entry of the standard API client config
|
74
61
|
# file. (See #construct_settings for information on this yaml.)
|
75
62
|
# @param retry_params [Hash] A dictionary parsed from the
|
@@ -79,28 +66,55 @@ module Google
|
|
79
66
|
# used in the standard API client config file to API response
|
80
67
|
# status codes.
|
81
68
|
# @return [RetryOptions, nil]
|
82
|
-
def
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
codes = retry_codes.fetch(retry_codes_name, []).map do |name|
|
91
|
-
retry_names[name]
|
69
|
+
def construct_retry(method_config, retry_codes, retry_params, retry_names)
|
70
|
+
return nil unless method_config
|
71
|
+
codes = nil
|
72
|
+
if retry_codes && method_config.key?('retry_codes_name')
|
73
|
+
retry_codes_name = method_config['retry_codes_name']
|
74
|
+
codes = retry_codes.fetch(retry_codes_name, []).map do |name|
|
75
|
+
retry_names[name]
|
76
|
+
end
|
92
77
|
end
|
93
78
|
|
79
|
+
backoff_settings = nil
|
94
80
|
if retry_params && method_config.key?('retry_params_name')
|
95
81
|
params = retry_params[method_config['retry_params_name']]
|
96
82
|
backoff_settings = BackoffSettings.new(
|
97
|
-
*params.values_at(*BackoffSettings.members.map(&:to_s))
|
83
|
+
*params.values_at(*BackoffSettings.members.map(&:to_s))
|
84
|
+
)
|
98
85
|
end
|
99
86
|
|
100
87
|
RetryOptions.new(codes, backoff_settings)
|
101
88
|
end
|
102
89
|
|
103
|
-
|
90
|
+
# Helper for #construct_settings.
|
91
|
+
#
|
92
|
+
# Takes two retry options, and merges them into a single RetryOption
|
93
|
+
# instance.
|
94
|
+
#
|
95
|
+
# @param retry_options [RetryOptions] The base RetryOptions.
|
96
|
+
# @param overrides [RetryOptions] The RetryOptions used for overriding
|
97
|
+
# +retry+. Use the values if it is not nil. If entire
|
98
|
+
# +overrides+ is nli, ignore the base retry and return nil.
|
99
|
+
# @return [RetryOptions, nil]
|
100
|
+
def merge_retry_options(retry_options, overrides)
|
101
|
+
return nil if overrides.nil?
|
102
|
+
|
103
|
+
if overrides.retry_codes.nil? && overrides.backoff_settings.nil?
|
104
|
+
return retry_options
|
105
|
+
end
|
106
|
+
|
107
|
+
codes = retry_options.retry_codes
|
108
|
+
codes = overrides.retry_codes unless overrides.retry_codes.nil?
|
109
|
+
backoff_settings = retry_options.backoff_settings
|
110
|
+
unless overrides.backoff_settings.nil?
|
111
|
+
backoff_settings = overrides.backoff_settings
|
112
|
+
end
|
113
|
+
|
114
|
+
RetryOptions.new(codes, backoff_settings)
|
115
|
+
end
|
116
|
+
|
117
|
+
def upper_camel_to_lower_underscore(string)
|
104
118
|
string.scan(/[[:upper:]][^[:upper:]]*/).map(&:downcase).join('_')
|
105
119
|
end
|
106
120
|
|
@@ -154,12 +168,10 @@ module Google
|
|
154
168
|
# service, used as a key into the client config file (in the
|
155
169
|
# example above, this value should be
|
156
170
|
# 'google.fake.v1.ServiceName').
|
157
|
-
# @param client_config [Hash] A
|
158
|
-
#
|
159
|
-
# @param
|
160
|
-
#
|
161
|
-
# @param retry_override [Hash] A dictionary of method names to
|
162
|
-
# RetryOptions that override those specified in +client_config+.
|
171
|
+
# @param client_config [Hash] A hash parsed from the standard
|
172
|
+
# API client config file.
|
173
|
+
# @param config_overrides [Hash] A hash in the same structure of
|
174
|
+
# client_config to override the settings.
|
163
175
|
# @param retry_names [Hash] A dictionary mapping the strings
|
164
176
|
# referring to response status codes to the Python objects
|
165
177
|
# representing those codes.
|
@@ -173,41 +185,55 @@ module Google
|
|
173
185
|
# methods that are page streaming-enabled.
|
174
186
|
# @return [CallSettings, nil] A CallSettings, or nil if the
|
175
187
|
# service is not found in the config.
|
176
|
-
def construct_settings(
|
177
|
-
|
178
|
-
|
188
|
+
def construct_settings(service_name, client_config, config_overrides,
|
189
|
+
retry_names, timeout, bundle_descriptors: {},
|
190
|
+
page_descriptors: {})
|
179
191
|
defaults = {}
|
180
192
|
|
181
193
|
service_config = client_config.fetch('interfaces', {})[service_name]
|
182
194
|
return nil unless service_config
|
183
195
|
|
196
|
+
overrides = config_overrides.fetch('interfaces', {})[service_name] || {}
|
197
|
+
|
184
198
|
service_config['methods'].each_pair do |method_name, method_config|
|
185
|
-
snake_name =
|
199
|
+
snake_name = upper_camel_to_lower_underscore(method_name)
|
186
200
|
|
201
|
+
overriding_method =
|
202
|
+
overrides.fetch('methods', {}).fetch(method_name, {})
|
203
|
+
|
204
|
+
bundling_config = method_config.fetch('bundling', nil)
|
205
|
+
if overriding_method && overriding_method.key?('bundling')
|
206
|
+
bundling_config = overriding_method['bundling']
|
207
|
+
end
|
187
208
|
bundle_descriptor = bundle_descriptors[snake_name]
|
188
209
|
|
189
210
|
defaults[snake_name] = CallSettings.new(
|
190
211
|
timeout: timeout,
|
191
|
-
retry_options:
|
192
|
-
method_config,
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
212
|
+
retry_options: merge_retry_options(
|
213
|
+
construct_retry(method_config,
|
214
|
+
service_config['retry_codes'],
|
215
|
+
service_config['retry_params'],
|
216
|
+
retry_names),
|
217
|
+
construct_retry(overriding_method,
|
218
|
+
overrides['retry_codes'],
|
219
|
+
overrides['retry_params'],
|
220
|
+
retry_names)
|
221
|
+
),
|
197
222
|
page_descriptor: page_descriptors[snake_name],
|
198
|
-
bundler:
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
bundle_descriptor: bundle_descriptor)
|
223
|
+
bundler: construct_bundling(bundling_config,
|
224
|
+
bundle_descriptor),
|
225
|
+
bundle_descriptor: bundle_descriptor
|
226
|
+
)
|
203
227
|
end
|
204
228
|
|
205
229
|
defaults
|
206
230
|
end
|
207
231
|
|
208
|
-
module_function :construct_settings, :
|
209
|
-
:
|
210
|
-
|
211
|
-
|
232
|
+
module_function :construct_settings, :construct_bundling,
|
233
|
+
:construct_retry, :upper_camel_to_lower_underscore,
|
234
|
+
:merge_retry_options
|
235
|
+
private_class_method :construct_bundling, :construct_retry,
|
236
|
+
:upper_camel_to_lower_underscore,
|
237
|
+
:merge_retry_options
|
212
238
|
end
|
213
239
|
end
|
data/lib/google/gax/version.rb
CHANGED
@@ -63,8 +63,8 @@ describe Google::Gax do
|
|
63
63
|
page_size = 3
|
64
64
|
pages_to_stream = 5
|
65
65
|
|
66
|
-
page_descriptor = Google::Gax::PageDescriptor.new(
|
67
|
-
|
66
|
+
page_descriptor = Google::Gax::PageDescriptor.new('page_token',
|
67
|
+
'next_page_token', 'nums')
|
68
68
|
settings = CallSettings.new(page_descriptor: page_descriptor)
|
69
69
|
timeout_arg = nil
|
70
70
|
func = proc do |request, timeout: nil|
|
@@ -82,8 +82,9 @@ describe Google::Gax do
|
|
82
82
|
|
83
83
|
it 'iterates over elements' do
|
84
84
|
my_callable = Google::Gax.create_api_call(func, settings)
|
85
|
-
expect(my_callable.call('page_token' => 0).to_a).to
|
86
|
-
(0...(page_size * pages_to_stream))
|
85
|
+
expect(my_callable.call('page_token' => 0).to_a).to match_array(
|
86
|
+
(0...(page_size * pages_to_stream))
|
87
|
+
)
|
87
88
|
expect(timeout_arg).to_not be_nil
|
88
89
|
end
|
89
90
|
|
@@ -99,14 +100,59 @@ describe Google::Gax do
|
|
99
100
|
stream = my_callable.call('page_token' => 0)
|
100
101
|
expect(stream.enum_for(:each_page).to_a.size).to eq(pages_to_stream + 1)
|
101
102
|
end
|
103
|
+
|
104
|
+
it 'starts from the specified page_token' do
|
105
|
+
my_settings = settings.merge(Google::Gax::CallOptions.new(page_token: 3))
|
106
|
+
my_callable = Google::Gax.create_api_call(func, my_settings)
|
107
|
+
expect(my_callable.call({}).to_a).to match_array(
|
108
|
+
3...(page_size * pages_to_stream)
|
109
|
+
)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe 'failures without retry' do
|
114
|
+
it 'simply fails' do
|
115
|
+
settings = CallSettings.new
|
116
|
+
timeout_arg = nil
|
117
|
+
call_count = 0
|
118
|
+
func = proc do |timeout: nil|
|
119
|
+
timeout_arg = timeout
|
120
|
+
call_count += 1
|
121
|
+
raise GRPC::Cancelled, ''
|
122
|
+
end
|
123
|
+
my_callable = Google::Gax.create_api_call(func, settings)
|
124
|
+
begin
|
125
|
+
my_callable.call
|
126
|
+
expect(true).to be false # should not reach to this line.
|
127
|
+
rescue Google::Gax::GaxError => exc
|
128
|
+
expect(exc.cause).to be_a(GRPC::Cancelled)
|
129
|
+
end
|
130
|
+
expect(timeout_arg).to_not be_nil
|
131
|
+
expect(call_count).to eq(1)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'does not wrap unknown errors' do
|
135
|
+
settings = CallSettings.new
|
136
|
+
timeout_arg = nil
|
137
|
+
call_count = 0
|
138
|
+
func = proc do |timeout: nil|
|
139
|
+
timeout_arg = timeout
|
140
|
+
call_count += 1
|
141
|
+
raise CustomException.new('', FAKE_STATUS_CODE_1)
|
142
|
+
end
|
143
|
+
my_callable = Google::Gax.create_api_call(func, settings)
|
144
|
+
expect { my_callable.call }.to raise_error(CustomException)
|
145
|
+
expect(timeout_arg).to_not be_nil
|
146
|
+
expect(call_count).to eq(1)
|
147
|
+
end
|
102
148
|
end
|
103
149
|
|
104
150
|
describe 'retryable' do
|
105
151
|
RetryOptions = Google::Gax::RetryOptions
|
106
152
|
BackoffSettings = Google::Gax::BackoffSettings
|
107
153
|
|
108
|
-
retry_options = RetryOptions.new(
|
109
|
-
|
154
|
+
retry_options = RetryOptions.new([FAKE_STATUS_CODE_1],
|
155
|
+
BackoffSettings.new(0, 0, 0, 0, 0, 0, 1))
|
110
156
|
settings = CallSettings.new(timeout: 0, retry_options: retry_options)
|
111
157
|
|
112
158
|
it 'retries the API call' do
|
@@ -138,7 +184,8 @@ describe Google::Gax do
|
|
138
184
|
raise CustomException.new('', FAKE_STATUS_CODE_1)
|
139
185
|
end
|
140
186
|
my_callable = Google::Gax.create_api_call(
|
141
|
-
func, CallSettings.new(timeout: 0, retry_options: retry_options)
|
187
|
+
func, CallSettings.new(timeout: 0, retry_options: retry_options)
|
188
|
+
)
|
142
189
|
expect { my_callable.call }.to raise_error(Google::Gax::RetryError)
|
143
190
|
expect(call_count).to eq(1)
|
144
191
|
end
|
@@ -160,7 +207,8 @@ describe Google::Gax do
|
|
160
207
|
|
161
208
|
time_now = Time.now
|
162
209
|
allow(Time).to receive(:now).exactly(4).times.and_return(
|
163
|
-
*([time_now] * to_attempt + [time_now + 2])
|
210
|
+
*([time_now] * to_attempt + [time_now + 2])
|
211
|
+
)
|
164
212
|
|
165
213
|
func = proc do
|
166
214
|
call_count += 1
|
@@ -170,7 +218,7 @@ describe Google::Gax do
|
|
170
218
|
my_callable = Google::Gax.create_api_call(func, settings)
|
171
219
|
begin
|
172
220
|
my_callable.call
|
173
|
-
|
221
|
+
expect(true).to be false # should not reach to this line.
|
174
222
|
rescue Google::Gax::RetryError => exc
|
175
223
|
expect(exc.cause).to be_a(CustomException)
|
176
224
|
end
|
@@ -210,7 +258,8 @@ describe Google::Gax do
|
|
210
258
|
backoff = BackoffSettings.new(3, 2, 24, 5, 2, 80, 2500)
|
211
259
|
retry_options = RetryOptions.new([FAKE_STATUS_CODE_1], backoff)
|
212
260
|
my_callable = Google::Gax.create_api_call(
|
213
|
-
func, CallSettings.new(timeout: 0, retry_options: retry_options)
|
261
|
+
func, CallSettings.new(timeout: 0, retry_options: retry_options)
|
262
|
+
)
|
214
263
|
|
215
264
|
begin
|
216
265
|
my_callable.call(0)
|
@@ -69,7 +69,8 @@ describe Google::Gax::PathTemplate do
|
|
69
69
|
template = PathTemplate.new('hello/world')
|
70
70
|
expect { template.match('hello') }.to raise_error(ArgumentError)
|
71
71
|
expect { template.match('hello/world/fail') }.to raise_error(
|
72
|
-
ArgumentError
|
72
|
+
ArgumentError
|
73
|
+
)
|
73
74
|
end
|
74
75
|
|
75
76
|
it 'should fail on mismatched literal' do
|
@@ -71,7 +71,8 @@ A_CONFIG = {
|
|
71
71
|
|
72
72
|
PAGE_DESCRIPTORS = {
|
73
73
|
'page_streaming_method' => Google::Gax::PageDescriptor.new(
|
74
|
-
'page_token', 'next_page_token', 'page_streams'
|
74
|
+
'page_token', 'next_page_token', 'page_streams'
|
75
|
+
)
|
75
76
|
}.freeze
|
76
77
|
|
77
78
|
BUNDLE_DESCRIPTORS = {
|
@@ -87,9 +88,10 @@ RETRY_DICT = {
|
|
87
88
|
describe Google::Gax do
|
88
89
|
it 'creates settings' do
|
89
90
|
defaults = Google::Gax.construct_settings(
|
90
|
-
SERVICE_NAME, A_CONFIG, {},
|
91
|
+
SERVICE_NAME, A_CONFIG, {}, RETRY_DICT, 30,
|
91
92
|
bundle_descriptors: BUNDLE_DESCRIPTORS,
|
92
|
-
page_descriptors: PAGE_DESCRIPTORS
|
93
|
+
page_descriptors: PAGE_DESCRIPTORS
|
94
|
+
)
|
93
95
|
settings = defaults['bundling_method']
|
94
96
|
expect(settings.timeout).to be(30)
|
95
97
|
# TODO: uncomment this when bundling is added.
|
@@ -99,7 +101,8 @@ describe Google::Gax do
|
|
99
101
|
expect(settings.retry_options).to be_a(Google::Gax::RetryOptions)
|
100
102
|
expect(settings.retry_options.retry_codes).to be_a(Array)
|
101
103
|
expect(settings.retry_options.backoff_settings).to be_a(
|
102
|
-
Google::Gax::BackoffSettings
|
104
|
+
Google::Gax::BackoffSettings
|
105
|
+
)
|
103
106
|
|
104
107
|
settings = defaults['page_streaming_method']
|
105
108
|
expect(settings.timeout).to be(30)
|
@@ -109,17 +112,28 @@ describe Google::Gax do
|
|
109
112
|
expect(settings.retry_options).to be_a(Google::Gax::RetryOptions)
|
110
113
|
expect(settings.retry_options.retry_codes).to be_a(Array)
|
111
114
|
expect(settings.retry_options.backoff_settings).to be_a(
|
112
|
-
Google::Gax::BackoffSettings
|
115
|
+
Google::Gax::BackoffSettings
|
116
|
+
)
|
113
117
|
end
|
114
118
|
|
115
119
|
it 'overrides settings' do
|
116
|
-
|
117
|
-
|
120
|
+
overrides = {
|
121
|
+
'interfaces' => {
|
122
|
+
SERVICE_NAME => {
|
123
|
+
'methods' => {
|
124
|
+
'PageStreamingMethod' => nil,
|
125
|
+
'BundlingMethod' => {
|
126
|
+
'bundling' => nil
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
}
|
118
132
|
defaults = Google::Gax.construct_settings(
|
119
|
-
SERVICE_NAME, A_CONFIG,
|
120
|
-
RETRY_DICT, 30,
|
133
|
+
SERVICE_NAME, A_CONFIG, overrides, RETRY_DICT, 30,
|
121
134
|
bundle_descriptors: BUNDLE_DESCRIPTORS,
|
122
|
-
page_descriptors: PAGE_DESCRIPTORS
|
135
|
+
page_descriptors: PAGE_DESCRIPTORS
|
136
|
+
)
|
123
137
|
|
124
138
|
settings = defaults['bundling_method']
|
125
139
|
expect(settings.timeout).to be(30)
|
@@ -131,4 +145,60 @@ describe Google::Gax do
|
|
131
145
|
expect(settings.page_descriptor).to be_a(Google::Gax::PageDescriptor)
|
132
146
|
expect(settings.retry_options).to be_nil
|
133
147
|
end
|
148
|
+
|
149
|
+
it 'overrides settings more precisely' do
|
150
|
+
override = {
|
151
|
+
'interfaces' => {
|
152
|
+
SERVICE_NAME => {
|
153
|
+
'retry_codes' => {
|
154
|
+
'bar_retry' => [],
|
155
|
+
'baz_retry' => ['code_a']
|
156
|
+
},
|
157
|
+
'retry_params' => {
|
158
|
+
'default' => {
|
159
|
+
'initial_retry_delay_millis' => 1000,
|
160
|
+
'retry_delay_multiplier' => 1.2,
|
161
|
+
'max_retry_delay_millis' => 10_000,
|
162
|
+
'initial_rpc_timeout_millis' => 3000,
|
163
|
+
'rpc_timeout_multiplier' => 1.3,
|
164
|
+
'max_rpc_timeout_millis' => 30_000,
|
165
|
+
'total_timeout_millis' => 300_000
|
166
|
+
}
|
167
|
+
},
|
168
|
+
'methods' => {
|
169
|
+
'BundlingMethod' => {
|
170
|
+
'retry_params_name' => 'default',
|
171
|
+
'retry_codes_name' => 'baz_retry'
|
172
|
+
}
|
173
|
+
}
|
174
|
+
}
|
175
|
+
}
|
176
|
+
}
|
177
|
+
defaults = Google::Gax.construct_settings(
|
178
|
+
SERVICE_NAME, A_CONFIG, override, RETRY_DICT, 30,
|
179
|
+
bundle_descriptors: BUNDLE_DESCRIPTORS,
|
180
|
+
page_descriptors: PAGE_DESCRIPTORS
|
181
|
+
)
|
182
|
+
|
183
|
+
settings = defaults['bundling_method']
|
184
|
+
backoff = settings.retry_options.backoff_settings
|
185
|
+
expect(backoff.initial_retry_delay_millis).to be(1000)
|
186
|
+
expect(settings.retry_options.retry_codes).to match_array(
|
187
|
+
[RETRY_DICT['code_a']]
|
188
|
+
)
|
189
|
+
expect(settings.bundler).to be(nil)
|
190
|
+
expect(settings.bundle_descriptor).to be_a(Google::Gax::BundleDescriptor)
|
191
|
+
|
192
|
+
# page_streaming_method is unaffected because it's not specified in
|
193
|
+
# overrides. 'bar_retry' or 'default' definitions in overrides should
|
194
|
+
# not affect the methods which are not in the overrides.
|
195
|
+
settings = defaults['page_streaming_method']
|
196
|
+
backoff = settings.retry_options.backoff_settings
|
197
|
+
expect(backoff.initial_retry_delay_millis).to be(100)
|
198
|
+
expect(backoff.retry_delay_multiplier).to be(1.2)
|
199
|
+
expect(backoff.max_retry_delay_millis).to be(1000)
|
200
|
+
expect(settings.retry_options.retry_codes).to match_array(
|
201
|
+
[RETRY_DICT['code_c']]
|
202
|
+
)
|
203
|
+
end
|
134
204
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: google-gax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Google API Authors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-05-
|
11
|
+
date: 2016-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: googleauth
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 0.2.3
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: bundler
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.9'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.9'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: codecov
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -167,7 +153,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
167
153
|
requirements:
|
168
154
|
- - ">="
|
169
155
|
- !ruby/object:Gem::Version
|
170
|
-
version:
|
156
|
+
version: 2.0.0
|
171
157
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
158
|
requirements:
|
173
159
|
- - ">="
|