Class: Async::Container::Notify::Socket

Inherits:
Client
  • Object
show all
Defined in:
lib/async/container/notify/socket.rb

Overview

Implements the systemd NOTIFY_SOCKET process readiness protocol. See <www.freedesktop.org/software/systemd/man/sd_notify.html> for more details of the underlying protocol.

Constant Summary collapse

NOTIFY_SOCKET =

The name of the environment variable which contains the path to the notification socket.

'NOTIFY_SOCKET'
MAXIMUM_MESSAGE_SIZE =

The maximum allowed size of the UDP message.

4096

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Client

#ready!, #reloading!, #restarting!, #status!, #stopping!

Constructor Details

#initialize(path) ⇒ Socket

Initialize the notification client.



50
51
52
53
# File 'lib/async/container/notify/socket.rb', line 50

def initialize(path)
	@path = path
	@endpoint = IO::Endpoint.unix(path, ::Socket::SOCK_DGRAM)
end

Class Method Details

.open!(environment = ENV) ⇒ Object

Open a notification client attached to the current NOTIFY_SOCKET if possible.



42
43
44
45
46
# File 'lib/async/container/notify/socket.rb', line 42

def self.open!(environment = ENV)
	if path = environment.delete(NOTIFY_SOCKET)
		self.new(path)
	end
end

Instance Method Details

#dump(message) ⇒ Object

Dump a message in the format requied by ‘sd_notify`.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/async/container/notify/socket.rb', line 57

def dump(message)
	buffer = String.new
	
	message.each do |key, value|
		# Conversions required by NOTIFY_SOCKET specifications:
		if value == true
			value = 1
		elsif value == false
			value = 0
		end
		
		buffer << "#{key.to_s.upcase}=#{value}\n"
	end
	
	return buffer
end

#error!(text, **message) ⇒ Object

Send the specified error. ‘sd_notify` requires an `errno` key, which defaults to `-1` to indicate a generic error.



92
93
94
95
96
# File 'lib/async/container/notify/socket.rb', line 92

def error!(text, **message)
	message[:errno] ||= -1
	
	send(status: text, **message)
end

#send(**message) ⇒ Object

Send the given message.



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/async/container/notify/socket.rb', line 76

def send(**message)
	data = dump(message)
	
	if data.bytesize > MAXIMUM_MESSAGE_SIZE
		raise ArgumentError, "Message length #{message.bytesize} exceeds #{MAXIMUM_MESSAGE_SIZE}: #{message.inspect}"
	end
	
	Sync do
		@endpoint.connect do |peer|
			peer.send(data)
		end
	end
end