Class: Rubyists::Leopard::NatsServiceDiscovery
- Inherits:
-
Object
- Object
- Rubyists::Leopard::NatsServiceDiscovery
- Defined in:
- lib/leopard/nats_service_discovery.rb,
lib/leopard/nats_service_discovery/cli.rb,
lib/leopard/nats_service_discovery/operation.rb,
lib/leopard/nats_service_discovery/operation/info.rb,
lib/leopard/nats_service_discovery/operation/ping.rb,
lib/leopard/nats_service_discovery/operation/verb.rb,
lib/leopard/nats_service_discovery/operation/stats.rb,
lib/leopard/nats_service_discovery/operation/collect.rb,
lib/leopard/nats_service_discovery/operation/connect.rb,
lib/leopard/nats_service_discovery/operation/services.rb,
lib/leopard/nats_service_discovery/operation/subject_map.rb,
lib/leopard/nats_service_discovery/operation/discovery_options.rb
Overview
Collects NATS Service API monitoring responses from a cluster.
The NATS Service API uses request/reply subjects such as $SRV.INFO.
Cluster-wide requests can receive multiple replies, so this helper creates
an inbox subscription, publishes the request, and collects replies until a
short timeout elapses.
Defined Under Namespace
Constant Summary collapse
- DEFAULT_PREFIX =
Default NATS Service API monitoring prefix.
'$SRV'- DEFAULT_TIMEOUT =
Default idle timeout used to decide that all service replies arrived.
0.25
Instance Attribute Summary collapse
-
#client ⇒ Object
readonly
Returns the value of attribute client.
-
#prefix ⇒ Object
readonly
Returns the value of attribute prefix.
Instance Method Summary collapse
-
#collect_json(subject, timeout:) ⇒ Array<Hash>
private
Collects JSON replies for a Service API subject until
timeoutelapses. -
#collect_replies(sub, replies, timeout) ⇒ void
private
Appends parsed replies to the provided accumulator until timeout.
-
#endpoint_subject_map(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) ⇒ Hash{String => Array<Hash>}
Builds a subject-to-listener map from service info responses.
-
#info(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) ⇒ Array<Hash>
Collects
$SRV.INFOresponses. -
#initialize(client:, prefix: DEFAULT_PREFIX) ⇒ NatsServiceDiscovery
constructor
A new instance of NatsServiceDiscovery.
-
#listener_entry(service, endpoint) ⇒ Hash
private
Builds a subject-map listener entry from a service and endpoint payload.
-
#no_responders?(msg) ⇒ Boolean
private
Reports whether a reply is the server no-responders status message.
-
#ping(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) ⇒ Array<Hash>
Collects
$SRV.PINGresponses. -
#present?(value) ⇒ Boolean
private
Reports whether a value is present for subject construction.
-
#service_subject(verb, name: nil, id: nil) ⇒ String
Builds a Service API monitoring subject.
-
#stats(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) ⇒ Array<Hash>
Collects
$SRV.STATSresponses. -
#subscribe_to_inbox ⇒ NATS::Subscription
private
Subscribes to an ephemeral reply inbox and flushes the subscription.
Constructor Details
#initialize(client:, prefix: DEFAULT_PREFIX) ⇒ NatsServiceDiscovery
Returns a new instance of NatsServiceDiscovery.
24 25 26 27 |
# File 'lib/leopard/nats_service_discovery.rb', line 24 def initialize(client:, prefix: DEFAULT_PREFIX) @client = client @prefix = prefix end |
Instance Attribute Details
#client ⇒ Object (readonly)
Returns the value of attribute client.
20 21 22 |
# File 'lib/leopard/nats_service_discovery.rb', line 20 def client @client end |
#prefix ⇒ Object (readonly)
Returns the value of attribute prefix.
20 21 22 |
# File 'lib/leopard/nats_service_discovery.rb', line 20 def prefix @prefix end |
Instance Method Details
#collect_json(subject, timeout:) ⇒ Array<Hash> (private)
Collects JSON replies for a Service API subject until timeout elapses.
105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/leopard/nats_service_discovery.rb', line 105 def collect_json(subject, timeout:) replies = [] sub = subscribe_to_inbox client.publish(subject, '', sub.subject) begin collect_replies(sub, replies, timeout) rescue NATS::Timeout replies end ensure sub&.unsubscribe end |
#collect_replies(sub, replies, timeout) ⇒ void (private)
This method returns an undefined value.
Appends parsed replies to the provided accumulator until timeout.
134 135 136 137 138 139 140 141 |
# File 'lib/leopard/nats_service_discovery.rb', line 134 def collect_replies(sub, replies, timeout) loop do msg = sub.next_msg(timeout:) next if no_responders?(msg) replies << JSON.parse(msg.data) end end |
#endpoint_subject_map(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) ⇒ Hash{String => Array<Hash>}
Builds a subject-to-listener map from service info responses.
69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/leopard/nats_service_discovery.rb', line 69 def endpoint_subject_map(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) info(name:, id:, timeout:).each_with_object({}) do |service, subjects| Array(service['endpoints']).each do |endpoint| subject = endpoint['subject'] next if subject.to_s.empty? subjects[subject] ||= [] subjects[subject] << listener_entry(service, endpoint) end end end |
#info(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) ⇒ Array<Hash>
Collects $SRV.INFO responses.
47 48 49 |
# File 'lib/leopard/nats_service_discovery.rb', line 47 def info(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) collect_json(service_subject('INFO', name:, id:), timeout:) end |
#listener_entry(service, endpoint) ⇒ Hash (private)
Builds a subject-map listener entry from a service and endpoint payload.
158 159 160 161 162 163 164 165 166 167 |
# File 'lib/leopard/nats_service_discovery.rb', line 158 def listener_entry(service, endpoint) { 'service' => service['name'], 'service_id' => service['id'], 'version' => service['version'], 'endpoint' => endpoint['name'], 'queue_group' => endpoint['queue_group'], 'metadata' => endpoint['metadata'], } end |
#no_responders?(msg) ⇒ Boolean (private)
Reports whether a reply is the server no-responders status message.
148 149 150 |
# File 'lib/leopard/nats_service_discovery.rb', line 148 def no_responders?(msg) msg.header && msg.header['Status'] == '503' end |
#ping(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) ⇒ Array<Hash>
Collects $SRV.PING responses.
36 37 38 |
# File 'lib/leopard/nats_service_discovery.rb', line 36 def ping(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) collect_json(service_subject('PING', name:, id:), timeout:) end |
#present?(value) ⇒ Boolean (private)
Reports whether a value is present for subject construction.
174 175 176 |
# File 'lib/leopard/nats_service_discovery.rb', line 174 def present?(value) !value.nil? && !value.to_s.empty? end |
#service_subject(verb, name: nil, id: nil) ⇒ String
Builds a Service API monitoring subject.
88 89 90 91 92 93 94 95 |
# File 'lib/leopard/nats_service_discovery.rb', line 88 def service_subject(verb, name: nil, id: nil) raise ArgumentError, 'service id requires a service name' if present?(id) && !present?(name) parts = [prefix, verb.to_s.upcase] parts << name.to_s if present?(name) parts << id.to_s if present?(id) parts.join('.') end |
#stats(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) ⇒ Array<Hash>
Collects $SRV.STATS responses.
58 59 60 |
# File 'lib/leopard/nats_service_discovery.rb', line 58 def stats(name: nil, id: nil, timeout: DEFAULT_TIMEOUT) collect_json(service_subject('STATS', name:, id:), timeout:) end |
#subscribe_to_inbox ⇒ NATS::Subscription (private)
Subscribes to an ephemeral reply inbox and flushes the subscription.
121 122 123 124 125 |
# File 'lib/leopard/nats_service_discovery.rb', line 121 def subscribe_to_inbox sub = client.subscribe(client.new_inbox) client.flush sub end |