ione 1.2.0.pre5 → 1.2.0.pre6
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/lib/ione/io/acceptor.rb +16 -8
 - data/lib/ione/io/base_connection.rb +9 -11
 - data/lib/ione/io/io_reactor.rb +67 -52
 - data/lib/ione/version.rb +1 -1
 - data/spec/integration/io_spec.rb +7 -7
 - data/spec/ione/io/acceptor_spec.rb +2 -2
 - data/spec/ione/io/connection_common.rb +4 -4
 - data/spec/ione/io/connection_spec.rb +1 -1
 - data/spec/ione/io/io_reactor_spec.rb +42 -38
 - data/spec/ione/io/server_connection_spec.rb +1 -1
 - data/spec/ione/io/ssl_acceptor_spec.rb +3 -3
 - data/spec/ione/io/ssl_connection_spec.rb +1 -1
 - data/spec/support/fake_server.rb +5 -5
 - metadata +1 -1
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 580012a6e7c6d917610532fc3fbd917ab9cd7a50
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: e5deb87d0deebb5d4cc9d3a1b516b672ef6848a5
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 5760948be8fe0975500e3f673ffc0b4b4be1ed04aaccbfc44bc4535c668c1d7fec678a2fd498e608fd642a9e6e7354df4e01863f632afff471c4e70b57b6d895
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: e912eadf89022cb82d6f65726d1f48ccd8f17c1b434eb0a70dc783adef9407941331830ddc3898fb206e84b34aa300f0ed1b86115e98b684bc20544d38caa36b
         
     | 
    
        data/lib/ione/io/acceptor.rb
    CHANGED
    
    | 
         @@ -17,6 +17,7 @@ module Ione 
     | 
|
| 
       17 
17 
     | 
    
         
             
                    @socket_impl = socket_impl || ServerSocket
         
     | 
| 
       18 
18 
     | 
    
         
             
                    @accept_listeners = []
         
     | 
| 
       19 
19 
     | 
    
         
             
                    @lock = Mutex.new
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @state = :binding
         
     | 
| 
       20 
21 
     | 
    
         
             
                  end
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
23 
     | 
    
         
             
                  def on_accept(&listener)
         
     | 
| 
         @@ -38,6 +39,7 @@ module Ione 
     | 
|
| 
       38 
39 
     | 
    
         
             
                        retry
         
     | 
| 
       39 
40 
     | 
    
         
             
                      end
         
     | 
| 
       40 
41 
     | 
    
         
             
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @state = :connected
         
     | 
| 
       41 
43 
     | 
    
         
             
                    Future.resolved(self)
         
     | 
| 
       42 
44 
     | 
    
         
             
                  rescue => e
         
     | 
| 
       43 
45 
     | 
    
         
             
                    close
         
     | 
| 
         @@ -45,13 +47,19 @@ module Ione 
     | 
|
| 
       45 
47 
     | 
    
         
             
                  end
         
     | 
| 
       46 
48 
     | 
    
         | 
| 
       47 
49 
     | 
    
         
             
                  def close
         
     | 
| 
       48 
     | 
    
         
            -
                     
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                      @ 
     | 
| 
       51 
     | 
    
         
            -
                     
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
      
 50 
     | 
    
         
            +
                    @lock.synchronize do
         
     | 
| 
      
 51 
     | 
    
         
            +
                      return false if @state == :closed
         
     | 
| 
      
 52 
     | 
    
         
            +
                      @state = :closed
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
                    if @io
         
     | 
| 
      
 55 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 56 
     | 
    
         
            +
                        @io.close
         
     | 
| 
      
 57 
     | 
    
         
            +
                      rescue SystemCallError, IOError
         
     | 
| 
      
 58 
     | 
    
         
            +
                        # nothing to do, the socket was most likely already closed
         
     | 
| 
      
 59 
     | 
    
         
            +
                      ensure
         
     | 
| 
      
 60 
     | 
    
         
            +
                        @io = nil
         
     | 
| 
      
 61 
     | 
    
         
            +
                      end
         
     | 
| 
       53 
62 
     | 
    
         
             
                    end
         
     | 
| 
       54 
     | 
    
         
            -
                    @io = nil
         
     | 
| 
       55 
63 
     | 
    
         
             
                    true
         
     | 
| 
       56 
64 
     | 
    
         
             
                  end
         
     | 
| 
       57 
65 
     | 
    
         | 
| 
         @@ -60,11 +68,11 @@ module Ione 
     | 
|
| 
       60 
68 
     | 
    
         
             
                  end
         
     | 
| 
       61 
69 
     | 
    
         | 
| 
       62 
70 
     | 
    
         
             
                  def closed?
         
     | 
| 
       63 
     | 
    
         
            -
                    @ 
     | 
| 
      
 71 
     | 
    
         
            +
                    @state == :closed
         
     | 
| 
       64 
72 
     | 
    
         
             
                  end
         
     | 
| 
       65 
73 
     | 
    
         | 
| 
       66 
74 
     | 
    
         
             
                  def connected?
         
     | 
| 
       67 
     | 
    
         
            -
                     
     | 
| 
      
 75 
     | 
    
         
            +
                    @state != :closed
         
     | 
| 
       68 
76 
     | 
    
         
             
                  end
         
     | 
| 
       69 
77 
     | 
    
         | 
| 
       70 
78 
     | 
    
         
             
                  def connecting?
         
     | 
| 
         @@ -10,6 +10,7 @@ module Ione 
     | 
|
| 
       10 
10 
     | 
    
         
             
                    @port = port
         
     | 
| 
       11 
11 
     | 
    
         
             
                    @unblocker = unblocker
         
     | 
| 
       12 
12 
     | 
    
         
             
                    @state = :connecting
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @writable = false
         
     | 
| 
       13 
14 
     | 
    
         
             
                    @lock = Mutex.new
         
     | 
| 
       14 
15 
     | 
    
         
             
                    @write_buffer = ByteBuffer.new
         
     | 
| 
       15 
16 
     | 
    
         
             
                    @closed_promise = Promise.new
         
     | 
| 
         @@ -22,6 +23,7 @@ module Ione 
     | 
|
| 
       22 
23 
     | 
    
         
             
                    @lock.synchronize do
         
     | 
| 
       23 
24 
     | 
    
         
             
                      return false if @state == :closed
         
     | 
| 
       24 
25 
     | 
    
         
             
                      @state = :closed
         
     | 
| 
      
 26 
     | 
    
         
            +
                      @writable = false
         
     | 
| 
       25 
27 
     | 
    
         
             
                    end
         
     | 
| 
       26 
28 
     | 
    
         
             
                    if @io
         
     | 
| 
       27 
29 
     | 
    
         
             
                      begin
         
     | 
