zoidberg 0.2.2 → 0.3.0
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 +3 -0
- data/lib/zoidberg.rb +24 -2
- data/lib/zoidberg/future.rb +5 -5
- data/lib/zoidberg/pool.rb +1 -1
- data/lib/zoidberg/proxy/liberated.rb +6 -32
- data/lib/zoidberg/shell.rb +21 -35
- data/lib/zoidberg/timer.rb +5 -0
- data/lib/zoidberg/version.rb +1 -1
- data/zoidberg.gemspec +2 -0
- metadata +31 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63955382f221d56234b75d3e1993cb559975d767
|
4
|
+
data.tar.gz: 3039f9fd4a011778e47f4f5aa49e8ba25adf5083
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34a88ecf7b4d6bd6c97d7199eac16a4f3dab30e3e1747d1be07049ec29e3924d48f3b520abcc95115d3a4272f0e9142b7c88bab994a1c5347183e9ce9dda5861
|
7
|
+
data.tar.gz: 8931326058903b2a82fc0b517bee6e22174a3037b444b6e4c2ae88807470170bb5a1a71eb2c4d26ca3d521a9685310e372a47129f141f0f46d3d10243a058d29
|
data/CHANGELOG.md
CHANGED
data/lib/zoidberg.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'bogo'
|
2
|
-
require 'thread'
|
3
2
|
require 'securerandom'
|
3
|
+
require 'concurrent'
|
4
|
+
require 'concurrent-edge'
|
5
|
+
|
4
6
|
require 'zoidberg/version'
|
5
7
|
|
6
8
|
# Why not Zoidberg!?
|
@@ -24,7 +26,9 @@ module Zoidberg
|
|
24
26
|
|
25
27
|
class << self
|
26
28
|
|
27
|
-
|
29
|
+
# @return [TrueClass, FalseClass]
|
30
|
+
attr_reader :signal_shutdown
|
31
|
+
# @return [Module]
|
28
32
|
attr_accessor :default_shell
|
29
33
|
|
30
34
|
# @return [Zoidberg::Logger]
|
@@ -48,10 +52,28 @@ module Zoidberg
|
|
48
52
|
SecureRandom.uuid
|
49
53
|
end
|
50
54
|
|
55
|
+
# Flag shutdown state
|
56
|
+
#
|
57
|
+
# @param val [Truthy, Falsey]
|
58
|
+
# @return [TrueClass, FalseClass]
|
59
|
+
def signal_shutdown=(val)
|
60
|
+
@signal_shutdown = !!val
|
61
|
+
# NOTE: Manually call registered at exit items to force
|
62
|
+
# global thread pools and related structures to be shut
|
63
|
+
# down. Wrapped in a thread to prevent locking issues
|
64
|
+
# when set within trap context
|
65
|
+
Thread.new{ Concurrent.const_get(:AtExit).run } if val
|
66
|
+
@signal_shutdown
|
67
|
+
end
|
68
|
+
|
69
|
+
# Reset shutdown state
|
70
|
+
#
|
71
|
+
# @return [FalseClass]
|
51
72
|
def signal_reset
|
52
73
|
self.signal_shutdown = false
|
53
74
|
end
|
54
75
|
|
76
|
+
# @return [TrueClass, FalseClass]
|
55
77
|
def in_shutdown?
|
56
78
|
!!self.signal_shutdown
|
57
79
|
end
|
data/lib/zoidberg/future.rb
CHANGED
@@ -4,21 +4,21 @@ module Zoidberg
|
|
4
4
|
# Perform action and fetch result in the future
|
5
5
|
class Future
|
6
6
|
|
7
|
-
# @return [
|
8
|
-
attr_reader :
|
7
|
+
# @return [Concurrent::Future] underlying thread running task
|
8
|
+
attr_reader :future
|
9
9
|
|
10
10
|
# Create a new instance
|
11
11
|
#
|
12
12
|
# @yield block to execute
|
13
13
|
# @return [self]
|
14
14
|
def initialize(&block)
|
15
|
-
@
|
15
|
+
@future = Concurrent::Future.execute(&block)
|
16
16
|
end
|
17
17
|
|
18
18
|
# @return [Object] result value
|
19
19
|
def value
|
20
20
|
unless(@value)
|
21
|
-
@value = @
|
21
|
+
@value = @future.value
|
22
22
|
end
|
23
23
|
@value
|
24
24
|
end
|
@@ -27,7 +27,7 @@ module Zoidberg
|
|
27
27
|
#
|
28
28
|
# @return [TrueClass, FalseClass]
|
29
29
|
def available?
|
30
|
-
|
30
|
+
future.fulfilled?
|
31
31
|
end
|
32
32
|
|
33
33
|
end
|
data/lib/zoidberg/pool.rb
CHANGED
@@ -10,8 +10,8 @@ module Zoidberg
|
|
10
10
|
|
11
11
|
# @return [Thread] current owner of lock
|
12
12
|
attr_reader :_locker
|
13
|
-
# @return [
|
14
|
-
attr_reader :
|
13
|
+
# @return [Concurrent::CachedThreadPool]
|
14
|
+
attr_reader :_thread_pool
|
15
15
|
|
16
16
|
# Create a new proxy instance, new real instance, and link them
|
17
17
|
#
|
@@ -24,7 +24,7 @@ module Zoidberg
|
|
24
24
|
@_locker = nil
|
25
25
|
@_locker_count = 0
|
26
26
|
@_zoidberg_signal = nil
|
27
|
-
@
|
27
|
+
@_thread_pool = ::Concurrent::CachedThreadPool.new
|
28
28
|
@_supervised = klass.ancestors.include?(::Zoidberg::Supervise)
|
29
29
|
end
|
30
30
|
|
@@ -85,25 +85,6 @@ module Zoidberg
|
|
85
85
|
!_zoidberg_locked?
|
86
86
|
end
|
87
87
|
|
88
|
-
# Register a running thread for this instance. Registered
|
89
|
-
# threads are tracked and killed on cleanup
|
90
|
-
#
|
91
|
-
# @param thread [Thread]
|
92
|
-
# @return [TrueClass]
|
93
|
-
def _zoidberg_thread(thread)
|
94
|
-
_raw_threads.push(thread)
|
95
|
-
true
|
96
|
-
end
|
97
|
-
|
98
|
-
# Deregister a thread once it has completed
|
99
|
-
#
|
100
|
-
# @param thread [Thread]
|
101
|
-
# @return [TrueClass]
|
102
|
-
def _zoidberg_unthread(thread)
|
103
|
-
_raw_threads.delete(thread)
|
104
|
-
true
|
105
|
-
end
|
106
|
-
|
107
88
|
# Aquire the lock to access real instance. If already locked, will
|
108
89
|
# wait until lock can be aquired.
|
109
90
|
#
|
@@ -151,16 +132,9 @@ module Zoidberg
|
|
151
132
|
oid = _raw_instance.object_id
|
152
133
|
::Zoidberg.logger.debug "*** Destroying zoidberg instance #{object_string}"
|
153
134
|
super do
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
next if thread == ::Thread.current
|
158
|
-
thread.join(::Zoidberg::Proxy::Liberated::THREAD_KILL_AFTER)
|
159
|
-
if(thread.alive?)
|
160
|
-
::Zoidberg.logger.error "Failed to halt async thread, killing: #{thread.inspect}"
|
161
|
-
thread.kill
|
162
|
-
end
|
163
|
-
end
|
135
|
+
_thread_pool.shutdown
|
136
|
+
unless(_thread_pool.wait_for_termination(2))
|
137
|
+
_thread_pool.kill
|
164
138
|
end
|
165
139
|
@_accessing_threads.each do |thread|
|
166
140
|
if(thread.alive?)
|
data/lib/zoidberg/shell.rb
CHANGED
@@ -37,27 +37,24 @@ module Zoidberg
|
|
37
37
|
@target = proxy._raw_instance
|
38
38
|
end
|
39
39
|
def method_missing(*args, &block)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
got_lock = false
|
50
|
-
end
|
51
|
-
raise
|
52
|
-
rescue StandardError, ScriptError => e
|
53
|
-
origin_proxy._zoidberg_unexpected_error(e)
|
54
|
-
raise
|
55
|
-
ensure
|
56
|
-
origin_proxy._release_lock! if got_lock
|
57
|
-
origin_proxy._zoidberg_unthread(Thread.current)
|
40
|
+
origin_proxy._thread_pool << lambda{
|
41
|
+
got_lock = false
|
42
|
+
begin
|
43
|
+
origin_proxy._aquire_lock! if locked
|
44
|
+
got_lock = locked
|
45
|
+
target.send(*args, &block)
|
46
|
+
rescue Zoidberg::DeadException => e
|
47
|
+
if(e.origin_object_id == target.object_id)
|
48
|
+
got_lock = false
|
58
49
|
end
|
59
|
-
|
60
|
-
|
50
|
+
raise
|
51
|
+
rescue StandardError, ScriptError => e
|
52
|
+
origin_proxy._zoidberg_unexpected_error(e)
|
53
|
+
raise
|
54
|
+
ensure
|
55
|
+
origin_proxy._release_lock! if got_lock
|
56
|
+
end
|
57
|
+
}
|
61
58
|
nil
|
62
59
|
end
|
63
60
|
end
|
@@ -89,7 +86,7 @@ module Zoidberg
|
|
89
86
|
def async(locked=false, &block)
|
90
87
|
if(block_given?)
|
91
88
|
unless(locked)
|
92
|
-
|
89
|
+
_zoidberg_proxy._thread_pool << lambda{
|
93
90
|
begin
|
94
91
|
self.instance_exec(&block)
|
95
92
|
rescue Zoidberg::DeadException => e
|
@@ -103,9 +100,9 @@ module Zoidberg
|
|
103
100
|
_zoidberg_proxy._zoidberg_unexpected_error(e)
|
104
101
|
raise
|
105
102
|
end
|
106
|
-
|
103
|
+
}
|
107
104
|
else
|
108
|
-
|
105
|
+
_zoidberg_proxy._thread_pool << lambda{
|
109
106
|
_zoidberg_proxy._aquire_lock!
|
110
107
|
begin
|
111
108
|
got_lock = true
|
@@ -123,25 +120,14 @@ module Zoidberg
|
|
123
120
|
ensure
|
124
121
|
_zoidberg_proxy._release_lock! if got_lock
|
125
122
|
end
|
126
|
-
|
123
|
+
}
|
127
124
|
end
|
128
|
-
_zoidberg_thread(thread)
|
129
125
|
nil
|
130
126
|
else
|
131
127
|
::Zoidberg::SoftShell::AsyncProxy.new(locked, _zoidberg_proxy)
|
132
128
|
end
|
133
129
|
end
|
134
130
|
|
135
|
-
# Register a running thread for this instance. Registered
|
136
|
-
# threads are tracked and killed on cleanup
|
137
|
-
#
|
138
|
-
# @param thread [Thread]
|
139
|
-
# @return [TrueClass]
|
140
|
-
def _zoidberg_thread(thread)
|
141
|
-
_zoidberg_proxy._zoidberg_thread(thread)
|
142
|
-
true
|
143
|
-
end
|
144
|
-
|
145
131
|
# Provide a customized sleep behavior which will unlock the real
|
146
132
|
# instance while sleeping
|
147
133
|
#
|
data/lib/zoidberg/timer.rb
CHANGED
data/lib/zoidberg/version.rb
CHANGED
data/zoidberg.gemspec
CHANGED
@@ -11,6 +11,8 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.require_path = 'lib'
|
12
12
|
s.license = 'Apache 2.0'
|
13
13
|
s.add_runtime_dependency 'bogo'
|
14
|
+
s.add_runtime_dependency 'concurrent-ruby', '~> 1.0.0'
|
15
|
+
s.add_runtime_dependency 'concurrent-ruby-edge', '~> 0.2.0'
|
14
16
|
s.add_runtime_dependency 'mono_logger'
|
15
17
|
s.add_development_dependency 'pry'
|
16
18
|
s.add_development_dependency 'minitest'
|
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.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bogo
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: concurrent-ruby
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: concurrent-ruby-edge
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.2.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.2.0
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: mono_logger
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,3 +147,4 @@ signing_key:
|
|
119
147
|
specification_version: 4
|
120
148
|
summary: Why not?
|
121
149
|
test_files: []
|
150
|
+
has_rdoc:
|