ione 1.2.0.pre1 → 1.2.0.pre2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 48f64612b814b95e3c12619aad2ad8da60d00f7b
4
- data.tar.gz: 6094996f6fedbe6449c0033cae40ccc19cafe46c
3
+ metadata.gz: 571332add4f394d8de9adbe6b371de13c84e3a09
4
+ data.tar.gz: 006892c0ffe2f9fdb489ba5848d28be6e45ad27c
5
5
  SHA512:
6
- metadata.gz: 00e1194cf9716e8f5030b634f21740d622c96862682a0427266dd76fa453290ed60460b2fdae08f9165d28df12bbfa3ca24de2d03043935c3407335a5e85afd5
7
- data.tar.gz: 9dda73caa92ee3a8f5853f3edf81496082e9c748663295b2f6f5c1f6c5a21f324d54d8e921a3afb4ec580e8253b0d1c5e24ecf2985a7684a10a962b926f25612
6
+ metadata.gz: f41e94213226b72a09487b4ff615ab01b3be84ffe351f5dcd78ef2e350a0bcc17b117395fdcf35944d8ab78f4ae9383821140fa43cfb15866f9e78af9cc970ec
7
+ data.tar.gz: 91778d76c5ef9fdf87ec0d51a29abb495056d0e3843badaec6ca6eeb86683f4aa82948a6e0a68d93ddf0dc012e54eafe4d84ba91d4d38224de3eb658297f1c2e
data/lib/ione/future.rb CHANGED
@@ -44,7 +44,7 @@ module Ione
44
44
  #
45
45
  # @param [Ione::Future] future the future to observe
46
46
  def observe(future)
47
- future.on_complete do |_, v, e|
47
+ future.on_complete do |v, e|
48
48
  if e
49
49
  fail(e)
50
50
  else
@@ -215,7 +215,7 @@ module Ione
215
215
  # @return [Ione::Future] a new future representing the transformed value
216
216
  def map(value=nil, &block)
217
217
  f = CompletableFuture.new
218
- on_complete do |_, v, e|
218
+ on_complete do |v, e|
219
219
  if e
220
220
  f.fail(e)
221
221
  else
@@ -242,13 +242,13 @@ module Ione
242
242
  # @return [Ione::Future] a new future representing the transformed value
243
243
  def flat_map(&block)
244
244
  f = CompletableFuture.new
245
- on_complete do |_, v, e|
245
+ on_complete do |v, e|
246
246
  if e
247
247
  f.fail(e)
248
248
  else
249
249
  begin
250
250
  ff = block.call(v)
251
- ff.on_complete do |_, vv, ee|
251
+ ff.on_complete do |vv, ee|
252
252
  if ee
253
253
  f.fail(ee)
254
254
  else
@@ -288,14 +288,14 @@ module Ione
288
288
  # @return [Ione::Future] a new future representing the transformed value
289
289
  def then(&block)
290
290
  f = CompletableFuture.new
291
- on_complete do |_, v, e|
291
+ on_complete do |v, e|
292
292
  if e
293
293
  f.fail(e)
294
294
  else
295
295
  begin
296
296
  fv = block.call(v)
297
297
  if fv.respond_to?(:on_complete)
298
- fv.on_complete do |_, vv, ee|
298
+ fv.on_complete do |vv, ee|
299
299
  if ee
300
300
  f.fail(ee)
301
301
  else
@@ -334,7 +334,7 @@ module Ione
334
334
  # @return [Ione::Future] a new future representing a value recovered from the error
335
335
  def recover(value=nil, &block)
336
336
  f = CompletableFuture.new
337
- on_complete do |_, v, e|
337
+ on_complete do |v, e|
338
338
  if e
339
339
  begin
340
340
  f.resolve(block ? block.call(e) : value)
@@ -372,11 +372,11 @@ module Ione
372
372
  # error
373
373
  def fallback(&block)
374
374
  f = CompletableFuture.new
375
- on_complete do |_, v, e|
375
+ on_complete do |v, e|
376
376
  if e
377
377
  begin
378
378
  ff = block.call(e)
379
- ff.on_complete do |_, vv, ee|
379
+ ff.on_complete do |vv, ee|
380
380
  if ee
381
381
  f.fail(ee)
382
382
  else
@@ -401,8 +401,8 @@ module Ione
401
401
  #
402
402
  # @yieldparam [Object] value the value of the resolved future
403
403
  def on_value(&listener)
