zoidberg 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|