zoidberg 0.1.8 → 0.1.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: df52de1159262a58d00a216caaa8fe027a77dd9b
4
- data.tar.gz: 6cfa6c993544ef1e5eac1e8ebbc441d229127028
3
+ metadata.gz: 2bbdb961e871a0119977fa6b936a00ba8c0799ec
4
+ data.tar.gz: 8c83222944c0a2a60f0452d02dc72ce5b6b51bf1
5
5
  SHA512:
6
- metadata.gz: 1a1428042644789759af29f18a7f91b9f4a4dd65a7aad27c965451ba2681f87730a2ad39b21efb1adbc34076ae032d759f11d25384aeb5923d468a6b29041b8e
7
- data.tar.gz: 5996f95418dc32387a87558bdf43ea02494726124ec1955702f61b21a7e7137fedf4dfe0772617287dc40ad4d2f1298603b58b6b80cbf88bd45c2d3f077fdb22
6
+ metadata.gz: d3e02732c39a3611c5e17224b6b27b6303c19fd7eeb884cf0215dec496b8d38a494ea322c1c4840d237831581afb70c17a74f422e0131f04d10ff08e310014d9
7
+ data.tar.gz: 7f9d18e3ad68bd304a00581a807b929e05d9c472a5761734bac8b525c232189c2dd40e38a3d25fdf767de12c3c5a00e064d6ff0cc00b8356b867b3a25670001a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ # v0.1.10
2
+ * Handle unexpected errors from asyncs while supervised
3
+ * Pool releases lock once worker has been aquired
4
+ * Provide better string generation of abort exceptions
5
+
1
6
  # v0.1.8
2
7
  * Fix to properly remove canceled actions
3
8
 
data/README.md CHANGED
@@ -4,10 +4,12 @@
4
4
 
5
5
  ## About
6
6
 
7
- Zoidberg is a small library attempting to provide synchronization
8
- and supervision without requiring any modifications to existing
9
- implementations. It is heavily inspired by Celluloid and while some
10
- APIs may look familiar they do not share a familiar implementation.
7
+ Zoidberg does a couple things. First, it can be a simple way to
8
+ provide implicit synchronization for thread safety in existing
9
+ code that is otherwise unsafe. Second, it can provide supervision
10
+ and pooling. This library is heavily inspired by Celluloid but,
11
+ while some APIs may look familiar, they do not share a familiar
12
+ implementation.
11
13
 
12
14
  ## Usage
13
15
 
@@ -120,6 +122,10 @@ and running it lots of times we get:
120
122
  So this is pretty neat. We had a class that was shown to not be thread
121
123
  safe. We tossed a module into that class. Now that class is thread safe.
122
124
 
125
+ ### Should I really do this?
126
+
127
+ Maybe?
128
+
123
129
  ## Features
124
130
 
125
131
  ### Implicit Locking
@@ -129,6 +135,39 @@ behavior can be short circuited if the actual instance creates a thread
129
135
  and calls a method on itself. Otherwise, all external access to the
130
136
  instance will be automatically synchronized. Nifty.
131
137
 
138
+ This synchronization behavior comes from the shells included within
139
+ Zoidberg. There are two styles of shells available:
140
+
141
+ #### `Zoidberg::SoftShell`
142
+
143
+ This is the default shell used when the generic `Zoidberg::Shell` module
144
+ is included. It will wrap the raw instance and synchronize requests to
145
+ the instance.
146
+
147
+ #### `Zoidberg::HardShell`
148
+
149
+ This shell is still in development and not fully supported yet. The
150
+ hard shell is an implementation that is more reflective of the actor
151
+ model with a single thread wrapping an instance and synchronizing access.
152
+
153
+ ### Supervision
154
+
155
+ Zoidberg can provide instance supervision. To enable supervision on a
156
+ class, include the module:
157
+
158
+ ```ruby
159
+
160
+ class Fubar
161
+ include Zoidberg::Supervise
162
+ end
163
+ ```
164
+
165
+ This will implicitly load the `Zoidberg::Shell` module and new instances
166
+ will be supervised. Supervision means Zoidberg will watch for unexpected
167
+ exceptions. What are "unexpected exceptions"? They are any exception raised
168
+ via `raise`. This will cause the instance to be torn down and a new instance
169
+ to be instantiated.
170
+
132
171
  ### Supervision
133
172
 
134
173
  Zoidberg provides lazy supervision. There is no single supervisor. Instead
data/lib/zoidberg/pool.rb CHANGED
@@ -78,7 +78,8 @@ module Zoidberg
78
78
  # Used to proxy request to worker
79
79
  def method_missing(*args, &block)
80
80
  worker = _zoidberg_free_worker
81
- defer{ worker.send(*args, &block) }
81
+ current_self._release_lock!
82
+ worker.send(*args, &block)
82
83
  end
83
84
 
