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.



33
34
35
36
# File 'lib/async/container/notify/socket.rb', line 33

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.



25
26
27
28
29
# File 'lib/async/container/notify/socket.rb', line 25

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`.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/async/container/notify/socket.rb', line 40

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.



75
76
77
78
79
# File 'lib/async/container/notify/socket.rb', line 75

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

#send(**message) ⇒ Object

Send the given message.



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

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