ione 1.2.5 → 1.3.0.pre0

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
- SHA256:
3
- metadata.gz: 9c062de288365ad9e47516ad7b9d3ab028ab9449964c88675c0b913657a8ef07
4
- data.tar.gz: f349d422d1df3001a9c5fb5df55c329ed60cebc9dad20ddf1a97f52883c53093
2
+ SHA1:
3
+ metadata.gz: 6374a6945473a540ef416dec0eaef9f2c5a23913
4
+ data.tar.gz: c4b5defcacf2770af407842ee88edc7f9e172a6b
5
5
  SHA512:
6
- metadata.gz: 4523ab1052502a8da1879f73481f8326b260b478d71c7e9d882b264e2c274092ae0801a43c5884492ea06fd69dd3ac02ab184ef309dbcf1cf5b8d441f37e8bd6
7
- data.tar.gz: 1e5d1c7f51593988a2270ec4c6b74cd61d72a1dd2c6a69d5c6f4b2053052aa4ee3bd52375c4e419d423110bd70994350662a61850907570db47ea45c24a7575b
6
+ metadata.gz: 72ee4392985a601b028b4e6aa170accff6e8e50c27fc2cb7674cb9b3dd5b29091e8f92b3b5e26a515f372036fcaf1727bb866e1e8165a0f9567fd1749be91bac
7
+ data.tar.gz: 231ee2abbb3d771d56d0fdab4c26b42f0684254b13056bf898dbce22d3ea2031e34aacc096a04dae6ee08a394ca880f03a362d7bbf9a96598becdbaaeec7e84c
data/lib/ione/future.rb CHANGED
@@ -599,8 +599,6 @@ module Ione
599
599
  @lock = Mutex.new
600
600
  @state = PENDING_STATE
601
601
  @listeners = []
602
- @value = nil
603
- @error = nil
604
602
  end
605
603
 
606
604
  # Registers a listener that will be called when this future completes,
@@ -861,9 +859,9 @@ module Ione
861
859
  looping = more = true
862
860
  while more
863
861
  more = false
864
- @futures.pop.on_complete do |value, error|
865
- if error || @futures.empty? || !looping || !Thread.current.equal?(outer)
866
- await_next(value, error)
862
+ @futures.pop.on_complete do |v, e|
863
+ if e || @futures.empty? || !looping || !Thread.current.equal?(outer)
864
+ await_next(v, e)
867
865
  else
868
866
  more = true
869
867
  end
@@ -22,7 +22,6 @@ module Ione
22
22
  @backlog = backlog
23
23
  @unblocker = unblocker
24
24
  @reactor = reactor
25
- @io = nil
26
25
  @socket_impl = socket_impl || ServerSocket
27
26
  @accept_listeners = []
28
27
  @lock = Mutex.new
@@ -77,6 +76,9 @@ module Ione
77
76
  true
78
77
  end
79
78
 
79
+ # @private
80
+ alias_method :drain, :close
81
+
80
82
  # @private
81
83
  def to_io
82
84
  @io
@@ -15,12 +15,10 @@ module Ione
15
15
  def initialize(host, port, unblocker)
16
16
  @host = host
17
17
  @port = port
18
- @io = nil
19
18
  @unblocker = unblocker
20
19
  @state = CONNECTING_STATE
21
20
  @writable = false
22
21
  @lock = Mutex.new
23
- @data_listener = nil
24
22
  @write_buffer = ByteBuffer.new
25
23
  @closed_promise = Promise.new
26
24
  end
@@ -61,8 +59,24 @@ module Ione
61
59
  # has closed
62
60
  # @since v1.1.0
63
61
  def drain
64
- @state = DRAINING_STATE
65
- close unless @writable
62
+ @lock.lock
63
+ begin
64
+ return if @state == DRAINING_STATE || @state == CLOSED_STATE
65
+ @state = DRAINING_STATE
66
+ ensure
67
+ @lock.unlock
68
+ end
69
+ if writable?
70
+ if @io.respond_to?(:close_read)
71
+ begin
72
+ @io.close_read
73
+ rescue SystemCallError, IOError
74
+ # nothing to do, the socket was most likely already closed
75
+ end
76
+ end
77
+ else
78
+ close
79
+ end
66
80
  @closed_promise.future
67
81
  end
68
82
 
@@ -14,7 +14,6 @@ module Ione
14
14
  @connection_timeout = connection_timeout
15
15
  @clock = clock
16
16
  @socket_impl = socket_impl
