Class: InterruptHandler

Inherits:
Object
  • Object
show all
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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeInterruptHandler

Returns a new instance of InterruptHandler.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/overcommit/interrupt_handler.rb', line 10

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_signalsObject

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_interruptObject

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_receivedObject

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



67
68
69
# File 'lib/overcommit/interrupt_handler.rb', line 67

def disable!
  instance.isolate_signals = false
end

.disable_until_finished_or_interruptedObject

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


59
60
61
62
63
64
65
# File 'lib/overcommit/interrupt_handler.rb', line 59

def disable_until_finished_or_interrupted
  instance.reenable_on_interrupt = true
  instance.isolate_signals = false
  yield
ensure
  instance.isolate_signals = true
end

.enable!Object



71
72
73
# File 'lib/overcommit/interrupt_handler.rb', line 71

def enable!
  instance.isolate_signals = true
end

.isolate_from_interruptsObject



75
76
77
78
79
80
81
# File 'lib/overcommit/interrupt_handler.rb', line 75

def isolate_from_interrupts
  instance.signal_received = false
  instance.isolate_signals = true
  result = yield
  instance.isolate_signals = false
  result
end

.signal_received?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/overcommit/interrupt_handler.rb', line 83

def signal_received?
  instance.signal_received
end