Class: Ffmprb::Util::Thread
- Inherits:
-
Thread
- Object
- Thread
- Ffmprb::Util::Thread
- Defined in:
- lib/ffmprb/util/thread.rb
Overview
NOTE doesn’t have specs (and not too proud about it)
Direct Known Subclasses
Defined Under Namespace
Classes: Error, ParentError
Class Attribute Summary collapse
-
.timeout ⇒ Object
Returns the value of attribute timeout.
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Class Method Summary collapse
- .join_children!(limit = nil, timeout: self.timeout) ⇒ Object
- .timeout_or_live(limit = nil, log: "while doing this", timeout: self.timeout, &blk) ⇒ Object
Instance Method Summary collapse
- #child_dies(thr) ⇒ Object
- #child_lives(thr) ⇒ Object
-
#initialize(name = "some", &blk) ⇒ Thread
constructor
A new instance of Thread.
- #join_children!(limit = nil, timeout: self.class.timeout) ⇒ Object
-
#live! ⇒ Object
TODO protected: none of these methods should be called by a user code, the only public methods are above.
Constructor Details
#initialize(name = "some", &blk) ⇒ Thread
Returns a new instance of Thread.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/ffmprb/util/thread.rb', line 44 def initialize(name="some", &blk) @name = name @parent = Thread.current @live_children = [] @children_mon = Monitor.new @dead_children_q = Queue.new Ffmprb.logger.debug "about to launch #{name}" sync_q = Queue.new super() do @parent.child_lives self if @parent.respond_to? :child_lives sync_q.enq :ok Ffmprb.logger.debug "#{name} thread launched" begin blk.call.tap do Ffmprb.logger.debug "#{name} thread done" end rescue Exception Ffmprb.logger.warn "#{$!.class} raised in #{name} thread: #{$!.}\nBacktrace:\n\t#{$!.backtrace.join("\n\t")}" cause = $! Ffmprb.logger.warn "...caused by #{cause.class}: #{cause.}\nBacktrace:\n\t#{cause.backtrace.join("\n\t")}" while cause = cause.cause fail $! # XXX I have no idea why I need to give it `$!` -- the docs say I need not ensure @parent.child_dies self if @parent.respond_to? :child_dies end end sync_q.deq end |
Class Attribute Details
.timeout ⇒ Object
Returns the value of attribute timeout.
13 14 15 |
# File 'lib/ffmprb/util/thread.rb', line 13 def timeout @timeout end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
42 43 44 |
# File 'lib/ffmprb/util/thread.rb', line 42 def name @name end |
Class Method Details
.join_children!(limit = nil, timeout: self.timeout) ⇒ Object
36 37 38 |
# File 'lib/ffmprb/util/thread.rb', line 36 def join_children!(limit=nil, timeout: self.timeout) Thread.current.join_children! limit, timeout: timeout end |
.timeout_or_live(limit = nil, log: "while doing this", timeout: self.timeout, &blk) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/ffmprb/util/thread.rb', line 15 def timeout_or_live(limit=nil, log: "while doing this", timeout: self.timeout, &blk) started_at = Time.now tries = 0 logged_tries = 0 begin tries += 1 time = Time.now - started_at fail TimeLimitError if limit && time > limit Timeout.timeout timeout do blk.call time end rescue Timeout::Error if tries > 2 * logged_tries Ffmprb.logger.info "A little bit of timeout #{log.respond_to?(:call)? log.call : log} (##{tries})" logged_tries = tries end current.live! retry end end |
Instance Method Details
#child_dies(thr) ⇒ Object
86 87 88 89 90 91 92 |
# File 'lib/ffmprb/util/thread.rb', line 86 def child_dies(thr) @children_mon.synchronize do Ffmprb.logger.debug "releasing #{thr.name} thread" @dead_children_q.enq thr fail "System Error" unless @live_children.delete thr end end |
#child_lives(thr) ⇒ Object
79 80 81 82 83 84 |
# File 'lib/ffmprb/util/thread.rb', line 79 def child_lives(thr) @children_mon.synchronize do Ffmprb.logger.debug "picking up #{thr.name} thread" @live_children << thr end end |
#join_children!(limit = nil, timeout: self.class.timeout) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/ffmprb/util/thread.rb', line 94 def join_children!(limit=nil, timeout: self.class.timeout) timeout = [timeout, limit].compact.min Ffmprb.logger.debug "joining threads: #{@live_children.size} live, #{@dead_children_q.size} dead" until @live_children.empty? && @dead_children_q.empty? thr = self.class.timeout_or_live limit, log: "joining threads: #{@live_children.size} live, #{@dead_children_q.size} dead", timeout: timeout do @dead_children_q.deq end Ffmprb.logger.debug "joining the late #{thr.name} thread" fail "System Error" unless thr.join(timeout) # NOTE should not block end end |
#live! ⇒ Object
TODO protected: none of these methods should be called by a user code, the only public methods are above
75 76 77 |
# File 'lib/ffmprb/util/thread.rb', line 75 def live! fail ParentError if @parent.status.nil? end |