| 
         @@ -50,7 +52,7 @@ module Ione 
     | 
|
| 
       50 
52 
     | 
    
         
             
                  #   has closed
         
     | 
| 
       51 
53 
     | 
    
         
             
                  def drain
         
     | 
| 
       52 
54 
     | 
    
         
             
                    @state = :draining
         
     | 
| 
       53 
     | 
    
         
            -
                    close  
     | 
| 
      
 55 
     | 
    
         
            +
                    close unless @writable
         
     | 
| 
       54 
56 
     | 
    
         
             
                    @closed_promise.future
         
     | 
| 
       55 
57 
     | 
    
         
             
                  end
         
     | 
| 
       56 
58 
     | 
    
         | 
| 
         @@ -71,13 +73,7 @@ module Ione 
     | 
|
| 
       71 
73 
     | 
    
         | 
| 
       72 
74 
     | 
    
         
             
                  # @private
         
     | 
| 
       73 
75 
     | 
    
         
             
                  def writable?
         
     | 
| 
       74 
     | 
    
         
            -
                    @ 
     | 
| 
       75 
     | 
    
         
            -
                    begin
         
     | 
| 
       76 
     | 
    
         
            -
                      empty_buffer = @write_buffer.empty?
         
     | 
| 
       77 
     | 
    
         
            -
                    ensure
         
     | 
| 
       78 
     | 
    
         
            -
                      @lock.unlock
         
     | 
| 
       79 
     | 
    
         
            -
                    end
         
     | 
| 
       80 
     | 
    
         
            -
                    !(closed? || empty_buffer)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    @writable && @state != :closed
         
     | 
| 
       81 
77 
     | 
    
         
             
                  end
         
     | 
| 
       82 
78 
     | 
    
         | 
| 
       83 
79 
     | 
    
         
             
                  # Register to receive notifications when new data is read from the socket.
         
     | 
| 
         @@ -131,10 +127,11 @@ module Ione 
     | 
|
| 
       131 
127 
     | 
    
         
             
                        elsif bytes
         
     | 
| 
       132 
128 
     | 
    
         
             
                          @write_buffer.append(bytes)
         
     | 
| 
       133 
129 
     | 
    
         
             
                        end
         
     | 
| 
      
 130 
     | 
    
         
            +
                        @writable = !@write_buffer.empty?
         
     | 
| 
       134 
131 
     | 
    
         
             
                      ensure
         
     | 
| 
       135 
132 
     | 
    
         
             
                        @lock.unlock
         
     | 
| 
       136 
133 
     | 
    
         
             
                      end
         
     | 
| 
       137 
     | 
    
         
            -
                      @unblocker.unblock 
     | 
| 
      
 134 
     | 
    
         
            +
                      @unblocker.unblock
         
     | 
| 
       138 
135 
     | 
    
         
             
                    end
         
     | 
| 
       139 
136 
     | 
    
         
             
                  end
         
     | 
| 
       140 
137 
     | 
    
         | 
| 
         @@ -143,11 +140,12 @@ module Ione 
     | 
|
| 
       143 
140 
     | 
    
         
             
                    if @state == :connected || @state == :draining
         
     | 
| 
       144 
141 
     | 
    
         
             
                      @lock.lock
         
     | 
| 
       145 
142 
     | 
    
         
             
                      begin
         
     | 
| 
       146 
     | 
    
         
            -
                         
     | 
| 
      
 143 
     | 
    
         
            +
                        if @writable
         
     | 
| 
       147 
144 
     | 
    
         
             
                          bytes_written = @io.write_nonblock(@write_buffer.cheap_peek)
         
     | 
| 
       148 
145 
     | 
    
         
             
                          @write_buffer.discard(bytes_written)
         
     | 
| 
       149 
146 
     | 
    
         
             
                        end
         
     | 
| 
       150 
     | 
    
         
            -
                         
     | 
| 
      
 147 
     | 
    
         
            +
                        @writable = !@write_buffer.empty?
         
     | 
| 
      
 148 
     | 
    
         
            +
                        if @state == :draining && !@writable
         
     | 
| 
       151 
149 
     | 
    
         
             
                          close
         
     | 
| 
       152 
150 
     | 
    
         
             
                        end
         
     | 
| 
       153 
151 
     | 
    
         
             
                      ensure
         
     | 
    
        data/lib/ione/io/io_reactor.rb
    CHANGED
    
    | 
         @@ -87,6 +87,7 @@ module Ione 
     | 
|
| 
       87 
87 
     | 
    
         
             
                    @unblocker = Unblocker.new
         
     | 
| 
       88 
88 
     | 
    
         
             
                    @io_loop = IoLoopBody.new(options)
         
     | 
| 
       89 
89 
     | 
    
         
             
                    @io_loop.add_socket(@unblocker)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    @scheduler = Scheduler.new
         
     | 
| 
       90 
91 
     | 
    
         
             
                    @running = false
         
     | 
| 
       91 
92 
     | 
    
         
             
                    @stopped = false
         
     | 
| 
       92 
93 
     | 
    
         
             
                    @started_promise = Promise.new
         
     | 
| 
         @@ -128,10 +129,13 @@ module Ione 
     | 
|
| 
       128 
129 
     | 
    
         
             
                    Thread.start do
         
     | 
| 
       129 
130 
     | 
    
         
             
                      @started_promise.fulfill(self)
         
     | 
| 
       130 
131 
     | 
    
         
             
                      begin
         
     | 
| 
       131 
     | 
    
         
            -
                         
     | 
| 
      
 132 
     | 
    
         
            +
                        until @stopped
         
     | 
| 
      
 133 
     | 
    
         
            +
                          @io_loop.tick
         
     | 
| 
      
 134 
     | 
    
         
            +
                          @scheduler.tick
         
     | 
| 
      
 135 
     | 
    
         
            +
                        end
         
     | 
| 
       132 
136 
     | 
    
         
             
                      ensure
         
     | 
| 
       133 
137 
     | 
    
         
             
                        @io_loop.close_sockets
         
     | 
| 
       134 
     | 
    
         
            -
                        @ 
     | 
| 
      
 138 
     | 
    
         
            +
                        @scheduler.cancel_timers
         
     | 
| 
       135 
139 
     | 
    
         
             
                        @running = false
         
     | 
| 
       136 
140 
     | 
    
         
             
                        if $!
         
     | 
| 
       137 
141 
     | 
    
         
             
                          @stopped_promise.fail($!)
         
     | 
| 
         @@ -181,7 +185,7 @@ module Ione 
     | 
|
| 
       181 
185 
     | 
    
         
             
                    connection = Connection.new(host, port, timeout, @unblocker, @clock)
         
     | 
| 
       182 
186 
     | 
    
         
             
                    f = connection.connect
         
     | 
| 
       183 