404
- on_complete do |f, value|
405
- listener.call(value) if f.resolved?
404
+ on_complete do |value, error|
405
+ listener.call(value) unless error
406
406
  end
407
407
  nil
408
408
  end
@@ -413,8 +413,8 @@ module Ione
413
413
  #
414
414
  # @yieldparam [Error] error the error that failed the future
415
415
  def on_failure(&listener)
416
- on_complete do |f, _, error|
417
- listener.call(error) if f.failed?
416
+ on_complete do |_, error|
417
+ listener.call(error) if error
418
418
  end
419
419
  nil
420
420
  end
@@ -456,7 +456,7 @@ module Ione
456
456
  end
457
457
  end
458
458
  if run_immediately
459
- listener.call(self, @value, @error) rescue nil
459
+ call_listener(listener)
460
460
  end
461
461
  nil
462
462
  end
@@ -493,6 +493,7 @@ module Ione
493
493
  semaphore.pop
494
494
  end
495
495
  end
496
+ alias_method :get, :value
496
497
 
497
498
  # Returns true if this future is resolved or failed
498
499
  def completed?
@@ -526,6 +527,25 @@ module Ione
526
527
  @lock.unlock
527
528
  end
528
529
  end
530
+
531
+ private
532
+
533
+ def call_listener(listener)
534
+ begin
535
+ n = listener.arity
536
+ if n == 1
537
+ listener.call(self)
538
+ elsif n == 2 || n == -3
539
+ listener.call(@value, @error)
540
+ elsif n == 0
541
+ listener.call
542
+ else
543
+ listener.call(@value, @error, self)
544
+ end
545
+ rescue
546
+ # swallowed
547
+ end
548
+ end
529
549
  end
530
550
 
531
551
  # @private
@@ -543,7 +563,7 @@ module Ione
543
563
  @lock.unlock
544
564
  end
545
565
  listeners.each do |listener|
546
- listener.call(self, v, nil) rescue nil
566
+ call_listener(listener)
547
567
  end
548
568
  nil
549
569
  end
@@ -561,7 +581,7 @@ module Ione
561
581
  @lock.unlock
562
582
  end
563
583
  listeners.each do |listener|
564
- listener.call(self, nil, error) rescue nil
584
+ call_listener(listener)
565
585
  end
566
586
  nil
567
587
  end
@@ -574,7 +594,7 @@ module Ione
574
594
  remaining = futures.count
575
595
  values = Array.new(remaining)
576
596
  futures.each_with_index do |f, i|
577
- f.on_complete do |_, v, e|
597
+ f.on_complete do |v, e|
578
598
  unless failed?
579
599
  if e
580
600
  fail(e)
@@ -651,7 +671,7 @@ module Ione
651
671
  private
652
672
 
653
673
  def reduce_next(i)
654
- @futures[i].on_complete do |_, v, e|
674
+ @futures[i].on_complete do |v, e|
655
675
  unless failed?
656
676
  if e
657
677
  fail(e)
@@ -669,7 +689,7 @@ module Ione
669
689
  super
670
690
  if @remaining > 0
671
691
  futures.each do |f|
672
- f.on_complete do |_, v, e|
692
+ f.on_complete do |v, e|
673
693
  unless failed?
674
694
  if e
675
695
  fail(e)
@@ -690,7 +710,7 @@ module Ione
690
710
  def initialize(futures)
691
711
  super()
692
712
  futures.each do |f|
693
- f.on_complete do |_, v, e|
713
+ f.on_complete do |v, e|
694
714
  unless completed?
695
715
  if e
696
716
  if futures.all?(&:failed?)
@@ -721,7 +741,7 @@ module Ione
721
741
  true
722
742
  end
723
743
 
724
- def resolved?
744
+ def resolvesd?
725
745
  true
726
746
  end
727
747
 
@@ -730,7 +750,7 @@ module Ione
730
750
  end
731
751
 
732
752
  def on_complete(&listener)
733
- listener.call(self, @value, nil) rescue nil
753
+ call_listener(listener)
734
754
  end
735
755
 
736
756
  def on_value(&listener)
@@ -768,7 +788,7 @@ module Ione
768
788
  end
769
789
 
770
790
  def on_complete(&listener)
771
- listener.call(self, nil, @error) rescue nil
791
+ call_listener(listener)
772
792
  end
773
793
 
774
794
  def on_value
@@ -778,4 +798,4 @@ module Ione
778
798
  listener.call(@error) rescue nil
779
799
  end
780
800
  end
