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.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/overcommit/interrupt_handler.rb', line 13 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.
10 11 12 |
# File 'lib/overcommit/interrupt_handler.rb', line 10 def isolate_signals @isolate_signals end |
#reenable_on_interrupt ⇒ Object
Returns the value of attribute reenable_on_interrupt.
10 11 12 |
# File 'lib/overcommit/interrupt_handler.rb', line 10 def reenable_on_interrupt @reenable_on_interrupt end |
#signal_received ⇒ Object
Returns the value of attribute signal_received.
10 11 12 |
# File 'lib/overcommit/interrupt_handler.rb', line 10 def signal_received @signal_received end |
Class Method Details
.disable! ⇒ Object
Disable interrupt isolation.
71 72 73 |
# File 'lib/overcommit/interrupt_handler.rb', line 71 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
62 63 64 65 66 67 68 |
# File 'lib/overcommit/interrupt_handler.rb', line 62 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.
76 77 78 |
# File 'lib/overcommit/interrupt_handler.rb', line 76 def enable! instance.isolate_signals = true end |
.isolate_from_interrupts { ... } ⇒ Object
Enable interrupt isolation while executing the provided block.
83 84 85 86 87 88 89 |
# File 'lib/overcommit/interrupt_handler.rb', line 83 def isolate_from_interrupts instance.signal_received = false instance.isolate_signals = true result = yield instance.isolate_signals = false result end |