Class: Zoidberg::Proxy::Confined
- Inherits:
-
Zoidberg::Proxy
- Object
- Zoidberg::Proxy
- Zoidberg::Proxy::Confined
- Defined in:
- lib/zoidberg/proxy/confined.rb
Instance Attribute Summary collapse
-
#_blocked ⇒ TrueClass, FalseClass
readonly
Blocked running task.
-
#_requests ⇒ Queue
readonly
Current request queue.
-
#_source_thread ⇒ Thread
readonly
Container thread.
Instance Method Summary collapse
-
#_async_request(blocking, method_name, *args, &block) ⇒ Object
Call into instance asynchronously.
-
#_isolated_request(method_name, *args) { ... } ⇒ Object
Send the method request to the wrapped instance.
- #_zoidberg_available? ⇒ Boolean
-
#initialize(klass, *args, &block) ⇒ self
constructor
Create a new isolation wrapper.
-
#method_missing(*args, &block) ⇒ Object
Wrapping for provided object.
Methods inherited from Zoidberg::Proxy
#_zoidberg_destroy!, #_zoidberg_handle_unexpected_error, #_zoidberg_link, #_zoidberg_link=, #_zoidberg_locked?, #_zoidberg_object, #_zoidberg_signal, #_zoidberg_signal=, #_zoidberg_unexpected_error, inherited, register, registry, scrub!
Constructor Details
#initialize(klass, *args, &block) ⇒ self
Create a new isolation wrapper
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/zoidberg/proxy/confined.rb', line 19 def initialize(klass, *args, &block) @_requests = ::Queue.new @_blocked = false @_source_thread = ::Thread.new do ::Zoidberg.logger.debug 'Starting the isolation request processor' ::Thread.current[:root_fiber] = ::Fiber.current _isolate! end @_build_args = [klass, *args, block] @_raw_instance = klass.unshelled_new(*args, &block) @_raw_instance._zoidberg_proxy(self) if(@_raw_instance.class.include?(::Zoidberg::Supervise)) @_supervised = true end ::Zoidberg.logger.debug "Zoidberg object isolation wrap: #{@_build_args.inspect}" end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(*args, &block) ⇒ Object
Wrapping for provided object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/zoidberg/proxy/confined.rb', line 53 def method_missing(*args, &block) res = nil begin if(::ENV['ZOIDBERG_TESTING']) ::Kernel.require 'timeout' ::Timeout.timeout(::ENV.fetch('ZOIDBERG_TESTING_TIMEOUT', 5).to_i) do res = _isolated_request(*args, &block) end else res = _isolated_request(*args, &block) end rescue ::Zoidberg::Supervise::AbortException => e ::Kernel.raise e.original_exception rescue ::Exception => e _zoidberg_unexpected_error(e) ::Zoidberg.logger.debug "Exception on: #{_raw_instance.class}##{args.first}(#{args.slice(1, args.size).map(&:inspect).join(', ')})" ::Kernel.raise e end res end |
Instance Attribute Details
#_blocked ⇒ TrueClass, FalseClass (readonly)
13 14 15 |
# File 'lib/zoidberg/proxy/confined.rb', line 13 def _blocked @_blocked end |
#_requests ⇒ Queue (readonly)
11 12 13 |
# File 'lib/zoidberg/proxy/confined.rb', line 11 def _requests @_requests end |
#_source_thread ⇒ Thread (readonly)
9 10 11 |
# File 'lib/zoidberg/proxy/confined.rb', line 9 def _source_thread @_source_thread end |
Instance Method Details
#_async_request(blocking, method_name, *args, &block) ⇒ Object
Note:
use caution with shared data using this method
Call into instance asynchronously
39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/zoidberg/proxy/confined.rb', line 39 def _async_request(blocking, method_name, *args, &block) ::Zoidberg.logger.debug "Received async request from remote thread. Added to queue: #{_raw_instance.class}##{method_name}(#{args.map(&:inspect).join(', ')})" _requests << ::Smash.new( :uuid => ::Zoidberg.uuid, :arguments => [method_name, *args], :block => block, :response => nil, :async => true, :blocking => blocking == :blocking ) nil end |
#_isolated_request(method_name, *args) { ... } ⇒ Object
Send the method request to the wrapped instance
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/zoidberg/proxy/confined.rb', line 80 def _isolated_request(method_name, *args, &block) if(_source_thread == ::Thread.current) ::Zoidberg.logger.debug "Received request from source thread: #{_raw_instance.class}##{method_name}(#{args.map(&:inspect).join(', ')})" _raw_instance.__send__(method_name, *args, &block) else unless(_source_thread.alive?) ::Kernel.raise ::Zoidberg::DeadException.new('Instance in terminated state!') end ::Zoidberg.logger.debug "Received request from remote thread. Added to queue: #{_raw_instance.class}##{method_name}(#{args.map(&:inspect).join(', ')})" response_queue = ::Queue.new _requests << ::Smash.new( :uuid => ::Zoidberg.uuid, :arguments => [method_name, *args], :block => block, :response => response_queue ) result = response_queue.pop if(result.is_a?(::Exception)) ::Kernel.raise result else result end end end |
#_zoidberg_available? ⇒ Boolean
105 106 107 |
# File 'lib/zoidberg/proxy/confined.rb', line 105 def _zoidberg_available? !_blocked end |