Class: InterruptHandler
- Inherits:
-
Object
- Object
- InterruptHandler
- Includes:
- Singleton
- Defined in:
- lib/overcommit/interrupt_handler.rb
Overview
Provides a handler for interrupt signals (SIGINT), allowing the application to finish what it’s currently working on.
Instance Attribute Summary collapse
-
#isolate_signals ⇒ Object
Returns the value of attribute isolate_signals.
-
#reenable_on_interrupt ⇒ Object
Returns the value of attribute reenable_on_interrupt.
-
#signal_received ⇒ Object
Returns the value of attribute signal_received.
Class Method Summary collapse
-
.disable! ⇒ Object
Disable interrupt isolation.
-
.disable_until_finished_or_interrupted ⇒ Object
Provide a way to allow a single Ctrl-C interrupt to happen and atomically re-enable interrupt protections once that interrupt is propagated.
-
.enable! ⇒ Object
Enable interrupt isolation.
-
.isolate_from_interrupts { ... } ⇒ Object
Enable interrupt isolation while executing the provided block.
Instance Method Summary collapse
-
#initialize ⇒ InterruptHandler
constructor
Initialize safe interrupt signal handling.
Constructor Details
#initialize ⇒ InterruptHandler
Initialize safe interrupt signal handling.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/overcommit/interrupt_handler.rb', line 11 def initialize self.isolate_signals = false self.signal_received = false self.reenable_on_interrupt = false Signal.trap('INT') do if isolate_signals self.signal_received = true else if reenable_on_interrupt self.reenable_on_interrupt = false self.isolate_signals = true end raise Interrupt # Allow interrupt to propagate to code end end end |
Instance Attribute Details
#isolate_signals ⇒ Object
Returns the value of attribute isolate_signals.
8 9 10 |
# File 'lib/overcommit/interrupt_handler.rb', line 8 def isolate_signals @isolate_signals end |
#reenable_on_interrupt ⇒ Object
Returns the value of attribute reenable_on_interrupt.
8 9 10 |
# File 'lib/overcommit/interrupt_handler.rb', line 8 def reenable_on_interrupt @reenable_on_interrupt end |
#signal_received ⇒ Object
Returns the value of attribute signal_received.
8 9 10 |
# File 'lib/overcommit/interrupt_handler.rb', line 8 def signal_received @signal_received end |
Class Method Details
.disable! ⇒ Object
Disable interrupt isolation.
69 70 71 |
# File 'lib/overcommit/interrupt_handler.rb', line 69 def disable! instance.isolate_signals = false end |
.disable_until_finished_or_interrupted ⇒ Object
Provide a way to allow a single Ctrl-C interrupt to happen and atomically re-enable interrupt protections once that interrupt is propagated.
This prevents a race condition where code like the following:
begin
InterruptHandler.disable!
... do stuff ...
rescue Interrupt
... handle it ...
ensure
InterruptHandler.enable!
end
…could have the enable! call to the interrupt handler not called in the event another interrupt was received in between the interrupt being handled and the ensure block being entered.
Thus you should always write:
begin
InterruptHandler.disable_until_finished_or_interrupted do
... do stuff ...
end
rescue Interrupt
... handle it ...
rescue
... handle any other exceptions ...
end
60 61 62 63 64 65 66 |
# File 'lib/overcommit/interrupt_handler.rb', line 60 def disable_until_finished_or_interrupted instance.reenable_on_interrupt = true instance.isolate_signals = false yield ensure instance.isolate_signals = true end |
.enable! ⇒ Object
Enable interrupt isolation.
74 75 76 |
# File 'lib/overcommit/interrupt_handler.rb', line 74 def enable! instance.isolate_signals = true end |
.isolate_from_interrupts { ... } ⇒ Object
Enable interrupt isolation while executing the provided block.
81 82 83 84 85 86 87 |
# File 'lib/overcommit/interrupt_handler.rb', line 81 def isolate_from_interrupts instance.signal_received = false instance.isolate_signals = true result = yield instance.isolate_signals = false result end |