google-gax 0.1.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|