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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b5612e05c65dc847f524f1e20345fcffb037c459c493e2cb5d73a1b4964e8b0
4
- data.tar.gz: cbc83ab219046f20cd04f6b99bc438554b76d5b25fe0f2a462cbc3bc0859659d
3
+ metadata.gz: c9ecf3850f21fa9285cc2c274629a706829cbe25d5d8db5773548421cba3619d
4
+ data.tar.gz: 6d9fcd1a57350ce6746a959ee72da073c7c5b6332b3e5686a168d86201c1d7b7
5
5
  SHA512:
6
- metadata.gz: 6357075c07a05e8a7cc85eeda99fb4b7cf276c1a2590d5c7ce3e4578bbc0e08fd47b4a713873a98ed9c033aac293f6d5239970a56de8db403b79afee78bdee2c
7
- data.tar.gz: 8728f7d6aa88546d3cf9de9713400447f41510bc7d5005ed9e77b266d0d9b7c4a285f6056d41f88e1ddb17d82b8ae36d2f9e626893b99919be4d4f8e50836538
6
+ metadata.gz: 4f19565cfe07b0c6281698f9815090419799176b546134be71829a75bac552b0d007cbfc6718448c4e73af0870055672d449ac808cf4a68c5c21b1d666a696aa
7
+ data.tar.gz: 386fbecdf6b82bdccc771d7c0221fc883762998a3233722343d3db190b3868ec57b9b675840a356ab0b3461bf33e6194414aa25edfc97401315017d41eef1423
checksums.yaml.gz.sig CHANGED
Binary file
@@ -4,7 +4,5 @@
4
4
  # Copyright, 2020-2025, by Samuel Williams.
5
5
 
6
6
  def restart
7
- require_relative "../../lib/falcon/command/supervisor"
8
-
9
- Falcon::Command::Supervisor["restart"].call
7
+ context.lookup("async:container:supervisor:restart").call
10
8
  end
@@ -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 "io/endpoint/unix_endpoint"
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
- # The service class to use for the supervisor.
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
- # Options to use when creating the container.
40
- def container_options
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
- server = Falcon::Server.new(evaluator.middleware, @bound_endpoint, protocol: @endpoint.protocol, scheme: @endpoint.scheme)
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
 
@@ -4,5 +4,5 @@
4
4
  # Copyright, 2017-2024, by Samuel Williams.
5
5
 
6
6
  module Falcon
7
- VERSION = "0.50.0"
7
+ VERSION = "0.51.0"
8
8
  end
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.50.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-02-11 00:00:00.000000000 Z
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