187 
     | 
    
         
             
                    @io_loop.add_socket(connection)
         
     | 
| 
       184 
     | 
    
         
            -
                    @unblocker.unblock 
     | 
| 
      
 188 
     | 
    
         
            +
                    @unblocker.unblock
         
     | 
| 
       185 
189 
     | 
    
         
             
                    if ssl
         
     | 
| 
       186 
190 
     | 
    
         
             
                      f = f.flat_map do
         
     | 
| 
       187 
191 
     | 
    
         
             
                        ssl_context = ssl == true ? nil : ssl
         
     | 
| 
         @@ -189,7 +193,7 @@ module Ione 
     | 
|
| 
       189 
193 
     | 
    
         
             
                        ff = upgraded_connection.connect
         
     | 
| 
       190 
194 
     | 
    
         
             
                        @io_loop.remove_socket(connection)
         
     | 
| 
       191 
195 
     | 
    
         
             
                        @io_loop.add_socket(upgraded_connection)
         
     | 
| 
       192 
     | 
    
         
            -
                        @unblocker.unblock 
     | 
| 
      
 196 
     | 
    
         
            +
                        @unblocker.unblock
         
     | 
| 
       193 
197 
     | 
    
         
             
                        ff
         
     | 
| 
       194 
198 
     | 
    
         
             
                      end
         
     | 
| 
       195 
199 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -212,7 +216,7 @@ module Ione 
     | 
|
| 
       212 
216 
     | 
    
         
             
                    end
         
     | 
| 
       213 
217 
     | 
    
         
             
                    f = server.bind
         
     | 
| 
       214 
218 
     | 
    
         
             
                    @io_loop.add_socket(server)
         
     | 
| 
       215 
     | 
    
         
            -
                    @unblocker.unblock 
     | 
| 
      
 219 
     | 
    
         
            +
                    @unblocker.unblock
         
     | 
| 
       216 
220 
     | 
    
         
             
                    f = f.map(&block) if block_given?
         
     | 
| 
       217 
221 
     | 
    
         
             
                    f
         
     | 
| 
       218 
222 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -220,7 +224,7 @@ module Ione 
     | 
|
| 
       220 
224 
     | 
    
         
             
                  # @private
         
     | 
| 
       221 
225 
     | 
    
         
             
                  def accept(socket)
         
     | 
| 
       222 
226 
     | 
    
         
             
                    @io_loop.add_socket(socket)
         
     | 
| 
       223 
     | 
    
         
            -
                    @unblocker.unblock 
     | 
| 
      
 227 
     | 
    
         
            +
                    @unblocker.unblock
         
     | 
| 
       224 
228 
     | 
    
         
             
                  end
         
     | 
| 
       225 
229 
     | 
    
         | 
| 
       226 
230 
     | 
    
         
             
                  # Returns a future that completes after the specified number of seconds.
         
     | 
| 
         @@ -229,7 +233,7 @@ module Ione 
     | 
|
| 
       229 
233 
     | 
    
         
             
                  #   future is completed
         
     | 
| 
       230 
234 
     | 
    
         
             
                  # @return [Ione::Future] a future that completes when the timer expires
         
     | 
| 
       231 
235 
     | 
    
         
             
                  def schedule_timer(timeout)
         
     | 
| 
       232 
     | 
    
         
            -
                    @ 
     | 
| 
      
 236 
     | 
    
         
            +
                    @scheduler.schedule_timer(timeout)
         
     | 
| 
       233 
237 
     | 
    
         
             
                  end
         
     | 
| 
       234 
238 
     | 
    
         | 
| 
       235 
239 
     | 
    
         
             
                  # Cancels a previously scheduled timer.
         
     | 
| 
         @@ -238,7 +242,7 @@ module Ione 
     | 
|
| 
       238 
242 
     | 
    
         
             
                  #
         
     | 
| 
       239 
243 
     | 
    
         
             
                  # @param timer_future [Ione::Future] the future returned by {#schedule_timer}
         
     | 
| 
       240 
244 
     | 
    
         
             
                  def cancel_timer(timer_future)
         
     | 
| 
       241 
     | 
    
         
            -
                    @ 
     | 
| 
      
 245 
     | 
    
         
            +
                    @scheduler.cancel_timer(timer_future)
         
     | 
| 
       242 
246 
     | 
    
         
             
                  end
         
     | 
| 
       243 
247 
     | 
    
         | 
| 
       244 
248 
     | 
    
         
             
                  def to_s
         
     | 
| 
         @@ -269,7 +273,7 @@ module Ione 
     | 
|
| 
       269 
273 
     | 
    
         
             
                    @in.nil?
         
     | 
| 
       270 
274 
     | 
    
         
             
                  end
         
     | 
| 
       271 
275 
     | 
    
         | 
| 
       272 
     | 
    
         
            -
                  def unblock 
     | 
| 
      
 276 
     | 
    
         
            +
                  def unblock
         
     | 
| 
       273 
277 
     | 
    
         
             
                    @lock.lock
         
     | 
| 
       274 
278 
     | 
    
         
             
                    @in.write(PING_BYTE)
         
     | 
| 
       275 
279 
     | 
    
         
             
                  ensure
         
     | 
| 
         @@ -322,7 +326,7 @@ module Ione 
     | 
|
| 
       322 
326 
     | 
    
         
             
                  end
         
     | 
| 
       323 
327 
     | 
    
         | 
| 
       324 
328 
     | 
    
         
             
                  def to_s
         
     | 
| 
       325 
     | 
    
         
            -
                    "#<Timer  
     | 
| 
      
 329 
     | 
    
         
            +
                    "#<Timer @time=#{@time}>"
         
     | 
| 
       326 
330 
     | 
    
         
             
                  end
         
     | 
| 
       327 
331 
     | 
    
         
             
                  alias_method :inspect, :to_s
         
     | 
| 
       328 
332 
     | 
    
         
             
                end
         
     | 
| 
         @@ -332,10 +336,9 @@ module Ione 
     | 
|
| 
       332 
336 
     | 
    
         
             
                  def initialize(options={})
         
     | 
| 
       333 
337 
     | 
    
         
             
                    @selector = options[:selector] || IO
         
     | 
| 
       334 
338 
     | 
    
         
             
                    @clock = options[:clock] || Time
         
     | 
| 
      
 339 
     | 
    
         
            +
                    @timeout = options[:tick_resolution] || 1
         
     | 
| 
       335 
340 
     | 
    
         
             
                    @lock = Mutex.new
         
     | 
| 
       336 
341 
     | 
    
         
             
                    @sockets = []
         
     | 
| 
       337 
     | 
    
         
            -
                    @timer_queue = Heap.new
         
     | 
| 
       338 
     | 
    
         
            -
                    @pending_timers = {}
         
     | 
