Module: AsyncAware
Overview
Prototype support for simple parallel requests. It is the callers responsibility to ensure that blocks are side-effect free.
Defined Under Namespace
Classes: ThreadTimedOut
Instance Method Summary collapse
- #async(&block) ⇒ Object
- #join(limit = nil) ⇒ Object
-
#join!(limit = nil) ⇒ Object
Throw the first exception encountered.
Instance Method Details
#async(&block) ⇒ Object
8 9 10 11 12 13 14 15 16 |
# File 'app/models/async_aware.rb', line 8 def async(&block) (@threads ||= []) << Thread.start do begin Thread.current[:out] = yield block rescue => e Thread.current[:out] = e end end end |
#join(limit = nil) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'app/models/async_aware.rb', line 17 def join(limit=nil) running = @threads t1 = Time.now.to_i threads = begin @threads.map{ |t| limit ? t.join(limit) : t.join } ensure @threads.each(&:kill) @threads = nil end #puts "**** Joined #{Time.now.to_i - t1} (limit=#{limit})" #puts running.map{ |t| " #{t.inspect}: #{threads.include?(t) ? "" : "(did not finish) "}#{t[:out].inspect}" }.join("\n") running.map do |t| if threads.include?(t) t[:out] else begin; raise(ThreadTimedOut.new(t, limit)); rescue => e; e; end end end end |
#join!(limit = nil) ⇒ Object
Throw the first exception encountered
43 44 45 46 47 48 49 |
# File 'app/models/async_aware.rb', line 43 def join!(limit=nil) join(limit).tap do |results| exceptions = results.select{ |r| r.is_a? StandardError } exceptions[1..-1].each{ |e| Rails.logger.error "#{e.class} (#{e})\n #{Rails.backtrace_cleaner.clean(e.backtrace).join("\n ")}" } if exceptions.size > 1 raise exceptions.first unless exceptions.empty? end end |