17
- @addrinfos = nil
18
17
  @connected_promise = Promise.new
19
18
  on_closed(&method(:cleanup_on_close))
20
19
  end
@@ -95,9 +95,8 @@ module Ione
95
95
  @clock = options[:clock] || Time
96
96
  @state = PENDING_STATE
97
97
  @error_listeners = []
98
- @unblocker = nil
99
98
  @io_loop = IoLoopBody.new(@options)
100
- @scheduler = Scheduler.new(@options)
99
+ @scheduler = Scheduler.new
101
100
  @lock = Mutex.new
102
101
  end
103
102
 
@@ -164,6 +163,11 @@ module Ione
164
163
  error = e
165
164
  ensure
166
165
  begin
166
+ begin
167
+ @io_loop.drain_sockets
168
+ rescue => ee
169
+ error ||= ee
170
+ end
167
171
  @io_loop.close_sockets
168
172
  @scheduler.cancel_timers
169
173
  @unblocker = nil
@@ -194,6 +198,7 @@ module Ione
194
198
  Future.resolved(self)
195
199
  elsif @state != STOPPED_STATE && @state != CRASHED_STATE
196
200
  @state = STOPPING_STATE
201
+ @unblocker.unblock
197
202
  @stopped_promise.future
198
203
  else
199
204
  @stopped_promise.future
@@ -423,6 +428,9 @@ module Ione
423
428
  @out = nil
424
429
  end
425
430
 
431
+ def drain
432
+ end
433
+
426
434
  def to_io
427
435
  @out
428
436
  end
@@ -468,6 +476,7 @@ module Ione
468
476
  @selector = options[:selector] || IO
469
477
  @clock = options[:clock] || Time
470
478
  @timeout = options[:tick_resolution] || 1
479
+ @drain_timeout = options[:drain_timeout] || 5
471
480
  @lock = Mutex.new
472
481
  @sockets = []
473
482
  end
@@ -487,6 +496,18 @@ module Ione
487
496
  end
488
497
  end
489
498
 
499
+ def drain_sockets
500
+ threshold = @clock.now + @drain_timeout
501
+ until @clock.now >= threshold || @sockets.none?(&:writable?)
502
+ @sockets.each(&:drain)
503
+ tick
504
+ @lock.synchronize { @sockets = @sockets.reject(&:closed?) }
505
+ end
506
+ if @clock.now >= threshold
507
+ raise ReactorError, sprintf('Socket drain timeout after %p s', @drain_timeout)
508
+ end
509
+ end
510
+
490
511
  def close_sockets
491
512
  @sockets.each do |s|
492
513
  begin
@@ -571,8 +592,8 @@ module Ione
571
592
  ensure
572
593
  @lock.unlock
573
594
  end
574
- timers.each do |t|
575
- t.fail(CancelledError.new)
595
+ timers.each do |timer|
596
+ timer.fail(CancelledError.new)
576
597
  end
577
598
  nil
578
599
  end
@@ -593,8 +614,8 @@ module Ione
593
614
  ensure
594
615
  @lock.unlock
595
616
  end
596
- expired_timers.each do |t|
597
- t.fulfill
617
+ expired_timers.each do |timer|
618
+ timer.fulfill
598
619
  end
599
620
  end
600
621
  end
@@ -605,4 +626,4 @@ module Ione
605
626
  end
606
627
  end
607
628
  end
608
- end
629
+ end
@@ -12,7 +12,6 @@ module Ione
12
12
  @socket_impl = socket_impl
13
13
  @ssl_context = ssl_context
14
14
  @raw_io = io
15
- @io = nil
16
15
  @connected_promise = Promise.new
17
16
  on_closed(&method(:cleanup_on_close))
18
17
  end
data/lib/ione/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Ione
4
- VERSION = '1.2.5'.freeze
4
+ VERSION = '1.3.0.pre0'.freeze
5
5
  end
@@ -37,7 +37,7 @@ describe 'An IO reactor' do
37
37
  fake_server.await_connects(1)
38
38
  fake_server.broadcast('hello world')
39
39
  await { protocol_handler.data.bytesize > 0 }
40
- protocol_handler.data.should eq('hello world')
40
+ protocol_handler.data.should == 'hello world'
41
41
  end
42
42
 
43
43
  it 'receives data on multiple connections' do
@@ -45,7 +45,7 @@ describe 'An IO reactor' do
45
45
  fake_server.await_connects(10)
