cql-rb 2.0.0.pre0 → 2.0.0.pre1
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/README.md +14 -2
- data/lib/cql.rb +8 -3
- data/lib/cql/client.rb +21 -356
- data/lib/cql/client/authenticators.rb +70 -0
- data/lib/cql/client/batch.rb +54 -0
- data/lib/cql/client/{asynchronous_client.rb → client.rb} +241 -6
- data/lib/cql/client/connector.rb +3 -2
- data/lib/cql/client/{asynchronous_prepared_statement.rb → prepared_statement.rb} +103 -0
- data/lib/cql/protocol.rb +1 -2
- data/lib/cql/protocol/cql_byte_buffer.rb +285 -0
- data/lib/cql/protocol/cql_protocol_handler.rb +3 -3
- data/lib/cql/protocol/frame_decoder.rb +3 -3
- data/lib/cql/protocol/frame_encoder.rb +2 -2
- data/lib/cql/protocol/request.rb +0 -2
- data/lib/cql/protocol/requests/auth_response_request.rb +2 -2
- data/lib/cql/protocol/requests/batch_request.rb +10 -10
- data/lib/cql/protocol/requests/credentials_request.rb +2 -2
- data/lib/cql/protocol/requests/execute_request.rb +13 -13
- data/lib/cql/protocol/requests/options_request.rb +2 -2
- data/lib/cql/protocol/requests/prepare_request.rb +2 -2
- data/lib/cql/protocol/requests/query_request.rb +13 -13
- data/lib/cql/protocol/requests/register_request.rb +2 -2
- data/lib/cql/protocol/requests/startup_request.rb +2 -2
- data/lib/cql/protocol/response.rb +2 -4
- data/lib/cql/protocol/responses/auth_challenge_response.rb +2 -2
- data/lib/cql/protocol/responses/auth_success_response.rb +2 -2
- data/lib/cql/protocol/responses/authenticate_response.rb +2 -2
- data/lib/cql/protocol/responses/detailed_error_response.rb +15 -15
- data/lib/cql/protocol/responses/error_response.rb +4 -4
- data/lib/cql/protocol/responses/event_response.rb +3 -3
- data/lib/cql/protocol/responses/prepared_result_response.rb +4 -4
- data/lib/cql/protocol/responses/raw_rows_result_response.rb +1 -1
- data/lib/cql/protocol/responses/ready_response.rb +1 -1
- data/lib/cql/protocol/responses/result_response.rb +3 -3
- data/lib/cql/protocol/responses/rows_result_response.rb +22 -22
- data/lib/cql/protocol/responses/schema_change_event_response.rb +2 -2
- data/lib/cql/protocol/responses/schema_change_result_response.rb +2 -2
- data/lib/cql/protocol/responses/set_keyspace_result_response.rb +2 -2
- data/lib/cql/protocol/responses/status_change_event_response.rb +2 -2
- data/lib/cql/protocol/responses/supported_response.rb +2 -2
- data/lib/cql/protocol/responses/void_result_response.rb +1 -1
- data/lib/cql/protocol/type_converter.rb +78 -81
- data/lib/cql/time_uuid.rb +6 -0
- data/lib/cql/uuid.rb +2 -1
- data/lib/cql/version.rb +1 -1
- data/spec/cql/client/batch_spec.rb +8 -8
- data/spec/cql/client/{asynchronous_client_spec.rb → client_spec.rb} +162 -0
- data/spec/cql/client/connector_spec.rb +13 -3
- data/spec/cql/client/{asynchronous_prepared_statement_spec.rb → prepared_statement_spec.rb} +148 -1
- data/spec/cql/client/request_runner_spec.rb +2 -2
- data/spec/cql/protocol/cql_byte_buffer_spec.rb +895 -0
- data/spec/cql/protocol/cql_protocol_handler_spec.rb +1 -1
- data/spec/cql/protocol/frame_decoder_spec.rb +14 -14
- data/spec/cql/protocol/frame_encoder_spec.rb +7 -7
- data/spec/cql/protocol/requests/auth_response_request_spec.rb +4 -4
- data/spec/cql/protocol/requests/batch_request_spec.rb +21 -21
- data/spec/cql/protocol/requests/credentials_request_spec.rb +2 -2
- data/spec/cql/protocol/requests/execute_request_spec.rb +13 -13
- data/spec/cql/protocol/requests/options_request_spec.rb +1 -1
- data/spec/cql/protocol/requests/prepare_request_spec.rb +2 -2
- data/spec/cql/protocol/requests/query_request_spec.rb +13 -13
- data/spec/cql/protocol/requests/register_request_spec.rb +2 -2
- data/spec/cql/protocol/requests/startup_request_spec.rb +4 -4
- data/spec/cql/protocol/responses/auth_challenge_response_spec.rb +5 -5
- data/spec/cql/protocol/responses/auth_success_response_spec.rb +5 -5
- data/spec/cql/protocol/responses/authenticate_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/detailed_error_response_spec.rb +15 -15
- data/spec/cql/protocol/responses/error_response_spec.rb +5 -5
- data/spec/cql/protocol/responses/event_response_spec.rb +8 -8
- data/spec/cql/protocol/responses/prepared_result_response_spec.rb +7 -7
- data/spec/cql/protocol/responses/raw_rows_result_response_spec.rb +1 -1
- data/spec/cql/protocol/responses/ready_response_spec.rb +2 -2
- data/spec/cql/protocol/responses/result_response_spec.rb +16 -16
- data/spec/cql/protocol/responses/rows_result_response_spec.rb +21 -21
- data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +2 -2
- data/spec/cql/protocol/responses/status_change_event_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/supported_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +3 -3
- data/spec/cql/protocol/responses/void_result_response_spec.rb +2 -2
- data/spec/cql/protocol/type_converter_spec.rb +25 -13
- data/spec/cql/time_uuid_spec.rb +17 -4
- data/spec/cql/uuid_spec.rb +5 -1
- data/spec/integration/protocol_spec.rb +48 -42
- data/spec/spec_helper.rb +0 -1
- metadata +27 -39
- data/lib/cql/byte_buffer.rb +0 -177
- data/lib/cql/client/synchronous_client.rb +0 -79
- data/lib/cql/client/synchronous_prepared_statement.rb +0 -63
- data/lib/cql/future.rb +0 -515
- data/lib/cql/io.rb +0 -15
- data/lib/cql/io/connection.rb +0 -220
- data/lib/cql/io/io_reactor.rb +0 -349
- data/lib/cql/protocol/decoding.rb +0 -187
- data/lib/cql/protocol/encoding.rb +0 -114
- data/spec/cql/byte_buffer_spec.rb +0 -337
- data/spec/cql/client/synchronous_client_spec.rb +0 -170
- data/spec/cql/client/synchronous_prepared_statement_spec.rb +0 -155
- data/spec/cql/future_spec.rb +0 -737
- data/spec/cql/io/connection_spec.rb +0 -484
- data/spec/cql/io/io_reactor_spec.rb +0 -402
- data/spec/cql/protocol/decoding_spec.rb +0 -547
- data/spec/cql/protocol/encoding_spec.rb +0 -386
- data/spec/integration/io_spec.rb +0 -283
- data/spec/support/fake_server.rb +0 -106
data/lib/cql/future.rb
DELETED
@@ -1,515 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'thread'
|
4
|
-
|
5
|
-
|
6
|
-
module Cql
|
7
|
-
FutureError = Class.new(CqlError)
|
8
|
-
|
9
|
-
# A promise of delivering a value some time in the future.
|
10
|
-
#
|
11
|
-
# A promise is the write end of a Promise/Future pair. It can be fulfilled
|
12
|
-
# with a value or failed with an error. The value can be read through the
|
13
|
-
# future returned by {#future}.
|
14
|
-
#
|
15
|
-
# @private
|
16
|
-
class Promise
|
17
|
-
attr_reader :future
|
18
|
-
|
19
|
-
def initialize
|
20
|
-
@future = CompletableFuture.new
|
21
|
-
end
|
22
|
-
|
23
|
-
# Fulfills the promise.
|
24
|
-
#
|
25
|
-
# This will resolve this promise's future, and trigger all listeners of that
|
26
|
-
# future. The value of the future will be the specified value, or nil if
|
27
|
-
# no value is specified.
|
28
|
-
#
|
29
|
-
# @param [Object] value the value of the future
|
30
|
-
def fulfill(value=nil)
|
31
|
-
@future.resolve(value)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Fails the promise.
|
35
|
-
#
|
36
|
-
# This will fail this promise's future, and trigger all listeners of that
|
37
|
-
# future.
|
38
|
-
#
|
39
|
-
# @param [Error] error the error which prevented the promise to be fulfilled
|
40
|
-
def fail(error)
|
41
|
-
@future.fail(error)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Observe a future and fulfill the promise with the future's value when the
|
45
|
-
# future resolves, or fail with the future's error when the future fails.
|
46
|
-
#
|
47
|
-
# @param [Cql::Future] future the future to observe
|
48
|
-
def observe(future)
|
49
|
-
future.on_value { |v| fulfill(v) }
|
50
|
-
future.on_failure { |e| fail(e) }
|
51
|
-
end
|
52
|
-
|
53
|
-
# Run the given block and fulfill this promise with its result. If the block
|
54
|
-
# raises an error, fail this promise with the error.
|
55
|
-
#
|
56
|
-
# All arguments given will be passed onto the block.
|
57
|
-
#
|
58
|
-
# @example
|
59
|
-
# promise.try { 3 + 4 }
|
60
|
-
# promise.future.value # => 7
|
61
|
-
#
|
62
|
-
# @example
|
63
|
-
# promise.try do
|
64
|
-
# do_something_that_will_raise_an_error
|
65
|
-
# end
|
66
|
-
# promise.future.value # => (raises error)
|
67
|
-
#
|
68
|
-
# @example
|
69
|
-
# promise.try('foo', 'bar', &proc_taking_two_arguments)
|
70
|
-
#
|
71
|
-
# @yieldparam [Array] ctx the arguments passed to {#try}
|
72
|
-
def try(*ctx)
|
73
|
-
fulfill(yield(*ctx))
|
74
|
-
rescue => e
|
75
|
-
fail(e)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# @private
|
80
|
-
module FutureFactories
|
81
|
-
# Combines multiple futures into a new future which resolves when all
|
82
|
-
# constituent futures complete, or fails when one or more of them fails.
|
83
|
-
#
|
84
|
-
# The value of the combined future is an array of the values of the
|
85
|
-
# constituent futures.
|
86
|
-
#
|
87
|
-
# @param [Array<Cql::Future>] futures the futures to combine
|
88
|
-
# @return [Cql::Future<Array>] an array of the values of the constituent
|
89
|
-
# futures
|
90
|
-
def all(*futures)
|
91
|
-
return resolved([]) if futures.empty?
|
92
|
-
CombinedFuture.new(futures)
|
93
|
-
end
|
94
|
-
|
95
|
-
# Returns a future which will be resolved with the value of the first
|
96
|
-
# (resolved) of the specified futures. If all of the futures fail, the
|
97
|
-
# returned future will also fail (with the error of the last failed future).
|
98
|
-
#
|
99
|
-
# @param [Array<Cql::Future>] futures the futures to monitor
|
100
|
-
# @return [Cql::Future] a future which represents the first completing future
|
101
|
-
def first(*futures)
|
102
|
-
return resolved if futures.empty?
|
103
|
-
FirstFuture.new(futures)
|
104
|
-
end
|
105
|
-
|
106
|
-
# Creates a new pre-resolved future.
|
107
|
-
#
|
108
|
-
# @param [Object, nil] value the value of the created future
|
109
|
-
# @return [Cql::Future] a resolved future
|
110
|
-
def resolved(value=nil)
|
111
|
-
ResolvedFuture.new(value)
|
112
|
-
end
|
113
|
-
|
114
|
-
# Creates a new pre-failed future.
|
115
|
-
#
|
116
|
-
# @param [Error] error the error of the created future
|
117
|
-
# @return [Cql::Future] a failed future
|
118
|
-
def failed(error)
|
119
|
-
FailedFuture.new(error)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# @private
|
124
|
-
module FutureCombinators
|
125
|
-
# Returns a new future representing a transformation of this future's value.
|
126
|
-
#
|
127
|
-
# @example
|
128
|
-
# future2 = future1.map { |value| value * 2 }
|
129
|
-
#
|
130
|
-
# @param [Object] value the value of this future (when no block is given)
|
131
|
-
# @yieldparam [Object] value the value of this future
|
132
|
-
# @yieldreturn [Object] the transformed value
|
133
|
-
# @return [Cql::Future] a new future representing the transformed value
|
134
|
-
def map(value=nil, &block)
|
135
|
-
CompletableFuture.new.tap do |f|
|
136
|
-
on_failure { |e| f.fail(e) }
|
137
|
-
on_value { |v| run(f, value, block, v) }
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
# Returns a new future representing a transformation of this future's value,
|
142
|
-
# but where the transformation itself may be asynchronous.
|
143
|
-
#
|
144
|
-
# @example
|
145
|
-
# future2 = future1.flat_map { |value| method_returning_a_future(value) }
|
146
|
-
#
|
147
|
-
# This method is useful when you want to chain asynchronous operations.
|
148
|
-
#
|
149
|
-
# @yieldparam [Object] value the value of this future
|
150
|
-
# @yieldreturn [Cql::Future] a future representing the transformed value
|
151
|
-
# @return [Cql::Future] a new future representing the transformed value
|
152
|
-
def flat_map(&block)
|
153
|
-
CompletableFuture.new.tap do |f|
|
154
|
-
on_failure { |e| f.fail(e) }
|
155
|
-
on_value { |v| chain(f, block, v) }
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
# Returns a new future which represents either the value of the original
|
160
|
-
# future, or the result of the given block, if the original future fails.
|
161
|
-
#
|
162
|
-
# This method is similar to{#map}, but is triggered by a failure. You can
|
163
|
-
# also think of it as a `rescue` block for asynchronous operations.
|
164
|
-
#
|
165
|
-
# If the block raises an error a failed future with that error will be
|
166
|
-
# returned (this can be used to transform an error into another error,
|
167
|
-
# instead of tranforming an error into a value).
|
168
|
-
#
|
169
|
-
# @example
|
170
|
-
# future2 = future1.recover { |error| 'foo' }
|
171
|
-
# future1.fail(error)
|
172
|
-
# future2.value # => 'foo'
|
173
|
-
#
|
174
|
-
# @param [Object] value the value when no block is given
|
175
|
-
# @yieldparam [Object] error the error from the original future
|
176
|
-
# @yieldreturn [Object] the value of the new future
|
177
|
-
# @return [Cql::Future] a new future representing a value recovered from the error
|
178
|
-
def recover(value=nil, &block)
|
179
|
-
CompletableFuture.new.tap do |f|
|
180
|
-
on_failure { |e| run(f, value, block, e) }
|
181
|
-
on_value { |v| f.resolve(v) }
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
# Returns a new future which represents either the value of the original
|
186
|
-
# future, or the value of the future returned by the given block.
|
187
|
-
#
|
188
|
-
# This is like {#recover} but for cases when the handling of an error is
|
189
|
-
# itself asynchronous. In other words, {#fallback} is to {#recover} what
|
190
|
-
# {#flat_map} is to {#map}.
|
191
|
-
#
|
192
|
-
# If the block raises an error a failed future with that error will be
|
193
|
-
# returned (this can be used to transform an error into another error,
|
194
|
-
# instead of tranforming an error into a value).
|
195
|
-
#
|
196
|
-
# @example
|
197
|
-
# result = http_get('/foo/bar').fallback do |error|
|
198
|
-
# http_get('/baz')
|
199
|
-
# end
|
200
|
-
# result.value # either the response to /foo/bar, or if that failed
|
201
|
-
# # the response to /baz
|
202
|
-
#
|
203
|
-
# @yieldparam [Object] error the error from the original future
|
204
|
-
# @yieldreturn [Object] the value of the new future
|
205
|
-
# @return [Cql::Future] a new future representing a value recovered from the
|
206
|
-
# error
|
207
|
-
def fallback(&block)
|
208
|
-
CompletableFuture.new.tap do |f|
|
209
|
-
on_failure { |e| chain(f, block, e) }
|
210
|
-
on_value { |v| f.resolve(v) }
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
private
|
215
|
-
|
216
|
-
def run(f, value, producer, arg)
|
217
|
-
value = producer ? producer.call(arg) : value
|
218
|
-
f.resolve(value)
|
219
|
-
rescue => e
|
220
|
-
f.fail(e)
|
221
|
-
end
|
222
|
-
|
223
|
-
def chain(f, constructor, arg)
|
224
|
-
ff = constructor.call(arg)
|
225
|
-
ff.on_failure { |e| f.fail(e) }
|
226
|
-
ff.on_value { |v| f.resolve(v) }
|
227
|
-
rescue => e
|
228
|
-
f.fail(e)
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
# @private
|
233
|
-
module FutureCallbacks
|
234
|
-
# Registers a listener that will be called when this future completes,
|
235
|
-
# i.e. resolves or fails. The listener will be called with the future as
|
236
|
-
# solve argument
|
237
|
-
#
|
238
|
-
# @yieldparam [Cql::Future] future the future
|
239
|
-
def on_complete(&listener)
|
240
|
-
run_immediately = false
|
241
|
-
@lock.synchronize do
|
242
|
-
if @resolved || @failed
|
243
|
-
run_immediately = true
|
244
|
-
else
|
245
|
-
@complete_listeners << listener
|
246
|
-
end
|
247
|
-
end
|
248
|
-
if run_immediately
|
249
|
-
listener.call(self) rescue nil
|
250
|
-
end
|
251
|
-
nil
|
252
|
-
end
|
253
|
-
|
254
|
-
# Registers a listener that will be called when this future becomes
|
255
|
-
# resolved. The listener will be called with the value of the future as
|
256
|
-
# sole argument.
|
257
|
-
#
|
258
|
-
# @yieldparam [Object] value the value of the resolved future
|
259
|
-
def on_value(&listener)
|
260
|
-
run_immediately = false
|
261
|
-
@lock.synchronize do
|
262
|
-
if @resolved
|
263
|
-
run_immediately = true
|
264
|
-
elsif !@failed
|
265
|
-
@value_listeners << listener
|
266
|
-
end
|
267
|
-
end
|
268
|
-
if run_immediately
|
269
|
-
listener.call(value) rescue nil
|
270
|
-
end
|
271
|
-
nil
|
272
|
-
end
|
273
|
-
|
274
|
-
# Registers a listener that will be called when this future fails. The
|
275
|
-
# lisener will be called with the error that failed the future as sole
|
276
|
-
# argument.
|
277
|
-
#
|
278
|
-
# @yieldparam [Error] error the error that failed the future
|
279
|
-
def on_failure(&listener)
|
280
|
-
run_immediately = false
|
281
|
-
@lock.synchronize do
|
282
|
-
if @failed
|
283
|
-
run_immediately = true
|
284
|
-
elsif !@resolved
|
285
|
-
@failure_listeners << listener
|
286
|
-
end
|
287
|
-
end
|
288
|
-
if run_immediately
|
289
|
-
listener.call(@error) rescue nil
|
290
|
-
end
|
291
|
-
nil
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
|
-
# A future represents the value of a process that may not yet have completed.
|
296
|
-
#
|
297
|
-
# @see Cql::Promise
|
298
|
-
# @private
|
299
|
-
class Future
|
300
|
-
extend FutureFactories
|
301
|
-
include FutureCombinators
|
302
|
-
include FutureCallbacks
|
303
|
-
|
304
|
-
def initialize
|
305
|
-
@lock = Mutex.new
|
306
|
-
@resolved = false
|
307
|
-
@failed = false
|
308
|
-
@failure_listeners = []
|
309
|
-
@value_listeners = []
|
310
|
-
@complete_listeners = []
|
311
|
-
end
|
312
|
-
|
313
|
-
# Returns the value of this future, blocking until it is available if
|
314
|
-
# necessary.
|
315
|
-
#
|
316
|
-
# If the future fails this method will raise the error that failed the
|
317
|
-
# future.
|
318
|
-
#
|
319
|
-
# @return [Object] the value of this future
|
320
|
-
def value
|
321
|
-
semaphore = nil
|
322
|
-
@lock.synchronize do
|
323
|
-
raise @error if @failed
|
324
|
-
return @value if @resolved
|
325
|
-
semaphore = Queue.new
|
326
|
-
u = proc { semaphore << :unblock }
|
327
|
-
@value_listeners << u
|
328
|
-
@failure_listeners << u
|
329
|
-
end
|
330
|
-
while true
|
331
|
-
@lock.synchronize do
|
332
|
-
raise @error if @failed
|
333
|
-
return @value if @resolved
|
334
|
-
end
|
335
|
-
semaphore.pop
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
# Returns true if this future is resolved or failed
|
340
|
-
def completed?
|
341
|
-
resolved? || failed?
|
342
|
-
end
|
343
|
-
|
344
|
-
# Returns true if this future is resolved
|
345
|
-
def resolved?
|
346
|
-
@lock.synchronize { @resolved }
|
347
|
-
end
|
348
|
-
|
349
|
-
# Returns true if this future has failed
|
350
|
-
def failed?
|
351
|
-
@lock.synchronize { @failed }
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
# @private
|
356
|
-
class CompletableFuture < Future
|
357
|
-
def resolve(v=nil)
|
358
|
-
value_listeners = nil
|
359
|
-
complete_listeners = nil
|
360
|
-
@lock.synchronize do
|
361
|
-
raise FutureError, 'Future already completed' if @resolved || @failed
|
362
|
-
@resolved = true
|
363
|
-
@value = v
|
364
|
-
value_listeners = @value_listeners
|
365
|
-
complete_listeners = @complete_listeners
|
366
|
-
@value_listeners = nil
|
367
|
-
@failure_listeners = nil
|
368
|
-
@complete_listeners = nil
|
369
|
-
end
|
370
|
-
value_listeners.each do |listener|
|
371
|
-
listener.call(v) rescue nil
|
372
|
-
end
|
373
|
-
complete_listeners.each do |listener|
|
374
|
-
listener.call(self) rescue nil
|
375
|
-
end
|
376
|
-
nil
|
377
|
-
end
|
378
|
-
|
379
|
-
def fail(error)
|
380
|
-
failure_listeners = nil
|
381
|
-
complete_listeners = nil
|
382
|
-
@lock.synchronize do
|
383
|
-
raise FutureError, 'Future already completed' if @failed || @resolved
|
384
|
-
@failed = true
|
385
|
-
@error = error
|
386
|
-
failure_listeners = @failure_listeners
|
387
|
-
complete_listeners = @complete_listeners
|
388
|
-
@value_listeners = nil
|
389
|
-
@failure_listeners = nil
|
390
|
-
@complete_listeners = nil
|
391
|
-
end
|
392
|
-
failure_listeners.each do |listener|
|
393
|
-
listener.call(error) rescue nil
|
394
|
-
end
|
395
|
-
complete_listeners.each do |listener|
|
396
|
-
listener.call(self) rescue nil
|
397
|
-
end
|
398
|
-
nil
|
399
|
-
end
|
400
|
-
end
|
401
|
-
|
402
|
-
# @private
|
403
|
-
class CombinedFuture < CompletableFuture
|
404
|
-
def initialize(futures)
|
405
|
-
super()
|
406
|
-
values = Array.new(futures.size)
|
407
|
-
remaining = futures.size
|
408
|
-
futures.each_with_index do |f, i|
|
409
|
-
f.on_value do |v|
|
410
|
-
@lock.synchronize do
|
411
|
-
values[i] = v
|
412
|
-
remaining -= 1
|
413
|
-
end
|
414
|
-
if remaining == 0
|
415
|
-
resolve(values)
|
416
|
-
end
|
417
|
-
end
|
418
|
-
f.on_failure do |e|
|
419
|
-
unless failed?
|
420
|
-
fail(e)
|
421
|
-
end
|
422
|
-
end
|
423
|
-
end
|
424
|
-
end
|
425
|
-
end
|
426
|
-
|
427
|
-
# @private
|
428
|
-
class FirstFuture < CompletableFuture
|
429
|
-
def initialize(futures)
|
430
|
-
super()
|
431
|
-
futures.each do |f|
|
432
|
-
f.on_value do |value|
|
433
|
-
resolve(value) unless completed?
|
434
|
-
end
|
435
|
-
f.on_failure do |e|
|
436
|
-
fail(e) if futures.all?(&:failed?)
|
437
|
-
end
|
438
|
-
end
|
439
|
-
end
|
440
|
-
end
|
441
|
-
|
442
|
-
# @private
|
443
|
-
class ResolvedFuture < Future
|
444
|
-
def initialize(value=nil)
|
445
|
-
@resolved = true
|
446
|
-
@failed = false
|
447
|
-
@value = value
|
448
|
-
@error = nil
|
449
|
-
end
|
450
|
-
|
451
|
-
def value
|
452
|
-
@value
|
453
|
-
end
|
454
|
-
|
455
|
-
def completed?
|
456
|
-
true
|
457
|
-
end
|
458
|
-
|
459
|
-
def resolved?
|
460
|
-
true
|
461
|
-
end
|
462
|
-
|
463
|
-
def failed?
|
464
|
-
false
|
465
|
-
end
|
466
|
-
|
467
|
-
def on_complete(&listener)
|
468
|
-
listener.call(self) rescue nil
|
469
|
-
end
|
470
|
-
|
471
|
-
def on_value(&listener)
|
472
|
-
listener.call(value) rescue nil
|
473
|
-
end
|
474
|
-
|
475
|
-
def on_failure
|
476
|
-
end
|
477
|
-
end
|
478
|
-
|
479
|
-
# @private
|
480
|
-
class FailedFuture < Future
|
481
|
-
def initialize(error)
|
482
|
-
@resolved = false
|
483
|
-
@failed = true
|
484
|
-
@value = nil
|
485
|
-
@error = error
|
486
|
-
end
|
487
|
-
|
488
|
-
def value
|
489
|
-
raise @error
|
490
|
-
end
|
491
|
-
|
492
|
-
def completed?
|
493
|
-
true
|
494
|
-
end
|
495
|
-
|
496
|
-
def resolved?
|
497
|
-
false
|
498
|
-
end
|
499
|
-
|
500
|
-
def failed?
|
501
|
-
true
|
502
|
-
end
|
503
|
-
|
504
|
-
def on_complete(&listener)
|
505
|
-
listener.call(self) rescue nil
|
506
|
-
end
|
507
|
-
|
508
|
-
def on_value
|
509
|
-
end
|
510
|
-
|
511
|
-
def on_failure(&listener)
|
512
|
-
listener.call(@error) rescue nil
|
513
|
-
end
|
514
|
-
end
|
515
|
-
end
|