google-gax 0.6.0 → 0.7.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 +1 -274
- data/lib/google/gax/api_callable.rb +0 -3
- data/lib/google/gax/bundling.rb +1 -1
- data/lib/google/gax/constants.rb +34 -0
- data/lib/google/gax/operation.rb +253 -0
- data/lib/google/gax/path_template.rb +3 -2
- data/lib/google/gax/settings.rb +275 -2
- data/lib/google/gax/version.rb +1 -1
- data/lib/google/longrunning/{operations_api.rb → operations_client.rb} +34 -53
- data/spec/google/gax/operation_spec.rb +338 -0
- metadata +21 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ed0b03acfdc65e94f59a9de7d9ef17c82d8de2c
|
4
|
+
data.tar.gz: b49bdf5c29d4abea509227477aebe0ad2242ee5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fd2ba9b1d30101302aae49b74160fc00d509dd065b20e2416e962a8a28c42008694f67ec30e6cc13ff7dc526bb34b8b2a879857ea5dd584525b34999e8e0de0
|
7
|
+
data.tar.gz: e632150cec07b9861a0ffe258f3d994cb3f047be303acbcae91844f331afbbc37e311b1c47cd540746b3790efddc4e972fd00ce8dee0af54abac2e11e6ab01ae
|
data/lib/google/gax.rb
CHANGED
@@ -28,6 +28,7 @@
|
|
28
28
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
29
|
|
30
30
|
require 'google/gax/api_callable'
|
31
|
+
require 'google/gax/constants'
|
31
32
|
require 'google/gax/errors'
|
32
33
|
require 'google/gax/path_template'
|
33
34
|
require 'google/gax/settings'
|
@@ -36,279 +37,5 @@ require 'google/gax/version'
|
|
36
37
|
module Google
|
37
38
|
# Gax defines Google API extensions
|
38
39
|
module Gax
|
39
|
-
# rubocop:disable Metrics/ParameterLists
|
40
|
-
|
41
|
-
# Encapsulates the call settings for an ApiCallable
|
42
|
-
# @!attribute [r] timeout
|
43
|
-
# @return [Numeric]
|
44
|
-
# @!attribute [r] retry_options
|
45
|
-
# @return [RetryOptions]
|
46
|
-
# @!attribute [r] page_descriptor
|
47
|
-
# @return [PageDescriptor]
|
48
|
-
# @!attribute [r] page_token
|
49
|
-
# @return [Object]
|
50
|
-
# @!attribute [r] bundle_descriptor
|
51
|
-
# @return [BundleDescriptor]
|
52
|
-
# @!attribute [r] kwargs
|
53
|
-
# @return [Hash]
|
54
|
-
class CallSettings
|
55
|
-
attr_reader :timeout, :retry_options, :page_descriptor, :page_token,
|
56
|
-
:bundler, :bundle_descriptor, :kwargs, :errors
|
57
|
-
|
58
|
-
# @param timeout [Numeric] The client-side timeout for API calls. This
|
59
|
-
# parameter is ignored for retrying calls.
|
60
|
-
# @param retry_options [RetryOptions] The configuration for retrying upon
|
61
|
-
# transient error. If set to nil, this call will not retry.
|
62
|
-
# @param page_descriptor [PageDescriptor] indicates the structure of page
|
63
|
-
# streaming to be performed. If set to nil, page streaming is not
|
64
|
-
# performed.
|
65
|
-
# @param page_token [Object] determines the page token used in the
|
66
|
-
# page streaming request. If there is no page_descriptor, this has no
|
67
|
-
# meaning.
|
68
|
-
# @param bundler orchestrates bundling. If nil, bundling is not
|
69
|
-
# performed.
|
70
|
-
# @param bundle_descriptor [BundleDescriptor] indicates the structure of
|
71
|
-
# the bundle. If nil, bundling is not performed.
|
72
|
-
# @param kwargs [Hash]
|
73
|
-
# Additional keyword argments to be passed to the API call.
|
74
|
-
# @param errors [Array<Exception>]
|
75
|
-
# Configures the exceptions to wrap with GaxError.
|
76
|
-
def initialize(timeout: 30, retry_options: nil, page_descriptor: nil,
|
77
|
-
page_token: nil, bundler: nil, bundle_descriptor: nil,
|
78
|
-
kwargs: {}, errors: [])
|
79
|
-
@timeout = timeout
|
80
|
-
@retry_options = retry_options
|
81
|
-
@page_descriptor = page_descriptor
|
82
|
-
@page_token = page_token
|
83
|
-
@bundler = bundler
|
84
|
-
@bundle_descriptor = bundle_descriptor
|
85
|
-
@kwargs = kwargs
|
86
|
-
@errors = errors
|
87
|
-
end
|
88
|
-
|
89
|
-
# @return true when it has retry codes.
|
90
|
-
def retry_codes?
|
91
|
-
@retry_options && @retry_options.retry_codes
|
92
|
-
end
|
93
|
-
|
94
|
-
# @return true when it has valid bundler configuration.
|
95
|
-
def bundler?
|
96
|
-
@bundler && @bundle_descriptor
|
97
|
-
end
|
98
|
-
|
99
|
-
# Creates a new CallSetting instance which is based on this but merged
|
100
|
-
# settings from options.
|
101
|
-
# @param options [CallOptions, nil] The overriding call settings.
|
102
|
-
# @return a new merged call settings.
|
103
|
-
def merge(options)
|
104
|
-
unless options
|
105
|
-
return CallSettings.new(timeout: @timeout,
|
106
|
-
retry_options: @retry_options,
|
107
|
-
page_descriptor: @page_descriptor,
|
108
|
-
page_token: @page_token,
|
109
|
-
bundler: @bundler,
|
110
|
-
bundle_descriptor: @bundle_descriptor,
|
111
|
-
kwargs: @kwargs,
|
112
|
-
errors: @errors)
|
113
|
-
end
|
114
|
-
|
115
|
-
timeout = if options.timeout == :OPTION_INHERIT
|
116
|
-
@timeout
|
117
|
-
else
|
118
|
-
options.timeout
|
119
|
-
end
|
120
|
-
retry_options = if options.retry_options == :OPTION_INHERIT
|
121
|
-
@retry_options
|
122
|
-
else
|
123
|
-
options.retry_options
|
124
|
-
end
|
125
|
-
page_token = if options.page_token == :OPTION_INHERIT
|
126
|
-
@page_token
|
127
|
-
else
|
128
|
-
options.page_token
|
129
|
-
end
|
130
|
-
|
131
|
-
kwargs = @kwargs.dup
|
132
|
-
kwargs.update(options.kwargs) if options.kwargs != :OPTION_INHERIT
|
133
|
-
|
134
|
-
CallSettings.new(timeout: timeout,
|
135
|
-
retry_options: retry_options,
|
136
|
-
page_descriptor: @page_descriptor,
|
137
|
-
page_token: page_token,
|
138
|
-
bundler: @bundler,
|
139
|
-
bundle_descriptor: @bundle_descriptor,
|
140
|
-
kwargs: kwargs,
|
141
|
-
errors: @errors)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
private_constant :CallSettings
|
146
|
-
|
147
|
-
# Encapsulates the overridable settings for a particular API call
|
148
|
-
# @!attribute [r] timeout
|
149
|
-
# @return [Numeric, :OPTION_INHERIT]
|
150
|
-
# @!attribute [r] retry_options
|
151
|
-
# @return [RetryOptions, :OPTION_INHERIT]
|
152
|
-
# @!attribute [r] page_token
|
153
|
-
# @return [Object, :OPTION_INHERIT, :INITIAL_PAGE]
|
154
|
-
# @!attribute [r] kwargs
|
155
|
-
# @return [Hash, :OPTION_INHERIT]
|
156
|
-
class CallOptions
|
157
|
-
attr_reader :timeout, :retry_options, :page_token, :kwargs
|
158
|
-
|
159
|
-
# @param timeout [Numeric, :OPTION_INHERIT]
|
160
|
-
# The client-side timeout for API calls.
|
161
|
-
# @param retry_options [RetryOptions, :OPTION_INHERIT]
|
162
|
-
# The configuration for retrying upon transient error.
|
163
|
-
# If set to nil, this call will not retry.
|
164
|
-
# @param page_token [Object, :OPTION_INHERIT]
|
165
|
-
# If set and the call is configured for page streaming, page streaming
|
166
|
-
# is starting with this page_token.
|
167
|
-
# @param kwargs [Hash, :OPTION_INHERIT]
|
168
|
-
# Additional keyword argments to be passed to the API call.
|
169
|
-
def initialize(timeout: :OPTION_INHERIT,
|
170
|
-
retry_options: :OPTION_INHERIT,
|
171
|
-
page_token: :OPTION_INHERIT,
|
172
|
-
kwargs: :OPTION_INHERIT)
|
173
|
-
@timeout = timeout
|
174
|
-
@retry_options = retry_options
|
175
|
-
@page_token = page_token
|
176
|
-
@kwargs = kwargs
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
# Describes the structure of a page-streaming call.
|
181
|
-
class PageDescriptor < Struct.new(:request_page_token_field,
|
182
|
-
:response_page_token_field,
|
183
|
-
:resource_field)
|
184
|
-
end
|
185
|
-
|
186
|
-
# Per-call configurable settings for retrying upon transient failure.
|
187
|
-
class RetryOptions < Struct.new(:retry_codes, :backoff_settings)
|
188
|
-
# @!attribute retry_codes
|
189
|
-
# @return [Array<Grpc::Code>] a list of exceptions upon which
|
190
|
-
# a retry should be attempted.
|
191
|
-
# @!attribute backoff_settings
|
192
|
-
# @return [BackoffSettings] configuring the retry exponential
|
193
|
-
# backoff algorithm.
|
194
|
-
end
|
195
|
-
|
196
|
-
# Parameters to the exponential backoff algorithm for retrying.
|
197
|
-
class BackoffSettings < Struct.new(
|
198
|
-
:initial_retry_delay_millis,
|
199
|
-
:retry_delay_multiplier,
|
200
|
-
:max_retry_delay_millis,
|
201
|
-
:initial_rpc_timeout_millis,
|
202
|
-
:rpc_timeout_multiplier,
|
203
|
-
:max_rpc_timeout_millis,
|
204
|
-
:total_timeout_millis
|
205
|
-
)
|
206
|
-
# @!attribute initial_retry_delay_millis
|
207
|
-
# @return [Numeric] the initial delay time, in milliseconds,
|
208
|
-
# between the completion of the first failed request and the
|
209
|
-
# initiation of the first retrying request.
|
210
|
-
# @!attribute retry_delay_multiplier
|
211
|
-
# @return [Numeric] the multiplier by which to increase the
|
212
|
-
# delay time between the completion of failed requests, and
|
213
|
-
# the initiation of the subsequent retrying request.
|
214
|
-
# @!attribute max_retry_delay_millis
|
215
|
-
# @return [Numeric] the maximum delay time, in milliseconds,
|
216
|
-
# between requests. When this value is reached,
|
217
|
-
# +retry_delay_multiplier+ will no longer be used to
|
218
|
-
# increase delay time.
|
219
|
-
# @!attribute initial_rpc_timeout_millis
|
220
|
-
# @return [Numeric] the initial timeout parameter to the request.
|
221
|
-
# @!attribute rpc_timeout_multiplier
|
222
|
-
# @return [Numeric] the multiplier by which to increase the
|
223
|
-
# timeout parameter between failed requests.
|
224
|
-
# @!attribute max_rpc_timeout_millis
|
225
|
-
# @return [Numeric] the maximum timeout parameter, in
|
226
|
-
# milliseconds, for a request. When this value is reached,
|
227
|
-
# +rpc_timeout_multiplier+ will no longer be used to
|
228
|
-
# increase the timeout.
|
229
|
-
# @!attribute total_timeout_millis
|
230
|
-
# @return [Numeric] the total time, in milliseconds, starting
|
231
|
-
# from when the initial request is sent, after which an
|
232
|
-
# error will be returned, regardless of the retrying
|
233
|
-
# attempts made meanwhile.
|
234
|
-
end
|
235
|
-
|
236
|
-
# Describes the structure of bundled call.
|
237
|
-
#
|
238
|
-
# request_discriminator_fields may include '.' as a separator, which is
|
239
|
-
# used to indicate object traversal. This allows fields in nested objects
|
240
|
-
# to be used to determine what requests to bundle.
|
241
|
-
class BundleDescriptor < Struct.new(:bundled_field,
|
242
|
-
:request_discriminator_fields,
|
243
|
-
:subresponse_field)
|
244
|
-
# @!attribute bundled_field
|
245
|
-
# @return [String] the repeated field in the request message
|
246
|
-
# that will have its elements aggregated by bundling.
|
247
|
-
# @!attribute request_discriminator_fields
|
248
|
-
# @return [Array<String>] a list of fields in the target
|
249
|
-
# request message class that are used to determine which
|
250
|
-
# messages should be bundled together.
|
251
|
-
# @!attribute subresponse_field
|
252
|
-
# @return [String] an optional field, when present it
|
253
|
-
# indicates the field in the response message that should be
|
254
|
-
# used to demultiplex the response into multiple response
|
255
|
-
# messages.
|
256
|
-
def initialize(bundled_field, request_discriminator_fields,
|
257
|
-
subresponse_field: nil)
|
258
|
-
super(bundled_field, request_discriminator_fields, subresponse_field)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
# Holds values used to configure bundling.
|
263
|
-
#
|
264
|
-
# The xxx_threshold attributes are used to configure when the bundled
|
265
|
-
# request should be made.
|
266
|
-
class BundleOptions < Struct.new(:element_count_threshold,
|
267
|
-
:element_count_limit,
|
268
|
-
:request_byte_threshold,
|
269
|
-
:request_byte_limit,
|
270
|
-
:delay_threshold_millis)
|
271
|
-
# @!attribute element_count_threshold
|
272
|
-
# @return [Numeric] the bundled request will be sent once the
|
273
|
-
# count of outstanding elements in the repeated field
|
274
|
-
# reaches this value.
|
275
|
-
# @!attribute element_count_limit
|
276
|
-
# @return [Numeric] represents a hard limit on the number of
|
277
|
-
# elements in the repeated field of the bundle; if adding a
|
278
|
-
# request to a bundle would exceed this value, the bundle is
|
279
|
-
# sent and the new request is added to a fresh bundle. It is
|
280
|
-
# invalid for a single request to exceed this limit.
|
281
|
-
# @!attribute request_byte_threshold
|
282
|
-
# @return [Numeric] the bundled request will be sent once the
|
283
|
-
# count of bytes in the request reaches this value. Note
|
284
|
-
# that this value is pessimistically approximated by summing
|
285
|
-
# the bytesizes of the elements in the repeated field, and
|
286
|
-
# therefore may be an under-approximation.
|
287
|
-
# @!attribute request_byte_limit
|
288
|
-
# @return [Numeric] represents a hard limit on the size of the
|
289
|
-
# bundled request; if adding a request to a bundle would
|
290
|
-
# exceed this value, the bundle is sent and the new request
|
291
|
-
# is added to a fresh bundle. It is invalid for a single
|
292
|
-
# request to exceed this limit. Note that this value is
|
293
|
-
# pessimistically approximated by summing the bytesizes of
|
294
|
-
# the elements in the repeated field, with a buffer applied
|
295
|
-
# to correspond to the resulting under-approximation.
|
296
|
-
# @!attribute delay_threshold_millis
|
297
|
-
# @return [Numeric] the bundled request will be sent this
|
298
|
-
# amount of time after the first element in the bundle was
|
299
|
-
# added to it.
|
300
|
-
def initialize(element_count_threshold: 0,
|
301
|
-
element_count_limit: 0,
|
302
|
-
request_byte_threshold: 0,
|
303
|
-
request_byte_limit: 0,
|
304
|
-
delay_threshold_millis: 0)
|
305
|
-
super(
|
306
|
-
element_count_threshold,
|
307
|
-
element_count_limit,
|
308
|
-
request_byte_threshold,
|
309
|
-
request_byte_limit,
|
310
|
-
delay_threshold_millis)
|
311
|
-
end
|
312
|
-
end
|
313
40
|
end
|
314
41
|
end
|
@@ -36,8 +36,6 @@ require 'google/gax/bundling'
|
|
36
36
|
|
37
37
|
module Google
|
38
38
|
module Gax
|
39
|
-
MILLIS_PER_SECOND = 1000.0
|
40
|
-
|
41
39
|
# A class to provide the Enumerable interface for page-streaming method.
|
42
40
|
# PagedEnumerable assumes that the API call returns a message for a page
|
43
41
|
# which holds a list of resources and the token to the next page.
|
@@ -341,7 +339,6 @@ module Google
|
|
341
339
|
result = nil
|
342
340
|
now = Time.now
|
343
341
|
deadline = now + total_timeout
|
344
|
-
|
345
342
|
loop do
|
346
343
|
begin
|
347
344
|
result = add_timeout_arg(a_func, timeout, kwargs).call(request)
|
data/lib/google/gax/bundling.rb
CHANGED
@@ -116,7 +116,7 @@ module Google
|
|
116
116
|
# The number of bundled elements in the repeated field.
|
117
117
|
# @return [Numeric]
|
118
118
|
def element_count
|
119
|
-
@inputs.reduce(0) { |
|
119
|
+
@inputs.reduce(0) { |acc, elem| acc + elem.count }
|
120
120
|
end
|
121
121
|
|
122
122
|
# The size of the request in bytes of the bundled field elements.
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Copyright 2016, Google Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are
|
6
|
+
# met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright
|
9
|
+
# notice, this list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above
|
11
|
+
# copyright notice, this list of conditions and the following disclaimer
|
12
|
+
# in the documentation and/or other materials provided with the
|
13
|
+
# distribution.
|
14
|
+
# * Neither the name of Google Inc. nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
19
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
20
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
21
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
22
|
+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
23
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
24
|
+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
25
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
26
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
27
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
module Google
|
31
|
+
module Gax
|
32
|
+
MILLIS_PER_SECOND = 1000.0
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,253 @@
|
|
1
|
+
# Copyright 2016, Google Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are
|
6
|
+
# met:
|
7
|
+
#
|
8
|
+
# * Redistributions of source code must retain the above copyright
|
9
|
+
# notice, this list of conditions and the following disclaimer.
|
10
|
+
# * Redistributions in binary form must reproduce the above
|
11
|
+
# copyright notice, this list of conditions and the following disclaimer
|
12
|
+
# in the documentation and/or other materials provided with the
|
13
|
+
# distribution.
|
14
|
+
# * Neither the name of Google Inc. nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
19
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
20
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
21
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
22
|
+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
23
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
24
|
+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
25
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
26
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
27
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
require 'time'
|
31
|
+
|
32
|
+
# These must be loaded separate from google/gax to avoid circular dependency.
|
33
|
+
require 'google/gax/constants'
|
34
|
+
require 'google/gax/settings'
|
35
|
+
|
36
|
+
module Google
|
37
|
+
module Gax
|
38
|
+
# A class used to wrap Google::Longrunning::Operation objects. This class
|
39
|
+
# provides helper methods to check the status of an Operation
|
40
|
+
#
|
41
|
+
# @example Checking Operation status
|
42
|
+
# require 'google/gax/operation'
|
43
|
+
# require 'google/longrunning/operations_client'
|
44
|
+
#
|
45
|
+
# operations_client = Google::Longrunning::OperationsClient.new
|
46
|
+
# op = Google::Gax::Operation.new(
|
47
|
+
# api.methodThatReturnsOperation(),
|
48
|
+
# operations_client,
|
49
|
+
# Google::Example::ResultType,
|
50
|
+
# Google::Example::MetadataType
|
51
|
+
# )
|
52
|
+
#
|
53
|
+
# op.done? # => false
|
54
|
+
# op.reload! # => operation completed
|
55
|
+
#
|
56
|
+
# if op.done?
|
57
|
+
# results = op.results
|
58
|
+
# handle_error(results) if op.error?
|
59
|
+
# # Handle results.
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# @example Working with callbacks
|
63
|
+
# require 'google/gax/operation'
|
64
|
+
# require 'google/longrunning/operations_client'
|
65
|
+
#
|
66
|
+
# operations_client = Google::Longrunning::OperationsClient.new
|
67
|
+
# op = Google::Gax::Operation.new(
|
68
|
+
# api.method_that_returns_operation,
|
69
|
+
# operations_client,
|
70
|
+
# Google::Example::ResultType,
|
71
|
+
# Google::Example::MetadataType
|
72
|
+
# )
|
73
|
+
#
|
74
|
+
# # Register a callback to be run when an operation is done.
|
75
|
+
# op.on_done do |operation|
|
76
|
+
# raise operation.results.message if operation.error?
|
77
|
+
# # process(operation.results)
|
78
|
+
# # process(operation.metadata)
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# # Reload the operation running callbacks if operation completed.
|
82
|
+
# op.reload!
|
83
|
+
#
|
84
|
+
# # Or block until the operation completes, passing a block to be called
|
85
|
+
# # on completion.
|
86
|
+
# op.wait_until_done do |operation|
|
87
|
+
# raise operation.results.message if operation.error?
|
88
|
+
# # process(operation.results)
|
89
|
+
# # process(operation.rmetadata)
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# @attribute [r] grpc_op
|
93
|
+
# @return [Google::Longrunning::Operation] The wrapped grpc
|
94
|
+
# operation object.
|
95
|
+
# @attribute [rw] call_options
|
96
|
+
# @return [Google::Gax::CallOptions] The call options used when reloading
|
97
|
+
# the operation.
|
98
|
+
class Operation
|
99
|
+
attr_reader :grpc_op
|
100
|
+
|
101
|
+
attr_accessor :call_options
|
102
|
+
|
103
|
+
# @param grpc_op [Google::Longrunning::Operation]
|
104
|
+
# The inital longrunning operation.
|
105
|
+
# @param client [Google::Longrunning::OperationsClient]
|
106
|
+
# The client that handles the grpc operations.
|
107
|
+
# @param result_type [Class] The class type to be unpacked from the
|
108
|
+
# result.
|
109
|
+
# @param metadata_type [Class] The class type to be unpacked from the
|
110
|
+
# metadata.
|
111
|
+
# @param call_options [Google::Gax::CallOptions]
|
112
|
+
# The call options that are used when reloading the operation.
|
113
|
+
def initialize(grpc_op, client, result_type, metadata_type,
|
114
|
+
call_options: nil)
|
115
|
+
@grpc_op = grpc_op
|
116
|
+
@client = client
|
117
|
+
@call_options = call_options
|
118
|
+
@result_type = result_type
|
119
|
+
@metadata_type = metadata_type
|
120
|
+
@callbacks = []
|
121
|
+
end
|
122
|
+
|
123
|
+
# If the operation is done, returns the result, otherwise returns nil.
|
124
|
+
# If the operation response is an error, the error will be returned.
|
125
|
+
# If a type is provided, the response will be unpacked using the type
|
126
|
+
# provided; returning nil if the response is not of the type provided.
|
127
|
+
# If the type is not of provided, the response will be unpacked using
|
128
|
+
# the response's type_url if the type_url is found in the
|
129
|
+
# Google::Protobuf::DescriptorPool.generated_pool.
|
130
|
+
# If the type cannot be found the raw response is retuned.
|
131
|
+
#
|
132
|
+
# @return [Object, Google::Rpc::Status, nil]
|
133
|
+
# The result of the operation. If it is an error a Google::Rpc::Status
|
134
|
+
# will be returned.
|
135
|
+
def results
|
136
|
+
return nil unless done?
|
137
|
+
return @grpc_op.error if error?
|
138
|
+
unpack(@grpc_op.response, @result_type)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns the metadata of an operation. If a type is provided,
|
142
|
+
# the metadata will be unpacked using the type provided; returning nil
|
143
|
+
# if the metadata is not of the type provided.
|
144
|
+
# If the type is not of provided, the metadata will be unpacked using
|
145
|
+
# the metadata's type_url if the type_url is found in the
|
146
|
+
# Google::Protobuf::DescriptorPool.generated_pool.
|
147
|
+
# If the type cannot be found the raw metadata is retuned.
|
148
|
+
#
|
149
|
+
# @return [Object, nil]
|
150
|
+
# The metadata of the operation. Can be nil.
|
151
|
+
def metadata
|
152
|
+
return nil if @grpc_op.metadata.nil?
|
153
|
+
unpack(@grpc_op.metadata, @metadata_type)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Checks if the operation is done. This does not send a new api call,
|
157
|
+
# but checks the result of the previous api call to see if done.
|
158
|
+
#
|
159
|
+
# @return [Boolean] Whether the operation is done.
|
160
|
+
def done?
|
161
|
+
@grpc_op.done
|
162
|
+
end
|
163
|
+
|
164
|
+
# Checks if the operation is done and the result is an error.
|
165
|
+
# If the operation is not finished then this will return false.
|
166
|
+
#
|
167
|
+
# @return [Boolean] Whether an error has been returned.
|
168
|
+
def error?
|
169
|
+
done? ? @grpc_op.result == :error : false
|
170
|
+
end
|
171
|
+
|
172
|
+
# Cancels the operation.
|
173
|
+
def cancel
|
174
|
+
@client.cancel_operation(@grpc_op.name)
|
175
|
+
end
|
176
|
+
|
177
|
+
# Reloads the operation object.
|
178
|
+
#
|
179
|
+
# @return [Google::Gax::Operation]
|
180
|
+
# Since this method changes internal state, it returns itself.
|
181
|
+
def reload!
|
182
|
+
@grpc_op = @client.get_operation(@grpc_op.name, options: @call_options)
|
183
|
+
if done?
|
184
|
+
@callbacks.each { |proc| proc.call(self) }
|
185
|
+
@callbacks.clear
|
186
|
+
end
|
187
|
+
self
|
188
|
+
end
|
189
|
+
alias refresh! reload!
|
190
|
+
|
191
|
+
# Blocking method to wait until the operation has completed or the
|
192
|
+
# maximum timeout has been reached. Upon completion, registered callbacks
|
193
|
+
# will be called, then - if a block is given - the block will be called.
|
194
|
+
#
|
195
|
+
# @param backoff_settings [Google::Gax::BackoffSettings]
|
196
|
+
# The backoff settings used to manipulate how this method retries
|
197
|
+
# checking if the operation is done.
|
198
|
+
# @yield operation [Google::Gax::Operation] Yields the finished Operation.
|
199
|
+
def wait_until_done!(backoff_settings: nil)
|
200
|
+
unless backoff_settings
|
201
|
+
backoff_settings = BackoffSettings.new(
|
202
|
+
10 * MILLIS_PER_SECOND,
|
203
|
+
1.3,
|
204
|
+
5 * 60 * MILLIS_PER_SECOND,
|
205
|
+
0,
|
206
|
+
0,
|
207
|
+
0,
|
208
|
+
60 * 60 * MILLIS_PER_SECOND
|
209
|
+
)
|
210
|
+
end
|
211
|
+
|
212
|
+
delay = backoff_settings.initial_retry_delay_millis / MILLIS_PER_SECOND
|
213
|
+
max_delay = backoff_settings.max_retry_delay_millis / MILLIS_PER_SECOND
|
214
|
+
delay_multiplier = backoff_settings.retry_delay_multiplier
|
215
|
+
total_timeout =
|
216
|
+
backoff_settings.total_timeout_millis / MILLIS_PER_SECOND
|
217
|
+
deadline = Time.now + total_timeout
|
218
|
+
until done?
|
219
|
+
sleep(delay)
|
220
|
+
if Time.now >= deadline
|
221
|
+
raise RetryError, 'Retry total timeout exceeded with exception'
|
222
|
+
end
|
223
|
+
delay = [delay * delay_multiplier, max_delay].min
|
224
|
+
reload!
|
225
|
+
end
|
226
|
+
yield(self) if block_given?
|
227
|
+
end
|
228
|
+
|
229
|
+
# Registers a callback to be run when a refreshed operation is marked
|
230
|
+
# as done. If the operation has completed prior to a call to this function
|
231
|
+
# the callback will be called instead of registered.
|
232
|
+
#
|
233
|
+
# @yield operation [Google::Gax::Operation] Yields the finished Operation.
|
234
|
+
def on_done(&block)
|
235
|
+
if done?
|
236
|
+
yield(self)
|
237
|
+
else
|
238
|
+
@callbacks.push(block)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
# TODO: This is from google/protobuf/well_known_types.rb.
|
243
|
+
# Using google/protobuf in gax-ruby is currently causing a dependency
|
244
|
+
# conflict with grpc. When grpc depends on google-protobuf v3.1.0
|
245
|
+
# remove this function and use Google::Protobuf::Any#unpack.
|
246
|
+
def unpack(any_pb, klass)
|
247
|
+
type_name = any_pb.type_url.split('/')[-1]
|
248
|
+
return klass.decode(any_pb.value) if type_name == klass.descriptor.name
|
249
|
+
end
|
250
|
+
private :unpack
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|