46
46
  fake_server.broadcast('hello world')
47
47
  await { protocol_handlers.all? { |c| c.data.bytesize > 0 } }
48
- protocol_handlers.sample.data.should eq('hello world')
48
+ protocol_handlers.sample.data.should == 'hello world'
49
49
  end
50
50
  end
51
51
 
@@ -81,7 +81,7 @@ describe 'An IO reactor' do
81
81
  socket = TCPSocket.new(ENV['SERVER_HOST'], port)
82
82
  socket.puts('HELLO')
83
83
  result = socket.read(5)
84
- result.should eq('HELLO')
84
+ result.should == 'HELLO'
85
85
  socket.close
86
86
  end
87
87
  end
@@ -49,7 +49,6 @@ describe 'SSL' do
49
49
  ssl_context = OpenSSL::SSL::SSLContext.new
50
50
  ssl_context.key = OpenSSL::PKey::RSA.new(ssl_key)
51
51
  ssl_context.cert = OpenSSL::X509::Certificate.new(ssl_cert)
52
- ssl_context.tmp_dh_callback = proc { SslSpec::DH_PARAMS }
53
52
 
54
53
  f = io_reactor.start
55
54
  f = f.flat_map do
@@ -81,8 +80,8 @@ describe 'SSL' do
81
80
  end
82
81
  client.write('hello world')
83
82
  response_received.future.value
84
- server_received_data.to_s.should eq('hello world')
85
- client_received_data.to_s.should eq('dlrow olleh')
83
+ server_received_data.to_s.should == 'hello world'
84
+ client_received_data.to_s.should == 'dlrow olleh'
86
85
  end
87
86
 
88
87
  it 'fails to send a message when not using encryption' do
@@ -96,7 +95,3 @@ describe 'SSL' do
96
95
  client.should be_closed
97
96
  end
98
97
  end
99
-
100
- module SslSpec
101
- DH_PARAMS = OpenSSL::PKey::DH.new(File.read(File.expand_path('../../resources/dh.pem', __FILE__)))
102
- end
@@ -15,28 +15,28 @@ module Ione
15
15
  end
16
16
 
17
17
  it 'can be initialized with bytes' do
18
- described_class.new('hello').length.should eq(5)
18
+ described_class.new('hello').length.should == 5
19
19
  end
20
20
  end
21
21
 
22
22
  describe '#length/#size/#bytesize' do
23
23
  it 'returns the number of bytes in the buffer' do
24
24
  buffer << 'foo'
25
- buffer.length.should eq(3)
25
+ buffer.length.should == 3
26
26
  end
27
27
 
28
28
  it 'is zero initially' do
29
- buffer.length.should eq(0)
29
+ buffer.length.should == 0
30
30
  end
31
31
 
32
32
  it 'is aliased as #size' do
33
33
  buffer << 'foo'
34
- buffer.size.should eq(3)
34
+ buffer.size.should == 3
35
35
  end
36
36
 
37
37
  it 'is aliased as #bytesize' do
38
38
  buffer << 'foo'
39
- buffer.bytesize.should eq(3)
39
+ buffer.bytesize.should == 3
40
40
  end
41
41
  end
42
42
 
@@ -67,19 +67,19 @@ module Ione
67
67
  end
68
68
 
69
69
  it 'stores its bytes as binary' do
70
- buffer.append('hällö').length.should eq(7)
71
- buffer.to_s.encoding.should eq(::Encoding::BINARY)
70
+ buffer.append('hällö').length.should == 7
71
+ buffer.to_s.encoding.should == ::Encoding::BINARY
72
72
  end
73
73
 
74
74
  it 'handles appending with multibyte strings' do
75
75
  buffer.append('hello')
76
76
  buffer.append('würld')
77
- buffer.to_s.should eq('hellowürld'.force_encoding(::Encoding::BINARY))
77
+ buffer.to_s.should == 'hellowürld'.force_encoding(::Encoding::BINARY)
78
78
  end
79
79
 
80
80
  it 'handles appending with another byte buffer' do
81
81
  buffer.append('hello ').append(ByteBuffer.new('world'))
82
- buffer.to_s.should eq('hello world')
82
+ buffer.to_s.should == 'hello world'
83
83
  end
84
84
  end
85
85
 
@@ -105,7 +105,7 @@ module Ione
105
105
  b2 = described_class.new
106
106
  b1.append('foo')
107
107
  b2.append('foo')
108
- b1.should eq(b2)
108
+ b1.should == b2
109
109
  end
