Module: Utilrb::EventLoop::Forwardable

Defined in:
lib/utilrb/event_loop.rb

Overview

Note:

It is not possible to delegate methods where the target method needs a code block.

The EventLoop::Forwardable module provides delegation of specified methods to a designated object like the ruby ::Forwardable module but defers the method call to a thread pool of an event loop if a callback is given. After the call returned the callback is called from the event loop thread while it is processing its event at the end of each step.

To ensure thread safety for all kind of objects the event loop defers only one method call per object in parallel even if the method is called without any callback. For this mechanism a sync key is used which is by default the designated object but can be set to any custom ruby object. If a method call is thread safe the sync key can be set to nil allowing the event loop to call it in parallel while another none thread safe method call of the designated object is processed.

Author:

Defined Under Namespace

Classes: DesignatedObjectNotFound, Forward

Instance Method Summary collapse

Instance Method Details

#def_event_loop_delegator(accessor, event_loop, method, options = Hash.new) ⇒ Object

Defines a method as delegator instance method with an optional alias name ali.

Method calls to ali will be delegated to accessor.method. If an error occurres during proccessing it will be raised like in the case of the original object but also forwarded to the error handlers of event loop.

Method calls to ali(*args,&block) will be delegated to accessor.method(*args) but called from a thread pool. Thereby the code block is used as callback called from the main thread after the call returned. If an error occurred it will be:

* given to the callback as second argument 
* forwarded to the error handlers of the event loop
* raised at the beginning of the next step if not marked as known error

To overwrite an error the callback can return :ignore_error or a new instance of an error. In an event of an error the error handlers of the event loop will not be called or called with the new error instance.

ali do |result,exception|
   if exception
       MyError.new
   else
      puts result
   end
end

ali do |result,exception|
   if exception 
       :ignore_error
   else
      puts result
   end
end

If the callback accepts only one argument the callback will not be called in an event of an error but the error will still be forwarded to the error handlers.

If the result shall be filtered before returned a filter method can be specified which is called from the event loop thread just before the result is returned.

Examples:

class Dummy
    # non thread safe method
    def test(wait)
        sleep wait
        Thread.current
    end

    # thread safe method
    def test_thread_safe(wait)
        sleep wait
        Thread.current
    end
end
class DummyAsync
    extend Utilrb::EventLoop::Forwardable
    def_event_loop_delegator :@obj,:@event_loop,:test,:alias => :atest
    def_event_loop_delegator :@obj,:@event_loop,:test_thread_safe,:sync_key => false

    def initialize(event_loop)
        @event_loop = event_loop
        @obj = Dummy.new
    end
end

event_loop = EventLoop.new
test = DummyAsync.new(event_loop)
puts test.atest 2
test.atest 2 do |result|
    puts result
end
test.thread_safe 2 do |result|
    puts result
end
sleep(0.1)
event_loop.step

Parameters:

  • accessor (Symbol)

    The symbol for the designated object.

  • event_loop (Symbol)

    The event loop accessor.

  • method (Symbol)

    The method called on the designated object.

  • options (Hash) (defaults to: Hash.new)

    The options

Options Hash (options):

  • :alias (Symbol)

    The alias of the method

  • :sync_key (Symbol)

    The sync key

  • :filter (Symbol)

    The filter method

  • :on_error (Symbol)

    Method which is called if an error occured

  • :known_errors (class)

    Known errors which will be rescued but still be forwarded.

See Also:


824
825
826
# File 'lib/utilrb/event_loop.rb', line 824

def def_event_loop_delegator(accessor,event_loop, method, options = Hash.new )
    Forward.def_event_loop_delegator(self,accessor,event_loop,method,options)
end

#def_event_loop_delegators(accessor, event_loop, *methods) ⇒ Object


828
829
830
# File 'lib/utilrb/event_loop.rb', line 828

def def_event_loop_delegators(accessor,event_loop, *methods)
    Forward.def_event_loop_delegators(self,accessor,event_loop,*methods)
end

#forward_to(accessor, event_loop, options = Hash.new, &block) ⇒ Object


832
833
834
835
# File 'lib/utilrb/event_loop.rb', line 832

def forward_to(accessor,event_loop,options = Hash.new,&block)
    obj = Forward.new(self,accessor,event_loop,options)
    obj.instance_eval(&block)
end