Class: RobustThread
- Inherits:
-
Object
- Object
- RobustThread
- Defined in:
- lib/robustthread.rb
Constant Summary collapse
- VALID_CALLBACKS =
[:before_init, :before_yield, :after_yield, :after_join, :before_exit]
Class Attribute Summary collapse
-
.callbacks ⇒ Object
Returns the value of attribute callbacks.
-
.exit_handler_initialized ⇒ Object
Returns the value of attribute exit_handler_initialized.
-
.logger ⇒ Object
Logger object (see README).
-
.say_goodnight ⇒ Object
Returns the value of attribute say_goodnight.
Instance Attribute Summary collapse
-
#exception ⇒ Object
readonly
If the Thread takes a poopie…
-
#label ⇒ Object
An identifier.
-
#thread ⇒ Object
readonly
The Thread object, brah.
Class Method Summary collapse
- .add_callback(sym, &block) ⇒ Object
-
.exception_handler(&block) ⇒ Object
Set exception handler.
-
.group ⇒ Object
The collection of RobustThread objects.
-
.log(msg, level = :info) ⇒ Object
Simple log interface.
-
.loop(opts = {}, &block) ⇒ Object
Loop an activity and exit it cleanly (see README).
Instance Method Summary collapse
-
#initialize(opts = {}, &block) ⇒ RobustThread
constructor
Create a new RobustThread (see README).
Constructor Details
#initialize(opts = {}, &block) ⇒ RobustThread
Create a new RobustThread (see README)
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/robustthread.rb', line 19 def initialize(opts={}, &block) self.class.send :init_exit_handler args = opts[:args] or [] self.class.send :do_before_init @thread = Thread.new(*args) do |*targs| begin self.class.send :do_before_yield block.call(*targs) self.class.send :do_after_yield rescue Exception => e @exception = e self.class.send :handle_exception, e end self.class.log "#{self.label.inspect} exited cleanly" end self.label = opts[:label] || @thread.inspect self.class.group << self end |
Class Attribute Details
.callbacks ⇒ Object
Returns the value of attribute callbacks.
40 41 42 |
# File 'lib/robustthread.rb', line 40 def callbacks @callbacks end |
.exit_handler_initialized ⇒ Object
Returns the value of attribute exit_handler_initialized.
40 41 42 |
# File 'lib/robustthread.rb', line 40 def exit_handler_initialized @exit_handler_initialized end |
.logger ⇒ Object
Logger object (see README)
44 45 46 |
# File 'lib/robustthread.rb', line 44 def logger @logger end |
.say_goodnight ⇒ Object
Returns the value of attribute say_goodnight.
40 41 42 |
# File 'lib/robustthread.rb', line 40 def say_goodnight @say_goodnight end |
Instance Attribute Details
#exception ⇒ Object (readonly)
If the Thread takes a poopie…
14 15 16 |
# File 'lib/robustthread.rb', line 14 def exception @exception end |
#label ⇒ Object
An identifier
16 17 18 |
# File 'lib/robustthread.rb', line 16 def label @label end |
#thread ⇒ Object (readonly)
The Thread object, brah
12 13 14 |
# File 'lib/robustthread.rb', line 12 def thread @thread end |
Class Method Details
.add_callback(sym, &block) ⇒ Object
94 95 96 97 98 99 100 |
# File 'lib/robustthread.rb', line 94 def add_callback(sym, &block) sym = sym.to_sym raise ArgumentError, "Invalid callback #{sym.inspect}" unless VALID_CALLBACKS.include? sym self.callbacks ||= {} self.callbacks[sym] ||= [] self.callbacks[sym] << block end |
.exception_handler(&block) ⇒ Object
Set exception handler
85 86 87 88 89 90 |
# File 'lib/robustthread.rb', line 85 def exception_handler(&block) unless block.arity == 1 raise ArgumentError, "Bad arity for exception handler. It may only accept a single argument" end @exception_handler = block end |
.group ⇒ Object
The collection of RobustThread objects
54 55 56 |
# File 'lib/robustthread.rb', line 54 def group @group ||= [] end |
.log(msg, level = :info) ⇒ Object
Simple log interface
49 50 51 |
# File 'lib/robustthread.rb', line 49 def log(msg, level=:info) self.logger.send level, "#{self}: " + msg end |
.loop(opts = {}, &block) ⇒ Object
Loop an activity and exit it cleanly (see README)
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/robustthread.rb', line 59 def loop(opts={}, &block) sleep_seconds = opts.delete(:seconds) || 2 self.new(opts) do |*args| Kernel.loop do break if self.say_goodnight block.call(*args) # We want to sleep for the right amount of time, but we also don't # want to wait until the sleep is done if our exit handler has been # called so we iterate over a loop, sleeping only 0.1 and checking # each iteration whether we need to die, and the timeout is a noop # indicating we need to continue. begin Timeout.timeout(sleep_seconds) do Kernel.loop do break if self.say_goodnight sleep 0.1 end end rescue Timeout::Error # OK end end end end |