lightio 0.3.2 → 0.4.0.pre
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/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
|