falcon 0.43.0 → 0.45.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 +1 -1
- data/changes.md +36 -0
- data/lib/falcon/command/host.rb +6 -32
- data/lib/falcon/command/proxy.rb +20 -15
- data/lib/falcon/command/redirect.rb +21 -15
- data/lib/falcon/command/serve.rb +44 -65
- data/lib/falcon/command/top.rb +1 -1
- data/lib/falcon/command/virtual.rb +15 -23
- data/lib/falcon/configuration.rb +26 -124
- data/lib/falcon/environment/application.rb +60 -0
- data/lib/falcon/environment/lets_encrypt_tls.rb +34 -0
- data/lib/falcon/environment/proxy.rb +109 -0
- data/lib/falcon/environment/rack.rb +20 -0
- data/lib/falcon/environment/rackup.rb +26 -0
- data/lib/falcon/environment/redirect.rb +50 -0
- data/lib/falcon/environment/self_signed_tls.rb +45 -0
- data/lib/falcon/environment/server.rb +69 -0
- data/lib/falcon/environment/supervisor.rb +40 -0
- data/lib/falcon/environment/tls.rb +97 -0
- data/lib/falcon/{environments.rb → environment.rb} +3 -4
- data/lib/falcon/service/server.rb +84 -0
- data/lib/falcon/service/supervisor.rb +4 -3
- data/lib/falcon/{controller → service}/virtual.rb +71 -18
- data/lib/falcon/version.rb +2 -2
- data/license.md +2 -0
- data.tar.gz.sig +0 -0
- metadata +28 -30
- metadata.gz.sig +0 -0
- data/lib/.DS_Store +0 -0
- data/lib/falcon/controller/host.rb +0 -55
- data/lib/falcon/controller/proxy.rb +0 -109
- data/lib/falcon/controller/redirect.rb +0 -59
- data/lib/falcon/controller/serve.rb +0 -110
- data/lib/falcon/environments/application.rb +0 -56
- data/lib/falcon/environments/lets_encrypt_tls.rb +0 -30
- data/lib/falcon/environments/proxy.rb +0 -22
- data/lib/falcon/environments/rack.rb +0 -33
- data/lib/falcon/environments/self_signed_tls.rb +0 -38
- data/lib/falcon/environments/supervisor.rb +0 -34
- data/lib/falcon/environments/tls.rb +0 -86
- data/lib/falcon/service/application.rb +0 -99
- data/lib/falcon/service/generic.rb +0 -61
- data/lib/falcon/service/proxy.rb +0 -49
- data/lib/falcon/services.rb +0 -82
@@ -1,56 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
-
# Copyright, 2020, by Daniel Evans.
|
6
|
-
|
7
|
-
require_relative '../proxy_endpoint'
|
8
|
-
require_relative '../server'
|
9
|
-
|
10
|
-
require_relative '../service/application'
|
11
|
-
|
12
|
-
# A general application environment.
|
13
|
-
# Suitable for use with any {Protocol::HTTP::Middleware}.
|
14
|
-
#
|
15
|
-
# @scope Falcon Environments
|
16
|
-
# @name application
|
17
|
-
environment(:application) do
|
18
|
-
# The middleware stack for the application.
|
19
|
-
# @attribute [Protocol::HTTP::Middleware]
|
20
|
-
middleware do
|
21
|
-
::Protocol::HTTP::Middleware::HelloWorld
|
22
|
-
end
|
23
|
-
|
24
|
-
# The scheme to use to communicate with the application.
|
25
|
-
# @attribute [String]
|
26
|
-
scheme 'https'
|
27
|
-
|
28
|
-
# The protocol to use to communicate with the application.
|
29
|
-
#
|
30
|
-
# Typically one of {Async::HTTP::Protocol::HTTP1} or {Async::HTTP::Protocl::HTTP2}.
|
31
|
-
#
|
32
|
-
# @attribute [Async::HTTP::Protocol]
|
33
|
-
protocol {Async::HTTP::Protocol::HTTP2}
|
34
|
-
|
35
|
-
# The IPC path to use for communication with the application.
|
36
|
-
# @attribute [String]
|
37
|
-
ipc_path {::File.expand_path("application.ipc", root)}
|
38
|
-
|
39
|
-
# The endpoint that will be used for communicating with the application server.
|
40
|
-
# @attribute [Async::IO::Endpoint]
|
41
|
-
endpoint do
|
42
|
-
::Falcon::ProxyEndpoint.unix(ipc_path,
|
43
|
-
protocol: protocol,
|
44
|
-
scheme: scheme,
|
45
|
-
authority: authority
|
46
|
-
)
|
47
|
-
end
|
48
|
-
|
49
|
-
# The service class to use for the application.
|
50
|
-
# @attribute [Class]
|
51
|
-
service ::Falcon::Service::Application
|
52
|
-
|
53
|
-
# Number of instances to start.
|
54
|
-
# @attribute [Integer | nil]
|
55
|
-
count nil
|
56
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2020-2023, by Samuel Williams.
|
5
|
-
|
6
|
-
load(:tls)
|
7
|
-
|
8
|
-
# A Lets Encrypt SSL context environment.
|
9
|
-
#
|
10
|
-
# Derived from {.tls}.
|
11
|
-
#
|
12
|
-
# @scope Falcon Environments
|
13
|
-
# @name lets_encrypt_tls
|
14
|
-
environment(:lets_encrypt_tls, :tls) do
|
15
|
-
# The Lets Encrypt certificate store path.
|
16
|
-
# @parameter [String]
|
17
|
-
lets_encrypt_root '/etc/letsencrypt/live'
|
18
|
-
|
19
|
-
# The public certificate path.
|
20
|
-
# @attribute [String]
|
21
|
-
ssl_certificate_path do
|
22
|
-
File.join(lets_encrypt_root, authority, "fullchain.pem")
|
23
|
-
end
|
24
|
-
|
25
|
-
# The private key path.
|
26
|
-
# @attribute [String]
|
27
|
-
ssl_private_key_path do
|
28
|
-
File.join(lets_encrypt_root, authority, "privkey.pem")
|
29
|
-
end
|
30
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
-
|
6
|
-
require_relative '../service/proxy'
|
7
|
-
|
8
|
-
# A HTTP proxy environment.
|
9
|
-
#
|
10
|
-
# Derived from {.application}.
|
11
|
-
#
|
12
|
-
# @scope Falcon Environments
|
13
|
-
# @name rack
|
14
|
-
environment(:proxy) do
|
15
|
-
# The upstream endpoint that will handle incoming requests.
|
16
|
-
# @attribute [Async::HTTP::Endpoint]
|
17
|
-
endpoint {::Async::HTTP::Endpoint.parse(url)}
|
18
|
-
|
19
|
-
# The service class to use for the proxy.
|
20
|
-
# @attribute [Class]
|
21
|
-
service ::Falcon::Service::Proxy
|
22
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
-
|
6
|
-
load :application
|
7
|
-
|
8
|
-
# A rack application environment.
|
9
|
-
#
|
10
|
-
# Derived from {.application}.
|
11
|
-
#
|
12
|
-
# @scope Falcon Environments
|
13
|
-
# @name rack
|
14
|
-
environment(:rack, :application) do
|
15
|
-
# The rack configuration path.
|
16
|
-
# @attribute [String]
|
17
|
-
config_path {::File.expand_path("config.ru", root)}
|
18
|
-
|
19
|
-
# Whether to enable the application layer cache.
|
20
|
-
# @attribute [String]
|
21
|
-
cache false
|
22
|
-
|
23
|
-
# The middleware stack for the rack application.
|
24
|
-
# @attribute [Protocol::HTTP::Middleware]
|
25
|
-
middleware do
|
26
|
-
app, _ = ::Rack::Builder.parse_file(config_path)
|
27
|
-
|
28
|
-
::Falcon::Server.middleware(app,
|
29
|
-
verbose: verbose,
|
30
|
-
cache: cache
|
31
|
-
)
|
32
|
-
end
|
33
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
-
|
6
|
-
require 'localhost/authority'
|
7
|
-
|
8
|
-
# A self-signed SSL context environment.
|
9
|
-
#
|
10
|
-
# @scope Falcon Environments
|
11
|
-
# @name self_signed_tls
|
12
|
-
environment(:self_signed_tls) do
|
13
|
-
# The default session identifier for the session cache.
|
14
|
-
# @attribute [String]
|
15
|
-
ssl_session_id {"falcon"}
|
16
|
-
|
17
|
-
# The SSL context to use for incoming connections.
|
18
|
-
# @attribute [OpenSSL::SSL::SSLContext]
|
19
|
-
ssl_context do
|
20
|
-
contexts = Localhost::Authority.fetch(authority)
|
21
|
-
|
22
|
-
contexts.server_context.tap do |context|
|
23
|
-
context.alpn_select_cb = lambda do |protocols|
|
24
|
-
if protocols.include? "h2"
|
25
|
-
return "h2"
|
26
|
-
elsif protocols.include? "http/1.1"
|
27
|
-
return "http/1.1"
|
28
|
-
elsif protocols.include? "http/1.0"
|
29
|
-
return "http/1.0"
|
30
|
-
else
|
31
|
-
return nil
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context.session_id_context = ssl_session_id
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
-
|
6
|
-
require_relative '../service/supervisor'
|
7
|
-
|
8
|
-
# A application process monitor environment.
|
9
|
-
#
|
10
|
-
# @scope Falcon Environments
|
11
|
-
# @name supervisor
|
12
|
-
environment(:supervisor) do
|
13
|
-
# The name of the supervisor
|
14
|
-
# @attribute [String]
|
15
|
-
name "supervisor"
|
16
|
-
|
17
|
-
# The IPC path to use for communication with the supervisor.
|
18
|
-
# @attribute [String]
|
19
|
-
ipc_path do
|
20
|
-
::File.expand_path("supervisor.ipc", root)
|
21
|
-
end
|
22
|
-
|
23
|
-
# The endpoint the supervisor will bind to.
|
24
|
-
# @attribute [Async::IO::Endpoint]
|
25
|
-
endpoint do
|
26
|
-
Async::IO::Endpoint.unix(ipc_path)
|
27
|
-
end
|
28
|
-
|
29
|
-
# The service class to use for the supervisor.
|
30
|
-
# @attribute [Class]
|
31
|
-
service do
|
32
|
-
::Falcon::Service::Supervisor
|
33
|
-
end
|
34
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
-
|
6
|
-
require_relative '../controller/proxy'
|
7
|
-
require_relative '../tls'
|
8
|
-
|
9
|
-
# A general SSL context environment.
|
10
|
-
#
|
11
|
-
# @scope Falcon Environments
|
12
|
-
# @name tls
|
13
|
-
environment(:tls) do
|
14
|
-
# The default session identifier for the session cache.
|
15
|
-
# @attribute [String]
|
16
|
-
ssl_session_id "falcon"
|
17
|
-
|
18
|
-
# The supported ciphers.
|
19
|
-
# @attribute [Array(String)]
|
20
|
-
ssl_ciphers Falcon::TLS::SERVER_CIPHERS
|
21
|
-
|
22
|
-
# The public certificate path.
|
23
|
-
# @attribute [String]
|
24
|
-
ssl_certificate_path do
|
25
|
-
File.expand_path("ssl/certificate.pem", root)
|
26
|
-
end
|
27
|
-
|
28
|
-
# The list of certificates loaded from that path.
|
29
|
-
# @attribute [Array(OpenSSL::X509::Certificate)]
|
30
|
-
ssl_certificates do
|
31
|
-
OpenSSL::X509::Certificate.load_file(ssl_certificate_path)
|
32
|
-
end
|
33
|
-
|
34
|
-
# The main certificate.
|
35
|
-
# @attribute [OpenSSL::X509::Certificate]
|
36
|
-
ssl_certificate {ssl_certificates[0]}
|
37
|
-
|
38
|
-
# The certificate chain.
|
39
|
-
# @attribute [Array(OpenSSL::X509::Certificate)]
|
40
|
-
ssl_certificate_chain {ssl_certificates[1..-1]}
|
41
|
-
|
42
|
-
# The private key path.
|
43
|
-
# @attribute [String]
|
44
|
-
ssl_private_key_path do
|
45
|
-
File.expand_path("ssl/private.key", root)
|
46
|
-
end
|
47
|
-
|
48
|
-
# The private key.
|
49
|
-
# @attribute [OpenSSL::PKey::RSA]
|
50
|
-
ssl_private_key do
|
51
|
-
OpenSSL::PKey::RSA.new(File.read(ssl_private_key_path))
|
52
|
-
end
|
53
|
-
|
54
|
-
# The SSL context to use for incoming connections.
|
55
|
-
# @attribute [OpenSSL::SSL::SSLContext]
|
56
|
-
ssl_context do
|
57
|
-
OpenSSL::SSL::SSLContext.new.tap do |context|
|
58
|
-
context.add_certificate(ssl_certificate, ssl_private_key, ssl_certificate_chain)
|
59
|
-
|
60
|
-
context.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT
|
61
|
-
context.session_id_context = ssl_session_id
|
62
|
-
|
63
|
-
context.alpn_select_cb = lambda do |protocols|
|
64
|
-
if protocols.include? "h2"
|
65
|
-
return "h2"
|
66
|
-
elsif protocols.include? "http/1.1"
|
67
|
-
return "http/1.1"
|
68
|
-
elsif protocols.include? "http/1.0"
|
69
|
-
return "http/1.0"
|
70
|
-
else
|
71
|
-
return nil
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# TODO Ruby 2.4 requires using ssl_version.
|
76
|
-
context.ssl_version = :TLSv1_2_server
|
77
|
-
|
78
|
-
context.set_params(
|
79
|
-
ciphers: ssl_ciphers,
|
80
|
-
verify_mode: OpenSSL::SSL::VERIFY_NONE,
|
81
|
-
)
|
82
|
-
|
83
|
-
context.setup
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
-
# Copyright, 2020, by Daniel Evans.
|
6
|
-
|
7
|
-
require_relative 'proxy'
|
8
|
-
|
9
|
-
require 'async/http/endpoint'
|
10
|
-
require 'async/io/shared_endpoint'
|
11
|
-
|
12
|
-
module Falcon
|
13
|
-
module Service
|
14
|
-
# Implements an application server using an internal clear-text proxy.
|
15
|
-
class Application < Proxy
|
16
|
-
def initialize(environment)
|
17
|
-
super
|
18
|
-
|
19
|
-
@bound_endpoint = nil
|
20
|
-
end
|
21
|
-
|
22
|
-
# The middleware that will be served by this application.
|
23
|
-
# @returns [Protocol::HTTP::Middleware]
|
24
|
-
def middleware
|
25
|
-
# In a multi-threaded container, we don't want to modify the shared evaluator's cache, so we create a new evaluator:
|
26
|
-
@environment.evaluator.middleware
|
27
|
-
end
|
28
|
-
|
29
|
-
# Number of instances to start.
|
30
|
-
# @returns [Integer | nil]
|
31
|
-
def count
|
32
|
-
@environment.evaluator.count
|
33
|
-
end
|
34
|
-
|
35
|
-
# Preload any resources specified by the environment.
|
36
|
-
def preload!
|
37
|
-
if scripts = @evaluator.preload
|
38
|
-
scripts.each do |path|
|
39
|
-
Console.logger.info(self) {"Preloading #{path}..."}
|
40
|
-
full_path = File.expand_path(path, self.root)
|
41
|
-
load(full_path)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Prepare the bound endpoint for the application instances.
|
47
|
-
# Invoke {preload!} to load shared resources into the parent process.
|
48
|
-
def start
|
49
|
-
Console.logger.info(self) {"Binding to #{self.endpoint}..."}
|
50
|
-
|
51
|
-
@bound_endpoint = Async::Reactor.run do
|
52
|
-
Async::IO::SharedEndpoint.bound(self.endpoint)
|
53
|
-
end.wait
|
54
|
-
|
55
|
-
preload!
|
56
|
-
|
57
|
-
super
|
58
|
-
end
|
59
|
-
|
60
|
-
# Setup instances of the application into the container.
|
61
|
-
# @parameter container [Async::Container::Generic]
|
62
|
-
def setup(container)
|
63
|
-
protocol = self.protocol
|
64
|
-
scheme = self.scheme
|
65
|
-
|
66
|
-
run_options = {
|
67
|
-
name: self.name,
|
68
|
-
restart: true,
|
69
|
-
}
|
70
|
-
|
71
|
-
run_options[:count] = count unless count.nil?
|
72
|
-
|
73
|
-
container.run(**run_options) do |instance|
|
74
|
-
Async do |task|
|
75
|
-
Console.logger.info(self) {"Starting application server for #{self.root}..."}
|
76
|
-
|
77
|
-
server = Server.new(self.middleware, @bound_endpoint, protocol: protocol, scheme: scheme)
|
78
|
-
|
79
|
-
server.run
|
80
|
-
|
81
|
-
instance.ready!
|
82
|
-
|
83
|
-
task.children.each(&:wait)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
super
|
88
|
-
end
|
89
|
-
|
90
|
-
# Close the bound endpoint.
|
91
|
-
def stop
|
92
|
-
@bound_endpoint&.close
|
93
|
-
@bound_endpoint = nil
|
94
|
-
|
95
|
-
super
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
-
|
6
|
-
module Falcon
|
7
|
-
module Service
|
8
|
-
# Captures the stateful behaviour of a specific service.
|
9
|
-
# Specifies the interfaces required by derived classes.
|
10
|
-
#
|
11
|
-
# Designed to be invoked within an {Async::Controller::Container}.
|
12
|
-
class Generic
|
13
|
-
# Convert the given environment into a service if possible.
|
14
|
-
# @parameter environment [Build::Environment] The environment to use to construct the service.
|
15
|
-
def self.wrap(environment)
|
16
|
-
evaluator = environment.evaluator
|
17
|
-
service = evaluator.service || self
|
18
|
-
|
19
|
-
return service.new(environment)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Initialize the service from the given environment.
|
23
|
-
# @parameter environment [Build::Environment]
|
24
|
-
def initialize(environment)
|
25
|
-
@environment = environment
|
26
|
-
@evaluator = @environment.evaluator
|
27
|
-
end
|
28
|
-
|
29
|
-
# Whether the service environment contains the specified keys.
|
30
|
-
# This is used for matching environment configuration to service behaviour.
|
31
|
-
def include?(keys)
|
32
|
-
keys.all?{|key| @environment.include?(key)}
|
33
|
-
end
|
34
|
-
|
35
|
-
# The name of the service.
|
36
|
-
# e.g. `myapp.com`.
|
37
|
-
def name
|
38
|
-
@evaluator.name
|
39
|
-
end
|
40
|
-
|
41
|
-
# The logger to use for this service.
|
42
|
-
# @returns [Console::Logger]
|
43
|
-
def logger
|
44
|
-
return Console.logger # .with(name: name)
|
45
|
-
end
|
46
|
-
|
47
|
-
# Start the service.
|
48
|
-
def start
|
49
|
-
end
|
50
|
-
|
51
|
-
# Setup the service into the specified container.
|
52
|
-
# @parameter container [Async::Container::Generic]
|
53
|
-
def setup(container)
|
54
|
-
end
|
55
|
-
|
56
|
-
# Stop the service.
|
57
|
-
def stop
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/lib/falcon/service/proxy.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2020-2023, by Samuel Williams.
|
5
|
-
|
6
|
-
require_relative 'generic'
|
7
|
-
|
8
|
-
require 'async/http/endpoint'
|
9
|
-
require 'async/io/shared_endpoint'
|
10
|
-
|
11
|
-
module Falcon
|
12
|
-
module Service
|
13
|
-
class Proxy < Generic
|
14
|
-
def name
|
15
|
-
"#{self.class} for #{self.authority}"
|
16
|
-
end
|
17
|
-
|
18
|
-
# The host that this proxy will receive connections for.
|
19
|
-
def authority
|
20
|
-
@evaluator.authority
|
21
|
-
end
|
22
|
-
|
23
|
-
# The upstream endpoint that this proxy will connect to.
|
24
|
-
def endpoint
|
25
|
-
@evaluator.endpoint
|
26
|
-
end
|
27
|
-
|
28
|
-
# The {OpenSSL::SSL::SSLContext} that will be used for incoming connections.
|
29
|
-
def ssl_context
|
30
|
-
@evaluator.ssl_context
|
31
|
-
end
|
32
|
-
|
33
|
-
# The root
|
34
|
-
def root
|
35
|
-
@evaluator.root
|
36
|
-
end
|
37
|
-
|
38
|
-
# The protocol this proxy will use to talk to the upstream host.
|
39
|
-
def protocol
|
40
|
-
endpoint.protocol
|
41
|
-
end
|
42
|
-
|
43
|
-
# The scheme this proxy will use to talk to the upstream host.
|
44
|
-
def scheme
|
45
|
-
endpoint.scheme
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
data/lib/falcon/services.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-2023, by Samuel Williams.
|
5
|
-
|
6
|
-
require_relative 'service/generic'
|
7
|
-
|
8
|
-
module Falcon
|
9
|
-
# Represents one or more services associated with a host.
|
10
|
-
#
|
11
|
-
# The services model allows falcon to manage one more more service associated with a given host. Some examples of services include:
|
12
|
-
#
|
13
|
-
# - Rack applications wrapped by {Service::Application}.
|
14
|
-
# - Host supervisor implemented in {Service::Supervisor}.
|
15
|
-
# - Proxy services wrapped by {Service::Proxy}.
|
16
|
-
#
|
17
|
-
# The list of services is typically generated from the user supplied `falcon.rb` configuration file, which is loaded into an immutable {Configuration} instance, which is mapped into a list of services.
|
18
|
-
class Services
|
19
|
-
# Initialize the services from the given configuration.
|
20
|
-
#
|
21
|
-
# @parameter configuration [Configuration]
|
22
|
-
def initialize(configuration)
|
23
|
-
@named = {}
|
24
|
-
|
25
|
-
configuration.each(:service) do |environment|
|
26
|
-
service = Service::Generic.wrap(environment)
|
27
|
-
|
28
|
-
add(service)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Enumerate all named services.
|
33
|
-
def each(&block)
|
34
|
-
@named.each_value(&block)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Add a named service.
|
38
|
-
#
|
39
|
-
# @parameter service [Service]
|
40
|
-
def add(service)
|
41
|
-
@named[service.name] = service
|
42
|
-
end
|
43
|
-
|
44
|
-
# Start all named services.
|
45
|
-
def start
|
46
|
-
@named.each do |name, service|
|
47
|
-
Console.logger.debug(self) {"Starting #{name}..."}
|
48
|
-
service.start
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Setup all named services into the given container.
|
53
|
-
#
|
54
|
-
# @parameter container [Async::Container::Generic]
|
55
|
-
def setup(container)
|
56
|
-
@named.each do |name, service|
|
57
|
-
Console.logger.debug(self) {"Setup #{name} into #{container}..."}
|
58
|
-
service.setup(container)
|
59
|
-
end
|
60
|
-
|
61
|
-
return container
|
62
|
-
end
|
63
|
-
|
64
|
-
# Stop all named services.
|
65
|
-
def stop
|
66
|
-
failed = false
|
67
|
-
|
68
|
-
@named.each do |name, service|
|
69
|
-
Console.logger.debug(self) {"Stopping #{name}..."}
|
70
|
-
|
71
|
-
begin
|
72
|
-
service.stop
|
73
|
-
rescue => error
|
74
|
-
failed = true
|
75
|
-
Console.logger.error(self, error)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
return failed
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|