781
- end
801
+ end
data/lib/ione/io.rb CHANGED
@@ -19,3 +19,6 @@ require 'ione/io/base_connection'
19
19
  require 'ione/io/connection'
20
20
  require 'ione/io/server_connection'
21
21
  require 'ione/io/acceptor'
22
+ require 'ione/io/ssl_connection'
23
+ require 'ione/io/ssl_server_connection'
24
+ require 'ione/io/ssl_acceptor'
@@ -6,6 +6,8 @@ module Ione
6
6
  class Acceptor
7
7
  ServerSocket = RUBY_ENGINE == 'jruby' ? ::ServerSocket : Socket
8
8
 
9
+ attr_reader :backlog
10
+
9
11
  def initialize(host, port, backlog, unblocker, reactor, socket_impl=nil)
10
12
  @host = host
11
13
  @port = port
@@ -27,8 +29,8 @@ module Ione
27
29
  addrinfos = @socket_impl.getaddrinfo(@host, @port, nil, Socket::SOCK_STREAM)
28
30
  begin
29
31
  _, port, _, ip, address_family, socket_type = addrinfos.shift
30
- @socket = @socket_impl.new(address_family, socket_type, 0)
31
- bind_socket(@socket, @socket_impl.sockaddr_in(port, ip), @backlog)
32
+ @io = @socket_impl.new(address_family, socket_type, 0)
33
+ bind_socket(@io, @socket_impl.sockaddr_in(port, ip), @backlog)
32
34
  rescue Errno::EADDRNOTAVAIL => e
33
35
  if addrinfos.empty?
34
36
  raise
@@ -38,26 +40,27 @@ module Ione
38
40
  end
39
41
  Future.resolved(self)
40
42
  rescue => e
43
+ close
41
44
  Future.failed(e)
42
45
  end
43
46
 
44
47
  def close
45
- return false unless @socket
48
+ return false unless @io
46
49
  begin
47
- @socket.close
50
+ @io.close
48
51
  rescue SystemCallError, IOError
49
52
  # nothing to do, the socket was most likely already closed
50
53
  end
51
- @socket = nil
54
+ @io = nil
52
55
  true
53
56
  end
54
57
 
55
58
  def to_io
56
- @socket
59
+ @io
57
60
  end
58
61
 
59
62
  def closed?
60
- @socket.nil?
63
+ @io.nil?
61
64
  end
62
65
 
63
66
  def connected?
@@ -73,12 +76,10 @@ module Ione
73
76
  end
74
77
 
75
78
  def read
76
- client_socket, client_sockaddr = @socket.accept_nonblock
77
- port, host = @socket_impl.unpack_sockaddr_in(client_sockaddr)
79
+ client_socket, host, port = accept
78
80
  connection = ServerConnection.new(client_socket, host, port, @unblocker)
79
81
  @reactor.accept(connection)
80
- listeners = @lock.synchronize { @accept_listeners }
81
- listeners.each { |l| l.call(connection) rescue nil }
82
+ notify_accept_listeners(connection)
82
83
  end
83
84
 
84
85
  if RUBY_ENGINE == 'jruby'
@@ -91,6 +92,19 @@ module Ione
91
92
  socket.listen(backlog)
92
93
  end
93
94
  end
95
+
96
+ private
97
+
98
+ def accept
99
+ client_socket, client_sockaddr = @io.accept_nonblock
100
+ port, host = @socket_impl.unpack_sockaddr_in(client_sockaddr)
101
+ return client_socket, host, port
102
+ end
103
+
104
+ def notify_accept_listeners(connection)
105
+ listeners = @lock.synchronize { @accept_listeners }
106
+ listeners.each { |l| l.call(connection) rescue nil }
107
+ end
94
108
  end
95
109
  end
96
110
  end
@@ -5,10 +5,13 @@ module Ione
5
5
  class BaseConnection
6
6
  attr_reader :host, :port
7
7
 
8
- def initialize(host, port)
8
+ def initialize(host, port, unblocker)
9
9
  @host = host
10
10
  @port = port
11
+ @unblocker = unblocker
11
12
  @state = :connecting
13
+ @lock = Mutex.new
14
+ @write_buffer = ByteBuffer.new
12
15
  @closed_promise = Promise.new
13
16
  end
14
17
 
@@ -9,13 +9,10 @@ module Ione
9
9
 
10
10
  # @private
11
11
  def initialize(host, port, connection_timeout, unblocker, clock, socket_impl=Socket)
12
- super(host, port)
12
+ super(host, port, unblocker)
13
13
  @connection_timeout = connection_timeout
