Class: RobustThread
- Inherits:
-
Object
- Object
- RobustThread
- Defined in:
- lib/robustthread.rb
Constant Summary collapse
- VALID_CALLBACKS =
[:before_init, :before_yield, :after_yield, :after_join]
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)
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/robustthread.rb', line 16 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 => 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.
37 38 39 |
# File 'lib/robustthread.rb', line 37 def callbacks @callbacks end |
.exit_handler_initialized ⇒ Object
Returns the value of attribute exit_handler_initialized.
37 38 39 |
# File 'lib/robustthread.rb', line 37 def exit_handler_initialized @exit_handler_initialized end |
.logger ⇒ Object
Logger object (see README)
41 42 43 |
# File 'lib/robustthread.rb', line 41 def logger @logger end |
.say_goodnight ⇒ Object
Returns the value of attribute say_goodnight.
37 38 39 |
# File 'lib/robustthread.rb', line 37 def say_goodnight @say_goodnight end |
Instance Attribute Details
#exception ⇒ Object (readonly)
If the Thread takes a poopie…
11 12 13 |
# File 'lib/robustthread.rb', line 11 def exception @exception end |
#label ⇒ Object
An identifier
13 14 15 |
# File 'lib/robustthread.rb', line 13 def label @label end |
#thread ⇒ Object (readonly)
The Thread object, brah
9 10 11 |
# File 'lib/robustthread.rb', line 9 def thread @thread end |
Class Method Details
.add_callback(sym, &block) ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/robustthread.rb', line 91 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
82 83 84 85 86 87 |
# File 'lib/robustthread.rb', line 82 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
51 52 53 |
# File 'lib/robustthread.rb', line 51 def group @group ||= [] end |
.log(msg, level = :info) ⇒ Object
Simple log interface
46 47 48 |
# File 'lib/robustthread.rb', line 46 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)
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/robustthread.rb', line 56 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 |