| 
       339 
342 
     | 
    
         
             
                  end
         
     | 
| 
       340 
343 
     | 
    
         | 
| 
       341 
344 
     | 
    
         
             
                  def add_socket(socket)
         
     | 
| 
         @@ -353,6 +356,53 @@ module Ione 
     | 
|
| 
       353 
356 
     | 
    
         
             
                    end
         
     | 
| 
       354 
357 
     | 
    
         
             
                  end
         
     | 
| 
       355 
358 
     | 
    
         | 
| 
      
 359 
     | 
    
         
            +
                  def close_sockets
         
     | 
| 
      
 360 
     | 
    
         
            +
                    @sockets.each do |s|
         
     | 
| 
      
 361 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 362 
     | 
    
         
            +
                        s.close
         
     | 
| 
      
 363 
     | 
    
         
            +
                      rescue
         
     | 
| 
      
 364 
     | 
    
         
            +
                        # the socket had most likely already closed due to an error
         
     | 
| 
      
 365 
     | 
    
         
            +
                      end
         
     | 
| 
      
 366 
     | 
    
         
            +
                    end
         
     | 
| 
      
 367 
     | 
    
         
            +
                  end
         
     | 
| 
      
 368 
     | 
    
         
            +
             
     | 
| 
      
 369 
     | 
    
         
            +
                  def tick
         
     | 
| 
      
 370 
     | 
    
         
            +
                    readables = []
         
     | 
| 
      
 371 
     | 
    
         
            +
                    writables = []
         
     | 
| 
      
 372 
     | 
    
         
            +
                    connecting = []
         
     | 
| 
      
 373 
     | 
    
         
            +
                    @sockets.each do |s|
         
     | 
| 
      
 374 
     | 
    
         
            +
                      if s.connected?
         
     | 
| 
      
 375 
     | 
    
         
            +
                        readables << s
         
     | 
| 
      
 376 
     | 
    
         
            +
                      elsif s.connecting?
         
     | 
| 
      
 377 
     | 
    
         
            +
                        connecting << s
         
     | 
| 
      
 378 
     | 
    
         
            +
                      end
         
     | 
| 
      
 379 
     | 
    
         
            +
                      if s.connecting? || s.writable?
         
     | 
| 
      
 380 
     | 
    
         
            +
                        writables << s
         
     | 
| 
      
 381 
     | 
    
         
            +
                      end
         
     | 
| 
      
 382 
     | 
    
         
            +
                    end
         
     | 
| 
      
 383 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 384 
     | 
    
         
            +
                      r, w, _ = @selector.select(readables, writables, nil, @timeout)
         
     | 
| 
      
 385 
     | 
    
         
            +
                      connecting.each { |s| s.connect }
         
     | 
| 
      
 386 
     | 
    
         
            +
                      r && r.each { |s| s.read }
         
     | 
| 
      
 387 
     | 
    
         
            +
                      w && w.each { |s| s.flush }
         
     | 
| 
      
 388 
     | 
    
         
            +
                    rescue IOError, Errno::EBADF
         
     | 
| 
      
 389 
     | 
    
         
            +
                    end
         
     | 
| 
      
 390 
     | 
    
         
            +
                  end
         
     | 
| 
      
 391 
     | 
    
         
            +
             
     | 