84
85
  # Find or wait for a free worker
@@ -74,7 +74,13 @@ module Zoidberg
74
74
  # @return [TrueClas]
75
75
  def _aquire_lock!
76
76
  if(@_lock)
77
- @_lock.lock unless @_locker == ::Thread.current
77
+ if(::ENV['ZOIDBERG_DEBUG'] == 'true')
78
+ ::Timeout.timeout(::ENV.fetch('ZOIDBERG_DEBUG_TIMEOUT', 10).to_i) do
79
+ @_lock.lock unless @_locker == ::Thread.current
80
+ end
81
+ else
82
+ @_lock.lock unless @_locker == ::Thread.current
83
+ end
78
84
  @_locker = ::Thread.current
79
85
  @_locker_count += 1
80
86
  _zoidberg_signal(:locked)
@@ -10,16 +10,19 @@ module Zoidberg
10
10
 
11
11
  class AsyncProxy
12
12
  attr_reader :target
13
- def initialize(instance)
13
+ attr_reader :origin_proxy
14
+ def initialize(instance, proxy)
14
15
  @target = instance
16
+ @origin_proxy = proxy
15
17
  end
16
18
  def method_missing(*args, &block)
17
19
  target._zoidberg_thread(
18
20
  Thread.new{
19
21
  begin
20
22
  target.send(*args, &block)
21
- rescue Exception => e
22
- target._zoidberg_proxy.send(:raise, e)
23
+ rescue StandardError, ScriptError => e
24
+ origin_proxy._zoidberg_unexpected_error(e)
25
+ raise
23
26
  end
24
27
  }
25
28
  )
@@ -38,7 +41,7 @@ module Zoidberg
38
41
  result = yield if block_given?
39
42
  _zoidberg_proxy._aquire_lock!
40
43
  result
41
- rescue Exception => e
44
+ rescue ::StandardError, ::ScriptError => e
42
45
  _zoidberg_proxy._aquire_lock!
43
46
  raise e
44
47
  end
@@ -52,15 +55,27 @@ module Zoidberg
52
55
  if(block_given?)
53
56
  unless(locked)
54
57
  thread = ::Thread.new do
55
- self.instance_exec(&block)
58
+ begin
59
+ self.instance_exec(&block)
60
+ rescue ::StandardError, ::ScriptError => e
61
+ current_self._zoidberg_unexpected_error(e)
62
+ raise
63
+ end
56
64
  end
57
65
  else
58
- thread = ::Thread.new{ current_self.instance_exec(&block) }
66
+ thread = ::Thread.new do
67
+ begin
68
+ current_self.instance_exec(&block)
69
+ rescue ::StandardError, ::ScriptError => e
70
+ current_self._zoidberg_unexpected_error(e)
71
+ raise
72
+ end
73
+ end
59
74
  end
60
75
  _zoidberg_thread(thread)
61
76
  nil
62
77
  else
63
- ::Zoidberg::SoftShell::AsyncProxy.new(locked ? current_self : self)
78
+ ::Zoidberg::SoftShell::AsyncProxy.new(locked ? current_self : self, current_self)
64
79
  end
65
80
  end
66
81
 
@@ -232,7 +247,7 @@ module Zoidberg
232
247
  # @param arg [Object] optional argument to transmit
233
248
  # @return [TrueClass, FalseClass]
234
249
  def signal(name, arg=nil)
235
- current_self._zoidberg_signal_interface.signal(*[name, arg].compact)
250
+ _zoidberg_signal_interface.signal(*[name, arg].compact)
236
251
  end
237
252
 
238
253
  # Broadcast a signal to all waiters
@@ -6,6 +6,14 @@ module Zoidberg
6
6
  # Customized exception type to wrap allowed errors
7
7
  class AbortException < StandardError
8
8
  attr_accessor :original_exception
9
+
10
+ def to_s
11
+ if(original_exception)
12
+ "#{original_exception.class}: #{original_exception}"
13
+ else
14
+ super
15
+ end
16
+ end
9
17
  end
10
18
 
11
19
  module InstanceMethods
@@ -16,6 +24,9 @@ module Zoidberg
16
24
  # @param e [Exception]
17
25
  # @raises [AbortException]
18
26
  def abort(e)
27
+ unless(e.is_a?(::Exception))
28
+ e = StandardError.new(e)
29
+ end
19
30
  new_e = ::Zoidberg::Supervise::AbortException.new
20
31
  new_e.original_exception = e
21
32
  ::Kernel.raise new_e
@@ -1,4 +1,4 @@
1
1
  module Zoidberg
2
2
  # Current library version
3
- VERSION = Gem::Version.new('0.1.8')
3
+ VERSION = Gem::Version.new('0.1.10')
4
4
  end
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.8
4
+ version: 0.1.10
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-09-23 00:00:00.000000000 Z
11
+ date: 2015-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bogo