async-service-supervisor-envoy 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 554c82adfbbf77fc5fe7e0ee5a0bbe9a67de5161cc7699eab8b98cf4c0cb5847
4
+ data.tar.gz: 44a9f2a1488f5108dc18b859b43f0ad3ec2709490784e0500587c240790d9749
5
+ SHA512:
6
+ metadata.gz: 7752e3f6af3a6795a5f294867cb4cf11523cb4192d464ea29834278f4d7f799969c18c4a9cc9bbd70ddd035b34dc532378333be2aad12488b7822af761284954
7
+ data.tar.gz: a9abeeb77d2eb1ca67d219fdb9ef75820c841d7bf9c15b86ee012e4296702524ecacdd2780d9b21b1d2e3520873048741b960b1d92c5a0a0b91761bc8845ef97
checksums.yaml.gz.sig ADDED
Binary file
data/code.md ADDED
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,94 @@
1
+ # Getting Started
2
+
3
+ This guide explains how to use `async-service-supervisor-envoy` to publish supervised worker endpoints to Envoy using xDS.
4
+
5
+ ## Installation
6
+
7
+ Add the gem to your project:
8
+
9
+ ~~~ bash
10
+ $ bundle add async-service-supervisor-envoy
11
+ ~~~
12
+
13
+ The gem depends on `async-service-supervisor` and `async-grpc-xds`.
14
+
15
+ ## Core Concepts
16
+
17
+ `async-service-supervisor-envoy` provides:
18
+
19
+ - {ruby Async::Service::Supervisor::Envoy::Monitor} - A supervisor monitor that publishes worker endpoints through xDS.
20
+ - {ruby Async::Service::Supervisor::Envoy::Endpoint} - A small value object for endpoint state.
21
+
22
+ The monitor runs an xDS control plane endpoint. Envoy connects to it using ADS and receives CDS/EDS updates derived from supervisor worker state.
23
+
24
+ ## Endpoint State
25
+
26
+ Workers are published when they register concrete endpoint state:
27
+
28
+ ``` ruby
29
+ state = {
30
+ endpoint: {
31
+ name: "myservice",
32
+ scheme: :http,
33
+ protocols: ["http/1.1"],
34
+ addresses: [
35
+ {address: "127.0.0.1", port: 50051},
36
+ {path: "/run/myservice/worker.ipc"}
37
+ ]
38
+ }
39
+ }
40
+ ```
41
+
42
+ Workers without endpoint state are ignored by the Envoy monitor.
43
+
44
+ Falcon cluster workers can register their concrete post-bind listener automatically:
45
+
46
+ ``` ruby
47
+ service "application" do
48
+ include Falcon::Environment::Cluster
49
+ include Async::Service::Supervisor::Envoy::Supervised
50
+ end
51
+ ```
52
+
53
+ Falcon describes its bound server resource as a listener. The integration converts that listener into Envoy upstream endpoint state, including its name, scheme, supported protocols, and every concrete IP or Unix socket address. Addresses belonging to one listener remain grouped as one Envoy load-balancer endpoint.
54
+
55
+ ## Monitor Usage
56
+
57
+ Add the monitor to your supervisor environment:
58
+
59
+ ``` ruby
60
+ require "async/service/supervisor/envoy"
61
+
62
+ Async::Service::Supervisor::Envoy::Monitor.new(
63
+ bind: "http://127.0.0.1:18000"
64
+ )
65
+ ```
66
+
67
+ By default, workers are grouped into clusters by `state[:name]`.
68
+
69
+ ## Custom Mapping
70
+
71
+ You can customize cluster grouping, endpoint selection, and health with a delegate:
72
+
73
+ ``` ruby
74
+ class EnvoyDelegate < Async::Service::Supervisor::Envoy::Delegate
75
+ def endpoint_list(supervisor_controller)
76
+ super
77
+ end
78
+
79
+ def cluster(supervisor_controller, endpoint)
80
+ super
81
+ end
82
+
83
+ def healthy?(supervisor_controller, endpoint)
84
+ true
85
+ end
86
+ end
87
+
88
+ Async::Service::Supervisor::Envoy::Monitor.new(
89
+ bind: "http://127.0.0.1:18000",
90
+ delegate: EnvoyDelegate.new
91
+ )
92
+ ```
93
+
94
+ Disconnected workers are removed from EDS. Registered workers that fail the delegate health check remain in EDS with an unhealthy endpoint status.
@@ -0,0 +1,12 @@
1
+ # Automatically generated context index for Utopia::Project guides.
2
+ # Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
3
+ ---
4
+ description: Envoy xDS monitor for async-service-supervisor.
5
+ metadata:
6
+ documentation_uri: https://socketry.github.io/async-service-supervisor-envoy/
7
+ source_code_uri: https://github.com/socketry/async-service-supervisor-envoy.git
8
+ files:
9
+ - path: getting-started.md
10
+ title: Getting Started
11
+ description: This guide explains how to use `async-service-supervisor-envoy` to
12
+ publish supervised worker endpoints to Envoy using xDS.
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2026, by Samuel Williams.
5
+
6
+ require_relative "endpoint"
7
+
8
+ module Async
9
+ module Service
10
+ module Supervisor
11
+ module Envoy
12
+ # Maps supervisor state into Envoy upstream endpoints.
13
+ class Delegate
14
+ # Extract serialized endpoints from a supervisor controller.
15
+ # @parameter supervisor_controller [Object] The supervisor controller describing the worker.
16
+ # @returns [Hash | Array(Hash) | Nil] The serialized endpoint state.
17
+ def endpoints(supervisor_controller)
18
+ state = supervisor_controller.state
19
+
20
+ state[:endpoints] || state[:endpoint]
21
+ end
22
+
23
+ # Convert serialized state into Envoy endpoint values.
24
+ # @parameter supervisor_controller [Object] The supervisor controller describing the worker.
25
+ # @returns [Array(Endpoint)] The upstream endpoints to publish.
26
+ def endpoint_list(supervisor_controller)
27
+ case endpoints = self.endpoints(supervisor_controller)
28
+ when nil
29
+ []
30
+ when Array
31
+ endpoints.map{|endpoint| Endpoint.wrap(endpoint)}
32
+ else
33
+ [Endpoint.wrap(endpoints)]
34
+ end
35
+ end
36
+
37
+ # Select the Envoy cluster name for an endpoint.
38
+ # @parameter supervisor_controller [Object] The supervisor controller describing the worker.
39
+ # @parameter endpoint [Endpoint] The endpoint being published.
40
+ # @returns [String | Nil] The cluster name, or nil to skip the endpoint.
41
+ def cluster(supervisor_controller, endpoint)
42
+ endpoint.name
43
+ end
44
+
45
+ # Determine whether an endpoint should be published as healthy.
46
+ # @parameter supervisor_controller [Object] The supervisor controller describing the worker.
47
+ # @parameter endpoint [Endpoint] The endpoint being published.
48
+ # @returns [Boolean] Whether the endpoint is healthy.
49
+ def healthy?(supervisor_controller, endpoint)
50
+ true
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2026, by Samuel Williams.
5
+
6
+ module Async
7
+ module Service
8
+ module Supervisor
9
+ module Envoy
10
+ # Represents one upstream endpoint published to Envoy EDS.
11
+ class Endpoint
12
+ # Wrap serialized endpoint state.
13
+ # @parameter value [Endpoint | Hash] The value to wrap.
14
+ # @returns [Endpoint] The endpoint value.
15
+ def self.wrap(value)
16
+ case value
17
+ when self
18
+ value
19
+ when Hash
20
+ new(**value)
21
+ else
22
+ raise ArgumentError, "Invalid Envoy endpoint: #{value.inspect}"
23
+ end
24
+ end
25
+
26
+ # Normalize a concrete endpoint address.
27
+ # @parameter value [Hash] The address value.
28
+ # @returns [Hash] A normalized IP or Unix address.
29
+ def self.normalize_address(value)
30
+ if path = value[:path]
31
+ raise ArgumentError, "A Unix endpoint cannot specify an IP address or port!" if value[:address] || value[:port]
32
+
33
+ {path: path.to_s}.freeze
34
+ elsif value[:address] && value[:port]
35
+ {address: value[:address].to_s, port: Integer(value[:port])}.freeze
36
+ else
37
+ raise ArgumentError, "An endpoint address requires either path, or address and port: #{value.inspect}"
38
+ end
39
+ end
40
+
41
+ # Initialize an endpoint.
42
+ # @parameter name [String] The upstream cluster name.
43
+ # @parameter scheme [String | Symbol] The upstream application scheme.
44
+ # @parameter protocols [Array(String)] The supported upstream HTTP protocol names.
45
+ # @parameter addresses [Array(Hash)] The grouped concrete addresses.
46
+ def initialize(name:, scheme:, protocols:, addresses:)
47
+ @name = name.to_s
48
+ @scheme = scheme.to_sym
49
+ @protocols = protocols.map(&:to_s).uniq.freeze
50
+ raise ArgumentError, "An endpoint requires at least one protocol!" if @protocols.empty?
51
+ @addresses = addresses.map{|value| self.class.normalize_address(value)}.freeze
52
+ raise ArgumentError, "An endpoint requires at least one address!" if @addresses.empty?
53
+ end
54
+
55
+ # @attribute [String] The upstream cluster name.
56
+ attr :name
57
+
58
+ # @attribute [Symbol] The upstream application scheme.
59
+ attr :scheme
60
+
61
+ # @attribute [Array(String)] The supported upstream HTTP protocol names.
62
+ attr :protocols
63
+
64
+ # @attribute [Array(Hash)] The grouped concrete addresses.
65
+ attr :addresses
66
+
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2026, by Samuel Williams.
5
+
6
+ require "async/http/endpoint"
7
+ require "async/service/supervisor/monitor"
8
+ require "async/grpc/xds/control_plane"
9
+ require "async/grpc/xds/server"
10
+
11
+ require_relative "delegate"
12
+ require_relative "endpoint"
13
+
14
+ module Async
15
+ module Service
16
+ module Supervisor
17
+ # Provides Envoy integration for supervisor-managed services.
18
+ module Envoy
19
+ # Represents a supervisor monitor that publishes worker endpoints to Envoy using xDS.
20
+ class Monitor < Async::Service::Supervisor::Monitor
21
+ # Initialize the monitor.
22
+ # @parameter bind [String | Nil] The optional address for the xDS control plane server.
23
+ # @parameter delegate [Delegate] The delegate used to map supervisor state into Envoy endpoints.
24
+ # @parameter control_plane [Async::GRPC::XDS::ControlPlane] The xDS control plane to update.
25
+ def initialize(
26
+ bind: nil,
27
+ delegate: Delegate.new,
28
+ control_plane: Async::GRPC::XDS::ControlPlane.new,
29
+ **options
30
+ )
31
+ super(**options)
32
+
33
+ @bind = bind
34
+ @delegate = delegate
35
+ @control_plane = control_plane
36
+ @controllers = {}
37
+ @published_clusters = {}
38
+ @server_task = nil
39
+ @mutex = Mutex.new
40
+ end
41
+
42
+ # @attribute [Async::GRPC::XDS::ControlPlane] The xDS control plane receiving cluster and endpoint updates.
43
+ attr :control_plane
44
+
45
+ # @attribute [Delegate] The delegate used to map supervisor state into Envoy endpoints.
46
+ attr :delegate
47
+
48
+ # Register a supervisor worker with Envoy.
49
+ # @parameter supervisor_controller [Object] The supervisor controller describing the worker.
50
+ # @returns [void]
51
+ def register(supervisor_controller)
52
+ @mutex.synchronize do
53
+ @controllers[supervisor_controller.id] = supervisor_controller
54
+ reconcile
55
+ end
56
+ end
57
+
58
+ # Remove a supervisor worker from Envoy.
59
+ # @parameter supervisor_controller [Object] The supervisor controller describing the worker.
60
+ # @returns [void]
61
+ def remove(supervisor_controller)
62
+ @mutex.synchronize do
63
+ @controllers.delete(supervisor_controller.id)
64
+ reconcile
65
+ end
66
+ end
67
+
68
+ # Run the monitor and optional xDS server task.
69
+ # @parameter parent [Async::Task] The parent task used for the xDS server.
70
+ # @returns [Async::Task] The monitor task.
71
+ def run(parent: Async::Task.current)
72
+ task = super(parent: parent)
73
+
74
+ if @bind
75
+ @server_task = parent.async do
76
+ endpoint = Async::HTTP::Endpoint.parse(@bind, protocol: Async::HTTP::Protocol::HTTP2)
77
+ Async::GRPC::XDS::Server.new(@control_plane).run(endpoint)
78
+ end
79
+ end
80
+
81
+ task
82
+ end
83
+
84
+ # Convert the currently published endpoints to JSON-compatible data.
85
+ # @returns [Hash] The clusters and endpoint hashes.
86
+ def as_json
87
+ @mutex.synchronize do
88
+ {
89
+ clusters: build_clusters
90
+ }
91
+ end
92
+ end
93
+
94
+ # Refresh endpoint health and publish updated EDS state.
95
+ # @returns [void]
96
+ def run_once
97
+ @mutex.synchronize do
98
+ reconcile
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def build_record(supervisor_controller, endpoint)
105
+ cluster = @delegate.cluster(supervisor_controller, endpoint)
106
+ return unless cluster
107
+
108
+ {
109
+ cluster: cluster.to_s,
110
+ endpoint: endpoint,
111
+ healthy: @delegate.healthy?(supervisor_controller, endpoint),
112
+ }
113
+ end
114
+
115
+ def build_records(supervisor_controller)
116
+ @delegate.endpoint_list(supervisor_controller).filter_map do |endpoint|
117
+ build_record(supervisor_controller, endpoint)
118
+ end
119
+ end
120
+
121
+ def reconcile
122
+ records_by_cluster = build_records_by_cluster
123
+ clusters = build_clusters(records_by_cluster)
124
+
125
+ records_by_cluster.each do |cluster, records|
126
+ configuration = cluster_configuration(records)
127
+
128
+ unless @published_clusters[cluster] == configuration
129
+ @control_plane.update_cluster(cluster, **configuration)
130
+ @published_clusters[cluster] = configuration
131
+ end
132
+ end
133
+
134
+ (@published_clusters.keys | clusters.keys).each do |cluster|
135
+ @control_plane.update_endpoints(cluster, clusters.fetch(cluster, []))
136
+ end
137
+ end
138
+
139
+ def build_records_by_cluster
140
+ @controllers.each_value.flat_map do |controller|
141
+ build_records(controller)
142
+ end.group_by do |record|
143
+ record[:cluster]
144
+ end
145
+ end
146
+
147
+ def build_clusters(records_by_cluster = build_records_by_cluster)
148
+ records_by_cluster.transform_values do |records|
149
+ records.map do |record|
150
+ {addresses: record[:endpoint].addresses, healthy: record[:healthy]}
151
+ end
152
+ end
153
+ end
154
+
155
+ def cluster_configuration(records)
156
+ schemes = records.map{|record| record[:endpoint].scheme}.uniq
157
+ protocols = records.map{|record| record[:endpoint].protocols}
158
+ common_protocols = protocols.reduce{|common, names| common & names}
159
+
160
+ raise ArgumentError, "Envoy cluster contains incompatible schemes: #{schemes.inspect}" if schemes.size > 1
161
+ raise ArgumentError, "Envoy cluster contains no common protocols: #{protocols.inspect}" if common_protocols.empty?
162
+ raise ArgumentError, "HTTPS upstream endpoints are not yet supported!" if schemes.first == :https
163
+
164
+ {protocol: envoy_protocol(common_protocols)}
165
+ end
166
+
167
+ def envoy_protocol(protocols)
168
+ protocols.each do |protocol|
169
+ case protocol
170
+ when "h2"
171
+ return :http2
172
+ when "http/1.1", "http/1.0"
173
+ return :http1
174
+ end
175
+ end
176
+
177
+ raise ArgumentError, "Envoy cluster contains no supported protocols: #{protocols.inspect}"
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2026, by Samuel Williams.
5
+
6
+ require "async/service/supervisor/supervised"
7
+
8
+ module Async
9
+ module Service
10
+ module Supervisor
11
+ module Envoy
12
+ # Registers post-bind cluster listeners with the supervisor.
13
+ module Supervised
14
+ include Async::Service::Supervisor::Supervised
15
+
16
+ # Prepare and register a worker after its listener has been bound.
17
+ # @parameter instance [Async::Container::Instance] The container instance.
18
+ # @parameter listener [Object] The bound listener descriptor.
19
+ def prepare_worker!(instance, listener:)
20
+ prepare!(instance, state: {endpoint: envoy_endpoint(listener)})
21
+ end
22
+
23
+ # Convert a bound listener into serialized Envoy endpoint state.
24
+ # @parameter listener [Object] The bound listener descriptor.
25
+ # @returns [Hash] The serialized endpoint.
26
+ def envoy_endpoint(listener)
27
+ {
28
+ name: listener.name,
29
+ scheme: listener.scheme,
30
+ protocols: listener.protocols,
31
+ addresses: listener.addresses.map{|address| envoy_address(address)},
32
+ }
33
+ end
34
+
35
+ # Convert a concrete bound address to serializable supervisor state.
36
+ # @parameter address [Addrinfo] The bound address.
37
+ # @returns [Hash] The serialized address.
38
+ # @raises [ArgumentError] If the address family is unsupported.
39
+ def envoy_address(address)
40
+ if address.ip?
41
+ {address: address.ip_address, port: address.ip_port}
42
+ elsif address.unix?
43
+ {path: address.unix_path}
44
+ else
45
+ raise ArgumentError, "Unsupported listener address: #{address.inspect}"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2026, by Samuel Williams.
5
+
6
+ # @namespace
7
+ module Async
8
+ # @namespace
9
+ module Service
10
+ # @namespace
11
+ module Supervisor
12
+ # @namespace
13
+ module Envoy
14
+ VERSION = "0.0.1"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2026, by Samuel Williams.
5
+
6
+ require_relative "envoy/version"
7
+ require_relative "envoy/delegate"
8
+ require_relative "envoy/endpoint"
9
+ require_relative "envoy/monitor"
10
+ require_relative "envoy/supervised"
data/license.md ADDED
@@ -0,0 +1,3 @@
1
+ # License
2
+
3
+ Released under the MIT license.
data/readme.md ADDED
@@ -0,0 +1,75 @@
1
+ # Async::Service::Supervisor::Envoy
2
+
3
+ Provides an Envoy xDS monitor for `async-service-supervisor`.
4
+
5
+ [![Development Status](https://github.com/socketry/async-service-supervisor-envoy/workflows/Test/badge.svg)](https://github.com/socketry/async-service-supervisor-envoy/actions?workflow=Test)
6
+
7
+ ## Features
8
+
9
+ `async-service-supervisor-envoy` publishes supervised worker endpoints to Envoy:
10
+
11
+ - **xDS control plane** - Runs an ADS server backed by `async-grpc-xds`.
12
+ - **Supervisor integration** - Registers and removes endpoints from supervisor worker lifecycle events.
13
+ - **Multiple clusters** - Groups workers by `state[:name]` by default.
14
+ - **Endpoint contract** - Converts concrete post-bind worker listeners into Envoy upstream endpoints, including grouped IP or Unix socket addresses.
15
+ - **Delegate mapping** - Uses a delegate object for endpoint selection, cluster grouping, and health without active probing.
16
+
17
+ ## Usage
18
+
19
+ Please see the [project documentation](https://socketry.github.io/async-service-supervisor-envoy/) for more details.
20
+
21
+ - [Getting Started](https://socketry.github.io/async-service-supervisor-envoy/guides/getting-started/index) - This guide explains how to use `async-service-supervisor-envoy` to publish supervised worker endpoints to Envoy using xDS.
22
+
23
+ ## Releases
24
+
25
+ Please see the [project releases](https://socketry.github.io/async-service-supervisor-envoy/releases/index) for all releases.
26
+
27
+ ### v0.0.1
28
+
29
+ - Register concrete Falcon cluster listeners as Envoy upstream endpoint state after binding.
30
+ - Publish grouped IP and Unix-domain-socket endpoint addresses to Envoy.
31
+ - Configure generated clusters from each endpoint's supported HTTP protocol names.
32
+
33
+ ### v0.1.0
34
+
35
+ - Initial release.
36
+
37
+ ## See Also
38
+
39
+ - [async-service-supervisor](https://github.com/socketry/async-service-supervisor) - Supervisor for managed Async service workers.
40
+ - [async-grpc-xds](https://github.com/socketry/async-grpc-xds) - xDS support for Async::GRPC.
41
+ - [Envoy xDS](https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol) - Envoy dynamic configuration protocol.
42
+
43
+ ## Contributing
44
+
45
+ We welcome contributions to this project.
46
+
47
+ 1. Fork it.
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
50
+ 4. Push to the branch (`git push origin my-new-feature`).
51
+ 5. Create new Pull Request.
52
+
53
+ ### Running Tests
54
+
55
+ To run the test suite:
56
+
57
+ ``` shell
58
+ bundle exec sus
59
+ ```
60
+
61
+ ### Making Releases
62
+
63
+ To make a new release:
64
+
65
+ ``` shell
66
+ bundle exec bake gem:release:patch # or minor or major
67
+ ```
68
+
69
+ ### Developer Certificate of Origin
70
+
71
+ In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
72
+
73
+ ### Community Guidelines
74
+
75
+ This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
data/releases.md ADDED
@@ -0,0 +1,11 @@
1
+ # Releases
2
+
3
+ ## v0.0.1
4
+
5
+ - Register concrete Falcon cluster listeners as Envoy upstream endpoint state after binding.
6
+ - Publish grouped IP and Unix-domain-socket endpoint addresses to Envoy.
7
+ - Configure generated clusters from each endpoint's supported HTTP protocol names.
8
+
9
+ ## v0.1.0
10
+
11
+ - Initial release.
data.tar.gz.sig ADDED
Binary file
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: async-service-supervisor-envoy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Samuel Williams
8
+ bindir: bin
9
+ cert_chain:
10
+ - |
11
+ -----BEGIN CERTIFICATE-----
12
+ MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
13
+ ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
14
+ CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
15
+ MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
16
+ MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
17
+ bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
18
+ igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
19
+ 9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
20
+ sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
21
+ e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
22
+ XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
23
+ RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
24
+ tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
25
+ zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
26
+ xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
27
+ BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
28
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
29
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
30
+ cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
31
+ xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
32
+ c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
33
+ 8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
34
+ JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
35
+ eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
36
+ Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
37
+ voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
38
+ -----END CERTIFICATE-----
39
+ date: 1980-01-02 00:00:00.000000000 Z
40
+ dependencies:
41
+ - !ruby/object:Gem::Dependency
42
+ name: async
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.38'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.38'
55
+ - !ruby/object:Gem::Dependency
56
+ name: async-grpc-xds
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: async-http
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: async-service-supervisor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.18'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.18'
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - code.md
102
+ - context/getting-started.md
103
+ - context/index.yaml
104
+ - lib/async/service/supervisor/envoy.rb
105
+ - lib/async/service/supervisor/envoy/delegate.rb
106
+ - lib/async/service/supervisor/envoy/endpoint.rb
107
+ - lib/async/service/supervisor/envoy/monitor.rb
108
+ - lib/async/service/supervisor/envoy/supervised.rb
109
+ - lib/async/service/supervisor/envoy/version.rb
110
+ - license.md
111
+ - readme.md
112
+ - releases.md
113
+ homepage: https://github.com/socketry/async-service-supervisor-envoy
114
+ licenses:
115
+ - MIT
116
+ metadata:
117
+ documentation_uri: https://socketry.github.io/async-service-supervisor-envoy/
118
+ source_code_uri: https://github.com/socketry/async-service-supervisor-envoy.git
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '3.3'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubygems_version: 4.0.10
134
+ specification_version: 4
135
+ summary: Envoy xDS monitor for async-service-supervisor.
136
+ test_files: []
metadata.gz.sig ADDED
@@ -0,0 +1,5 @@
1
+ S��&�v�59�u���cW�!b9j�1<��]��F�<:��6
2
+ iB<A8�Wm*]������W
3
+ `f�T춐n����@�?o� �����*��,͔�Qv����
4
+ /��0�h��x�YMsxdv��#����R|?^&�<z��0�[y����Lۭn%ף�4��M͸3�Gp��٨�J)�3�_|^󏞤!Q)�vK��ߵ}ծa=��L��goA�Mt�
5
+ ߉�TV�C�욶����v*Ӏ��]LP.J