Class: Zoidberg::Proxy
- Inherits:
- BasicObject
- Defined in:
- lib/zoidberg/proxy.rb,
lib/zoidberg/proxy.rb,
lib/zoidberg/proxy/confined.rb,
lib/zoidberg/proxy/liberated.rb
Overview
Instance proxy that filters requests to shelled instance
Defined Under Namespace
Constant Summary collapse
- @@__registry =
::Hash.new
Class Method Summary collapse
-
.inherited(klass) ⇒ Object
Setup proxy for proper scrubbing support.
-
.register(r_id, proxy) ⇒ Zoidberg::Proxy
Register the proxy a WeakRef is pointing to.
-
.registry ⇒ Hash
WeakRef -> Proxy mapping.
-
.scrub!(o_id) ⇒ Truthy, Falsey
Destroy the proxy referenced by the WeakRef with the provided ID.
Instance Method Summary collapse
- #_aquire_lock!(&block) ⇒ TrueClass
- #_release_lock!(&block) ⇒ TrueClass
-
#_zoidberg_available? ⇒ TrueClass, FalseClass
Currently unlocked.
-
#_zoidberg_destroy!(error = nil, &block) ⇒ TrueClass
Destroy the real instance.
-
#_zoidberg_handle_unexpected_error(error) ⇒ TrueClass
When real instance is being supervised, unexpected exceptions will force the real instance to be terminated and replaced with a fresh instance.
- #_zoidberg_link ⇒ Object, NilClass
- #_zoidberg_link=(inst) ⇒ Object
-
#_zoidberg_locked? ⇒ TrueClass, FalseClass
Currently locked.
- #_zoidberg_object ⇒ self
-
#_zoidberg_set_instance(inst) ⇒ NilClass
Set the raw instance into the proxy and link proxy to instance.
-
#_zoidberg_signal(*args) ⇒ TrueClass, FalseClass
Send a signal if the optional signal instance has been set.
-
#_zoidberg_signal=(signal) ⇒ Signal
Set an optional state signal instance.
-
#_zoidberg_signal_interface ⇒ Object
Initialize the signal instance if not.
- #_zoidberg_timer ⇒ Timer
-
#_zoidberg_unexpected_error(e) ⇒ Object
Properly handle an unexpected exception when encountered.
- #_zoidberg_unsupervise ⇒ Object
- #async(*args, &block) ⇒ Object
-
#initialize(*_) ⇒ Proxy
constructor
Abstract class gets no builder.
-
#inspect ⇒ Object
Override to directly output object inspection.
- #signal(*args) ⇒ Object
- #terminate ⇒ Object
-
#to_s ⇒ Object
Override to directly output object stringification.
Constructor Details
#initialize(*_) ⇒ Proxy
Abstract class gets no builder
52 53 54 |
# File 'lib/zoidberg/proxy.rb', line 52 def initialize(*_) raise NotImplementedError end |
Class Method Details
.inherited(klass) ⇒ Object
Setup proxy for proper scrubbing support
42 43 44 45 46 47 48 49 |
# File 'lib/zoidberg/proxy.rb', line 42 def self.inherited(klass) klass.class_eval do # @return [Array] arguments used to build real instance attr_accessor :_build_args # @return [Object] wrapped instance attr_reader :_raw_instance end end |
.register(r_id, proxy) ⇒ Zoidberg::Proxy
Register the proxy a WeakRef is pointing to
24 25 26 |
# File 'lib/zoidberg/proxy.rb', line 24 def register(r_id, proxy) @@__registry[r_id] = proxy end |
.registry ⇒ Hash
Returns WeakRef -> Proxy mapping.
15 16 17 |
# File 'lib/zoidberg/proxy.rb', line 15 def registry @@__registry end |
.scrub!(o_id) ⇒ Truthy, Falsey
Destroy the proxy referenced by the WeakRef with the provided ID
33 34 35 36 37 38 |
# File 'lib/zoidberg/proxy.rb', line 33 def scrub!(o_id) proxy = @@__registry.delete(o_id) if(proxy) proxy._zoidberg_destroy! end end |
Instance Method Details
#_aquire_lock!(&block) ⇒ TrueClass
76 77 78 79 80 |
# File 'lib/zoidberg/proxy.rb', line 76 def _aquire_lock!(&block) result = block ? block.call : true _zoidberg_signal(:locked) result end |
#_release_lock!(&block) ⇒ TrueClass
83 84 85 86 87 |
# File 'lib/zoidberg/proxy.rb', line 83 def _release_lock!(&block) result = block ? block.call : true _zoidberg_signal(:unlocked, self) if _zoidberg_available? result end |
#_zoidberg_available? ⇒ TrueClass, FalseClass
Returns currently unlocked.
90 91 92 |
# File 'lib/zoidberg/proxy.rb', line 90 def _zoidberg_available? !_zoidberg_locked? end |
#_zoidberg_destroy!(error = nil, &block) ⇒ TrueClass
Destroy the real instance. Will update all methods on real instance to raise exceptions noting it as terminated rendering it unusable. This is generally used with the supervise module but can be used on its own if desired.
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/zoidberg/proxy.rb', line 190 def _zoidberg_destroy!(error=nil, &block) unless(_raw_instance.respond_to?(:_zoidberg_destroyed)) if(::Zoidberg.in_shutdown?) @_zoidberg_timer.terminate if @_zoidberg_timer @_zoidberg_signal.terminate if @_zoidberg_signal end if(_raw_instance.respond_to?(:terminate)) begin if(_raw_instance.method(:terminate).arity == 0) _raw_instance.terminate else _raw_instance.terminate(error) end rescue => e ::Zoidberg.logger.error "Unexpected exception caught during terminatation of #{self}: #{e}" ::Zoidberg.logger.debug "#{e.class}: #{e}\n#{e.backtrace.join("\n")}" end end block.call if block oid = _raw_instance.object_id death_from_above = ::Proc.new do |*_| ::Kernel.raise ::Zoidberg::DeadException.new('Instance in terminated state!', oid) end death_from_above_display = ::Proc.new do "#<#{self.class.name}:TERMINATED>" end _raw_instance.instance_variables.each do |i_var| _raw_instance.remove_instance_variable(i_var) end ( _raw_instance.public_methods(false) + _raw_instance.protected_methods(false) + _raw_instance.private_methods(false) ).each do |m_name| next if m_name.to_sym == :alive? _raw_instance.send(:define_singleton_method, m_name, &death_from_above) end _raw_instance.send(:define_singleton_method, :to_s, &death_from_above_display) _raw_instance.send(:define_singleton_method, :inspect, &death_from_above_display) _raw_instance.send(:define_singleton_method, :_zoidberg_destroyed, ::Proc.new{ true }) end true end |
#_zoidberg_handle_unexpected_error(error) ⇒ TrueClass
When real instance is being supervised, unexpected exceptions will force the real instance to be terminated and replaced with a fresh instance.
If the real instance provides a #restart method that will be called instead of forcibly terminating the current real instance and rebuild a new instance.
If the real instance provides a #restarted! method, that method will be called on the newly created instance on replacement
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/zoidberg/proxy.rb', line 156 def _zoidberg_handle_unexpected_error(error) if(_raw_instance.respond_to?(:restart)) unless(::Zoidberg.in_shutdown?) begin _raw_instance.restart(error) return # short circuit rescue => e end end end _zoidberg_destroy! if(@_supervised && !::Zoidberg.in_shutdown?) _aquire_lock! begin args = _build_args.dup inst = args.shift.unshelled_new(*args.first, &args.last) _zoidberg_set_instance(inst) ::Zoidberg.logger.debug "Supervised instance has been rebuilt: #{inst}" if(_raw_instance.respond_to?(:restarted!)) _raw_instance.restarted! end ensure _release_lock! end end true end |
#_zoidberg_link ⇒ Object, NilClass
100 101 102 |
# File 'lib/zoidberg/proxy.rb', line 100 def _zoidberg_link @_zoidberg_link end |
#_zoidberg_link=(inst) ⇒ Object
95 96 97 |
# File 'lib/zoidberg/proxy.rb', line 95 def _zoidberg_link=(inst) @_zoidberg_link = inst end |
#_zoidberg_locked? ⇒ TrueClass, FalseClass
Returns currently locked.
71 72 73 |
# File 'lib/zoidberg/proxy.rb', line 71 def _zoidberg_locked? false end |
#_zoidberg_object ⇒ self
241 242 243 |
# File 'lib/zoidberg/proxy.rb', line 241 def _zoidberg_object self end |
#_zoidberg_set_instance(inst) ⇒ NilClass
Set the raw instance into the proxy and link proxy to instance
64 65 66 67 68 |
# File 'lib/zoidberg/proxy.rb', line 64 def _zoidberg_set_instance(inst) @_raw_instance = inst @_raw_instance._zoidberg_proxy(self) nil end |
#_zoidberg_signal(*args) ⇒ TrueClass, FalseClass
Send a signal if the optional signal instance has been set
116 117 118 119 120 121 122 123 |
# File 'lib/zoidberg/proxy.rb', line 116 def _zoidberg_signal(*args) if(@_zoidberg_signal) @_zoidberg_signal.signal(*args) true else false end end |
#_zoidberg_signal=(signal) ⇒ Signal
Set an optional state signal instance
108 109 110 |
# File 'lib/zoidberg/proxy.rb', line 108 def _zoidberg_signal=(signal) @_zoidberg_signal = signal end |
#_zoidberg_signal_interface ⇒ Object
Initialize the signal instance if not
264 265 266 267 268 269 |
# File 'lib/zoidberg/proxy.rb', line 264 def _zoidberg_signal_interface unless(@_zoidberg_signal) @_zoidberg_signal = ::Zoidberg::Signal.new(:cache_signals => self.class.option?(:cache_signals)) end @_zoidberg_signal end |
#_zoidberg_timer ⇒ Timer
272 273 274 275 276 277 |
# File 'lib/zoidberg/proxy.rb', line 272 def _zoidberg_timer unless(@_zoidberg_timer) @_zoidberg_timer = Timer.new end @_zoidberg_timer end |
#_zoidberg_unexpected_error(e) ⇒ Object
Properly handle an unexpected exception when encountered
128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/zoidberg/proxy.rb', line 128 def _zoidberg_unexpected_error(e) ::Zoidberg.logger.error "Unexpected exception: #{e.class} - #{e}" ::Zoidberg.logger.debug "#{e.class}: #{e}\n#{e.backtrace.join("\n")}" if(_zoidberg_link) if(_zoidberg_link.class.trap_exit) ::Zoidberg.logger.warn "Calling linked exit trapper #{@_raw_instance.class.name} -> #{_zoidberg_link.class}: #{e.class} - #{e}" _zoidberg_link.async.send( _zoidberg_link.class.trap_exit, @_raw_instance, e ) end else _zoidberg_handle_unexpected_error(e) end end |
#_zoidberg_unsupervise ⇒ Object
56 57 58 |
# File 'lib/zoidberg/proxy.rb', line 56 def _zoidberg_unsupervise @_supervised = false end |
#async(*args, &block) ⇒ Object
259 260 261 |
# File 'lib/zoidberg/proxy.rb', line 259 def async(*args, &block) _raw_instance.async(*args, &block) end |
#inspect ⇒ Object
Override to directly output object inspection
251 252 253 |
# File 'lib/zoidberg/proxy.rb', line 251 def inspect _raw_instance.inspect end |
#signal(*args) ⇒ Object
255 256 257 |
# File 'lib/zoidberg/proxy.rb', line 255 def signal(*args) _raw_instance.signal(*args) end |
#terminate ⇒ Object
234 235 236 237 |
# File 'lib/zoidberg/proxy.rb', line 234 def terminate _zoidberg_unsupervise _zoidberg_destroy! end |
#to_s ⇒ Object
Override to directly output object stringification
246 247 248 |
# File 'lib/zoidberg/proxy.rb', line 246 def to_s _raw_instance.to_s end |