ione 1.2.0.pre1 → 1.2.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
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