Class: Async::Signals::Controller

Inherits:
Object
  • Object
show all
Defined in:
lib/async/signals/controller.rb

Overview

Coordinates process-wide signal handlers for multiple consumers.

Defined Under Namespace

Classes: Registration, State

Instance Method Summary collapse

Constructor Details

#initializeController

Initialize the controller.



103
104
105
106
107
# File 'lib/async/signals/controller.rb', line 103

def initialize
	@mutex = ::Thread::Mutex.new
	@states = {}
	@dispatch = {}.freeze
end

Instance Method Details

#dispatch(signal) ⇒ Object

Dispatch a signal to all currently active handlers.



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/async/signals/controller.rb', line 138

def dispatch(signal)
	number = ::Signal.list.fetch(signal)
	
	@dispatch[signal]&.each do |handler|
		begin
			handler.call(number)
		rescue Exception => error
			warn "Async::Signals handler failed: #{error.class}: #{error.message}"
		end
	end
end

#install(handlers) ⇒ Object

Install signal handlers.



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/async/signals/controller.rb', line 113

def install(handlers)
	installed_handlers = handlers.to_h.freeze
	registration = Registration.new(self, installed_handlers)
	
	@mutex.synchronize do
		installed_handlers.each do |signal, handler|
			add(signal, registration, handler)
		end
		
		update_dispatch
	end
	
	if block_given?
		begin
			return yield handlers
		ensure
			registration.close
		end
	else
		return registration
	end
end

#remove(registration, handlers) ⇒ Object

Remove a set of installed handlers.



153
154
155
156
157
158
159
160
161
# File 'lib/async/signals/controller.rb', line 153

def remove(registration, handlers)
	@mutex.synchronize do
		handlers.each_key do |signal|
			remove_signal(signal, registration)
		end
		
		update_dispatch
	end
end

#reset!Object

Reset all installed signal handlers to their previous signal traps.



164
165
166
167
168
169
170
171
172
173
# File 'lib/async/signals/controller.rb', line 164

def reset!
	@mutex.synchronize do
		@states.each do |signal, state|
			::Signal.trap(signal, state.previous)
		end
		
		@states.clear
		update_dispatch
	end
end