Class: Async::Service::Supervisor::Envoy::Monitor

Inherits:
Monitor
  • Object
show all
Defined in:
lib/async/service/supervisor/envoy/monitor.rb

Overview

Represents a supervisor monitor that publishes worker endpoints to Envoy using xDS.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bind: nil, delegate: Delegate.new, control_plane: Async::GRPC::XDS::ControlPlane.new, orca: false, processor: nil, utilization_monitor: nil, interval: 1, **options) ⇒ Monitor

Initialize the monitor.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 35

def initialize(
	bind: nil,
	delegate: Delegate.new,
	control_plane: Async::GRPC::XDS::ControlPlane.new,
	orca: false,
	processor: nil,
	utilization_monitor: nil,
	interval: 1,
	**options
)
	super(interval: interval, **options)
	
	@bind = bind
	@delegate = delegate
	@control_plane = control_plane
	@interval = interval
	@orca = orca
	@controllers = {}
	@published_clusters = {}
	@server_task = nil
	@mutex = Mutex.new
	
	if @orca
		raise ArgumentError, "ORCA reporting requires a TCP bind address!" unless @bind
		raise ArgumentError, "ORCA reporting requires a utilization monitor!" unless utilization_monitor
		
		@orca_port = server_endpoint.url.port
		raise ArgumentError, "ORCA reporting requires a fixed TCP port!" unless @orca_port&.positive?
		
		@processor = processor || Process::Metrics::Processor.new
		@utilization_monitor = utilization_monitor
		@request_totals = {}
		@load_reports = {}
		@authorities = {}
	end
end

Instance Attribute Details

#control_planeObject (readonly)

Returns the value of attribute control_plane.



73
74
75
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 73

def control_plane
  @control_plane
end

#delegateObject (readonly)

Returns the value of attribute delegate.



76
77
78
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 76

def delegate
  @delegate
end

#The xDS control plane receiving cluster and endpoint updates.(xDScontrolplanereceivingcluster) ⇒ Object (readonly)



73
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 73

attr :control_plane

Instance Method Details

#as_jsonObject

Convert the currently published endpoints to JSON-compatible data.



124
125
126
127
128
129
130
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 124

def as_json
	@mutex.synchronize do
		{
			clusters: build_clusters
		}
	end
end

#load_report(authority) ⇒ Object

Get the latest ORCA report for a worker authority.



144
145
146
147
148
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 144

def load_report(authority)
	return unless @orca
	
	@mutex.synchronize{@load_reports[authority]}
end

#register(supervisor_controller) ⇒ Object

Register a supervisor worker with Envoy.



81
82
83
84
85
86
87
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 81

def register(supervisor_controller)
	@mutex.synchronize do
		@controllers[supervisor_controller.id] = supervisor_controller
		@authorities[worker_hostname(supervisor_controller)] = supervisor_controller.id if @orca
		reconcile
	end
end

#remove(supervisor_controller) ⇒ Object

Remove a supervisor worker from Envoy.



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 92

def remove(supervisor_controller)
	@mutex.synchronize do
		@controllers.delete(supervisor_controller.id)
		if @orca
			hostname = worker_hostname(supervisor_controller)
			@authorities.delete(hostname)
			@load_reports.delete(hostname)
			@request_totals.delete(supervisor_controller.id)
		end
		reconcile
	end
end

#run(parent: Async::Task.current) ⇒ Object

Run the monitor and optional xDS server task.



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 108

def run(parent: Async::Task.current)
	task = super(parent: parent)
	
	if @bind
		@server_task = parent.async do
			server = Async::GRPC::XDS::Server.new(@control_plane)
			server.dispatcher.register(ORCAService.new(self, minimum_interval: @interval)) if @orca
			server.run(server_endpoint)
		end
	end
	
	task
end

#run_onceObject

Refresh endpoint health and publish updated EDS state.



152
153
154
155
156
157
158
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 152

def run_once
	sample_load_reports if @orca
	
	@mutex.synchronize do
		reconcile
	end
end

#The delegate used to map supervisor state into Envoy endpoints.=(delegateusedtomapsupervisorstateintoEnvoyendpoints. = (value)) ⇒ Object



76
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 76

attr :delegate

#worker?(authority) ⇒ Boolean

Determine whether an ORCA worker authority is currently registered.

Returns:

  • (Boolean)


135
136
137
138
139
# File 'lib/async/service/supervisor/envoy/monitor.rb', line 135

def worker?(authority)
	return false unless @orca
	
	@mutex.synchronize{@authorities.key?(authority)}
end