14
- @unblocker = unblocker
15
14
  @clock = clock
16
15
  @socket_impl = socket_impl
17
- @lock = Mutex.new
18
- @write_buffer = ByteBuffer.new
19
16
  @connected_promise = Promise.new
20
17
  on_closed(&method(:cleanup_on_close))
21
18
  end
@@ -156,23 +156,57 @@ module Ione
156
156
  #
157
157
  # @param host [String] the host to connect to
158
158
  # @param port [Integer] the port to connect to
159
- # @param timeout [Numeric] the number of seconds to wait for a connection
160
- # before failing
159
+ # @param options_or_timeout [Hash, Numeric] a hash of options (see below)
160
+ # or the connection timeout (equivalent to using the `:timeout` option).
161
+ # @option options_or_timeout [Numeric] :timeout (5) the number of seconds
162
+ # to wait for a connection before failing
163
+ # @option options_or_timeout [Boolean, OpenSSL::SSL::SSLContext] :ssl (false)
164
+ # pass an `OpenSSL::SSL::SSLContext` to upgrade the connection to SSL,
165
+ # or true to upgrade the connection and create a new context.
161
166
  # @yieldparam [Ione::Io::Connection] connection the newly opened connection
162
167
  # @return [Ione::Future] a future that will resolve when the connection is
163
168
  # open. The value will be the connection, or when a block is given to
164
169
  # what the block returns
165
- def connect(host, port, timeout, &block)
170
+ def connect(host, port, options=nil, &block)
171
+ if options.is_a?(Numeric) || options.nil?
172
+ timeout = options || 5
173
+ ssl = false
174
+ elsif options
175
+ timeout = options[:timeout] || 5
176
+ ssl = options[:ssl]
177
+ end
166
178
  connection = Connection.new(host, port, timeout, @unblocker, @clock)
167
179
  f = connection.connect
168
180
  @io_loop.add_socket(connection)
169
181
  @unblocker.unblock!
182
+ if ssl
183
+ f = f.flat_map do
184
+ ssl_context = ssl == true ? nil : ssl
185
+ upgraded_connection = SslConnection.new(host, port, connection.to_io, @unblocker, ssl_context)
186
+ ff = upgraded_connection.connect
187
+ @io_loop.remove_socket(connection)
188
+ @io_loop.add_socket(upgraded_connection)
189
+ @unblocker.unblock!
190
+ ff
191
+ end
192
+ end
170
193
  f = f.map(&block) if block_given?
171
194
  f
172
195
  end
173
196
 
174
- def bind(host, port, backlog, &block)
175
- server = Acceptor.new(host, port, backlog, @unblocker, self)
197
+ def bind(host, port, options=nil, &block)
198
+ if options.is_a?(Integer) || options.nil?
199
+ backlog = options || 5
200
+ ssl_context = nil
201
+ elsif options
202
+ backlog = options[:backlog] || 5
203
+ ssl_context = options[:ssl]
204
+ end
205
+ if ssl_context
206
+ server = SslAcceptor.new(host, port, backlog, @unblocker, self, ssl_context)
207
+ else
208
+ server = Acceptor.new(host, port, backlog, @unblocker, self)
209
+ end
176
210
  f = server.bind
177
211
  @io_loop.add_socket(server)
178
212
  @unblocker.unblock!
@@ -261,6 +295,7 @@ module Ione
261
295
  private
262
296
 
263
297
  PING_BYTE = "\0".freeze
298
+ DEFAULT_CONNECT_OPTIONS = {:timeout => 5}.freeze
264
299
  end
265
300
 
266
301
  # @private
@@ -282,6 +317,12 @@ module Ione
282
317
  @lock.unlock
283
318
  end
284
319
 
320
+ def remove_socket(socket)
321
+ @lock.synchronize do
322
+ @sockets = @sockets.reject { |s| s == socket || s.closed? }
323
+ end
324
+ end
325
+
285
326
  def schedule_timer(timeout, promise=Promise.new)
286
327
  @lock.lock
287
328
  timers = @timers.reject { |pair| pair[1].nil? }
@@ -5,11 +5,8 @@ module Ione
5
5
  class ServerConnection < BaseConnection
6
6
  # @private
7
7
  def initialize(socket, host, port, unblocker)
8
- super(host, port)
8
+ super(host, port, unblocker)
9
9
  @io = socket
10
- @unblocker = unblocker
11
- @lock = Mutex.new
12
- @write_buffer = ByteBuffer.new
13
10
  @state = :connected
14
11
  end
15
12
  end