zoidberg 0.1.10 → 0.1.12
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/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
|