lightio 0.3.2 → 0.4.0.pre
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 +5 -3
- data/Rakefile +9 -1
- data/examples/echo_server.rb +2 -0
- data/examples/echo_server_with_raw_socket.rb +2 -1
- data/examples/monkey_patch.rb +26 -0
- data/lib/lightio.rb +3 -0
- data/lib/lightio/core/beam.rb +1 -1
- data/lib/lightio/core/ioloop.rb +11 -5
- data/lib/lightio/library.rb +2 -0
- data/lib/lightio/library/base.rb +96 -0
- data/lib/lightio/library/file.rb +9 -0
- data/lib/lightio/library/io.rb +14 -85
- data/lib/lightio/library/queue.rb +4 -1
- data/lib/lightio/library/sized_queue.rb +3 -0
- data/lib/lightio/library/socket.rb +93 -127
- data/lib/lightio/library/thread.rb +153 -122
- data/lib/lightio/library/threads_wait.rb +7 -8
- data/lib/lightio/module.rb +11 -0
- data/lib/lightio/module/base.rb +40 -0
- data/lib/lightio/module/file.rb +10 -0
- data/lib/lightio/module/io.rb +88 -0
- data/lib/lightio/module/socket.rb +165 -0
- data/lib/lightio/module/thread.rb +76 -0
- data/lib/lightio/module/threads_wait.rb +13 -0
- data/lib/lightio/monkey.rb +150 -0
- data/lib/lightio/raw_proxy.rb +24 -0
- data/lib/lightio/version.rb +1 -1
- data/lib/lightio/wrap.rb +16 -63
- data/lightio.gemspec +2 -0
- metadata +17 -6
- data/lib/lightio/library/mutex.rb +0 -93
@@ -0,0 +1,24 @@
|
|
1
|
+
# helper for access raw ruby object methods
|
2
|
+
# use it to avoid monkey patch affect
|
3
|
+
|
4
|
+
module LightIO
|
5
|
+
class RawProxy
|
6
|
+
def initialize(klass, methods: [], instance_methods: [])
|
7
|
+
@klass = klass
|
8
|
+
@methods = methods.map {|method| [method.to_sym, klass.method(method)]}.to_h
|
9
|
+
@instance_methods = instance_methods.map {|method| [method.to_sym, klass.instance_method(method)]}.to_h
|
10
|
+
end
|
11
|
+
|
12
|
+
def send(method, *args)
|
13
|
+
method = method.to_sym
|
14
|
+
return method_missing(method, *args) unless @methods.key?(method)
|
15
|
+
@methods[method].call(*args)
|
16
|
+
end
|
17
|
+
|
18
|
+
def instance_send(instance, method, *args)
|
19
|
+
method = method.to_sym
|
20
|
+
return method_missing(method, *args) unless @instance_methods.key?(method)
|
21
|
+
@instance_methods[method].bind(instance).call(*args)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/lightio/version.rb
CHANGED
data/lib/lightio/wrap.rb
CHANGED
@@ -1,22 +1,11 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
RAW_IO = ::IO
|
1
|
+
# wrap module
|
2
|
+
# wrap ruby objects, and make it work with lightio
|
4
3
|
|
4
|
+
module LightIO::Wrap
|
5
5
|
# wrapper for normal ruby objects
|
6
6
|
module Wrapper
|
7
|
-
# wrap raw ruby objects
|
8
|
-
#
|
9
|
-
# @param [Object] io raw ruby object, param name is 'io' just for consistent
|
10
|
-
def initialize(io=nil)
|
11
|
-
@io ||= io
|
12
|
-
end
|
13
|
-
|
14
|
-
def method_missing(method, *args)
|
15
|
-
@io.public_send(method, *args)
|
16
|
-
end
|
17
|
-
|
18
7
|
# both works in class scope and singleton class scope
|
19
|
-
module
|
8
|
+
module HelperMethods
|
20
9
|
protected
|
21
10
|
# run method in thread pool for performance
|
22
11
|
def wrap_methods_run_in_threads_pool(*args)
|
@@ -24,60 +13,20 @@ module LightIO::Wrap
|
|
24
13
|
end
|
25
14
|
end
|
26
15
|
|
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
|
62
|
-
end
|
63
|
-
|
64
16
|
class << self
|
65
17
|
def included(base)
|
66
|
-
base.send :extend,
|
67
|
-
base.singleton_class.send :extend, SingletonClassCommonMethods
|
18
|
+
base.send :extend, HelperMethods
|
68
19
|
end
|
69
20
|
end
|
70
21
|
end
|
71
22
|
|
72
23
|
# wrapper for ruby io objects
|
73
24
|
module IOWrapper
|
74
|
-
include Wrapper
|
75
25
|
# wrap raw ruby io objects
|
76
26
|
#
|
77
27
|
# @param [IO, Socket] io raw ruby io object
|
78
|
-
def initialize(
|
79
|
-
super
|
80
|
-
@io_watcher ||= LightIO::Watchers::IO.new(@io)
|
28
|
+
def initialize(*args)
|
29
|
+
@obj ||= super
|
81
30
|
end
|
82
31
|
|
83
32
|
protected
|
@@ -87,20 +36,24 @@ module LightIO::Wrap
|
|
87
36
|
# @param [args] args arguments pass to method
|
88
37
|
def wait_nonblock(method, *args)
|
89
38
|
loop do
|
90
|
-
result =
|
39
|
+
result = __send__(method, *args, exception: false)
|
91
40
|
case result
|
92
41
|
when :wait_readable
|
93
|
-
|
42
|
+
io_watcher.wait_readable
|
94
43
|
when :wait_writable
|
95
|
-
|
44
|
+
io_watcher.wait_writable
|
96
45
|
else
|
97
46
|
return result
|
98
47
|
end
|
99
48
|
end
|
100
49
|
end
|
101
50
|
|
51
|
+
def io_watcher
|
52
|
+
@io_watcher ||= LightIO::Watchers::IO.new(@obj)
|
53
|
+
end
|
54
|
+
|
102
55
|
module ClassMethods
|
103
|
-
include Wrapper::ClassMethods
|
56
|
+
# include Wrapper::ClassMethods
|
104
57
|
protected
|
105
58
|
# wrap blocking method with "#{method}_nonblock"
|
106
59
|
#
|
@@ -118,8 +71,8 @@ module LightIO::Wrap
|
|
118
71
|
|
119
72
|
class << self
|
120
73
|
def included(base)
|
121
|
-
Wrapper.included(base)
|
122
74
|
base.send :extend, ClassMethods
|
75
|
+
base.send :include, Wrapper
|
123
76
|
end
|
124
77
|
end
|
125
78
|
end
|
data/lightio.gemspec
CHANGED
@@ -14,6 +14,8 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.homepage = "https://github.com/jjyr/lightio"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
17
|
+
spec.required_ruby_version = '>= 2.3.4'
|
18
|
+
|
17
19
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
20
|
f.match(%r{^(test|spec|features)/})
|
19
21
|
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.
|
4
|
+
version: 0.4.0.pre
|
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-01-
|
11
|
+
date: 2018-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- examples/beams.rb
|
93
93
|
- examples/echo_server.rb
|
94
94
|
- examples/echo_server_with_raw_socket.rb
|
95
|
+
- examples/monkey_patch.rb
|
95
96
|
- lib/lightio.rb
|
96
97
|
- lib/lightio/core.rb
|
97
98
|
- lib/lightio/core/backend/nio.rb
|
@@ -101,15 +102,25 @@ files:
|
|
101
102
|
- lib/lightio/core/light_fiber.rb
|
102
103
|
- lib/lightio/errors.rb
|
103
104
|
- lib/lightio/library.rb
|
105
|
+
- lib/lightio/library/base.rb
|
106
|
+
- lib/lightio/library/file.rb
|
104
107
|
- lib/lightio/library/io.rb
|
105
108
|
- lib/lightio/library/kernel_ext.rb
|
106
|
-
- lib/lightio/library/mutex.rb
|
107
109
|
- lib/lightio/library/queue.rb
|
108
110
|
- lib/lightio/library/sized_queue.rb
|
109
111
|
- lib/lightio/library/socket.rb
|
110
112
|
- lib/lightio/library/thread.rb
|
111
113
|
- lib/lightio/library/threads_wait.rb
|
112
114
|
- lib/lightio/library/timeout.rb
|
115
|
+
- lib/lightio/module.rb
|
116
|
+
- lib/lightio/module/base.rb
|
117
|
+
- lib/lightio/module/file.rb
|
118
|
+
- lib/lightio/module/io.rb
|
119
|
+
- lib/lightio/module/socket.rb
|
120
|
+
- lib/lightio/module/thread.rb
|
121
|
+
- lib/lightio/module/threads_wait.rb
|
122
|
+
- lib/lightio/monkey.rb
|
123
|
+
- lib/lightio/raw_proxy.rb
|
113
124
|
- lib/lightio/version.rb
|
114
125
|
- lib/lightio/watchers.rb
|
115
126
|
- lib/lightio/watchers/io.rb
|
@@ -130,12 +141,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
141
|
requirements:
|
131
142
|
- - ">="
|
132
143
|
- !ruby/object:Gem::Version
|
133
|
-
version:
|
144
|
+
version: 2.3.4
|
134
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
146
|
requirements:
|
136
|
-
- - "
|
147
|
+
- - ">"
|
137
148
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
149
|
+
version: 1.3.1
|
139
150
|
requirements: []
|
140
151
|
rubyforge_project:
|
141
152
|
rubygems_version: 2.6.11
|
@@ -1,93 +0,0 @@
|
|
1
|
-
require_relative 'queue'
|
2
|
-
|
3
|
-
module LightIO::Library
|
4
|
-
class Thread
|
5
|
-
class Mutex
|
6
|
-
def initialize
|
7
|
-
@queue = LightIO::Library::Queue.new
|
8
|
-
@queue << true
|
9
|
-
@locked_thread = nil
|
10
|
-
end
|
11
|
-
|
12
|
-
def lock
|
13
|
-
raise ThreadError, "deadlock; recursive locking" if owner?
|
14
|
-
@queue.pop
|
15
|
-
@locked_thread = LightIO::Thread.current
|
16
|
-
self
|
17
|
-
end
|
18
|
-
|
19
|
-
def unlock
|
20
|
-
raise ThreadError, "Attempt to unlock a mutex which is not locked" unless owner?
|
21
|
-
@locked_thread = nil
|
22
|
-
@queue << true
|
23
|
-
self
|
24
|
-
end
|
25
|
-
|
26
|
-
def locked?
|
27
|
-
!@locked_thread.nil?
|
28
|
-
end
|
29
|
-
|
30
|
-
def owner?
|
31
|
-
@locked_thread == LightIO::Thread.current
|
32
|
-
end
|
33
|
-
|
34
|
-
def sleep(timeout=nil)
|
35
|
-
unlock
|
36
|
-
LightIO.sleep(timeout)
|
37
|
-
lock
|
38
|
-
end
|
39
|
-
|
40
|
-
def synchronize
|
41
|
-
raise ThreadError, 'must be called with a block' unless block_given?
|
42
|
-
lock
|
43
|
-
begin
|
44
|
-
yield
|
45
|
-
ensure
|
46
|
-
unlock
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def try_lock
|
51
|
-
if @locked_thread.nil?
|
52
|
-
lock
|
53
|
-
true
|
54
|
-
else
|
55
|
-
false
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
class ConditionVariable
|
61
|
-
def initialize
|
62
|
-
@queue = LightIO::Library::Queue.new
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
def broadcast
|
67
|
-
signal until @queue.num_waiting == 0
|
68
|
-
self
|
69
|
-
end
|
70
|
-
|
71
|
-
def signal
|
72
|
-
@queue << true unless @queue.num_waiting == 0
|
73
|
-
self
|
74
|
-
end
|
75
|
-
|
76
|
-
def wait(mutex, timeout=nil)
|
77
|
-
mutex.unlock
|
78
|
-
begin
|
79
|
-
LightIO::Library::Timeout.timeout(timeout) do
|
80
|
-
@queue.pop
|
81
|
-
end
|
82
|
-
rescue Timeout::Error
|
83
|
-
nil
|
84
|
-
end
|
85
|
-
mutex.lock
|
86
|
-
self
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
Mutex = Thread::Mutex
|
92
|
-
ConditionVariable = Thread::ConditionVariable
|
93
|
-
end
|