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! ⇒ TrueClass
- #_release_lock! ⇒ TrueClass
-
#_zoidberg_available? ⇒ TrueClass, FalseClass
Currently unlocked.
-
#_zoidberg_destroy!(error = nil, &block) ⇒ TrueClass
(also: #terminate)
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(sig) ⇒ TrueClass, FalseClass
Send a signal if the optional signal instance has been set.
-
#_zoidberg_signal=(signal) ⇒ Signal
Set an optional state signal instance.
-
#_zoidberg_unexpected_error(e) ⇒ Object
Properly handle an unexpected exception when encountered.
-
#initialize(*_) ⇒ Proxy
constructor
Abstract class gets no builder.
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! ⇒ TrueClass
72 73 74 |
# File 'lib/zoidberg/proxy.rb', line 72 def _aquire_lock! true end |
#_release_lock! ⇒ TrueClass
77 78 79 |
# File 'lib/zoidberg/proxy.rb', line 77 def _release_lock! true end |
#_zoidberg_available? ⇒ TrueClass, FalseClass
Returns currently unlocked.
82 83 84 |
# File 'lib/zoidberg/proxy.rb', line 82 def _zoidberg_available? !_zoidberg_locked? end |
#_zoidberg_destroy!(error = nil, &block) ⇒ TrueClass Also known as: terminate
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.
182 183 184 185 186 187 188 189 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 |
# File 'lib/zoidberg/proxy.rb', line 182 def _zoidberg_destroy!(error=nil, &block) unless(_raw_instance.respond_to?(:_zoidberg_destroyed)) if(_raw_instance.respond_to?(:terminate)) if(_raw_instance.method(:terminate).arity == 0) _raw_instance.terminate else _raw_instance.terminate(error) end end death_from_above = ::Proc.new do ::Kernel.raise ::Zoidberg::DeadException.new('Instance in terminated state!') end death_from_above_display = ::Proc.new do "#<#{self.class.name}:TERMINATED>" end block.call if block _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
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/zoidberg/proxy.rb', line 154 def _zoidberg_handle_unexpected_error(error) unless(::Zoidberg.in_shutdown?) if(_raw_instance.respond_to?(:restart)) begin _raw_instance.restart(error) return # short circuit rescue => e end end _zoidberg_destroy! _aquire_lock! args = _build_args.dup inst = args.shift.unshelled_new(*args.first, &args.last) _zoidberg_set_instance(inst) if(_raw_instance.respond_to?(:restarted!)) _raw_instance.restarted! end _release_lock! end true end |
#_zoidberg_link ⇒ Object, NilClass
92 93 94 |
# File 'lib/zoidberg/proxy.rb', line 92 def _zoidberg_link @_zoidberg_link end |
#_zoidberg_link=(inst) ⇒ Object
87 88 89 |
# File 'lib/zoidberg/proxy.rb', line 87 def _zoidberg_link=(inst) @_zoidberg_link = inst end |
#_zoidberg_locked? ⇒ TrueClass, FalseClass
Returns currently locked.
67 68 69 |
# File 'lib/zoidberg/proxy.rb', line 67 def _zoidberg_locked? false end |
#_zoidberg_object ⇒ self
218 219 220 |
# File 'lib/zoidberg/proxy.rb', line 218 def _zoidberg_object self end |
#_zoidberg_set_instance(inst) ⇒ NilClass
Set the raw instance into the proxy and link proxy to instance
60 61 62 63 64 |
# File 'lib/zoidberg/proxy.rb', line 60 def _zoidberg_set_instance(inst) @_raw_instance = inst @_raw_instance._zoidberg_proxy(self) nil end |
#_zoidberg_signal(sig) ⇒ TrueClass, FalseClass
Send a signal if the optional signal instance has been set
108 109 110 111 112 113 114 115 |
# File 'lib/zoidberg/proxy.rb', line 108 def _zoidberg_signal(sig) if(@_zoidberg_signal) @_zoidberg_signal.signal(sig) true else false end end |
#_zoidberg_signal=(signal) ⇒ Signal
Set an optional state signal instance
100 101 102 |
# File 'lib/zoidberg/proxy.rb', line 100 def _zoidberg_signal=(signal) @_zoidberg_signal = signal end |
#_zoidberg_unexpected_error(e) ⇒ Object
Properly handle an unexpected exception when encountered
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/zoidberg/proxy.rb', line 120 def _zoidberg_unexpected_error(e) ::Zoidberg.logger.error "Unexpected exception: #{e.class} - #{e}" ::Zoidberg.logger.debug "#{e.class}: #{e}\n#{e.backtrace.join("\n")}" unless((defined?(Timeout) && e.is_a?(Timeout::Error)) || e.is_a?(::Zoidberg::DeadException)) 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 if(@_supervised) ::Zoidberg.logger.warn "Unexpected error for supervised class `#{@_raw_instance.class.name}`. Handling error (#{e.class} - #{e})" ::Zoidberg.logger.debug "#{e.class}: #{e}\n#{e.backtrace.join("\n")}" _zoidberg_handle_unexpected_error(e) end end end end |