zoidberg 0.1.8 → 0.1.10

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