ione 1.2.0 → 1.2.1
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/README.md +1 -1
- data/lib/ione/byte_buffer.rb +2 -0
- data/lib/ione/future.rb +91 -27
- data/lib/ione/io/acceptor.rb +27 -6
- data/lib/ione/io/base_connection.rb +25 -13
- data/lib/ione/io/connection.rb +3 -2
- data/lib/ione/io/io_reactor.rb +171 -50
- data/lib/ione/io/server_connection.rb +2 -1
- data/lib/ione/io/ssl_connection.rb +1 -1
- data/lib/ione/io/ssl_server_connection.rb +7 -4
- data/lib/ione/version.rb +1 -1
- data/spec/ione/future_spec.rb +112 -0
- data/spec/ione/io/connection_spec.rb +4 -4
- data/spec/ione/io/io_reactor_spec.rb +235 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e616ec4a5f533a25efb171aa4e6ede4b1ca5de6f
|
4
|
+
data.tar.gz: 433284b5a259cb2db15f8ac95882d13d1e63507a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f80b6f25ac0192d10eac99cc8e2dd15b373944bb89e3125f378ff17df4a7a07caf0f35955e5772b322911560a8dff3cc42704c4c25dc67c952cd8c15269e5c8b
|
7
|
+
data.tar.gz: 885562d9eb7bb0cd1e6499a0b975fb2d82dee2298918fef4887ca66b5b9d4959c4bdacdd8c2aa2deb2a8e0f44187017dcc44dd9b801a5432bf0888caa720cac9
|
data/README.md
CHANGED
@@ -27,7 +27,7 @@ Networking usually means pushing lots of bytes around and in Ruby it's easy to m
|
|
27
27
|
The [examples](https://github.com/iconara/ione/tree/master/examples) directory has some examples of what you can do with Ione, for example:
|
28
28
|
|
29
29
|
* [redis_client](https://github.com/iconara/ione/tree/master/examples/redis_client) is a more or less full featured Redis client that uses most of Ione's features.
|
30
|
-
* [http_client](https://github.com/iconara/ione/tree/master/examples/http_client) is a simplistic HTTP client that uses Ione and [http_parser.rb](http://rubygems.org/gems/http_parser.rb) to make HTTP GET request.
|
30
|
+
* [http_client](https://github.com/iconara/ione/tree/master/examples/http_client) is a simplistic HTTP client that uses Ione and [http_parser.rb](http://rubygems.org/gems/http_parser.rb) to make HTTP GET request. It also shows how to make TLS connections.
|
31
31
|
* [cql-rb](https://github.com/iconara/cql-rb) is a high performance Cassandra driver and where Ione was originally developed.
|
32
32
|
* [cassandra-driver](https://github.com/datastax/ruby-driver) is the successor to cql-rb.
|
33
33
|
* [ione-rpc](https://github.com/iconara/ione-rpc) is a RPC framework built on Ione. It makes it reasonably easy to build networked applications without having to reinvent the wheel.
|
data/lib/ione/byte_buffer.rb
CHANGED
@@ -14,6 +14,8 @@ module Ione
|
|
14
14
|
# buffer and one is the write buffer. Writes go to the write buffer only,
|
15
15
|
# and reads read from the read buffer until it is empty, then a new write
|
16
16
|
# buffer is created and the old write buffer becomes the new read buffer.
|
17
|
+
#
|
18
|
+
# @since v1.0.0
|
17
19
|
class ByteBuffer
|
18
20
|
def initialize(initial_bytes=nil)
|
19
21
|
@read_buffer = ''
|
data/lib/ione/future.rb
CHANGED
@@ -11,6 +11,7 @@ module Ione
|
|
11
11
|
# A promise is the write end of a Promise/Future pair. It can be fulfilled
|
12
12
|
# with a value or failed with an error. The value can be read through the
|
13
13
|
# future returned by {#future}.
|
14
|
+
# @since v1.0.0
|
14
15
|
class Promise
|
15
16
|
attr_reader :future
|
16
17
|
|
@@ -104,7 +105,7 @@ module Ione
|
|
104
105
|
#
|
105
106
|
# @example Creating a future for a blocking operation
|
106
107
|
# def find_my_ip
|
107
|
-
# promise =
|
108
|
+
# promise = Promise.new
|
108
109
|
# Thread.start do
|
109
110
|
# begin
|
110
111
|
# data = JSON.load(open('http://jsonip.org/').read)
|
@@ -178,7 +179,13 @@ module Ione
|
|
178
179
|
# @see Ione::Future::FutureCallbacks
|
179
180
|
# @see Ione::Future::FutureCombinators
|
180
181
|
# @see Ione::Future::FutureFactories
|
182
|
+
# @since v1.0.0
|
181
183
|
class Future
|
184
|
+
PENDING_STATE = 0
|
185
|
+
RESOLVED_STATE = 1
|
186
|
+
FAILED_STATE = 2
|
187
|
+
|
188
|
+
# @since v1.0.0
|
182
189
|
module Factories
|
183
190
|
# Combines multiple futures into a new future which resolves when all
|
184
191
|
# constituent futures complete, or fails when one or more of them fails.
|
@@ -207,6 +214,33 @@ module Ione
|
|
207
214
|
end
|
208
215
|
end
|
209
216
|
|
217
|
+
# Combines multiple futures into a new future which resolves when all
|
218
|
+
# constituent futures complete, or fails when one or more of them fails.
|
219
|
+
#
|
220
|
+
# The resulting future has no value.
|
221
|
+
#
|
222
|
+
# @example
|
223
|
+
# future = Future.after(delete_thing(1), delete_thing(2))
|
224
|
+
# future.value # => nil
|
225
|
+
#
|
226
|
+
# @param [Array<Ione::Future>] futures the futures to combine (this argument
|
227
|
+
# can be a splatted array or a regular array passed as sole argument)
|
228
|
+
# @return [Ione::Future] with a nil value once all futures have succeeded
|
229
|
+
# @since v1.3.0
|
230
|
+
def after(*futures)
|
231
|
+
if futures.size == 1 && (fs = futures.first).is_a?(Enumerable)
|
232
|
+
*futures = *fs
|
233
|
+
end
|
234
|
+
if futures.count == 0
|
235
|
+
ResolvedFuture::NIL
|
236
|
+
elsif futures.count == 1
|
237
|
+
futures.first.map(nil)
|
238
|
+
else
|
239
|
+
CombinedNilFuture.new(futures)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
|
210
244
|
# Returns a future which will be resolved with the value of the first
|
211
245
|
# (resolved) of the specified futures. If all of the futures fail, the
|
212
246
|
# returned future will also fail (with the error of the last failed future).
|
@@ -249,6 +283,7 @@ module Ione
|
|
249
283
|
# @yieldreturn [Ione::Future] a future
|
250
284
|
# @return [Ione::Future] a future that will resolve to an array of the values
|
251
285
|
# of the futures returned by the block
|
286
|
+
# @since v1.2.0
|
252
287
|
def traverse(values, &block)
|
253
288
|
all(values.map(&block))
|
254
289
|
rescue => e
|
@@ -286,7 +321,8 @@ module Ione
|
|
286
321
|
#
|
287
322
|
# @param [Array<Ione::Future>] futures an array of futures whose values
|
288
323
|
# should be reduced
|
289
|
-
# @param [Object] initial_value the initial value of the accumulator
|
324
|
+
# @param [Object] initial_value the initial value of the accumulator. When
|
325
|
+
# nil (the default) the value of the first future will be used instead.
|
290
326
|
# @param [Hash] options
|
291
327
|
# @option options [Boolean] :ordered (true) whether or not to respect the
|
292
328
|
# order of the input when reducing – when true the block will be called
|
@@ -302,6 +338,7 @@ module Ione
|
|
302
338
|
# @return [Ione::Future] a future that will resolve to the value returned
|
303
339
|
# from the last invocation of the block, or nil when the list of futures
|
304
340
|
# is empty.
|
341
|
+
# @since v1.2.0
|
305
342
|
def reduce(futures, initial_value=nil, options=nil, &reducer)
|
306
343
|
if options && options[:ordered] == false
|
307
344
|
UnorderedReducingFuture.new(futures, initial_value, reducer)
|
@@ -328,6 +365,7 @@ module Ione
|
|
328
365
|
end
|
329
366
|
end
|
330
367
|
|
368
|
+
# @since v1.0.0
|
331
369
|
module Combinators
|
332
370
|
# Returns a new future representing a transformation of this future's value.
|
333
371
|
#
|
@@ -411,6 +449,7 @@ module Ione
|
|
411
449
|
# @yieldreturn [Object, Ione::Future] the transformed value, or a future
|
412
450
|
# that will resolve to the transformed value.
|
413
451
|
# @return [Ione::Future] a new future representing the transformed value
|
452
|
+
# @since v1.2.0
|
414
453
|
def then(&block)
|
415
454
|
f = CompletableFuture.new
|
416
455
|
on_complete do |v, e|
|
@@ -519,6 +558,7 @@ module Ione
|
|
519
558
|
end
|
520
559
|
end
|
521
560
|
|
561
|
+
# @since v1.0.0
|
522
562
|
module Callbacks
|
523
563
|
# Registers a listener that will be called when this future becomes
|
524
564
|
# resolved. The listener will be called with the value of the future as
|
@@ -549,9 +589,10 @@ module Ione
|
|
549
589
|
include Combinators
|
550
590
|
include Callbacks
|
551
591
|
|
592
|
+
# @private
|
552
593
|
def initialize
|
553
594
|
@lock = Mutex.new
|
554
|
-
@state =
|
595
|
+
@state = PENDING_STATE
|
555
596
|
@listeners = []
|
556
597
|
end
|
557
598
|
|
@@ -595,12 +636,12 @@ module Ione
|
|
595
636
|
# @see Callbacks#on_failure
|
596
637
|
def on_complete(&listener)
|
597
638
|
run_immediately = false
|
598
|
-
if @state !=
|
639
|
+
if @state != PENDING_STATE
|
599
640
|
run_immediately = true
|
600
641
|
else
|
601
642
|
@lock.lock
|
602
643
|
begin
|
603
|
-
if @state ==
|
644
|
+
if @state == PENDING_STATE
|
604
645
|
@listeners << listener
|
605
646
|
else
|
606
647
|
run_immediately = true
|
@@ -634,13 +675,13 @@ module Ione
|
|
634
675
|
# @see Callbacks#on_failure
|
635
676
|
# @see Callbacks#on_complete
|
636
677
|
def value
|
637
|
-
raise @error if @state ==
|
638
|
-
return @value if @state ==
|
678
|
+
raise @error if @state == FAILED_STATE
|
679
|
+
return @value if @state == RESOLVED_STATE
|
639
680
|
semaphore = nil
|
640
681
|
@lock.lock
|
641
682
|
begin
|
642
|
-
raise @error if @state ==
|
643
|
-
return @value if @state ==
|
683
|
+
raise @error if @state == FAILED_STATE
|
684
|
+
return @value if @state == RESOLVED_STATE
|
644
685
|
semaphore = Queue.new
|
645
686
|
u = proc { semaphore << :unblock }
|
646
687
|
@listeners << u
|
@@ -650,8 +691,8 @@ module Ione
|
|
650
691
|
while true
|
651
692
|
@lock.lock
|
652
693
|
begin
|
653
|
-
raise @error if @state ==
|
654
|
-
return @value if @state ==
|
694
|
+
raise @error if @state == FAILED_STATE
|
695
|
+
return @value if @state == RESOLVED_STATE
|
655
696
|
ensure
|
656
697
|
@lock.unlock
|
657
698
|
end
|
@@ -662,10 +703,10 @@ module Ione
|
|
662
703
|
|
663
704
|
# Returns true if this future is resolved or failed
|
664
705
|
def completed?
|
665
|
-
return true unless @state ==
|
706
|
+
return true unless @state == PENDING_STATE
|
666
707
|
@lock.lock
|
667
708
|
begin
|
668
|
-
@state !=
|
709
|
+
@state != PENDING_STATE
|
669
710
|
ensure
|
670
711
|
@lock.unlock
|
671
712
|
end
|
@@ -673,10 +714,10 @@ module Ione
|
|
673
714
|
|
674
715
|
# Returns true if this future is resolved
|
675
716
|
def resolved?
|
676
|
-
return @state ==
|
717
|
+
return @state == RESOLVED_STATE unless @state == PENDING_STATE
|
677
718
|
@lock.lock
|
678
719
|
begin
|
679
|
-
@state ==
|
720
|
+
@state == RESOLVED_STATE
|
680
721
|
ensure
|
681
722
|
@lock.unlock
|
682
723
|
end
|
@@ -684,10 +725,10 @@ module Ione
|
|
684
725
|
|
685
726
|
# Returns true if this future has failed
|
686
727
|
def failed?
|
687
|
-
return @state ==
|
728
|
+
return @state == FAILED_STATE unless @state == PENDING_STATE
|
688
729
|
@lock.lock
|
689
730
|
begin
|
690
|
-
@state ==
|
731
|
+
@state == FAILED_STATE
|
691
732
|
ensure
|
692
733
|
@lock.unlock
|
693
734
|
end
|
@@ -731,9 +772,9 @@ module Ione
|
|
731
772
|
listeners = nil
|
732
773
|
@lock.lock
|
733
774
|
begin
|
734
|
-
raise FutureError, 'Future already completed' unless @state ==
|
775
|
+
raise FutureError, 'Future already completed' unless @state == PENDING_STATE
|
735
776
|
@value = v
|
736
|
-
@state =
|
777
|
+
@state = RESOLVED_STATE
|
737
778
|
listeners = @listeners
|
738
779
|
@listeners = nil
|
739
780
|
ensure
|
@@ -749,9 +790,9 @@ module Ione
|
|
749
790
|
listeners = nil
|
750
791
|
@lock.lock
|
751
792
|
begin
|
752
|
-
raise FutureError, 'Future already completed' unless @state ==
|
793
|
+
raise FutureError, 'Future already completed' unless @state == PENDING_STATE
|
753
794
|
@error = error
|
754
|
-
@state =
|
795
|
+
@state = FAILED_STATE
|
755
796
|
listeners = @listeners
|
756
797
|
@listeners = nil
|
757
798
|
ensure
|
@@ -793,14 +834,37 @@ module Ione
|
|
793
834
|
end
|
794
835
|
end
|
795
836
|
|
837
|
+
# @private
|
838
|
+
class CombinedNilFuture < CompletableFuture
|
839
|
+
def initialize(futures)
|
840
|
+
super()
|
841
|
+
@futures = futures
|
842
|
+
await_next(nil, nil)
|
843
|
+
end
|
844
|
+
|
845
|
+
def await_next(v, e)
|
846
|
+
if e
|
847
|
+
@futures = nil
|
848
|
+
fail(e)
|
849
|
+
elsif @futures.empty?
|
850
|
+
@futures = nil
|
851
|
+
resolve
|
852
|
+
else
|
853
|
+
@futures.pop.on_complete(&method(:await_next))
|
854
|
+
end
|
855
|
+
end
|
856
|
+
end
|
857
|
+
|
796
858
|
# @private
|
797
859
|
class ReducingFuture < CompletableFuture
|
860
|
+
NO_INITIAL_VALUE = Object.new
|
861
|
+
|
798
862
|
def initialize(futures, initial_value, reducer)
|
799
863
|
super()
|
800
864
|
@futures = Array(futures)
|
801
865
|
@remaining = @futures.size
|
802
866
|
@initial_value = initial_value
|
803
|
-
@accumulator = initial_value
|
867
|
+
@accumulator = initial_value.nil? ? NO_INITIAL_VALUE : initial_value
|
804
868
|
@reducer = reducer
|
805
869
|
end
|
806
870
|
|
@@ -810,10 +874,10 @@ module Ione
|
|
810
874
|
unless failed?
|
811
875
|
@lock.lock
|
812
876
|
begin
|
813
|
-
if @accumulator
|
814
|
-
@accumulator = @reducer.call(@accumulator, value)
|
815
|
-
else
|
877
|
+
if @accumulator.equal?(NO_INITIAL_VALUE)
|
816
878
|
@accumulator = value
|
879
|
+
else
|
880
|
+
@accumulator = @reducer.call(@accumulator, value)
|
817
881
|
end
|
818
882
|
@remaining -= 1
|
819
883
|
rescue => e
|
@@ -905,7 +969,7 @@ module Ione
|
|
905
969
|
# @private
|
906
970
|
class ResolvedFuture < Future
|
907
971
|
def initialize(value=nil)
|
908
|
-
@state =
|
972
|
+
@state = RESOLVED_STATE
|
909
973
|
@value = value
|
910
974
|
@error = nil
|
911
975
|
end
|
@@ -943,7 +1007,7 @@ module Ione
|
|
943
1007
|
# @private
|
944
1008
|
class FailedFuture < Future
|
945
1009
|
def initialize(error)
|
946
|
-
@state =
|
1010
|
+
@state = FAILED_STATE
|
947
1011
|
@value = nil
|
948
1012
|
@error = error
|
949
1013
|
end
|
data/lib/ione/io/acceptor.rb
CHANGED
@@ -3,11 +3,19 @@
|
|
3
3
|
|
4
4
|
module Ione
|
5
5
|
module Io
|
6
|
+
# An acceptor wraps a server socket and accepts client connections.
|
7
|
+
# @since v1.1.0
|
6
8
|
class Acceptor
|
9
|
+
# @private
|
7
10
|
ServerSocket = RUBY_ENGINE == 'jruby' ? ::ServerSocket : Socket
|
8
11
|
|
12
|
+
BINDING_STATE = 0
|
13
|
+
CONNECTED_STATE = 1
|
14
|
+
CLOSED_STATE = 2
|
15
|
+
|
9
16
|
attr_reader :backlog
|
10
17
|
|
18
|
+
# @private
|
11
19
|
def initialize(host, port, backlog, unblocker, reactor, socket_impl=nil)
|
12
20
|
@host = host
|
13
21
|
@port = port
|
@@ -17,15 +25,19 @@ module Ione
|
|
17
25
|
@socket_impl = socket_impl || ServerSocket
|
18
26
|
@accept_listeners = []
|
19
27
|
@lock = Mutex.new
|
20
|
-
@state =
|
28
|
+
@state = BINDING_STATE
|
21
29
|
end
|
22
30
|
|
31
|
+
# Register a listener to be notified when client connections are accepted
|
32
|
+
#
|
33
|
+
# @yieldparam [Ione::Io::ServerConnection] the connection to the client
|
23
34
|
def on_accept(&listener)
|
24
35
|
@lock.synchronize do
|
25
36
|
@accept_listeners << listener
|
26
37
|
end
|
27
38
|
end
|
28
39
|
|
40
|
+
# @private
|
29
41
|
def bind
|
30
42
|
addrinfos = @socket_impl.getaddrinfo(@host, @port, nil, Socket::SOCK_STREAM)
|
31
43
|
begin
|
@@ -39,17 +51,18 @@ module Ione
|
|
39
51
|
retry
|
40
52
|
end
|
41
53
|
end
|
42
|
-
@state =
|
54
|
+
@state = CONNECTED_STATE
|
43
55
|
Future.resolved(self)
|
44
56
|
rescue => e
|
45
57
|
close
|
46
58
|
Future.failed(e)
|
47
59
|
end
|
48
60
|
|
61
|
+
# Stop accepting connections
|
49
62
|
def close
|
50
63
|
@lock.synchronize do
|
51
|
-
return false if @state ==
|
52
|
-
@state =
|
64
|
+
return false if @state == CLOSED_STATE
|
65
|
+
@state = CLOSED_STATE
|
53
66
|
end
|
54
67
|
if @io
|
55
68
|
begin
|
@@ -63,26 +76,32 @@ module Ione
|
|
63
76
|
true
|
64
77
|
end
|
65
78
|
|
79
|
+
# @private
|
66
80
|
def to_io
|
67
81
|
@io
|
68
82
|
end
|
69
83
|
|
84
|
+
# Returns true if the acceptor has stopped accepting connections
|
70
85
|
def closed?
|
71
|
-
@state ==
|
86
|
+
@state == CLOSED_STATE
|
72
87
|
end
|
73
88
|
|
89
|
+
# Returns true if the acceptor is accepting connections
|
74
90
|
def connected?
|
75
|
-
@state !=
|
91
|
+
@state != CLOSED_STATE
|
76
92
|
end
|
77
93
|
|
94
|
+
# @private
|
78
95
|
def connecting?
|
79
96
|
false
|
80
97
|
end
|
81
98
|
|
99
|
+
# @private
|
82
100
|
def writable?
|
83
101
|
false
|
84
102
|
end
|
85
103
|
|
104
|
+
# @private
|
86
105
|
def read
|
87
106
|
client_socket, host, port = accept
|
88
107
|
connection = ServerConnection.new(client_socket, host, port, @unblocker)
|
@@ -91,10 +110,12 @@ module Ione
|
|
91
110
|
end
|
92
111
|
|
93
112
|
if RUBY_ENGINE == 'jruby'
|
113
|
+
# @private
|
94
114
|
def bind_socket(socket, addr, backlog)
|
95
115
|
socket.bind(addr, backlog)
|
96
116
|
end
|
97
117
|
else
|
118
|
+
# @private
|
98
119
|
def bind_socket(socket, addr, backlog)
|
99
120
|
socket.bind(addr)
|
100
121
|
socket.listen(backlog)
|
@@ -2,14 +2,21 @@
|
|
2
2
|
|
3
3
|
module Ione
|
4
4
|
module Io
|
5
|
+
# @since v1.0.0
|
5
6
|
class BaseConnection
|
7
|
+
CONNECTING_STATE = 0
|
8
|
+
CONNECTED_STATE = 1
|
9
|
+
DRAINING_STATE = 2
|
10
|
+
CLOSED_STATE = 3
|
11
|
+
|
6
12
|
attr_reader :host, :port
|
7
13
|
|
14
|
+
# @private
|
8
15
|
def initialize(host, port, unblocker)
|
9
16
|
@host = host
|
10
17
|
@port = port
|
11
18
|
@unblocker = unblocker
|
12
|
-
@state =
|
19
|
+
@state = CONNECTING_STATE
|
13
20
|
@writable = false
|
14
21
|
@lock = Mutex.new
|
15
22
|
@write_buffer = ByteBuffer.new
|
@@ -21,8 +28,8 @@ module Ione
|
|
21
28
|
# @return [true, false] returns false if the connection was already closed
|
22
29
|
def close(cause=nil)
|
23
30
|
@lock.synchronize do
|
24
|
-
return false if @state ==
|
25
|
-
@state =
|
31
|
+
return false if @state == CLOSED_STATE
|
32
|
+
@state = CLOSED_STATE
|
26
33
|
@writable = false
|
27
34
|
end
|
28
35
|
if @io
|
@@ -50,30 +57,31 @@ module Ione
|
|
50
57
|
#
|
51
58
|
# @return [Ione::Future] a future that resolves to the connection when it
|
52
59
|
# has closed
|
60
|
+
# @since v1.1.0
|
53
61
|
def drain
|
54
|
-
@state =
|
62
|
+
@state = DRAINING_STATE
|
55
63
|
close unless @writable
|
56
64
|
@closed_promise.future
|
57
65
|
end
|
58
66
|
|
59
67
|
# @private
|
60
68
|
def connecting?
|
61
|
-
@state ==
|
69
|
+
@state == CONNECTING_STATE
|
62
70
|
end
|
63
71
|
|
64
72
|
# Returns true if the connection is connected
|
65
73
|
def connected?
|
66
|
-
@state ==
|
74
|
+
@state == CONNECTED_STATE
|
67
75
|
end
|
68
76
|
|
69
77
|
# Returns true if the connection is closed
|
70
78
|
def closed?
|
71
|
-
@state ==
|
79
|
+
@state == CLOSED_STATE
|
72
80
|
end
|
73
81
|
|
74
82
|
# @private
|
75
83
|
def writable?
|
76
|
-
@writable && @state !=
|
84
|
+
@writable && @state != CLOSED_STATE
|
77
85
|
end
|
78
86
|
|
79
87
|
# Register to receive notifications when new data is read from the socket.
|
@@ -119,7 +127,7 @@ module Ione
|
|
119
127
|
# @yieldparam buffer [Ione::ByteBuffer] the connection's internal buffer
|
120
128
|
# @param bytes [String, Ione::ByteBuffer] the data to write to the socket
|
121
129
|
def write(bytes=nil)
|
122
|
-
if @state ==
|
130
|
+
if @state == CONNECTED_STATE || @state == CONNECTING_STATE
|
123
131
|
@lock.lock
|
124
132
|
begin
|
125
133
|
if block_given?
|
@@ -137,7 +145,7 @@ module Ione
|
|
137
145
|
|
138
146
|
# @private
|
139
147
|
def flush
|
140
|
-
if @state ==
|
148
|
+
if @state == CONNECTED_STATE || @state == DRAINING_STATE
|
141
149
|
@lock.lock
|
142
150
|
begin
|
143
151
|
if @writable
|
@@ -145,7 +153,7 @@ module Ione
|
|
145
153
|
@write_buffer.discard(bytes_written)
|
146
154
|
end
|
147
155
|
@writable = !@write_buffer.empty?
|
148
|
-
if @state ==
|
156
|
+
if @state == DRAINING_STATE && !@writable
|
149
157
|
close
|
150
158
|
end
|
151
159
|
ensure
|
@@ -158,7 +166,7 @@ module Ione
|
|
158
166
|
|
159
167
|
# @private
|
160
168
|
def read
|
161
|
-
new_data = @io.read_nonblock(
|
169
|
+
new_data = @io.read_nonblock(65536)
|
162
170
|
@data_listener.call(new_data) if @data_listener
|
163
171
|
rescue => e
|
164
172
|
close(e)
|
@@ -170,7 +178,11 @@ module Ione
|
|
170
178
|
end
|
171
179
|
|
172
180
|
def to_s
|
173
|
-
|
181
|
+
state_constant_name = self.class.constants.find do |name|
|
182
|
+
name.to_s.end_with?('_STATE') && self.class.const_get(name) == @state
|
183
|
+
end
|
184
|
+
state = state_constant_name.to_s.rpartition('_').first
|
185
|
+
%(#<#{self.class.name} #{state} #{@host}:#{@port}>)
|
174
186
|
end
|
175
187
|
end
|
176
188
|
end
|