Class: AMQP::SpecHelper::EventedExample
- Inherits:
-
Object
- Object
- AMQP::SpecHelper::EventedExample
- Defined in:
- lib/amqp-spec/evented_example.rb
Overview
Represents example running inside some type of event loop
Direct Known Subclasses
Instance Method Summary collapse
-
#done(delay = nil, &block) ⇒ Object
Breaks the event loop and finishes the spec.
-
#finish_em_loop ⇒ Object
Stops EM event loop.
-
#finish_example ⇒ Object
Called from #run_event_loop when event loop is stopped, but before the example returns.
-
#initialize(opts, example_group_instance, &block) ⇒ EventedExample
constructor
Create new evented example.
-
#run_em_hooks(type) ⇒ Object
Runs hooks of specified type (hopefully, inside the event loop).
-
#run_em_loop ⇒ Object
Runs given block inside EM event loop.
-
#timeout(spec_timeout) ⇒ Object
Sets timeout for currently running example.
Constructor Details
#initialize(opts, example_group_instance, &block) ⇒ EventedExample
Create new evented example
11 12 13 |
# File 'lib/amqp-spec/evented_example.rb', line 11 def initialize(opts, example_group_instance, &block) @opts, @example_group_instance, @block = opts, example_group_instance, block end |
Instance Method Details
#done(delay = nil, &block) ⇒ Object
Breaks the event loop and finishes the spec.
This is under-implemented (generic) method that only implements optional delay. It should be given a block that does actual work of finishing up the event loop and cleaning any remaining artifacts.
Please redefine it inside descendant class and call super.
33 34 35 36 37 38 39 |
# File 'lib/amqp-spec/evented_example.rb', line 33 def done(delay=nil, &block) if delay EM.add_timer delay, &block else block.call end end |
#finish_em_loop ⇒ Object
Stops EM event loop. It is called from #done
81 82 83 84 |
# File 'lib/amqp-spec/evented_example.rb', line 81 def finish_em_loop run_em_hooks :em_after EM.stop_event_loop if EM.reactor_running? end |
#finish_example ⇒ Object
Called from #run_event_loop when event loop is stopped, but before the example returns. Descendant classes may redefine to clean up type-specific state.
90 91 92 |
# File 'lib/amqp-spec/evented_example.rb', line 90 def finish_example raise @spec_exception if @spec_exception end |
#run_em_hooks(type) ⇒ Object
Runs hooks of specified type (hopefully, inside the event loop)
43 44 45 46 47 48 49 50 51 |
# File 'lib/amqp-spec/evented_example.rb', line 43 def run_em_hooks(type) @example_group_instance.class.em_hooks[type].each do |hook| if @example_group_instance.respond_to? :instance_eval_without_event_loop @example_group_instance.instance_eval_without_event_loop(&hook) else @example_group_instance.instance_eval(&hook) #_with_rescue(&hook) end end end |
#run_em_loop ⇒ Object
Runs given block inside EM event loop. Double-round exception handler needed because some of the exceptions bubble outside of event loop due to asynchronous nature of evented examples
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/amqp-spec/evented_example.rb', line 57 def run_em_loop begin EM.run do run_em_hooks :em_before @spec_exception = nil timeout(@opts[:spec_timeout]) if @opts[:spec_timeout] begin yield rescue Exception => @spec_exception # p "Inside loop, caught #{@spec_exception}" done # We need to properly terminate the event loop end end rescue Exception => @spec_exception # p "Outside loop, caught #{@spec_exception}" run_em_hooks :em_after # Event loop broken, but we still need to run em_after hooks ensure finish_example end end |
#timeout(spec_timeout) ⇒ Object
Sets timeout for currently running example
17 18 19 20 21 22 23 |
# File 'lib/amqp-spec/evented_example.rb', line 17 def timeout(spec_timeout) EM.cancel_timer(@spec_timer) if @spec_timer @spec_timer = EM.add_timer(spec_timeout) do @spec_exception = SpecTimeoutExceededError.new "Example timed out" done end end |