| 
      
 392 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 393 
     | 
    
         
            +
                    %(#<#{IoReactor.name} @connections=[#{@sockets.map(&:to_s).join(', ')}]>)
         
     | 
| 
      
 394 
     | 
    
         
            +
                  end
         
     | 
| 
      
 395 
     | 
    
         
            +
                end
         
     | 
| 
      
 396 
     | 
    
         
            +
             
     | 
| 
      
 397 
     | 
    
         
            +
                # @private
         
     | 
| 
      
 398 
     | 
    
         
            +
                class Scheduler
         
     | 
| 
      
 399 
     | 
    
         
            +
                  def initialize(options={})
         
     | 
| 
      
 400 
     | 
    
         
            +
                    @clock = options[:clock] || Time
         
     | 
| 
      
 401 
     | 
    
         
            +
                    @lock = Mutex.new
         
     | 
| 
      
 402 
     | 
    
         
            +
                    @timer_queue = Heap.new
         
     | 
| 
      
 403 
     | 
    
         
            +
                    @pending_timers = {}
         
     | 
| 
      
 404 
     | 
    
         
            +
                  end
         
     | 
| 
      
 405 
     | 
    
         
            +
             
     | 
| 
       356 
406 
     | 
    
         
             
                  def schedule_timer(timeout)
         
     | 
| 
       357 
407 
     | 
    
         
             
                    @lock.lock
         
     | 
| 
       358 
408 
     | 
    
         
             
                    timer = Timer.new(@clock.now + timeout)
         
     | 
| 
         @@ -378,16 +428,6 @@ module Ione 
     | 
|
| 
       378 
428 
     | 
    
         
             
                    end
         
     | 
| 
       379 
429 
     | 
    
         
             
                  end
         
     | 
| 
       380 
430 
     | 
    
         | 
| 
       381 
     | 
    
         
            -
                  def close_sockets
         
     | 
| 
       382 
     | 
    
         
            -
                    @sockets.each do |s|
         
     | 
| 
       383 
     | 
    
         
            -
                      begin
         
     | 
| 
       384 
     | 
    
         
            -
                        s.close unless s.closed?
         
     | 
| 
       385 
     | 
    
         
            -
                      rescue
         
     | 
| 
       386 
     | 
    
         
            -
                        # the socket had most likely already closed due to an error
         
     | 
| 
       387 
     | 
    
         
            -
                      end
         
     | 
| 
       388 
     | 
    
         
            -
                    end
         
     | 
| 
       389 
     | 
    
         
            -
                  end
         
     | 
| 
       390 
     | 
    
         
            -
             
     | 
| 
       391 
431 
     | 
    
         
             
                  def cancel_timers
         
     | 
| 
       392 
432 
     | 
    
         
             
                    while (timer = @timer_queue.pop)
         
     | 
| 
       393 
433 
     | 
    
         
             
                      @pending_timers.delete(timer.future)
         
     | 
| 
         @@ -395,36 +435,7 @@ module Ione 
     | 
|
| 
       395 
435 
     | 
    
         
             
                    end
         
     | 
| 
       396 
436 
     | 
    
         
             
                  end
         
     | 
| 
       397 
437 
     | 
    
         | 
| 
       398 
     | 
    
         
            -
                  def tick 
     | 
| 
       399 
     | 
    
         
            -
                    check_sockets!(timeout)
         
     | 
| 
       400 
     | 
    
         
            -
                    check_timers!
         
     | 
| 
       401 
     | 
    
         
            -
                  end
         
     | 
| 
       402 
     | 
    
         
            -
             
     | 
| 
       403 
     | 
    
         
            -
                  def to_s
         
     | 
| 
       404 
     | 
    
         
            -
                    %(#<#{IoReactor.name} @connections=[#{@sockets.map(&:to_s).join(', ')}]>)
         
     | 
| 
       405 
     | 
    
         
            -
                  end
         
     | 
| 
       406 
     | 
    
         
            -
             
     | 
| 
       407 
     | 
    
         
            -
                  private
         
     | 
| 
       408 
     | 
    
         
            -
             
     | 
| 
       409 
     | 
    
         
            -
                  def check_sockets!(timeout)
         
     | 
| 
       410 
     | 
    
         
            -
                    readables, writables, connecting = [], [], []
         
     | 
| 
       411 
     | 
    
         
            -
                    sockets = @sockets
         
     | 
| 
       412 
     | 
    
         
            -
                    sockets.each do |s|
         
     | 
| 
       413 
     | 
    
         
            -
                      next if s.closed?
         
     | 
| 
       414 
     | 
    
         
            -
                      readables << s if s.connected?
         
     | 
| 
       415 
     | 
    
         
            -
                      writables << s if s.connecting? || s.writable?
         
     | 
| 
       416 
     | 
    
         
            -
                      connecting << s if s.connecting?
         
     | 
| 
       417 
     | 
    
         
            -
                    end
         
     | 
| 
       418 
     | 
    
         
            -
                    begin
         
     | 
| 
       419 
     | 
    
         
            -
                      r, w, _ = @selector.select(readables, writables, nil, timeout)
         
     | 
| 
       420 
     | 
    
         
            -
                      connecting.each(&:connect)
         
     | 
| 
       421 
     | 
    
         
            -
                      r && r.each(&:read)
         
     | 
| 
       422 
     | 
    
         
            -
                      w && w.each(&:flush)
         
     | 
| 
       423 
     | 
    
         
            -
                    rescue IOError, Errno::EBADF
         
     | 
| 
       424 
     | 
    
         
            -
                    end
         
     | 
| 
       425 
     | 
    
         
            -
                  end
         
     | 
| 
       426 
     | 
    
         
            -
             
     | 
| 
       427 
     | 
    
         
            -
                  def check_timers!
         
     | 
| 
      
 438 
     | 
    
         
            +
                  def tick
         
     | 
| 
       428 
439 
     | 
    
         
             
                    now = @clock.now
         
     | 
| 
       429 
440 
     | 
    
         
             
                    first_timer = @timer_queue.peek
         
     | 
| 
       430 
441 
     | 
    
         
             
                    if first_timer && first_timer.time <= now
         
     | 
| 
         @@ -444,6 +455,10 @@ module Ione 
     | 
|
| 
       444 
455 
     | 
    
         
             
                      end
         
     | 
| 
       445 
456 
     | 
    
         
             
                    end
         
     | 
| 
       446 
457 
     | 
    
         
             
                  end
         
     | 
| 
      
 458 
     | 
    
         
            +
             
     | 
| 
      
 459 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 460 
     | 
    
         
            +
                    %(#<#{self.class.name} @timers=[#{@pending_timers.values.map(&:to_s).join(', ')}]>)
         
     | 
| 
      
 461 
     | 
    
         
            +
                  end
         
     | 
| 
       447 
462 
     | 
    
         
             
                end
         
     | 
| 
       448 
463 
     | 
    
         
             
              end
         
     | 
| 
       449 
464 
     | 
    
         
             
            end
         
     | 
    
        data/lib/ione/version.rb
    CHANGED
    
    
    
        data/spec/integration/io_spec.rb
    CHANGED
    
    | 
         @@ -18,32 +18,32 @@ describe 'An IO reactor' do 
     | 
|
| 
       18 
18 
     | 
    
         
             
                end
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                before do
         
     | 
| 
       21 
     | 
    
         
            -
                  fake_server.start 
     | 
| 
      
 21 
     | 
    
         
            +
                  fake_server.start
         
     | 
| 
       22 
22 
     | 
    
         
             
                  io_reactor.start
         
     | 
| 
       23 
23 
     | 
    
         
             
                end
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
                after do
         
     | 
| 
       26 
26 
     | 
    
         
             
                  io_reactor.stop
         
     | 
| 
       27 
     | 
    
         
            -
                  fake_server.stop 
     | 
| 
      
 27 
     | 
    
         
            +
                  fake_server.stop
         
     | 
| 
       28 
28 
     | 
    
         
             
                end
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
                it 'connects to the server' do
         
     | 
| 
       31 
31 
     | 
    
         
             
                  io_reactor.connect(ENV['SERVER_HOST'], fake_server.port, 1, &protocol_handler_factory)
         
     | 
| 
       32 
     | 
    
         
            -
                  fake_server.await_connects 
     | 
| 
      
 32 
     | 
    
         
            +
                  fake_server.await_connects(1)
         
     | 
| 
       33 
33 
     | 
    
         
             
                end
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
35 
     | 
    
         
             
                it 'receives data' do
         
     | 
| 
       36 
36 
     | 
    
         
             
                  protocol_handler = io_reactor.connect(ENV['SERVER_HOST'], fake_server.port, 1, &protocol_handler_factory).value
         
     | 
| 
       37 
     | 
    
         
            -
                  fake_server.await_connects 
     | 
| 
       38 
     | 
    
         
            -
                  fake_server.broadcast 
     | 
| 
      
 37 
     | 
    
         
            +
                  fake_server.await_connects(1)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  fake_server.broadcast('hello world')
         
     | 
| 
       39 
39 
     | 
    
         
             
                  await { protocol_handler.data.bytesize > 0 }
         
     | 
| 
       40 
40 
     | 
    
         
             
                  protocol_handler.data.should == 'hello world'
         
     | 
| 
       41 
41 
     | 
    
         
             
                end
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
43 
     | 
    
         
             
                it 'receives data on multiple connections' do
         
     | 
| 
       44 
44 
     | 
    
         
             
                  protocol_handlers = Array.new(10) { io_reactor.connect(ENV['SERVER_HOST'], fake_server.port, 1, &protocol_handler_factory).value }
         
     | 
| 
       45 
     | 
    
         
            -
                  fake_server.await_connects 
     | 
| 
       46 
     | 
    
         
            -
                  fake_server.broadcast 
     | 
| 
      
 45 
     | 
    
         
            +
                  fake_server.await_connects(10)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  fake_server.broadcast('hello world')
         
     | 
| 
       47 
47 
     | 
    
         
             
                  await { protocol_handlers.all? { |c| c.data.bytesize > 0 } }
         
     | 
| 
       48 
48 
     | 
    
         
             
                  protocol_handlers.sample.data.should == 'hello world'
         
     | 
| 
       49 
49 
     | 
    
         
             
                end
         
     | 
| 
         @@ -179,11 +179,11 @@ module Ione 
     | 
|
| 
       179 
179 
     | 
    
         
             
                    end
         
     | 
| 
       180 
180 
     | 
    
         | 
| 
       181 
181 
     | 
    
         
             
                    it 'passes the unblocker along to the connection handler' do
         
     | 
| 
       182 
     | 
    
         
            -
                      unblocker.stub(:unblock 
     | 
| 
      
 182 
     | 
    
         
            +
                      unblocker.stub(:unblock)
         
     | 
| 
       183 
183 
     | 
    
         
             
                      acceptor.bind
         
     | 
| 
       184 
184 
     | 
    
         
             
                      acceptor.read
         
     | 
| 
       185 
185 
     | 
    
         
             
                      accepted_handlers.first.write('foo')
         
     | 
| 
       186 
     | 
    
         
            -
                      unblocker.should have_received(:unblock 
     | 
| 
      
 186 
     | 
    
         
            +
                      unblocker.should have_received(:unblock)
         
     | 
| 
       187 
187 
     | 
    
         
             
                    end
         
     | 
| 
       188 
188 
     | 
    
         
             
                  end
         
     | 
| 
       189 
189 
     | 
    
         | 
| 
         @@ -95,7 +95,7 @@ shared_examples_for 'a connection' do |options| 
     | 
|
| 
       95 
95 
     | 
    
         
             
              describe '#write/#flush' do
         
     | 
| 
       96 
96 
     | 
    
         
             
                before do
         
     | 
| 
       97 
97 
     | 
    
         
             
                  socket.stub(:write_nonblock)
         
     | 
| 
       98 
     | 
    
         
            -
                  unblocker.stub(:unblock 
     | 
| 
      
 98 
     | 
    
         
            +
                  unblocker.stub(:unblock)
         
     | 
| 
       99 
99 
     | 
    
         
             
                end
         
     | 
| 
       100 
100 
     | 
    
         | 
| 
       101 
101 
     | 
    
         
             
                it 'appends to its buffer when #write is called' do
         
     | 
| 
         @@ -103,7 +103,7 @@ shared_examples_for 'a connection' do |options| 
     | 
|
| 
       103 
103 
     | 
    
         
             
                end
         
     | 
| 
       104 
104 
     | 
    
         | 
| 
       105 
105 
     | 
    
         
             
                it 'unblocks the reactor' do
         
     | 
| 
       106 
     | 
    
         
            -
                  unblocker.should_receive(:unblock 
     | 
| 
      
 106 
     | 
    
         
            +
                  unblocker.should_receive(:unblock)
         
     | 
| 
       107 
107 
     | 
    
         
             
                  handler.write('hello world')
         
     | 
| 
       108 
108 
     | 
    
         
             
                end
         
     | 
| 
       109 
109 
     | 
    
         | 
| 
         @@ -190,7 +190,7 @@ shared_examples_for 'a connection' do |options| 
     | 
|
| 
       190 
190 
     | 
    
         
             
                    handler.close
         
     | 
| 
       191 
191 
     | 
    
         
             
                    handler.write('hello world')
         
     | 
| 
       192 
192 
     | 
    
         
             
                    handler.flush
         
     | 
| 
       193 
     | 
    
         
            -
                    unblocker.should_not have_received(:unblock 
     | 
| 
      
 193 
     | 
    
         
            +
                    unblocker.should_not have_received(:unblock)
         
     | 
| 
       194 
194 
     | 
    
         
             
                  end
         
     | 
| 
       195 
195 
     | 
    
         
             
                end
         
     | 
| 
       196 
196 
     | 
    
         | 
| 
         @@ -214,7 +214,7 @@ shared_examples_for 'a connection' do |options| 
     | 
|
| 
       214 
214 
     | 
    
         
             
                    handler.drain
         
     | 
| 
       215 
215 
     | 
    
         
             
                    handler.write('hello world')
         
     | 
| 
       216 
216 
     | 
    
         
             
                    handler.flush
         
     | 
| 
       217 
     | 
    
         
            -
                    unblocker.should_not have_received(:unblock 
     | 
| 
      
 217 
     | 
    
         
            +
                    unblocker.should_not have_received(:unblock)
         
     | 
| 
       218 
218 
     | 
    
         
             
                  end
         
     | 
| 
       219 
219 
     | 
    
         
             
                end
         
     | 
| 
       220 
220 
     | 
    
         
             
              end
         
     | 
| 
         @@ -372,6 +372,13 @@ module Ione 
     | 
|
| 
       372 
372 
     | 
    
         
             
                      loop_body.tick
         
     | 
| 
       373 
373 
     | 
    
         
             
                    end
         
     | 
| 
       374 
374 
     | 
    
         | 
| 
      
 375 
     | 
    
         
            +
                    it 'passes writable sockets as both readable and writable to the selector' do
         
     | 
| 
      
 376 
     | 
    
         
            +
                      socket.stub(:connected?).and_return(true)
         
     | 
| 
      
 377 
     | 
    
         
            +
                      socket.stub(:writable?).and_return(true)
         
     | 
| 
      
 378 
     | 
    
         
            +
                      selector.should_receive(:select).with([socket], [socket], anything, anything).and_return([nil, nil, nil])
         
     | 
| 
      
 379 
     | 
    
         
            +
                      loop_body.tick
         
     | 
| 
      
 380 
     | 
    
         
            +
                    end
         
     | 
| 
      
 381 
     | 
    
         
            +
             
     | 
| 
       375 
382 
     | 
    
         
             
                    it 'passes connecting sockets as writable to the selector' do
         
     | 
| 
       376 
383 
     | 
    
         
             
                      socket.stub(:connecting?).and_return(true)
         
     | 
| 
       377 
384 
     | 
    
         
             
                      socket.stub(:connect)
         
     | 
| 
         @@ -383,9 +390,6 @@ module Ione 
     | 
|
| 
       383 
390 
     | 
    
         
             
                      socket.stub(:closed?).and_return(true)
         
     | 
| 
       384 
391 
     | 
    
         
             
                      selector.should_receive(:select).with([], [], anything, anything).and_return([nil, nil, nil])
         
     | 
| 
       385 
392 
     | 
    
         
             
                      loop_body.tick
         
     | 
| 
       386 
     | 
    
         
            -
                      socket.stub(:connected?).and_return(true)
         
     | 
| 
       387 
     | 
    
         
            -
                      selector.should_receive(:select).with([], [], anything, anything).and_return([nil, nil, nil])
         
     | 
| 
       388 
     | 
    
         
            -
                      loop_body.tick
         
     | 
| 
       389 
393 
     | 
    
         
             
                    end
         
     | 
| 
       390 
394 
     | 
    
         | 
| 
       391 
395 
     | 
    
         
             
                    it 'does nothing when IO.select raises Errno::EBADF' do
         
     | 
| 
         @@ -428,29 +432,9 @@ module Ione 
     | 
|
| 
       428 
432 
     | 
    
         
             
                    end
         
     | 
| 
       429 
433 
     | 
    
         | 
| 
       430 
434 
     | 
    
         
             
                    it 'allows the caller to specify a custom timeout' do
         
     | 
| 
      
 435 
     | 
    
         
            +
                      loop_body = described_class.new(selector: selector, clock: clock, tick_resolution: 99)
         
     | 
| 
       431 
436 
     | 
    
         
             
                      selector.should_receive(:select).with(anything, anything, anything, 99).and_return([[], [], []])
         
     | 
| 
       432 
     | 
    
         
            -
                      loop_body.tick(99)
         
     | 
| 
       433 
     | 
    
         
            -
                    end
         
     | 
| 
       434 
     | 
    
         
            -
             
     | 
| 
       435 
     | 
    
         
            -
                    it 'completes timers that have expired' do
         
     | 
| 
       436 
     | 
    
         
            -
                      selector.stub(:select).and_return([nil, nil, nil])
         
     | 
| 
       437 
     | 
    
         
            -
                      clock.stub(:now).and_return(1)
         
     | 
| 
       438 
     | 
    
         
            -
                      future = loop_body.schedule_timer(1)
         
     | 
| 
       439 
437 
     | 
    
         
             
                      loop_body.tick
         
     | 
| 
       440 
     | 
    
         
            -
                      future.should_not be_completed
         
     | 
| 
       441 
     | 
    
         
            -
                      clock.stub(:now).and_return(2)
         
     | 
| 
       442 
     | 
    
         
            -
                      loop_body.tick
         
     | 
| 
       443 
     | 
    
         
            -
                      future.should be_completed
         
     | 
| 
       444 
     | 
    
         
            -
                    end
         
     | 
| 
       445 
     | 
    
         
            -
             
     | 
| 
       446 
     | 
    
         
            -
                    it 'clears out timers that have expired' do
         
     | 
| 
       447 
     | 
    
         
            -
                      selector.stub(:select).and_return([nil, nil, nil])
         
     | 
| 
       448 
     | 
    
         
            -
                      clock.stub(:now).and_return(1)
         
     | 
| 
       449 
     | 
    
         
            -
                      future = loop_body.schedule_timer(1)
         
     | 
| 
       450 
     | 
    
         
            -
                      clock.stub(:now).and_return(2)
         
     | 
| 
       451 
     | 
    
         
            -
                      loop_body.tick
         
     | 
| 
       452 
     | 
    
         
            -
                      future.should be_completed
         
     | 
| 
       453 
     | 
    
         
            -
                      expect { loop_body.tick }.to_not raise_error
         
     | 
| 
       454 
438 
     | 
    
         
             
                    end
         
     | 
| 
       455 
439 
     | 
    
         
             
                  end
         
     | 
| 
       456 
440 
     | 
    
         | 
| 
         @@ -474,28 +458,48 @@ module Ione 
     | 
|
| 
       474 
458 
     | 
    
         
             
                      loop_body.add_socket(socket2)
         
     | 
| 
       475 
459 
     | 
    
         
             
                      loop_body.close_sockets
         
     | 
| 
       476 
460 
     | 
    
         
             
                    end
         
     | 
| 
      
 461 
     | 
    
         
            +
                  end
         
     | 
| 
      
 462 
     | 
    
         
            +
                end
         
     | 
| 
       477 
463 
     | 
    
         | 
| 
       478 
     | 
    
         
            -
             
     | 
| 
       479 
     | 
    
         
            -
             
     | 
| 
       480 
     | 
    
         
            -
             
     | 
| 
       481 
     | 
    
         
            -
                      loop_body.add_socket(socket)
         
     | 
| 
       482 
     | 
    
         
            -
                      loop_body.close_sockets
         
     | 
| 
       483 
     | 
    
         
            -
                    end
         
     | 
| 
      
 464 
     | 
    
         
            +
                describe Scheduler do
         
     | 
| 
      
 465 
     | 
    
         
            +
                  let :scheduler do
         
     | 
| 
      
 466 
     | 
    
         
            +
                    described_class.new(clock: clock)
         
     | 
| 
       484 
467 
     | 
    
         
             
                  end
         
     | 
| 
       485 
468 
     | 
    
         | 
| 
       486 
     | 
    
         
            -
                   
     | 
| 
       487 
     | 
    
         
            -
                     
     | 
| 
       488 
     | 
    
         
            -
             
     | 
| 
      
 469 
     | 
    
         
            +
                  let :clock do
         
     | 
| 
      
 470 
     | 
    
         
            +
                    double(:clock, now: 0)
         
     | 
| 
      
 471 
     | 
    
         
            +
                  end
         
     | 
| 
      
 472 
     | 
    
         
            +
             
     | 
| 
      
 473 
     | 
    
         
            +
                  describe '#tick' do
         
     | 
| 
      
 474 
     | 
    
         
            +
                    it 'completes timers that have expired' do
         
     | 
| 
      
 475 
     | 
    
         
            +
                      clock.stub(:now).and_return(1)
         
     | 
| 
      
 476 
     | 
    
         
            +
                      future = scheduler.schedule_timer(1)
         
     | 
| 
      
 477 
     | 
    
         
            +
                      scheduler.tick
         
     | 
| 
      
 478 
     | 
    
         
            +
                      future.should_not be_completed
         
     | 
| 
      
 479 
     | 
    
         
            +
                      clock.stub(:now).and_return(2)
         
     | 
| 
      
 480 
     | 
    
         
            +
                      scheduler.tick
         
     | 
| 
      
 481 
     | 
    
         
            +
                      future.should be_completed
         
     | 
| 
       489 
482 
     | 
    
         
             
                    end
         
     | 
| 
       490 
483 
     | 
    
         | 
| 
      
 484 
     | 
    
         
            +
                    it 'clears out timers that have expired' do
         
     | 
| 
      
 485 
     | 
    
         
            +
                      clock.stub(:now).and_return(1)
         
     | 
| 
      
 486 
     | 
    
         
            +
                      future = scheduler.schedule_timer(1)
         
     | 
| 
      
 487 
     | 
    
         
            +
                      clock.stub(:now).and_return(2)
         
     | 
| 
      
 488 
     | 
    
         
            +
                      scheduler.tick
         
     | 
| 
      
 489 
     | 
    
         
            +
                      future.should be_completed
         
     | 
| 
      
 490 
     | 
    
         
            +
                      expect { scheduler.tick }.to_not raise_error
         
     | 
| 
      
 491 
     | 
    
         
            +
                    end
         
     | 
| 
      
 492 
     | 
    
         
            +
                  end
         
     | 
| 
      
 493 
     | 
    
         
            +
             
     | 
| 
      
 494 
     | 
    
         
            +
                  describe '#cancel_timers' do
         
     | 
| 
       491 
495 
     | 
    
         
             
                    it 'fails all active timers with a CancelledError' do
         
     | 
| 
       492 
496 
     | 
    
         
             
                      clock.stub(:now).and_return(1)
         
     | 
| 
       493 
     | 
    
         
            -
                      f1 =  
     | 
| 
       494 
     | 
    
         
            -
                      f2 =  
     | 
| 
       495 
     | 
    
         
            -
                      f3 =  
     | 
| 
      
 497 
     | 
    
         
            +
                      f1 = scheduler.schedule_timer(1)
         
     | 
| 
      
 498 
     | 
    
         
            +
                      f2 = scheduler.schedule_timer(3)
         
     | 
| 
      
 499 
     | 
    
         
            +
                      f3 = scheduler.schedule_timer(3)
         
     | 
| 
       496 
500 
     | 
    
         
             
                      clock.stub(:now).and_return(2)
         
     | 
| 
       497 
     | 
    
         
            -
                       
     | 
| 
       498 
     | 
    
         
            -
                       
     | 
| 
      
 501 
     | 
    
         
            +
                      scheduler.tick
         
     | 
| 
      
 502 
     | 
    
         
            +
                      scheduler.cancel_timers
         
     | 
| 
       499 
503 
     | 
    
         
             
                      f1.should be_completed
         
     | 
| 
       500 
504 
     | 
    
         
             
                      f2.should be_failed
         
     | 
| 
       501 
505 
     | 
    
         
             
                      f3.should be_failed
         
     | 
| 
         @@ -92,15 +92,15 @@ module Ione 
     | 
|
| 
       92 
92 
     | 
    
         
             
                      end
         
     | 
| 
       93 
93 
     | 
    
         | 
| 
       94 
94 
     | 
    
         
             
                      it 'has a reference to the unblocker' do
         
     | 
| 
       95 
     | 
    
         
            -
                        unblocker.stub(:unblock 
     | 
| 
      
 95 
     | 
    
         
            +
                        unblocker.stub(:unblock)
         
     | 
| 
       96 
96 
     | 
    
         
             
                        acceptor.bind
         
     | 
| 
       97 
97 
     | 
    
         
             
                        acceptor.read
         
     | 
| 
       98 
98 
     | 
    
         
             
                        accepted_handlers.first.write('foo')
         
     | 
| 
       99 
     | 
    
         
            -
                        unblocker.should have_received(:unblock 
     | 
| 
      
 99 
     | 
    
         
            +
                        unblocker.should have_received(:unblock)
         
     | 
| 
       100 
100 
     | 
    
         
             
                      end
         
     | 
| 
       101 
101 
     | 
    
         | 
| 
       102 
102 
     | 
    
         
             
                      it 'writes to the SSL socket' do
         
     | 
| 
       103 
     | 
    
         
            -
                        unblocker.stub(:unblock 
     | 
| 
      
 103 
     | 
    
         
            +
                        unblocker.stub(:unblock)
         
     | 
| 
       104 
104 
     | 
    
         
             
                        ssl_socket.stub(:write_nonblock) { |b| b.bytesize }
         
     | 
| 
       105 
105 
     | 
    
         
             
                        acceptor.bind
         
     | 
| 
       106 
106 
     | 
    
         
             
                        acceptor.read
         
     | 
    
        data/spec/support/fake_server.rb
    CHANGED
    
    | 
         @@ -13,7 +13,7 @@ class FakeServer 
     | 
|
| 
       13 
13 
     | 
    
         
             
                @received_bytes = ''
         
     | 
| 
       14 
14 
     | 
    
         
             
              end
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
              def start 
     | 
| 
      
 16 
     | 
    
         
            +
              def start(options={})
         
     | 
| 
       17 
17 
     | 
    
         
             
                @lock.synchronize do
         
     | 
| 
       18 
18 
     | 
    
         
             
                  return if @running
         
     | 
| 
       19 
19 
     | 
    
         
             
                  @running = true
         
     | 
| 
         @@ -30,7 +30,7 @@ class FakeServer 
     | 
|
| 
       30 
30 
     | 
    
         
             
                self
         
     | 
| 
       31 
31 
     | 
    
         
             
              end
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
              def stop 
     | 
| 
      
 33 
     | 
    
         
            +
              def stop
         
     | 
| 
       34 
34 
     | 
    
         
             
                @lock.synchronize do
         
     | 
| 
       35 
35 
     | 
    
         
             
                  return unless @running
         
     | 
| 
       36 
36 
     | 
    
         
             
                  @running = false
         
     | 
| 
         @@ -41,13 +41,13 @@ class FakeServer 
     | 
|
| 
       41 
41 
     | 
    
         
             
                end
         
     | 
| 
       42 
42 
     | 
    
         
             
              end
         
     | 
| 
       43 
43 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
              def broadcast 
     | 
| 
      
 44 
     | 
    
         
            +
              def broadcast(bytes)
         
     | 
| 
       45 
45 
     | 
    
         
             
                @lock.synchronize do
         
     | 
| 
       46 
46 
     | 
    
         
             
                  @connections.each { |c| c.write_nonblock(bytes) }
         
     | 
| 
       47 
47 
     | 
    
         
             
                end
         
     | 
| 
       48 
48 
     | 
    
         
             
              end
         
     | 
| 
       49 
49 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
              def await_connects 
     | 
| 
      
 50 
     | 
    
         
            +
              def await_connects(n=1)
         
     | 
| 
       51 
51 
     | 
    
         
             
                started_at = Time.now
         
     | 
| 
       52 
52 
     | 
    
         
             
                until @connects >= n
         
     | 
| 
       53 
53 
     | 
    
         
             
                  sleep(0.01)
         
     | 
| 
         @@ -55,7 +55,7 @@ class FakeServer 
     | 
|
| 
       55 
55 
     | 
    
         
             
                end
         
     | 
| 
       56 
56 
     | 
    
         
             
              end
         
     | 
| 
       57 
57 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
              def await_disconnects 
     | 
| 
      
 58 
     | 
    
         
            +
              def await_disconnects(n=1)
         
     | 
| 
       59 
59 
     | 
    
         
             
                started_at = Time.now
         
     | 
| 
       60 
60 
     | 
    
         
             
                until @disconnects >= n
         
     | 
| 
       61 
61 
     | 
    
         
             
                  sleep(0.01)
         
     |