110
110
 
111
111
  it 'is equal to another buffer when both are empty' do
@@ -121,7 +121,7 @@ module Ione
121
121
  b2 = described_class.new
122
122
  b1.append('foo')
123
123
  b2.append('foo')
124
- b1.hash.should eq(b2.hash)
124
+ b1.hash.should == b2.hash
125
125
  end
126
126
 
127
127
  it 'is not equal to the hash code of another buffer with other contents' do
@@ -135,26 +135,26 @@ module Ione
135
135
  it 'is equal to the hash code of another buffer when both are empty' do
136
136
  b1 = described_class.new
137
137
  b2 = described_class.new
138
- b1.hash.should eq(b2.hash)
138
+ b1.hash.should == b2.hash
139
139
  end
140
140
  end
141
141
 
142
142
  describe '#to_s' do
143
143
  it 'returns the bytes' do
144
- buffer.append('hello world').to_s.should eq('hello world')
144
+ buffer.append('hello world').to_s.should == 'hello world'
145
145
  end
146
146
  end
147
147
 
148
148
  describe '#to_str' do
149
149
  it 'returns the bytes' do
150
- buffer.append('hello world').to_str.should eq('hello world')
150
+ buffer.append('hello world').to_str.should == 'hello world'
151
151
  end
152
152
  end
153
153
 
154
154
  describe '#inspect' do
155
155
  it 'returns the bytes wrapped in ByteBuffer(...)' do
156
156
  buffer.append("\xca\xfe")
157
- buffer.inspect.should eq('#<Ione::ByteBuffer: "\xCA\xFE">')
157
+ buffer.inspect.should == '#<Ione::ByteBuffer: "\xCA\xFE">'
158
158
  end
159
159
  end
160
160
 
@@ -162,12 +162,12 @@ module Ione
162
162
  it 'discards the specified number of bytes from the front of the buffer' do
163
163
  buffer.append('hello world')
164
164
  buffer.discard(4)
165
- buffer.should eq(ByteBuffer.new('o world'))
165
+ buffer.should == ByteBuffer.new('o world')
166
166
  end
167
167
 
168
168
  it 'returns the byte buffer' do
169
169
  buffer.append('hello world')
170
- buffer.discard(4).should eq(ByteBuffer.new('o world'))
170
+ buffer.discard(4).should == ByteBuffer.new('o world')
171
171
  end
172
172
 
173
173
  it 'raises an error if the number of bytes in the buffer is fewer than the number to discard' do
@@ -185,14 +185,14 @@ module Ione
185
185
  describe '#read' do
186
186
  it 'returns the specified number of bytes, as a string' do
187
187
  buffer.append('hello')
188
- buffer.read(4).should eq('hell')
188
+ buffer.read(4).should == 'hell'
189
189
  end
190
190
 
191
191
  it 'removes the bytes from the buffer' do
192
192
  buffer.append('hello')
193
193
  buffer.read(3)
194
- buffer.should eq(ByteBuffer.new('lo'))
195
- buffer.read(2).should eq('lo')
194
+ buffer.should == ByteBuffer.new('lo')
195
+ buffer.read(2).should == 'lo'
196
196
  end
197
197
 
198
198
  it 'raises an error if there are not enough bytes' do
@@ -208,22 +208,22 @@ module Ione
208
208
 
209
209
  it 'returns a string with binary encoding' do
210
210
  buffer.append('hello')
211
- buffer.read(4).encoding.should eq(::Encoding::BINARY)
211
+ buffer.read(4).encoding.should == ::Encoding::BINARY
212
212
  buffer.append('∆')
213
- buffer.read(2).encoding.should eq(::Encoding::BINARY)
213
+ buffer.read(2).encoding.should == ::Encoding::BINARY
214
214
  end
215
215
  end
216
216
 
217
217
  describe '#read_int' do
218
218
  it 'returns the first four bytes interpreted as an int' do
219
219
  buffer.append("\xca\xfe\xba\xbe\x01")
220
- buffer.read_int.should eq(0xcafebabe)
220
+ buffer.read_int.should == 0xcafebabe
221
221
  end
222
222
 
223
223
  it 'removes the bytes from the buffer' do
224
224
  buffer.append("\xca\xfe\xba\xbe\x01")
225
225
  buffer.read_int
226
- buffer.should eq(ByteBuffer.new("\x01"))
226
+ buffer.should == ByteBuffer.new("\x01")
227
227
  end
228
228
 
