zoidberg 0.1.10 → 0.1.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/zoidberg.rb +4 -0
- data/lib/zoidberg/pool.rb +2 -2
- data/lib/zoidberg/proxy.rb +38 -13
- data/lib/zoidberg/proxy/liberated.rb +49 -19
- data/lib/zoidberg/shell.rb +22 -12
- data/lib/zoidberg/version.rb +1 -1
- 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: 99176e505b497b0889a91f059c260a8b1ef45645
|
4
|
+
data.tar.gz: 52260a78198f95b9babc69b92af2ac00e43e9769
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6823ccd0afece4a93c2b4533dc301ffe75bc8344d4bba9409428cfedd8d10d5930f11a67c119accc05f4384cee6ae56b85d4891b938011c87f781acff22e971c
|
7
|
+
data.tar.gz: 7fd4eb56fbdf12be7e007f7fabf1cba8e6b8c850b3de906432330d89f559738c2a9d2d0b7038f3024d55fe4e4e1cc57515b69c1fa20adfbdd3ae3f1b145d1f9e
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# v0.1.12
|
2
|
+
* Move event signal to abstract proxy
|
3
|
+
* Update timeout library usage
|
4
|
+
* Remove defer usage fetching worker within pool
|
5
|
+
* Clean locking usage to prevent miscounts
|
6
|
+
* Fix async style locking to ensure expected behavior
|
7
|
+
|
1
8
|
# v0.1.10
|
2
9
|
* Handle unexpected errors from asyncs while supervised
|
3
10
|
* Pool releases lock once worker has been aquired
|
data/lib/zoidberg.rb
CHANGED
data/lib/zoidberg/pool.rb
CHANGED
@@ -86,8 +86,8 @@ module Zoidberg
|
|
86
86
|
#
|
87
87
|
# @return [Object]
|
88
88
|
def _zoidberg_free_worker
|
89
|
-
|
90
|
-
|
89
|
+
unless(worker = _workers.detect(&:_zoidberg_available?))
|
90
|
+
until((worker = _signal.wait_for(:unlocked))._zoidberg_available?); end
|
91
91
|
end
|
92
92
|
worker
|
93
93
|
end
|
data/lib/zoidberg/proxy.rb
CHANGED
@@ -69,13 +69,17 @@ module Zoidberg
|
|
69
69
|
end
|
70
70
|
|
71
71
|
# @return [TrueClass]
|
72
|
-
def _aquire_lock!
|
73
|
-
true
|
72
|
+
def _aquire_lock!(&block)
|
73
|
+
result = block ? block.call : true
|
74
|
+
_zoidberg_signal(:locked)
|
75
|
+
result
|
74
76
|
end
|
75
77
|
|
76
78
|
# @return [TrueClass]
|
77
|
-
def _release_lock!
|
78
|
-
true
|
79
|
+
def _release_lock!(&block)
|
80
|
+
result = block ? block.call : true
|
81
|
+
_zoidberg_signal(:unlocked, self) if _zoidberg_available?
|
82
|
+
result
|
79
83
|
end
|
80
84
|
|
81
85
|
# @return [TrueClass, FalseClass] currently unlocked
|
@@ -105,9 +109,9 @@ module Zoidberg
|
|
105
109
|
#
|
106
110
|
# @param sig [Symbol]
|
107
111
|
# @return [TrueClass, FalseClass] signal was sent
|
108
|
-
def _zoidberg_signal(
|
112
|
+
def _zoidberg_signal(*args)
|
109
113
|
if(@_zoidberg_signal)
|
110
|
-
@_zoidberg_signal.signal(
|
114
|
+
@_zoidberg_signal.signal(*args)
|
111
115
|
true
|
112
116
|
else
|
113
117
|
false
|
@@ -162,13 +166,16 @@ module Zoidberg
|
|
162
166
|
end
|
163
167
|
_zoidberg_destroy!
|
164
168
|
_aquire_lock!
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
_raw_instance.restarted!
|
169
|
+
begin
|
170
|
+
args = _build_args.dup
|
171
|
+
inst = args.shift.unshelled_new(*args.first, &args.last)
|
172
|
+
_zoidberg_set_instance(inst)
|
173
|
+
if(_raw_instance.respond_to?(:restarted!))
|
174
|
+
_raw_instance.restarted!
|
175
|
+
end
|
176
|
+
ensure
|
177
|
+
_release_lock!
|
170
178
|
end
|
171
|
-
_release_lock!
|
172
179
|
end
|
173
180
|
true
|
174
181
|
end
|
@@ -188,7 +195,7 @@ module Zoidberg
|
|
188
195
|
_raw_instance.terminate(error)
|
189
196
|
end
|
190
197
|
end
|
191
|
-
death_from_above = ::Proc.new do
|
198
|
+
death_from_above = ::Proc.new do |*_|
|
192
199
|
::Kernel.raise ::Zoidberg::DeadException.new('Instance in terminated state!')
|
193
200
|
end
|
194
201
|
death_from_above_display = ::Proc.new do
|
@@ -219,6 +226,24 @@ module Zoidberg
|
|
219
226
|
self
|
220
227
|
end
|
221
228
|
|
229
|
+
# Override to directly output object stringification
|
230
|
+
def to_s
|
231
|
+
_raw_instance.to_s
|
232
|
+
end
|
233
|
+
|
234
|
+
# Override to directly output object inspection
|
235
|
+
def inspect
|
236
|
+
_raw_instance.inspect
|
237
|
+
end
|
238
|
+
|
239
|
+
def signal(*args)
|
240
|
+
_raw_instance.signal(*args)
|
241
|
+
end
|
242
|
+
|
243
|
+
def async(*args, &block)
|
244
|
+
_raw_instance.async(*args, &block)
|
245
|
+
end
|
246
|
+
|
222
247
|
end
|
223
248
|
end
|
224
249
|
|
@@ -31,10 +31,27 @@ module Zoidberg
|
|
31
31
|
@_accessing_threads << ::Thread.current
|
32
32
|
begin
|
33
33
|
_aquire_lock!
|
34
|
+
@got_lock = true
|
34
35
|
if(::ENV['ZOIDBERG_TESTING'])
|
35
|
-
::
|
36
|
-
|
37
|
-
|
36
|
+
timer = ::Thread.new(::Thread.current) do |origin|
|
37
|
+
begin
|
38
|
+
time = ::ENV.fetch('ZOIDBERG_TESTING_TIMEOUT', 5).to_i
|
39
|
+
::Timeout.timeout(time) do
|
40
|
+
::Kernel.sleep(time)
|
41
|
+
end
|
42
|
+
nil
|
43
|
+
rescue => error
|
44
|
+
error
|
45
|
+
end
|
46
|
+
end
|
47
|
+
res = @_raw_instance.__send__(*args, &block)
|
48
|
+
if(timer.alive?)
|
49
|
+
timer.kill
|
50
|
+
else
|
51
|
+
val = timer.value
|
52
|
+
if(val.is_a?(Exception))
|
53
|
+
raise val
|
54
|
+
end
|
38
55
|
end
|
39
56
|
else
|
40
57
|
res = @_raw_instance.__send__(*args, &block)
|
@@ -51,9 +68,11 @@ module Zoidberg
|
|
51
68
|
::Kernel.raise e
|
52
69
|
end
|
53
70
|
ensure
|
54
|
-
|
55
|
-
|
56
|
-
|
71
|
+
if(@got_lock)
|
72
|
+
_release_lock!
|
73
|
+
t_idx = @_accessing_threads.index(::Thread.current)
|
74
|
+
@_accessing_threads.delete_at(t_idx) if t_idx
|
75
|
+
end
|
57
76
|
end
|
58
77
|
res
|
59
78
|
end
|
@@ -68,41 +87,52 @@ module Zoidberg
|
|
68
87
|
!_zoidberg_locked?
|
69
88
|
end
|
70
89
|
|
90
|
+
# Register a running thread for this instance. Registered
|
91
|
+
# threads are tracked and killed on cleanup
|
92
|
+
#
|
93
|
+
# @param thread [Thread]
|
94
|
+
# @return [TrueClass]
|
95
|
+
def _zoidberg_thread(thread)
|
96
|
+
_raw_threads[self.object_id].push(thread)
|
97
|
+
true
|
98
|
+
end
|
99
|
+
|
71
100
|
# Aquire the lock to access real instance. If already locked, will
|
72
101
|
# wait until lock can be aquired.
|
73
102
|
#
|
74
103
|
# @return [TrueClas]
|
75
104
|
def _aquire_lock!
|
76
|
-
|
77
|
-
if(
|
78
|
-
|
105
|
+
super do
|
106
|
+
if(@_lock)
|
107
|
+
if(::ENV['ZOIDBERG_DEBUG'] == 'true')
|
108
|
+
::Timeout.timeout(::ENV.fetch('ZOIDBERG_DEBUG_TIMEOUT', 10).to_i) do
|
109
|
+
@_lock.lock unless @_locker == ::Thread.current
|
110
|
+
end
|
111
|
+
else
|
79
112
|
@_lock.lock unless @_locker == ::Thread.current
|
80
113
|
end
|
81
|
-
|
82
|
-
@
|
114
|
+
@_locker = ::Thread.current
|
115
|
+
@_locker_count += 1
|
83
116
|
end
|
84
|
-
|
85
|
-
@_locker_count += 1
|
86
|
-
_zoidberg_signal(:locked)
|
117
|
+
true
|
87
118
|
end
|
88
|
-
true
|
89
119
|
end
|
90
120
|
|
91
121
|
# Release the lock to access real instance
|
92
122
|
#
|
93
123
|
# @return [TrueClass]
|
94
124
|
def _release_lock!
|
95
|
-
|
96
|
-
if(@_locker == ::Thread.current)
|
125
|
+
super do
|
126
|
+
if(@_lock && @_locker == ::Thread.current)
|
97
127
|
@_locker_count -= 1
|
98
128
|
if(@_locker_count < 1)
|
99
129
|
@_locker = nil
|
100
130
|
@_lock.unlock if @_lock.locked?
|
101
131
|
end
|
132
|
+
else
|
133
|
+
false
|
102
134
|
end
|
103
|
-
_zoidberg_signal(:unlocked)
|
104
135
|
end
|
105
|
-
true
|
106
136
|
end
|
107
137
|
|
108
138
|
# Ensure any async threads are killed and accessing threads are
|
data/lib/zoidberg/shell.rb
CHANGED
@@ -9,20 +9,26 @@ module Zoidberg
|
|
9
9
|
module SoftShell
|
10
10
|
|
11
11
|
class AsyncProxy
|
12
|
+
attr_reader :locked
|
12
13
|
attr_reader :target
|
13
14
|
attr_reader :origin_proxy
|
14
|
-
def initialize(
|
15
|
-
@
|
15
|
+
def initialize(locked_async, proxy)
|
16
|
+
@locked = locked_async
|
16
17
|
@origin_proxy = proxy
|
18
|
+
@target = proxy._raw_instance
|
17
19
|
end
|
18
20
|
def method_missing(*args, &block)
|
19
21
|
target._zoidberg_thread(
|
20
22
|
Thread.new{
|
23
|
+
origin_proxy._aquire_lock! if locked
|
24
|
+
got_lock = locked
|
21
25
|
begin
|
22
26
|
target.send(*args, &block)
|
23
27
|
rescue StandardError, ScriptError => e
|
24
28
|
origin_proxy._zoidberg_unexpected_error(e)
|
25
29
|
raise
|
30
|
+
ensure
|
31
|
+
origin_proxy._release_lock! if got_lock
|
26
32
|
end
|
27
33
|
}
|
28
34
|
)
|
@@ -36,14 +42,14 @@ module Zoidberg
|
|
36
42
|
# @yield block to execute without lock
|
37
43
|
# @return [Object] result of block
|
38
44
|
def defer
|
39
|
-
_zoidberg_proxy._release_lock!
|
45
|
+
re_lock = _zoidberg_proxy._release_lock!
|
40
46
|
begin
|
41
47
|
result = yield if block_given?
|
42
|
-
_zoidberg_proxy._aquire_lock!
|
43
48
|
result
|
44
49
|
rescue ::StandardError, ::ScriptError => e
|
45
|
-
_zoidberg_proxy._aquire_lock!
|
46
50
|
raise e
|
51
|
+
ensure
|
52
|
+
_zoidberg_proxy._aquire_lock! if re_lock
|
47
53
|
end
|
48
54
|
end
|
49
55
|
|
@@ -58,24 +64,28 @@ module Zoidberg
|
|
58
64
|
begin
|
59
65
|
self.instance_exec(&block)
|
60
66
|
rescue ::StandardError, ::ScriptError => e
|
61
|
-
|
67
|
+
_zoidberg_proxy._zoidberg_unexpected_error(e)
|
62
68
|
raise
|
63
69
|
end
|
64
70
|
end
|
65
71
|
else
|
66
72
|
thread = ::Thread.new do
|
73
|
+
_zoidberg_proxy._aquire_lock!
|
67
74
|
begin
|
68
|
-
|
75
|
+
got_lock = true
|
76
|
+
self.instance_exec(&block)
|
69
77
|
rescue ::StandardError, ::ScriptError => e
|
70
|
-
|
78
|
+
_zoidberg_proxy._zoidberg_unexpected_error(e)
|
71
79
|
raise
|
80
|
+
ensure
|
81
|
+
_zoidberg_proxy._release_lock! if got_lock
|
72
82
|
end
|
73
83
|
end
|
74
84
|
end
|
75
85
|
_zoidberg_thread(thread)
|
76
86
|
nil
|
77
87
|
else
|
78
|
-
::Zoidberg::SoftShell::AsyncProxy.new(locked
|
88
|
+
::Zoidberg::SoftShell::AsyncProxy.new(locked, _zoidberg_proxy)
|
79
89
|
end
|
80
90
|
end
|
81
91
|
|
@@ -85,7 +95,7 @@ module Zoidberg
|
|
85
95
|
# @param thread [Thread]
|
86
96
|
# @return [TrueClass]
|
87
97
|
def _zoidberg_thread(thread)
|
88
|
-
_zoidberg_proxy.
|
98
|
+
_zoidberg_proxy._zoidberg_thread(thread)
|
89
99
|
true
|
90
100
|
end
|
91
101
|
|
@@ -255,7 +265,7 @@ module Zoidberg
|
|
255
265
|
# @param arg [Object] optional argument to transmit
|
256
266
|
# @return [TrueClass, FalseClass]
|
257
267
|
def broadcast(name, arg=nil)
|
258
|
-
|
268
|
+
_zoidberg_signal_interface.broadcast(*[name, arg].compact)
|
259
269
|
end
|
260
270
|
|
261
271
|
# Wait for a given signal
|
@@ -263,7 +273,7 @@ module Zoidberg
|
|
263
273
|
# @param name [String, Symbol] name of signal
|
264
274
|
# @return [Object]
|
265
275
|
def wait_for(name)
|
266
|
-
defer{
|
276
|
+
defer{ _zoidberg_signal_interface.wait_for(name) }
|
267
277
|
end
|
268
278
|
alias_method :wait, :wait_for
|
269
279
|
|
data/lib/zoidberg/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zoidberg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bogo
|