lightio 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/lib/lightio/library/io.rb +11 -1
- data/lib/lightio/library/socket.rb +75 -8
- data/lib/lightio/version.rb +1 -1
- data/lib/lightio/wrap.rb +68 -64
- 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: 9cba17ec9773ba60846027a6cff7134fe1d39c61
|
4
|
+
data.tar.gz: 5d0f6c807416b005ae82720145b226201035f1b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe88bd0666ea6e80af7730ed55050b797209d71e36779cd188305ab0782ee39a54853b40c34f36b9c10a159d78b0553504d54236b4a212e320d6568af9209569
|
7
|
+
data.tar.gz: 63874db77eef6d3b89a96ef1bce0ce2ff2304bad349b21338e57910aead782521a48d14af2db8bd2c134d089291b9e68985a0d7b695593076db4d2f7cd053217
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
data/lib/lightio/library/io.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
module LightIO::Library
|
3
3
|
class IO
|
4
|
-
include LightIO::Wrap::
|
4
|
+
include LightIO::Wrap::IOWrapper
|
5
5
|
wrap ::IO
|
6
6
|
|
7
7
|
extend Forwardable
|
@@ -33,6 +33,16 @@ module LightIO::Library
|
|
33
33
|
outbuf
|
34
34
|
end
|
35
35
|
|
36
|
+
def close(*args)
|
37
|
+
# close watcher before io closed
|
38
|
+
@io_watcher&.close
|
39
|
+
@io.close(*args)
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_io
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
36
46
|
class << self
|
37
47
|
def open(*args)
|
38
48
|
io = self.new(*args)
|
@@ -1,22 +1,89 @@
|
|
1
1
|
require 'socket'
|
2
|
+
|
2
3
|
module LightIO::Library
|
3
4
|
|
4
|
-
class
|
5
|
+
class Addrinfo
|
5
6
|
include LightIO::Wrap::Wrapper
|
7
|
+
wrap ::Addrinfo
|
8
|
+
|
9
|
+
module WrapperHelper
|
10
|
+
protected
|
11
|
+
def wrap_socket_method(method)
|
12
|
+
define_method method do |*args|
|
13
|
+
socket = Socket._wrap(@io.send(method, *args))
|
14
|
+
if block_given?
|
15
|
+
begin
|
16
|
+
yield socket
|
17
|
+
ensure
|
18
|
+
socket.close
|
19
|
+
end
|
20
|
+
else
|
21
|
+
socket
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def wrap_socket_methods(*methods)
|
27
|
+
methods.each {|m| wrap_socket_method(m)}
|
28
|
+
end
|
29
|
+
|
30
|
+
def wrap_addrinfo_return_method(method)
|
31
|
+
define_method method do |*args|
|
32
|
+
result = (@io || raw_class).send(method, *args)
|
33
|
+
if result.is_a?(raw_class)
|
34
|
+
_wrap(result)
|
35
|
+
elsif result.respond_to?(:map)
|
36
|
+
result.map {|r| _wrap(r)}
|
37
|
+
else
|
38
|
+
result
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def wrap_addrinfo_return_methods(*methods)
|
44
|
+
methods.each {|m| wrap_addrinfo_return_method(m)}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
extend WrapperHelper
|
49
|
+
|
50
|
+
wrap_socket_methods :bind, :connect, :connect_from, :connect_to, :listen
|
51
|
+
|
52
|
+
wrap_addrinfo_return_methods :family_addrinfo, :ipv6_to_ipv4
|
53
|
+
|
54
|
+
class << self
|
55
|
+
extend WrapperHelper
|
56
|
+
|
57
|
+
def foreach(*args, &block)
|
58
|
+
Addrinfo.getaddrinfo(*args).each(&block)
|
59
|
+
end
|
60
|
+
|
61
|
+
wrap_addrinfo_return_methods :getaddrinfo, :ip, :udp, :tcp, :unix
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class BasicSocket < IO
|
66
|
+
include LightIO::Wrap::IOWrapper
|
6
67
|
wrap ::BasicSocket
|
7
68
|
|
8
69
|
wrap_blocking_methods :recv, :recvmsg, :sendmsg
|
9
70
|
|
71
|
+
def shutdown(*args)
|
72
|
+
# close watcher before io shutdown
|
73
|
+
@io_watcher.close
|
74
|
+
@io.shutdown(*args)
|
75
|
+
end
|
76
|
+
|
10
77
|
class << self
|
11
78
|
def for_fd(fd)
|
12
|
-
|
79
|
+
self._wrap(raw_class.for_fd(fd))
|
13
80
|
end
|
14
81
|
end
|
15
82
|
end
|
16
83
|
|
17
84
|
class Socket < BasicSocket
|
18
85
|
include ::Socket::Constants
|
19
|
-
include LightIO::Wrap::
|
86
|
+
include LightIO::Wrap::IOWrapper
|
20
87
|
wrap ::Socket
|
21
88
|
|
22
89
|
wrap_blocking_methods :connect, :recvfrom
|
@@ -24,7 +91,7 @@ module LightIO::Library
|
|
24
91
|
## implement ::Socket instance methods
|
25
92
|
def accept
|
26
93
|
socket, addrinfo = wait_nonblock(:accept_nonblock)
|
27
|
-
[
|
94
|
+
[self.class._wrap(socket), Addrinfo._wrap(addrinfo)]
|
28
95
|
end
|
29
96
|
|
30
97
|
def sys_accept
|
@@ -61,7 +128,7 @@ module LightIO::Library
|
|
61
128
|
|
62
129
|
|
63
130
|
class IPSocket < BasicSocket
|
64
|
-
include LightIO::Wrap::
|
131
|
+
include LightIO::Wrap::IOWrapper
|
65
132
|
wrap ::IPSocket
|
66
133
|
|
67
134
|
class << self
|
@@ -70,19 +137,19 @@ module LightIO::Library
|
|
70
137
|
end
|
71
138
|
|
72
139
|
class TCPSocket < IPSocket
|
73
|
-
include LightIO::Wrap::
|
140
|
+
include LightIO::Wrap::IOWrapper
|
74
141
|
wrap ::TCPSocket
|
75
142
|
wrap_methods_run_in_threads_pool :gethostbyname
|
76
143
|
end
|
77
144
|
|
78
145
|
class TCPServer < TCPSocket
|
79
|
-
include LightIO::Wrap::
|
146
|
+
include LightIO::Wrap::IOWrapper
|
80
147
|
wrap ::TCPServer
|
81
148
|
|
82
149
|
## implement ::Socket instance methods
|
83
150
|
def accept
|
84
151
|
socket = wait_nonblock(:accept_nonblock)
|
85
|
-
|
152
|
+
TCPSocket._wrap(socket)
|
86
153
|
end
|
87
154
|
|
88
155
|
def sys_accept
|
data/lib/lightio/version.rb
CHANGED
data/lib/lightio/wrap.rb
CHANGED
@@ -1,36 +1,86 @@
|
|
1
1
|
module LightIO::Wrap
|
2
2
|
WRAPPERS = {}
|
3
|
+
RAW_IO = ::IO
|
4
|
+
|
5
|
+
# wrapper for normal ruby objects
|
3
6
|
module Wrapper
|
4
|
-
# wrap raw ruby
|
7
|
+
# wrap raw ruby objects
|
5
8
|
#
|
6
|
-
# @param [
|
9
|
+
# @param [Object] io raw ruby object, param name is 'io' just for consistent
|
7
10
|
def initialize(io=nil)
|
8
11
|
@io ||= io
|
9
|
-
@io_watcher ||= LightIO::Watchers::IO.new(@io)
|
10
12
|
end
|
11
13
|
|
12
14
|
def method_missing(method, *args)
|
13
15
|
@io.public_send(method, *args)
|
14
16
|
end
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
# both works in class scope and singleton class scope
|
19
|
+
module SingletonClassCommonMethods
|
20
|
+
protected
|
21
|
+
# run method in thread pool for performance
|
22
|
+
def wrap_methods_run_in_threads_pool(*args)
|
23
|
+
#TODO
|
24
|
+
end
|
20
25
|
end
|
21
26
|
|
22
|
-
|
23
|
-
#
|
24
|
-
|
25
|
-
|
27
|
+
module ClassMethods
|
28
|
+
# Wrap raw io objects
|
29
|
+
def _wrap(io)
|
30
|
+
# In case ruby stdlib return already patched Sockets, just do nothing
|
31
|
+
if io.is_a? self
|
32
|
+
io
|
33
|
+
else
|
34
|
+
# old new
|
35
|
+
obj = allocate
|
36
|
+
obj.send(:initialize, io)
|
37
|
+
obj
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# override new method, return wrapped class
|
42
|
+
def new(*args)
|
43
|
+
io = raw_class.new(*args)
|
44
|
+
_wrap(io)
|
45
|
+
end
|
46
|
+
|
47
|
+
include SingletonClassCommonMethods
|
48
|
+
|
49
|
+
protected
|
50
|
+
|
51
|
+
attr_reader :raw_class
|
52
|
+
|
53
|
+
# Set wrapped class
|
54
|
+
def wrap(raw_class)
|
55
|
+
@raw_class=raw_class
|
56
|
+
WRAPPERS[raw_class] = self
|
57
|
+
end
|
58
|
+
|
59
|
+
def method_missing(method, *args)
|
60
|
+
raw_class.public_send(method, *args)
|
61
|
+
end
|
26
62
|
end
|
27
63
|
|
28
|
-
|
29
|
-
|
30
|
-
|
64
|
+
class << self
|
65
|
+
def included(base)
|
66
|
+
base.send :extend, ClassMethods
|
67
|
+
base.singleton_class.send :extend, SingletonClassCommonMethods
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# wrapper for ruby io objects
|
73
|
+
module IOWrapper
|
74
|
+
include Wrapper
|
75
|
+
# wrap raw ruby io objects
|
76
|
+
#
|
77
|
+
# @param [IO, Socket] io raw ruby io object
|
78
|
+
def initialize(io=nil)
|
79
|
+
super
|
31
80
|
@io_watcher ||= LightIO::Watchers::IO.new(@io)
|
32
81
|
end
|
33
82
|
|
83
|
+
protected
|
34
84
|
# wait io nonblock method
|
35
85
|
#
|
36
86
|
# @param [Symbol] method method name, example: wait_nonblock
|
@@ -51,45 +101,16 @@ module LightIO::Wrap
|
|
51
101
|
else
|
52
102
|
return result
|
53
103
|
end
|
54
|
-
rescue
|
104
|
+
rescue RAW_IO::WaitReadable
|
55
105
|
@io_watcher.wait_readable
|
56
|
-
rescue
|
106
|
+
rescue RAW_IO::WaitWritable
|
57
107
|
@io_watcher.wait_writable
|
58
108
|
end
|
59
109
|
end
|
60
110
|
end
|
61
111
|
|
62
|
-
# both works in class scope and singleton class scope
|
63
|
-
module SingletonClassCommonMethods
|
64
|
-
protected
|
65
|
-
# run method in thread pool for performance
|
66
|
-
def wrap_methods_run_in_threads_pool(*args)
|
67
|
-
#TODO
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
112
|
module ClassMethods
|
72
|
-
|
73
|
-
def _wrap(io)
|
74
|
-
# In case ruby stdlib return already patched Sockets, just do nothing
|
75
|
-
if io.is_a? self
|
76
|
-
io
|
77
|
-
else
|
78
|
-
# old new
|
79
|
-
obj = allocate
|
80
|
-
obj.send(:initialize, io)
|
81
|
-
obj
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
# override new method, return wrapped class
|
86
|
-
def new(*args)
|
87
|
-
io = raw_class.new(*args)
|
88
|
-
_wrap(io)
|
89
|
-
end
|
90
|
-
|
91
|
-
include SingletonClassCommonMethods
|
92
|
-
|
113
|
+
include Wrapper::ClassMethods
|
93
114
|
protected
|
94
115
|
# wrap blocking method with "#{method}_nonblock"
|
95
116
|
#
|
@@ -103,29 +124,12 @@ module LightIO::Wrap
|
|
103
124
|
def wrap_blocking_methods(*methods, exception_symbol: true)
|
104
125
|
methods.each {|m| wrap_blocking_method(m, exception_symbol: exception_symbol)}
|
105
126
|
end
|
106
|
-
|
107
|
-
attr_reader :raw_class
|
108
|
-
|
109
|
-
# Set wrapped class
|
110
|
-
def wrap(raw_class)
|
111
|
-
@raw_class=raw_class
|
112
|
-
WRAPPERS[raw_class] = self
|
113
|
-
end
|
114
|
-
|
115
|
-
def method_missing(method, *args)
|
116
|
-
raw_class.public_send(method, *args)
|
117
|
-
end
|
118
127
|
end
|
119
128
|
|
120
129
|
class << self
|
121
|
-
def new_and_wrap(*args)
|
122
|
-
io = raw_class.new(*args)
|
123
|
-
_wrap(io)
|
124
|
-
end
|
125
|
-
|
126
130
|
def included(base)
|
131
|
+
Wrapper.included(base)
|
127
132
|
base.send :extend, ClassMethods
|
128
|
-
base.singleton_class.send :extend, SingletonClassCommonMethods
|
129
133
|
end
|
130
134
|
end
|
131
135
|
end
|
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.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jiang Jinyang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|