falcon 0.50.0 → 0.51.0
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/bake/falcon/supervisor.rb +1 -3
- data/lib/falcon/command/top.rb +0 -2
- data/lib/falcon/environment/server.rb +17 -1
- data/lib/falcon/environment/supervisor.rb +4 -28
- data/lib/falcon/service/server.rb +6 -1
- data/lib/falcon/version.rb +1 -1
- data/readme.md +9 -0
- data/releases.md +35 -0
- data.tar.gz.sig +0 -0
- metadata +16 -18
- metadata.gz.sig +0 -0
- data/lib/falcon/command/supervisor.rb +0 -73
- data/lib/falcon/service/supervisor.rb +0 -123
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9ecf3850f21fa9285cc2c274629a706829cbe25d5d8db5773548421cba3619d
|
4
|
+
data.tar.gz: 6d9fcd1a57350ce6746a959ee72da073c7c5b6332b3e5686a168d86201c1d7b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f19565cfe07b0c6281698f9815090419799176b546134be71829a75bac552b0d007cbfc6718448c4e73af0870055672d449ac808cf4a68c5c21b1d666a696aa
|
7
|
+
data.tar.gz: 386fbecdf6b82bdccc771d7c0221fc883762998a3233722343d3db190b3868ec57b9b675840a356ab0b3461bf33e6194414aa25edfc97401315017d41eef1423
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/bake/falcon/supervisor.rb
CHANGED
data/lib/falcon/command/top.rb
CHANGED
@@ -8,7 +8,6 @@ require_relative "host"
|
|
8
8
|
require_relative "virtual"
|
9
9
|
require_relative "proxy"
|
10
10
|
require_relative "redirect"
|
11
|
-
require_relative "supervisor"
|
12
11
|
|
13
12
|
require_relative "../version"
|
14
13
|
|
@@ -38,7 +37,6 @@ module Falcon
|
|
38
37
|
"virtual" => Virtual,
|
39
38
|
"proxy" => Proxy,
|
40
39
|
"redirect" => Redirect,
|
41
|
-
"supervisor" => Supervisor,
|
42
40
|
}, default: "serve"
|
43
41
|
|
44
42
|
# Whether verbose logging is enabled.
|
@@ -45,14 +45,16 @@ module Falcon
|
|
45
45
|
"http://[::]:9292"
|
46
46
|
end
|
47
47
|
|
48
|
+
# The timeout used for client connections.
|
48
49
|
def timeout
|
49
50
|
nil
|
50
51
|
end
|
51
52
|
|
53
|
+
# Options to use when creating the endpoint.
|
52
54
|
def endpoint_options
|
53
55
|
{
|
54
56
|
reuse_address: true,
|
55
|
-
timeout: timeout,
|
57
|
+
timeout: self.timeout,
|
56
58
|
}
|
57
59
|
end
|
58
60
|
|
@@ -62,22 +64,36 @@ module Falcon
|
|
62
64
|
::Async::HTTP::Endpoint.parse(url).with(**endpoint_options)
|
63
65
|
end
|
64
66
|
|
67
|
+
# Whether to enable verbose logging.
|
65
68
|
def verbose
|
66
69
|
false
|
67
70
|
end
|
68
71
|
|
72
|
+
# Whether to enable the HTTP cache for this server.
|
69
73
|
def cache
|
70
74
|
false
|
71
75
|
end
|
72
76
|
|
77
|
+
# A client endpoint that can be used to connect to the server.
|
78
|
+
# @returns [Async::HTTP::Endpoint] The client endpoint.
|
73
79
|
def client_endpoint
|
74
80
|
::Async::HTTP::Endpoint.parse(url)
|
75
81
|
end
|
76
82
|
|
77
83
|
# Any scripts to preload before starting the server.
|
84
|
+
#
|
85
|
+
# @returns [Array(String)] The list of scripts to preload.
|
78
86
|
def preload
|
79
87
|
[]
|
80
88
|
end
|
89
|
+
|
90
|
+
# Make a server instance using the given endpoint. The endpoint may be a bound endpoint, so we take care to specify the protocol and scheme as per the original endpoint.
|
91
|
+
#
|
92
|
+
# @parameter endpoint [IO::Endpoint] The endpoint to bind to.
|
93
|
+
# @returns [Falcon::Server] The server instance.
|
94
|
+
def make_server(endpoint)
|
95
|
+
Falcon::Server.new(self.middleware, endpoint, protocol: self.endpoint.protocol, scheme: self.endpoint.scheme)
|
96
|
+
end
|
81
97
|
end
|
82
98
|
end
|
83
99
|
end
|
@@ -3,42 +3,18 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative "../service/supervisor"
|
7
6
|
require_relative "../environment"
|
8
7
|
|
9
|
-
require "
|
8
|
+
require "async/container/supervisor"
|
10
9
|
|
11
10
|
module Falcon
|
12
11
|
module Environment
|
13
12
|
# Provides an environment for hosting a supervisor which can monitor multiple applications.
|
14
13
|
module Supervisor
|
15
|
-
|
16
|
-
# @returns [Class]
|
17
|
-
def service_class
|
18
|
-
::Falcon::Service::Supervisor
|
19
|
-
end
|
20
|
-
|
21
|
-
# The name of the supervisor
|
22
|
-
# @returns [String]
|
23
|
-
def name
|
24
|
-
"supervisor"
|
25
|
-
end
|
26
|
-
|
27
|
-
# The IPC path to use for communication with the supervisor.
|
28
|
-
# @returns [String]
|
29
|
-
def ipc_path
|
30
|
-
::File.expand_path("supervisor.ipc", root)
|
31
|
-
end
|
32
|
-
|
33
|
-
# The endpoint the supervisor will bind to.
|
34
|
-
# @returns [::IO::Endpoint::Generic]
|
35
|
-
def endpoint
|
36
|
-
::IO::Endpoint.unix(ipc_path)
|
37
|
-
end
|
14
|
+
include Async::Container::Supervisor::Environment
|
38
15
|
|
39
|
-
|
40
|
-
|
41
|
-
{restart: true, count: 1, health_check_timeout: 30}
|
16
|
+
def monitors
|
17
|
+
[Async::Container::Supervisor::MemoryMonitor.new(interval: 10)]
|
42
18
|
end
|
43
19
|
end
|
44
20
|
|
@@ -5,6 +5,7 @@
|
|
5
5
|
# Copyright, 2020, by Daniel Evans.
|
6
6
|
|
7
7
|
require "async/service/generic"
|
8
|
+
require "async/container/supervisor/supervised"
|
8
9
|
require "async/http/endpoint"
|
9
10
|
|
10
11
|
require_relative "../server"
|
@@ -58,7 +59,11 @@ module Falcon
|
|
58
59
|
evaluator = @environment.evaluator
|
59
60
|
|
60
61
|
Async do |task|
|
61
|
-
|
62
|
+
if @environment.implements?(Async::Container::Supervisor::Supervised)
|
63
|
+
evaluator.make_supervised_worker(instance).run
|
64
|
+
end
|
65
|
+
|
66
|
+
server = evaluator.make_server(@bound_endpoint)
|
62
67
|
|
63
68
|
server.run
|
64
69
|
|
data/lib/falcon/version.rb
CHANGED
data/readme.md
CHANGED
@@ -45,6 +45,15 @@ Please see the [project documentation](https://socketry.github.io/falcon/) for m
|
|
45
45
|
|
46
46
|
Please see the [project releases](https://socketry.github.io/falcon/releases/index) for all releases.
|
47
47
|
|
48
|
+
### v0.51.0
|
49
|
+
|
50
|
+
- Introduce <code class="language-ruby">Falcon::Environment::Server\#make\_server</code> which gives you full control over the server creation process.
|
51
|
+
- [Introduce `Async::Container::Supervisor`.](https://socketry.github.io/falcon/releases/index#introduce-async::container::supervisor.)
|
52
|
+
|
53
|
+
### v0.50.0
|
54
|
+
|
55
|
+
- Add <code class="language-ruby">Falcon::Environment::Server\#endpoint\_options</code> to allow configuration of the endpoint options more easily.
|
56
|
+
|
48
57
|
### v0.49.0
|
49
58
|
|
50
59
|
- [Falcon Server Container Health Checks](https://socketry.github.io/falcon/releases/index#falcon-server-container-health-checks)
|
data/releases.md
CHANGED
@@ -1,5 +1,40 @@
|
|
1
1
|
# Releases
|
2
2
|
|
3
|
+
## v0.51.0
|
4
|
+
|
5
|
+
- Introduce {ruby Falcon::Environment::Server\#make\_server} which gives you full control over the server creation process.
|
6
|
+
|
7
|
+
### Introduce `Async::Container::Supervisor`.
|
8
|
+
|
9
|
+
`Async::Container::Supervisor` is a new supervisor implementation that replaces Falcon's own supervisor. This allows you to use the same supervisor for all your services, and provides a more consistent interface for managing services. The supervisor is now a separate gem, `async-container-supervisor`.
|
10
|
+
|
11
|
+
By default, the supervisor does not perform any monitoring, but you may add monitoring by defining them in the service definition. For example:
|
12
|
+
|
13
|
+
``` ruby
|
14
|
+
service "hello.localhost" do
|
15
|
+
# Configure server...
|
16
|
+
|
17
|
+
include Async::Container::Supervisor::Supervised
|
18
|
+
end
|
19
|
+
|
20
|
+
service "supervisor" do
|
21
|
+
include Async::Container::Supervisor::Environment
|
22
|
+
|
23
|
+
monitors do
|
24
|
+
[
|
25
|
+
# Limit total memory usage to 512MiB:
|
26
|
+
Async::Container::Supervisor::MemoryMonitor.new(interval: 10, limit: 1024 * 1024 * 512),
|
27
|
+
]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
We retain the `falcon:supervisor:restart` task, but you may prefer to use `async:container:supervisor:restart` directly.
|
33
|
+
|
34
|
+
## v0.50.0
|
35
|
+
|
36
|
+
- Add {ruby Falcon::Environment::Server\#endpoint\_options} to allow configuration of the endpoint options more easily.
|
37
|
+
|
3
38
|
## v0.49.0
|
4
39
|
|
5
40
|
### Falcon Server Container Health Checks
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: falcon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.51.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -60,7 +60,7 @@ cert_chain:
|
|
60
60
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
61
61
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
62
62
|
-----END CERTIFICATE-----
|
63
|
-
date: 2025-
|
63
|
+
date: 2025-03-01 00:00:00.000000000 Z
|
64
64
|
dependencies:
|
65
65
|
- !ruby/object:Gem::Dependency
|
66
66
|
name: async
|
@@ -90,6 +90,20 @@ dependencies:
|
|
90
90
|
- - "~>"
|
91
91
|
- !ruby/object:Gem::Version
|
92
92
|
version: '0.20'
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: async-container-supervisor
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 0.5.0
|
100
|
+
type: :runtime
|
101
|
+
prerelease: false
|
102
|
+
version_requirements: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - "~>"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 0.5.0
|
93
107
|
- !ruby/object:Gem::Dependency
|
94
108
|
name: async-http
|
95
109
|
requirement: !ruby/object:Gem::Requirement
|
@@ -174,20 +188,6 @@ dependencies:
|
|
174
188
|
- - "~>"
|
175
189
|
- !ruby/object:Gem::Version
|
176
190
|
version: '3.0'
|
177
|
-
- !ruby/object:Gem::Dependency
|
178
|
-
name: process-metrics
|
179
|
-
requirement: !ruby/object:Gem::Requirement
|
180
|
-
requirements:
|
181
|
-
- - "~>"
|
182
|
-
- !ruby/object:Gem::Version
|
183
|
-
version: '0.2'
|
184
|
-
type: :runtime
|
185
|
-
prerelease: false
|
186
|
-
version_requirements: !ruby/object:Gem::Requirement
|
187
|
-
requirements:
|
188
|
-
- - "~>"
|
189
|
-
- !ruby/object:Gem::Version
|
190
|
-
version: '0.2'
|
191
191
|
- !ruby/object:Gem::Dependency
|
192
192
|
name: protocol-http
|
193
193
|
requirement: !ruby/object:Gem::Requirement
|
@@ -246,7 +246,6 @@ files:
|
|
246
246
|
- lib/falcon/command/proxy.rb
|
247
247
|
- lib/falcon/command/redirect.rb
|
248
248
|
- lib/falcon/command/serve.rb
|
249
|
-
- lib/falcon/command/supervisor.rb
|
250
249
|
- lib/falcon/command/top.rb
|
251
250
|
- lib/falcon/command/virtual.rb
|
252
251
|
- lib/falcon/configuration.rb
|
@@ -272,7 +271,6 @@ files:
|
|
272
271
|
- lib/falcon/railtie.rb
|
273
272
|
- lib/falcon/server.rb
|
274
273
|
- lib/falcon/service/server.rb
|
275
|
-
- lib/falcon/service/supervisor.rb
|
276
274
|
- lib/falcon/service/virtual.rb
|
277
275
|
- lib/falcon/tls.rb
|
278
276
|
- lib/falcon/version.rb
|
metadata.gz.sig
CHANGED
Binary file
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-2024, by Samuel Williams.
|
5
|
-
|
6
|
-
require "samovar"
|
7
|
-
require "async"
|
8
|
-
require "json"
|
9
|
-
|
10
|
-
require "io/endpoint/unix_endpoint"
|
11
|
-
require "io/stream"
|
12
|
-
|
13
|
-
module Falcon
|
14
|
-
module Command
|
15
|
-
# Implements the `falcon supervisor` command.
|
16
|
-
#
|
17
|
-
# Talks to an instance of the supervisor to issue commands and print results.
|
18
|
-
class Supervisor < Samovar::Command
|
19
|
-
self.description = "Control and query a specific supervisor."
|
20
|
-
|
21
|
-
# The command line options.
|
22
|
-
# @attribute [Samovar::Options]
|
23
|
-
options do
|
24
|
-
option "--path <path>", "The control IPC path.", default: "supervisor.ipc"
|
25
|
-
end
|
26
|
-
|
27
|
-
# Implements the `falcon supervisor restart` command.
|
28
|
-
class Restart < Samovar::Command
|
29
|
-
self.description = "Restart the process group."
|
30
|
-
|
31
|
-
# Send the restart message to the supervisor.
|
32
|
-
def call(stream)
|
33
|
-
stream.puts({please: "restart"}.to_json, separator: "\0")
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Implements the `falcon supervisor metrics` command.
|
38
|
-
class Metrics < Samovar::Command
|
39
|
-
self.description = "Show metrics about the falcon processes."
|
40
|
-
|
41
|
-
# Send the metrics message to the supervisor and print the results.
|
42
|
-
def call(stream)
|
43
|
-
stream.puts({please: "metrics"}.to_json, separator: "\0", chomp: true)
|
44
|
-
response = JSON.parse(stream.read_until("\0"), symbolize_names: true)
|
45
|
-
|
46
|
-
$stdout.puts response
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# The nested command to execute.
|
51
|
-
# @name nested
|
52
|
-
# @attribute [Command]
|
53
|
-
nested :command, {
|
54
|
-
"restart" => Restart,
|
55
|
-
"metrics" => Metrics,
|
56
|
-
}, default: "metrics"
|
57
|
-
|
58
|
-
# The endpoint the supervisor is bound to.
|
59
|
-
def endpoint
|
60
|
-
::IO::Endpoint.unix(@options[:path])
|
61
|
-
end
|
62
|
-
|
63
|
-
# Connect to the supervisor and execute the requested command.
|
64
|
-
def call
|
65
|
-
Sync do
|
66
|
-
endpoint.connect do |socket|
|
67
|
-
@command.call(IO::Stream(socket))
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,123 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-2024, by Samuel Williams.
|
5
|
-
|
6
|
-
require "process/metrics"
|
7
|
-
require "json"
|
8
|
-
|
9
|
-
require "async/service/generic"
|
10
|
-
|
11
|
-
require "io/endpoint/bound_endpoint"
|
12
|
-
require "io/stream"
|
13
|
-
|
14
|
-
module Falcon
|
15
|
-
module Service
|
16
|
-
# Implements a host supervisor which can restart the host services and provide various metrics about the running processes.
|
17
|
-
class Supervisor < Async::Service::Generic
|
18
|
-
# Initialize the supervisor using the given environment.
|
19
|
-
# @parameter environment [Build::Environment]
|
20
|
-
def initialize(...)
|
21
|
-
super
|
22
|
-
|
23
|
-
@bound_endpoint = nil
|
24
|
-
end
|
25
|
-
|
26
|
-
# The endpoint which the supervisor will bind to.
|
27
|
-
# Typically a unix pipe in the same directory as the host.
|
28
|
-
def endpoint
|
29
|
-
@evaluator.endpoint
|
30
|
-
end
|
31
|
-
|
32
|
-
# Restart the process group that the supervisor belongs to.
|
33
|
-
def do_restart(message)
|
34
|
-
# Tell the parent of this process group to spin up a new process group/container.
|
35
|
-
# Wait for that to start accepting new connections.
|
36
|
-
# Stop accepting connections.
|
37
|
-
# Wait for existing connnections to drain.
|
38
|
-
# Terminate this process group.
|
39
|
-
signal = message[:signal] || :INT
|
40
|
-
|
41
|
-
Process.kill(signal, Process.ppid)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Capture process metrics relating to the process group that the supervisor belongs to.
|
45
|
-
def do_metrics(message)
|
46
|
-
Process::Metrics::General.capture(pid: Process.ppid, ppid: Process.ppid)
|
47
|
-
end
|
48
|
-
|
49
|
-
# Handle an incoming request.
|
50
|
-
# @parameter message [Hash] The decoded message.
|
51
|
-
def handle(message)
|
52
|
-
case message[:please]
|
53
|
-
when "restart"
|
54
|
-
self.do_restart(message)
|
55
|
-
when "metrics"
|
56
|
-
self.do_metrics(message)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# Bind the supervisor to the specified endpoint.
|
61
|
-
def start
|
62
|
-
Console.logger.info(self) {"Binding to #{self.endpoint}..."}
|
63
|
-
|
64
|
-
@bound_endpoint = Sync{self.endpoint.bound}
|
65
|
-
|
66
|
-
super
|
67
|
-
end
|
68
|
-
|
69
|
-
# Start the supervisor process which accepts connections from the bound endpoint and processes JSON formatted messages.
|
70
|
-
# @parameter container [Async::Container::Generic]
|
71
|
-
def setup(container)
|
72
|
-
container_options = @evaluator.container_options
|
73
|
-
health_check_timeout = container_options[:health_check_timeout]
|
74
|
-
|
75
|
-
container.run(name: self.name, **container_options) do |instance|
|
76
|
-
Async do
|
77
|
-
@bound_endpoint.accept do |peer|
|
78
|
-
stream = ::IO::Stream(peer)
|
79
|
-
|
80
|
-
while message = stream.read_until("\0")
|
81
|
-
response = handle(JSON.parse(message, symbolize_names: true))
|
82
|
-
stream.puts(response.to_json, separator: "\0")
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
instance.ready!
|
87
|
-
|
88
|
-
if health_check_timeout
|
89
|
-
Async(transient: true) do
|
90
|
-
while true
|
91
|
-
sleep(health_check_timeout / 2)
|
92
|
-
instance.ready!
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
super
|
100
|
-
end
|
101
|
-
|
102
|
-
# Release the bound endpoint.
|
103
|
-
def stop
|
104
|
-
@bound_endpoint&.close
|
105
|
-
@bound_endpoint = nil
|
106
|
-
|
107
|
-
super
|
108
|
-
end
|
109
|
-
|
110
|
-
def invoke(command)
|
111
|
-
@bound_endpoint.local_address_endpoint.connect do |peer|
|
112
|
-
stream = ::IO::Stream(peer)
|
113
|
-
|
114
|
-
stream.puts(command.to_json, separator: "\0")
|
115
|
-
|
116
|
-
response = JSON.parse(stream.read_until("\0"), symbolize_names: true)
|
117
|
-
|
118
|
-
return response
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|