ione 1.1.2 → 1.1.3.pre0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ione/future.rb +90 -37
- data/lib/ione/io/base_connection.rb +13 -4
- data/lib/ione/io/io_reactor.rb +16 -13
- data/lib/ione/version.rb +1 -1
- data/spec/ione/future_spec.rb +12 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 683f88dbcc94dbca64fc620cbad845bfb7eb359e
|
4
|
+
data.tar.gz: eda5367f48dda6be7a53664dc219b39e71797634
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdadd53947a7b24140b2d2a2dba5615a4251576af3114e6da458ec9c4d47b0be578d93d1f13f2bff774d49fbb85668430312d4fd4c0e4a211969b82ca24c38c9
|
7
|
+
data.tar.gz: d4d1dd59ae9d4300483c0b9e65084d905f80911d126ba1984f89537e4f53e2bfc7468c6bd7c45dc7fb4ef9c564046e654103e09367ce9349a5156835361deb19
|
data/lib/ione/future.rb
CHANGED
@@ -236,11 +236,18 @@ module Ione
|
|
236
236
|
# @yieldparam [Ione::Future] future the future
|
237
237
|
def on_complete(&listener)
|
238
238
|
run_immediately = false
|
239
|
-
@
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
239
|
+
if @state != :pending
|
240
|
+
run_immediately = true
|
241
|
+
else
|
242
|
+
@lock.lock
|
243
|
+
begin
|
244
|
+
if @state == :pending
|
245
|
+
@complete_listeners << listener
|
246
|
+
else
|
247
|
+
run_immediately = true
|
248
|
+
end
|
249
|
+
ensure
|
250
|
+
@lock.unlock
|
244
251
|
end
|
245
252
|
end
|
246
253
|
if run_immediately
|
@@ -256,11 +263,18 @@ module Ione
|
|
256
263
|
# @yieldparam [Object] value the value of the resolved future
|
257
264
|
def on_value(&listener)
|
258
265
|
run_immediately = false
|
259
|
-
@
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
266
|
+
if @state == :resolved
|
267
|
+
run_immediately = true
|
268
|
+
else
|
269
|
+
@lock.lock
|
270
|
+
begin
|
271
|
+
if @state == :pending
|
272
|
+
@value_listeners << listener
|
273
|
+
elsif @state == :resolved
|
274
|
+
run_immediately = true
|
275
|
+
end
|
276
|
+
ensure
|
277
|
+
@lock.unlock
|
264
278
|
end
|
265
279
|
end
|
266
280
|
if run_immediately
|
@@ -276,11 +290,18 @@ module Ione
|
|
276
290
|
# @yieldparam [Error] error the error that failed the future
|
277
291
|
def on_failure(&listener)
|
278
292
|
run_immediately = false
|
279
|
-
@
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
293
|
+
if @state == :failed
|
294
|
+
run_immediately = true
|
295
|
+
else
|
296
|
+
@lock.lock
|
297
|
+
begin
|
298
|
+
if @state == :pending
|
299
|
+
@failure_listeners << listener
|
300
|
+
elsif @state == :failed
|
301
|
+
run_immediately = true
|
302
|
+
end
|
303
|
+
ensure
|
304
|
+
@lock.unlock
|
284
305
|
end
|
285
306
|
end
|
286
307
|
if run_immediately
|
@@ -300,8 +321,7 @@ module Ione
|
|
300
321
|
|
301
322
|
def initialize
|
302
323
|
@lock = Mutex.new
|
303
|
-
@
|
304
|
-
@failed = false
|
324
|
+
@state = :pending
|
305
325
|
@failure_listeners = []
|
306
326
|
@value_listeners = []
|
307
327
|
@complete_listeners = []
|
@@ -315,19 +335,27 @@ module Ione
|
|
315
335
|
#
|
316
336
|
# @return [Object] the value of this future
|
317
337
|
def value
|
338
|
+
raise @error if @state == :failed
|
339
|
+
return @value if @state == :resolved
|
318
340
|
semaphore = nil
|
319
|
-
@lock.
|
320
|
-
|
321
|
-
|
341
|
+
@lock.lock
|
342
|
+
begin
|
343
|
+
raise @error if @state == :failed
|
344
|
+
return @value if @state == :resolved
|
322
345
|
semaphore = Queue.new
|
323
346
|
u = proc { semaphore << :unblock }
|
324
347
|
@value_listeners << u
|
325
348
|
@failure_listeners << u
|
349
|
+
ensure
|
350
|
+
@lock.unlock
|
326
351
|
end
|
327
352
|
while true
|
328
|
-
@lock.
|
329
|
-
|
330
|
-
|
353
|
+
@lock.lock
|
354
|
+
begin
|
355
|
+
raise @error if @state == :failed
|
356
|
+
return @value if @state == :resolved
|
357
|
+
ensure
|
358
|
+
@lock.unlock
|
331
359
|
end
|
332
360
|
semaphore.pop
|
333
361
|
end
|
@@ -335,17 +363,35 @@ module Ione
|
|
335
363
|
|
336
364
|
# Returns true if this future is resolved or failed
|
337
365
|
def completed?
|
338
|
-
|
366
|
+
return true unless @state == :pending
|
367
|
+
@lock.lock
|
368
|
+
begin
|
369
|
+
@state != :pending
|
370
|
+
ensure
|
371
|
+
@lock.unlock
|
372
|
+
end
|
339
373
|
end
|
340
374
|
|
341
375
|
# Returns true if this future is resolved
|
342
376
|
def resolved?
|
343
|
-
@
|
377
|
+
return @state == :resolved unless @state == :pending
|
378
|
+
@lock.lock
|
379
|
+
begin
|
380
|
+
@state == :resolved
|
381
|
+
ensure
|
382
|
+
@lock.unlock
|
383
|
+
end
|
344
384
|
end
|
345
385
|
|
346
386
|
# Returns true if this future has failed
|
347
387
|
def failed?
|
348
|
-
@
|
388
|
+
return @state == :failed unless @state == :pending
|
389
|
+
@lock.lock
|
390
|
+
begin
|
391
|
+
@state == :failed
|
392
|
+
ensure
|
393
|
+
@lock.unlock
|
394
|
+
end
|
349
395
|
end
|
350
396
|
end
|
351
397
|
|
@@ -354,15 +400,18 @@ module Ione
|
|
354
400
|
def resolve(v=nil)
|
355
401
|
value_listeners = nil
|
356
402
|
complete_listeners = nil
|
357
|
-
@lock.
|
358
|
-
|
359
|
-
@
|
403
|
+
@lock.lock
|
404
|
+
begin
|
405
|
+
raise FutureError, 'Future already completed' unless @state == :pending
|
360
406
|
@value = v
|
407
|
+
@state = :resolved
|
361
408
|
value_listeners = @value_listeners
|
362
409
|
complete_listeners = @complete_listeners
|
363
410
|
@value_listeners = nil
|
364
411
|
@failure_listeners = nil
|
365
412
|
@complete_listeners = nil
|
413
|
+
ensure
|
414
|
+
@lock.unlock
|
366
415
|
end
|
367
416
|
value_listeners.each do |listener|
|
368
417
|
listener.call(v) rescue nil
|
@@ -376,15 +425,18 @@ module Ione
|
|
376
425
|
def fail(error)
|
377
426
|
failure_listeners = nil
|
378
427
|
complete_listeners = nil
|
379
|
-
@lock.
|
380
|
-
|
381
|
-
@
|
428
|
+
@lock.lock
|
429
|
+
begin
|
430
|
+
raise FutureError, 'Future already completed' unless @state == :pending
|
382
431
|
@error = error
|
432
|
+
@state = :failed
|
383
433
|
failure_listeners = @failure_listeners
|
384
434
|
complete_listeners = @complete_listeners
|
385
435
|
@value_listeners = nil
|
386
436
|
@failure_listeners = nil
|
387
437
|
@complete_listeners = nil
|
438
|
+
ensure
|
439
|
+
@lock.unlock
|
388
440
|
end
|
389
441
|
failure_listeners.each do |listener|
|
390
442
|
listener.call(error) rescue nil
|
@@ -404,9 +456,12 @@ module Ione
|
|
404
456
|
remaining = futures.size
|
405
457
|
futures.each_with_index do |f, i|
|
406
458
|
f.on_value do |v|
|
407
|
-
@lock.
|
459
|
+
@lock.lock
|
460
|
+
begin
|
408
461
|
values[i] = v
|
409
462
|
remaining -= 1
|
463
|
+
ensure
|
464
|
+
@lock.unlock
|
410
465
|
end
|
411
466
|
if remaining == 0
|
412
467
|
resolve(values)
|
@@ -439,8 +494,7 @@ module Ione
|
|
439
494
|
# @private
|
440
495
|
class ResolvedFuture < Future
|
441
496
|
def initialize(value=nil)
|
442
|
-
@
|
443
|
-
@failed = false
|
497
|
+
@state = :resolved
|
444
498
|
@value = value
|
445
499
|
@error = nil
|
446
500
|
end
|
@@ -478,8 +532,7 @@ module Ione
|
|
478
532
|
# @private
|
479
533
|
class FailedFuture < Future
|
480
534
|
def initialize(error)
|
481
|
-
@
|
482
|
-
@failed = true
|
535
|
+
@state = :failed
|
483
536
|
@value = nil
|
484
537
|
@error = error
|
485
538
|
end
|
@@ -63,8 +63,11 @@ module Ione
|
|
63
63
|
|
64
64
|
# @private
|
65
65
|
def writable?
|
66
|
-
|
67
|
-
|
66
|
+
@lock.lock
|
67
|
+
begin
|
68
|
+
empty_buffer = @write_buffer.empty?
|
69
|
+
ensure
|
70
|
+
@lock.unlock
|
68
71
|
end
|
69
72
|
!(closed? || empty_buffer)
|
70
73
|
end
|
@@ -113,12 +116,15 @@ module Ione
|
|
113
116
|
# @param bytes [String, Ione::ByteBuffer] the data to write to the socket
|
114
117
|
def write(bytes=nil)
|
115
118
|
if @state == :connected || @state == :connecting
|
116
|
-
@lock.
|
119
|
+
@lock.lock
|
120
|
+
begin
|
117
121
|
if block_given?
|
118
122
|
yield @write_buffer
|
119
123
|
elsif bytes
|
120
124
|
@write_buffer.append(bytes)
|
121
125
|
end
|
126
|
+
ensure
|
127
|
+
@lock.unlock
|
122
128
|
end
|
123
129
|
@unblocker.unblock!
|
124
130
|
end
|
@@ -127,7 +133,8 @@ module Ione
|
|
127
133
|
# @private
|
128
134
|
def flush
|
129
135
|
if @state == :connected || @state == :draining
|
130
|
-
@lock.
|
136
|
+
@lock.lock
|
137
|
+
begin
|
131
138
|
unless @write_buffer.empty?
|
132
139
|
bytes_written = @io.write_nonblock(@write_buffer.cheap_peek)
|
133
140
|
@write_buffer.discard(bytes_written)
|
@@ -135,6 +142,8 @@ module Ione
|
|
135
142
|
if @state == :draining && @write_buffer.empty?
|
136
143
|
close
|
137
144
|
end
|
145
|
+
ensure
|
146
|
+
@lock.unlock
|
138
147
|
end
|
139
148
|
end
|
140
149
|
rescue => e
|
data/lib/ione/io/io_reactor.rb
CHANGED
@@ -224,9 +224,10 @@ module Ione
|
|
224
224
|
end
|
225
225
|
|
226
226
|
def unblock!
|
227
|
-
@lock.
|
228
|
-
|
229
|
-
|
227
|
+
@lock.lock
|
228
|
+
@in.write(PING_BYTE)
|
229
|
+
ensure
|
230
|
+
@lock.unlock
|
230
231
|
end
|
231
232
|
|
232
233
|
def read
|
@@ -264,20 +265,22 @@ module Ione
|
|
264
265
|
end
|
265
266
|
|
266
267
|
def add_socket(socket)
|
267
|
-
@lock.
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
268
|
+
@lock.lock
|
269
|
+
sockets = @sockets.reject { |s| s.closed? }
|
270
|
+
sockets << socket
|
271
|
+
@sockets = sockets
|
272
|
+
ensure
|
273
|
+
@lock.unlock
|
272
274
|
end
|
273
275
|
|
274
276
|
def schedule_timer(timeout, promise=Promise.new)
|
275
|
-
@lock.
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
end
|
277
|
+
@lock.lock
|
278
|
+
timers = @timers.reject { |pair| pair[1].nil? }
|
279
|
+
timers << [@clock.now + timeout, promise]
|
280
|
+
@timers = timers
|
280
281
|
promise.future
|
282
|
+
ensure
|
283
|
+
@lock.unlock
|
281
284
|
end
|
282
285
|
|
283
286
|
def close_sockets
|
data/lib/ione/version.rb
CHANGED
data/spec/ione/future_spec.rb
CHANGED
@@ -148,6 +148,10 @@ module Ione
|
|
148
148
|
promise.fail(StandardError.new('bork'))
|
149
149
|
future.should be_completed
|
150
150
|
end
|
151
|
+
|
152
|
+
it 'is false before the future has been resolved or failed' do
|
153
|
+
future.should_not be_completed
|
154
|
+
end
|
151
155
|
end
|
152
156
|
|
153
157
|
describe '#resolved?' do
|
@@ -165,6 +169,10 @@ module Ione
|
|
165
169
|
promise.fail(StandardError.new('bork'))
|
166
170
|
future.should_not be_resolved
|
167
171
|
end
|
172
|
+
|
173
|
+
it 'is false before the future has been resolved or failed' do
|
174
|
+
future.should_not be_resolved
|
175
|
+
end
|
168
176
|
end
|
169
177
|
|
170
178
|
describe '#failed?' do
|
@@ -177,6 +185,10 @@ module Ione
|
|
177
185
|
promise.fulfill
|
178
186
|
future.should_not be_failed
|
179
187
|
end
|
188
|
+
|
189
|
+
it 'is false before the future has been resolved or failed' do
|
190
|
+
future.should_not be_failed
|
191
|
+
end
|
180
192
|
end
|
181
193
|
|
182
194
|
describe '#on_complete' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ione
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.3.pre0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Theo Hultberg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Reactive programming framework for Ruby, painless evented IO, futures
|
14
14
|
and an efficient byte buffer
|
@@ -56,9 +56,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
56
56
|
version: 1.9.3
|
57
57
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - '
|
59
|
+
- - '>'
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 1.3.1
|
62
62
|
requirements: []
|
63
63
|
rubyforge_project:
|
64
64
|
rubygems_version: 2.2.1
|