lightio 0.4.2 → 0.4.3
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 +5 -5
- data/Gemfile.lock +1 -1
- data/README.md +1 -0
- data/lib/lightio/core/future.rb +1 -0
- data/lib/lightio/library/base.rb +7 -0
- data/lib/lightio/library/io.rb +124 -39
- data/lib/lightio/library/socket.rb +2 -0
- data/lib/lightio/version.rb +1 -1
- data/lib/lightio/watchers/io.rb +17 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0461dd68b60dfa05c34fabdcd916ef074de8e634634174fc5253dbc5083d221a
|
4
|
+
data.tar.gz: 0715bf64fe6b6150d629136b621eec9d6a79c72dc7110e19082dd4e59b14a0a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c7796bdbcb7cc253979813fe394fe65dec6eab3ee53384042a267fa5cf2fef316a946b732e0adc42f1c343c53c4602f7149617d7626066984156ea8fc581d0b
|
7
|
+
data.tar.gz: 71e6b9f3b63d6e236ea6fb5b0629f6634fe9d60d459d63f78fd5b7406027ca5858add3e0f0d502278938db0d6e2b4d8e930171850a9fa7305b695b6fc5de3ce5
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
[](https://travis-ci.org/socketry/lightio)
|
6
6
|
[](https://coveralls.io/github/socketry/lightio?branch=master)
|
7
7
|
[](https://github.com/jjyr/lightio/blob/master/LICENSE.txt)
|
8
|
+
[](https://gitter.im/lightio-dev/Lobby)
|
8
9
|
|
9
10
|
LightIO provide green thread to ruby. Like Golang's goroutine, or Crystal's fiber. In LightIO it called beam.
|
10
11
|
|
data/lib/lightio/core/future.rb
CHANGED
data/lib/lightio/library/base.rb
CHANGED
@@ -98,6 +98,7 @@ module LightIO::Library
|
|
98
98
|
else
|
99
99
|
mock_obj = allocate
|
100
100
|
mock_obj.instance_variable_set(:@obj, obj)
|
101
|
+
mock_obj.__send__(:call_lightio_initialize)
|
101
102
|
mock_obj
|
102
103
|
end
|
103
104
|
end
|
@@ -106,9 +107,15 @@ module LightIO::Library
|
|
106
107
|
def initialize(*args)
|
107
108
|
obj = self.class.send(:call_method_from_ancestors, :mock_klass).send(:origin_new, *args)
|
108
109
|
@obj = obj
|
110
|
+
call_lightio_initialize
|
111
|
+
@obj
|
109
112
|
end
|
110
113
|
|
111
114
|
private
|
115
|
+
def call_lightio_initialize
|
116
|
+
__send__(:lightio_initialize) if respond_to?(:lightio_initialize, true)
|
117
|
+
end
|
118
|
+
|
112
119
|
def light_io_raw_obj
|
113
120
|
@obj
|
114
121
|
end
|
data/lib/lightio/library/io.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'io/wait'
|
2
|
+
|
1
3
|
module LightIO::Library
|
2
4
|
class IO
|
3
5
|
include Base
|
@@ -19,8 +21,25 @@ module LightIO::Library
|
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
24
|
+
def lightio_initialize
|
25
|
+
@readbuf = StringIO.new
|
26
|
+
@readbuf.set_encoding(@obj.external_encoding) if @obj.respond_to?(:external_encoding)
|
27
|
+
@eof = nil
|
28
|
+
@seek = 0
|
29
|
+
end
|
30
|
+
|
22
31
|
def wait(timeout = nil, mode = :read)
|
23
|
-
|
32
|
+
# avoid wait if can immediately return
|
33
|
+
wait_result = if RUBY_VERSION < '2.4'
|
34
|
+
if mode == :read
|
35
|
+
@obj.wait_readable(0)
|
36
|
+
elsif mode == :write
|
37
|
+
@obj.wait_writable(0)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
@obj.wait(0, mode)
|
41
|
+
end
|
42
|
+
(wait_result || io_watcher.wait(timeout, mode)) && self
|
24
43
|
end
|
25
44
|
|
26
45
|
def wait_readable(timeout = nil)
|
@@ -31,30 +50,21 @@ module LightIO::Library
|
|
31
50
|
wait(timeout, :write) && self
|
32
51
|
end
|
33
52
|
|
34
|
-
def read(length=nil, outbuf=nil)
|
35
|
-
|
36
|
-
|
37
|
-
loop do
|
38
|
-
readlen = length.nil? ? 4096 : length - outbuf.size
|
39
|
-
if (data = wait_nonblock(:read_nonblock, readlen))
|
40
|
-
outbuf << data
|
41
|
-
if length == outbuf.size
|
42
|
-
return outbuf
|
43
|
-
end
|
44
|
-
else
|
45
|
-
return outbuf.empty? && length ? nil : outbuf
|
46
|
-
end
|
53
|
+
def read(length = nil, outbuf = nil)
|
54
|
+
while !fill_read_buf && (length.nil? || length > @readbuf.length - @readbuf.pos)
|
55
|
+
wait_readable
|
47
56
|
end
|
57
|
+
@readbuf.read(length, outbuf)
|
48
58
|
end
|
49
59
|
|
50
|
-
def readpartial(maxlen, outbuf=nil)
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
60
|
+
def readpartial(maxlen, outbuf = nil)
|
61
|
+
raise ArgumentError, "negative length #{maxlen} given" if maxlen < 0
|
62
|
+
fill_read_buf
|
63
|
+
while @readbuf.eof? && !io_eof?
|
64
|
+
wait_readable
|
65
|
+
fill_read_buf
|
56
66
|
end
|
57
|
-
outbuf
|
67
|
+
@readbuf.readpartial(maxlen, outbuf)
|
58
68
|
end
|
59
69
|
|
60
70
|
def getbyte
|
@@ -62,8 +72,13 @@ module LightIO::Library
|
|
62
72
|
end
|
63
73
|
|
64
74
|
def getc
|
65
|
-
|
66
|
-
@
|
75
|
+
fill_read_buf
|
76
|
+
until (c = @readbuf.getc)
|
77
|
+
return nil if nonblock_eof?
|
78
|
+
wait_readable
|
79
|
+
fill_read_buf
|
80
|
+
end
|
81
|
+
c
|
67
82
|
end
|
68
83
|
|
69
84
|
def readline(*args)
|
@@ -73,11 +88,10 @@ module LightIO::Library
|
|
73
88
|
end
|
74
89
|
|
75
90
|
def readlines(*args)
|
76
|
-
|
77
|
-
|
78
|
-
result << readline(*args)
|
91
|
+
until fill_read_buf
|
92
|
+
wait_readable
|
79
93
|
end
|
80
|
-
|
94
|
+
@readbuf.readlines(*args)
|
81
95
|
end
|
82
96
|
|
83
97
|
def readchar
|
@@ -93,8 +107,13 @@ module LightIO::Library
|
|
93
107
|
end
|
94
108
|
|
95
109
|
def eof
|
96
|
-
|
97
|
-
|
110
|
+
# until eof have a value
|
111
|
+
fill_read_buf
|
112
|
+
while @readbuf.eof? && @eof.nil?
|
113
|
+
wait_readable
|
114
|
+
fill_read_buf
|
115
|
+
end
|
116
|
+
nonblock_eof?
|
98
117
|
end
|
99
118
|
|
100
119
|
alias eof? eof
|
@@ -103,19 +122,17 @@ module LightIO::Library
|
|
103
122
|
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..2)" if args.size > 2
|
104
123
|
sep = $/
|
105
124
|
if args[0].is_a?(Numeric)
|
106
|
-
limit = args
|
125
|
+
limit = args[0]
|
107
126
|
else
|
108
|
-
sep = args
|
109
|
-
limit = args
|
127
|
+
sep = args[0] if args.size > 0
|
128
|
+
limit = args[1] if args[1].is_a?(Numeric)
|
110
129
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
break if c == sep
|
130
|
+
until fill_read_buf
|
131
|
+
break if limit && limit <= @readbuf.length
|
132
|
+
break if sep && @readbuf.string.index(sep)
|
133
|
+
wait_readable
|
116
134
|
end
|
117
|
-
|
118
|
-
$_ = s
|
135
|
+
@readbuf.gets(*args)
|
119
136
|
end
|
120
137
|
|
121
138
|
def print(*obj)
|
@@ -135,11 +152,79 @@ module LightIO::Library
|
|
135
152
|
end
|
136
153
|
end
|
137
154
|
|
155
|
+
def flush
|
156
|
+
@obj.flush
|
157
|
+
self
|
158
|
+
end
|
159
|
+
|
138
160
|
def close(*args)
|
139
161
|
# close watcher before io closed
|
140
162
|
io_watcher.close
|
141
163
|
@obj.close
|
142
164
|
end
|
165
|
+
|
166
|
+
private
|
167
|
+
|
168
|
+
def nonblock_eof?
|
169
|
+
@readbuf.eof? && io_eof?
|
170
|
+
end
|
171
|
+
|
172
|
+
def io_eof?
|
173
|
+
@eof
|
174
|
+
end
|
175
|
+
|
176
|
+
BUF_CHUNK_SIZE = 1024 * 16
|
177
|
+
|
178
|
+
def fill_read_buf
|
179
|
+
return true if @eof
|
180
|
+
while (data = @obj.read_nonblock(BUF_CHUNK_SIZE, exception: false))
|
181
|
+
case data
|
182
|
+
when :wait_readable, :wait_writable
|
183
|
+
# set eof to unknown(nil)
|
184
|
+
@eof = nil
|
185
|
+
return nil
|
186
|
+
else
|
187
|
+
# set eof to false
|
188
|
+
@eof = false if @eof.nil?
|
189
|
+
@readbuf.string << data
|
190
|
+
end
|
191
|
+
end
|
192
|
+
# set eof to true
|
193
|
+
@eof = true
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def set_encoding(*args)
|
198
|
+
@readbuf.set_encoding(*args)
|
199
|
+
super(*args)
|
200
|
+
end
|
201
|
+
|
202
|
+
def lineno
|
203
|
+
@readbuf.lineno
|
204
|
+
end
|
205
|
+
|
206
|
+
def lineno= no
|
207
|
+
@readbuf.lineno = no
|
208
|
+
end
|
209
|
+
|
210
|
+
def rewind
|
211
|
+
# clear buf if seek offset is not zero
|
212
|
+
unless @seek.zero?
|
213
|
+
@seek = 0
|
214
|
+
@readbuf.string.clear
|
215
|
+
end
|
216
|
+
@readbuf.rewind
|
217
|
+
end
|
218
|
+
|
219
|
+
def seek(*args)
|
220
|
+
@readbuf.string.clear
|
221
|
+
@seek = args[0]
|
222
|
+
@obj.seek(*args)
|
223
|
+
end
|
224
|
+
|
225
|
+
def binmode
|
226
|
+
@obj.binmode
|
227
|
+
self
|
143
228
|
end
|
144
229
|
|
145
230
|
prepend IOMethods
|
@@ -153,6 +153,7 @@ module LightIO::Library
|
|
153
153
|
@obj = socket
|
154
154
|
wait_nonblock(:connect_nonblock, remote_address)
|
155
155
|
@obj
|
156
|
+
lightio_initialize
|
156
157
|
end
|
157
158
|
|
158
159
|
private
|
@@ -167,6 +168,7 @@ module LightIO::Library
|
|
167
168
|
|
168
169
|
def initialize(*args)
|
169
170
|
@obj = ::TCPServer.send(:origin_new, *args)
|
171
|
+
lightio_initialize
|
170
172
|
end
|
171
173
|
|
172
174
|
def accept
|
data/lib/lightio/version.rb
CHANGED
data/lib/lightio/watchers/io.rb
CHANGED
@@ -21,16 +21,19 @@ module LightIO::Watchers
|
|
21
21
|
@io = io
|
22
22
|
@ioloop = LightIO::Core::IOloop.current
|
23
23
|
@waiting = false
|
24
|
-
ObjectSpace.define_finalizer(self, self.class.finalizer(@monitor))
|
25
24
|
@error = nil
|
26
25
|
# maintain socket status, see https://github.com/socketry/lightio/issues/1
|
27
26
|
@readiness = nil
|
27
|
+
@monitor = nil
|
28
28
|
end
|
29
29
|
|
30
30
|
# NIO::Monitor
|
31
31
|
def monitor(interests=:rw)
|
32
32
|
@monitor ||= begin
|
33
|
-
@
|
33
|
+
raise @error if @error
|
34
|
+
monitor = @ioloop.add_io_wait(@io, interests) {callback_on_waiting}
|
35
|
+
ObjectSpace.define_finalizer(self, self.class.finalizer(monitor))
|
36
|
+
monitor
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
@@ -41,7 +44,13 @@ module LightIO::Watchers
|
|
41
44
|
end
|
42
45
|
|
43
46
|
extend Forwardable
|
44
|
-
def_delegators :monitor, :interests, :interests
|
47
|
+
def_delegators :monitor, :interests, :interests=
|
48
|
+
|
49
|
+
def closed?
|
50
|
+
# check @monitor exists, avoid unnecessary monitor created
|
51
|
+
return true unless @monitor
|
52
|
+
monitor.closed?
|
53
|
+
end
|
45
54
|
|
46
55
|
# this method return previous IO.select status
|
47
56
|
# should avoid to directly use
|
@@ -90,9 +99,9 @@ module LightIO::Watchers
|
|
90
99
|
end
|
91
100
|
|
92
101
|
def close
|
102
|
+
set_close_error
|
93
103
|
return if closed?
|
94
104
|
monitor.close
|
95
|
-
@error = IOError.new('closed stream')
|
96
105
|
callback_on_waiting
|
97
106
|
end
|
98
107
|
|
@@ -107,6 +116,10 @@ module LightIO::Watchers
|
|
107
116
|
end
|
108
117
|
|
109
118
|
private
|
119
|
+
def set_close_error
|
120
|
+
@error ||= IOError.new('closed stream')
|
121
|
+
end
|
122
|
+
|
110
123
|
def check_monitor(mode)
|
111
124
|
case mode
|
112
125
|
when :read
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lightio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jiang Jinyang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -153,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
153
|
version: '0'
|
154
154
|
requirements: []
|
155
155
|
rubyforge_project:
|
156
|
-
rubygems_version: 2.
|
156
|
+
rubygems_version: 2.7.3
|
157
157
|
signing_key:
|
158
158
|
specification_version: 4
|
159
159
|
summary: LightIO is a ruby networking library, that combines ruby fiber and fast IO
|