229
229
  it 'raises an error if there are not enough bytes' do
@@ -235,13 +235,13 @@ module Ione
235
235
  describe '#read_short' do
236
236
  it 'returns the first two bytes interpreted as a short' do
237
237
  buffer.append("\xca\xfe\x01")
238
- buffer.read_short.should eq(0xcafe)
238
+ buffer.read_short.should == 0xcafe
239
239
  end
240
240
 
241
241
  it 'removes the bytes from the buffer' do
242
242
  buffer.append("\xca\xfe\x01")
243
243
  buffer.read_short
244
- buffer.should eq(ByteBuffer.new("\x01"))
244
+ buffer.should == ByteBuffer.new("\x01")
245
245
  end
246
246
 
247
247
  it 'raises an error if there are not enough bytes' do
@@ -253,14 +253,14 @@ module Ione
253
253
  describe '#read_byte' do
254
254
  it 'returns the first bytes interpreted as an int' do
255
255
  buffer.append("\x10\x01")
256
- buffer.read_byte.should eq(0x10)
257
- buffer.read_byte.should eq(0x01)
256
+ buffer.read_byte.should == 0x10
257
+ buffer.read_byte.should == 0x01
258
258
  end
259
259
 
260
260
  it 'removes the byte from the buffer' do
261
261
  buffer.append("\x10\x01")
262
262
  buffer.read_byte
263
- buffer.should eq(ByteBuffer.new("\x01"))
263
+ buffer.should == ByteBuffer.new("\x01")
264
264
  end
265
265
 
266
266
  it 'raises an error if there are no bytes' do
@@ -269,8 +269,8 @@ module Ione
269
269
 
270
270
  it 'can interpret the byte as signed' do
271
271
  buffer.append("\x81\x02")
272
- buffer.read_byte(true).should eq(-127)
273
- buffer.read_byte(true).should eq(2)
272
+ buffer.read_byte(true).should == -127
273
+ buffer.read_byte(true).should == 2
274
274
  end
275
275
  end
276
276
 
@@ -278,14 +278,14 @@ module Ione
278
278
  it 'changes the bytes at the specified location' do
279
279
  buffer.append('foo bar')
280
280
  buffer.update(4, 'baz')
281
- buffer.to_s.should eq('foo baz')
281
+ buffer.to_s.should == 'foo baz'
282
282
  end
283
283
 
284
284
  it 'handles updates after a read' do
285
285
  buffer.append('foo bar')
286
286
  buffer.read(1)
287
287
  buffer.update(3, 'baz')
288
- buffer.to_s.should eq('oo baz')
288
+ buffer.to_s.should == 'oo baz'
289
289
  end
290
290
 
291
291
  it 'handles updates after multiple reads and appends' do
@@ -295,7 +295,7 @@ module Ione
295
295
  buffer.update(4, 'baz')
296
296
  buffer.append('yyyy')
297
297
  buffer.read(1)
298
- buffer.to_s.should eq('o bbazyyyy')
298
+ buffer.to_s.should == 'o bbazyyyy'
299
299
  end
300
300
 
301
301
  it 'returns itself' do
@@ -335,12 +335,12 @@ module Ione
335
335
  describe '#index' do
336
336
  it 'returns the first index of the specified substring' do
337
337
  buffer.append('fizz buzz')
338
- buffer.index('zz').should eq(2)
338
+ buffer.index('zz').should == 2
339
339
  end
340
340
 
341
341
  it 'returns the first index of the specified substring, after the specified index' do
342
342
  buffer.append('fizz buzz')
343
- buffer.index('zz', 3).should eq(7)
343
+ buffer.index('zz', 3).should == 7
344
344
  end
345
345
 
346
346
  it 'returns nil when the substring is not found' do
@@ -352,14 +352,14 @@ module Ione
352
352
  buffer.append('foo bar')
353
353
  buffer.read(1)
354
354
  buffer.append(' baz baz')
355
- buffer.index('baz', 8).should eq(11)
355
+ buffer.index('baz', 8).should == 11
356
356
  end
357
357
 
358
358
  it 'returns the first index when the matching substring spans the read and write buffer' do
359
359
  buffer.append('foo bar')
360
360
  buffer.read(1)
361
361
  buffer.append('bar barbar')
362
- buffer.index('barbar', 0).should eq(3)
362
+ buffer.index('barbar', 0).should == 3
363
363
  end
364
364
 
365
365
  it 'returns nil when the substring does not fit in the search space' do