falcon 0.36.2 → 0.36.7
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
- data/lib/falcon/adapters/early_hints.rb +8 -0
- data/lib/falcon/adapters/input.rb +32 -11
- data/lib/falcon/adapters/output.rb +20 -1
- data/lib/falcon/adapters/rack.rb +61 -34
- data/lib/falcon/adapters/response.rb +23 -1
- data/lib/falcon/adapters/rewindable.rb +10 -3
- data/lib/falcon/command.rb +2 -0
- data/lib/falcon/command/host.rb +13 -2
- data/lib/falcon/command/paths.rb +4 -0
- data/lib/falcon/command/proxy.rb +14 -0
- data/lib/falcon/command/redirect.rb +12 -0
- data/lib/falcon/command/serve.rb +22 -15
- data/lib/falcon/command/supervisor.rb +15 -1
- data/lib/falcon/command/top.rb +16 -0
- data/lib/falcon/command/virtual.rb +15 -0
- data/lib/falcon/configuration.rb +69 -7
- data/lib/falcon/controller/host.rb +12 -0
- data/lib/falcon/controller/proxy.rb +13 -0
- data/lib/falcon/controller/redirect.rb +7 -0
- data/lib/falcon/controller/serve.rb +16 -1
- data/lib/falcon/controller/virtual.rb +17 -0
- data/lib/falcon/endpoint.rb +8 -0
- data/lib/falcon/{configuration/proxy.rb → environments.rb} +9 -5
- data/lib/falcon/environments/application.rb +72 -0
- data/lib/falcon/{configuration/application.rb → environments/lets_encrypt_tls.rb} +21 -20
- data/lib/falcon/{configuration/lets_encrypt_tls.rb → environments/proxy.rb} +13 -6
- data/lib/falcon/{configuration → environments}/rack.rb +14 -2
- data/lib/falcon/{configuration → environments}/self_signed_tls.rb +9 -1
- data/lib/falcon/{configuration → environments}/supervisor.rb +19 -5
- data/lib/falcon/{configuration → environments}/tls.rb +39 -5
- data/lib/falcon/extensions/openssl.rb +1 -0
- data/lib/falcon/middleware/proxy.rb +26 -5
- data/lib/falcon/middleware/redirect.rb +11 -0
- data/lib/falcon/{verbose.rb → middleware/verbose.rb} +34 -26
- data/lib/falcon/proxy_endpoint.rb +21 -0
- data/lib/falcon/server.rb +8 -2
- data/lib/falcon/service/application.rb +23 -1
- data/lib/falcon/service/generic.rb +18 -0
- data/lib/falcon/service/proxy.rb +6 -0
- data/lib/falcon/service/supervisor.rb +14 -2
- data/lib/falcon/services.rb +21 -0
- data/lib/falcon/tls.rb +4 -2
- data/lib/falcon/version.rb +1 -1
- data/lib/rack/handler/falcon.rb +7 -1
- metadata +64 -120
- data/.editorconfig +0 -5
- data/.github/FUNDING.yml +0 -3
- data/.github/workflows/development.yml +0 -60
- data/.gitignore +0 -14
- data/.rspec +0 -3
- data/Gemfile +0 -17
- data/README.md +0 -316
- data/examples/beer/config.ru +0 -57
- data/examples/beer/falcon.rb +0 -8
- data/examples/benchmark/config.ru +0 -39
- data/examples/benchmark/falcon.rb +0 -6
- data/examples/csv/config.ru +0 -31
- data/examples/google/falcon.rb +0 -14
- data/examples/hello/config.ru +0 -22
- data/examples/hello/falcon.rb +0 -24
- data/examples/hello/preload.rb +0 -7
- data/examples/internet/config.ru +0 -54
- data/examples/memory/allocations.rb +0 -39
- data/examples/memory/config.ru +0 -14
- data/examples/push/client.rb +0 -29
- data/examples/push/config.ru +0 -28
- data/examples/push/index.html +0 -14
- data/examples/push/script.js +0 -2
- data/examples/push/style.css +0 -4
- data/examples/redis/Gemfile +0 -9
- data/examples/redis/config.ru +0 -28
- data/examples/sequel/Gemfile +0 -4
- data/examples/sequel/config.ru +0 -8
- data/examples/sequel/data.sqlite3 +0 -0
- data/examples/server/standalone.rb +0 -27
- data/examples/sinatra/Gemfile +0 -7
- data/examples/sinatra/Gemfile.lock +0 -53
- data/examples/sinatra/config.ru +0 -16
- data/examples/trailers/config.ru +0 -34
- data/examples/trailers/falcon.rb +0 -8
- data/falcon.gemspec +0 -45
- data/gems/rack1.gemfile +0 -4
- data/gems/rack3.gemfile +0 -4
- data/logo-square.afdesign +0 -0
- data/logo.afdesign +0 -0
- data/logo.svg +0 -107
- data/server.rb +0 -21
- data/tasks/benchmark.rake +0 -103
data/lib/falcon/command/paths.rb
CHANGED
@@ -24,13 +24,17 @@ require_relative '../configuration'
|
|
24
24
|
|
25
25
|
module Falcon
|
26
26
|
module Command
|
27
|
+
# A helper for resolving wildcard configuration paths.
|
27
28
|
module Paths
|
29
|
+
# Resolve a set of `@paths` that may contain wildcards, into a sorted, unique array.
|
30
|
+
# @returns [Array(String)]
|
28
31
|
def resolved_paths(&block)
|
29
32
|
@paths.collect do |path|
|
30
33
|
Dir.glob(path)
|
31
34
|
end.flatten.sort.uniq.each(&block)
|
32
35
|
end
|
33
36
|
|
37
|
+
# Build a configuration based on the resolved paths.
|
34
38
|
def configuration
|
35
39
|
configuration = Configuration.new
|
36
40
|
|
data/lib/falcon/command/proxy.rb
CHANGED
@@ -27,31 +27,44 @@ require 'samovar'
|
|
27
27
|
|
28
28
|
module Falcon
|
29
29
|
module Command
|
30
|
+
# Implements the `falcon proxy` command.
|
31
|
+
#
|
32
|
+
# Manages a {Controller::Proxy} instance which is responsible for proxing incoming requests.
|
30
33
|
class Proxy < Samovar::Command
|
31
34
|
self.description = "Proxy to one or more backend hosts."
|
32
35
|
|
36
|
+
# The command line options.
|
37
|
+
# @attribute [Samovar::Options]
|
33
38
|
options do
|
34
39
|
option '--bind <address>', "Bind to the given hostname/address", default: "https://[::]:443"
|
35
40
|
|
36
41
|
option '-t/--timeout <duration>', "Specify the maximum time to wait for non-blocking operations.", type: Float, default: nil
|
37
42
|
end
|
38
43
|
|
44
|
+
# One or more paths to the configuration files.
|
45
|
+
# @name paths
|
46
|
+
# @attribute [Array(String)]
|
39
47
|
many :paths
|
40
48
|
|
41
49
|
include Paths
|
42
50
|
|
51
|
+
# Prepare a new controller for the command.
|
43
52
|
def controller
|
44
53
|
Controller::Proxy.new(self)
|
45
54
|
end
|
46
55
|
|
56
|
+
# The container class to use.
|
47
57
|
def container_class
|
48
58
|
Async::Container.best_container_class
|
49
59
|
end
|
50
60
|
|
61
|
+
# Options for the container.
|
62
|
+
# See {Controller::Serve#setup}.
|
51
63
|
def container_options
|
52
64
|
{}
|
53
65
|
end
|
54
66
|
|
67
|
+
# Prepare the environment and run the controller.
|
55
68
|
def call
|
56
69
|
Async.logger.info(self) do |buffer|
|
57
70
|
buffer.puts "Falcon Proxy v#{VERSION} taking flight!"
|
@@ -63,6 +76,7 @@ module Falcon
|
|
63
76
|
self.controller.run
|
64
77
|
end
|
65
78
|
|
79
|
+
# The endpoint to bind to.
|
66
80
|
def endpoint(**options)
|
67
81
|
Async::HTTP::Endpoint.parse(@options[:bind], timeout: @options[:timeout], **options)
|
68
82
|
end
|
@@ -30,6 +30,8 @@ module Falcon
|
|
30
30
|
class Redirect < Samovar::Command
|
31
31
|
self.description = "Redirect from insecure HTTP to secure HTTP."
|
32
32
|
|
33
|
+
# The command line options.
|
34
|
+
# @attribute [Samovar::Options]
|
33
35
|
options do
|
34
36
|
option '--bind <address>', "Bind to the given hostname/address", default: "http://[::]:80"
|
35
37
|
option '--redirect <address>', "Redirect using this address as a template.", default: "https://[::]:443"
|
@@ -37,22 +39,30 @@ module Falcon
|
|
37
39
|
option '-t/--timeout <duration>', "Specify the maximum time to wait for non-blocking operations.", type: Float, default: nil
|
38
40
|
end
|
39
41
|
|
42
|
+
# One or more paths to the configuration files.
|
43
|
+
# @name paths
|
44
|
+
# @attribute [Array(String)]
|
40
45
|
many :paths
|
41
46
|
|
42
47
|
include Paths
|
43
48
|
|
49
|
+
# Prepare a new controller for the command.
|
44
50
|
def controller
|
45
51
|
Controller::Redirect.new(self)
|
46
52
|
end
|
47
53
|
|
54
|
+
# The container class to use.
|
48
55
|
def container_class
|
49
56
|
Async::Container.best_container_class
|
50
57
|
end
|
51
58
|
|
59
|
+
# Options for the container.
|
60
|
+
# See {Controller::Serve#setup}.
|
52
61
|
def container_options
|
53
62
|
{}
|
54
63
|
end
|
55
64
|
|
65
|
+
# Prepare the environment and run the controller.
|
56
66
|
def call
|
57
67
|
Async.logger.info(self) do |buffer|
|
58
68
|
buffer.puts "Falcon Redirect v#{VERSION} taking flight!"
|
@@ -64,10 +74,12 @@ module Falcon
|
|
64
74
|
self.controller.run
|
65
75
|
end
|
66
76
|
|
77
|
+
# The endpoint to bind to.
|
67
78
|
def endpoint(**options)
|
68
79
|
Async::HTTP::Endpoint.parse(@options[:bind], timeout: @options[:timeout], **options)
|
69
80
|
end
|
70
81
|
|
82
|
+
# The template endpoint to redirect to.
|
71
83
|
def redirect_endpoint(**options)
|
72
84
|
Async::HTTP::Endpoint.parse(@options[:redirect], **options)
|
73
85
|
end
|
data/lib/falcon/command/serve.rb
CHANGED
@@ -40,9 +40,14 @@ require 'bundler'
|
|
40
40
|
|
41
41
|
module Falcon
|
42
42
|
module Command
|
43
|
+
# Implements the `falcon serve` command. Designed for *development*.
|
44
|
+
#
|
45
|
+
# Manages a {Controller::Serve} instance which is responsible for running applications in a development environment.
|
43
46
|
class Serve < Samovar::Command
|
44
47
|
self.description = "Run an HTTP server for development purposes."
|
45
48
|
|
49
|
+
# The command line options.
|
50
|
+
# @attribute [Samovar::Options]
|
46
51
|
options do
|
47
52
|
option '-b/--bind <address>', "Bind to the given hostname/address.", default: "https://localhost:9292"
|
48
53
|
|
@@ -63,6 +68,7 @@ module Falcon
|
|
63
68
|
option '--threads <count>', "Number of threads (hybrid only).", type: Integer
|
64
69
|
end
|
65
70
|
|
71
|
+
# The container class to use.
|
66
72
|
def container_class
|
67
73
|
case @options[:container]
|
68
74
|
when :threaded
|
@@ -74,57 +80,58 @@ module Falcon
|
|
74
80
|
end
|
75
81
|
end
|
76
82
|
|
83
|
+
# Whether verbose logging is enabled.
|
84
|
+
# @returns [Boolean]
|
77
85
|
def verbose?
|
78
86
|
@parent&.verbose?
|
79
87
|
end
|
80
88
|
|
89
|
+
# Whether to enable the application HTTP cache.
|
90
|
+
# @returns [Boolean]
|
81
91
|
def cache?
|
82
92
|
@options[:cache]
|
83
93
|
end
|
84
94
|
|
95
|
+
# Load the rack application from the specified configuration path.
|
96
|
+
# @returns [Protocol::HTTP::Middleware]
|
85
97
|
def load_app
|
86
98
|
rack_app, _ = Rack::Builder.parse_file(@options[:config])
|
87
99
|
|
88
100
|
return Server.middleware(rack_app, verbose: self.verbose?, cache: self.cache?)
|
89
101
|
end
|
90
102
|
|
91
|
-
|
92
|
-
|
93
|
-
options = {}
|
94
|
-
|
95
|
-
keys.each do |key|
|
96
|
-
if @options.key?(key)
|
97
|
-
options[key] = @options[key]
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
return options
|
102
|
-
end
|
103
|
-
|
103
|
+
# Options for the container.
|
104
|
+
# See {Controller::Serve#setup}.
|
104
105
|
def container_options
|
105
|
-
|
106
|
+
@options.slice(:count, :forks, :threads)
|
106
107
|
end
|
107
108
|
|
109
|
+
# Options for the {endpoint}.
|
108
110
|
def endpoint_options
|
109
|
-
|
111
|
+
@options.slice(:hostname, :port, :reuse_port, :timeout)
|
110
112
|
end
|
111
113
|
|
114
|
+
# The endpoint to bind to.
|
112
115
|
def endpoint
|
113
116
|
Endpoint.parse(@options[:bind], **endpoint_options)
|
114
117
|
end
|
115
118
|
|
119
|
+
# The endpoint suitable for a client to connect.
|
116
120
|
def client_endpoint
|
117
121
|
Async::HTTP::Endpoint.parse(@options[:bind], **endpoint_options)
|
118
122
|
end
|
119
123
|
|
124
|
+
# Create a new client suitable for accessing the application.
|
120
125
|
def client
|
121
126
|
Async::HTTP::Client.new(client_endpoint)
|
122
127
|
end
|
123
128
|
|
129
|
+
# Prepare a new controller for the command.
|
124
130
|
def controller
|
125
131
|
Controller::Serve.new(self)
|
126
132
|
end
|
127
133
|
|
134
|
+
# Prepare the environment and run the controller.
|
128
135
|
def call
|
129
136
|
Async.logger.info(self) do |buffer|
|
130
137
|
buffer.puts "Falcon v#{VERSION} taking flight! Using #{self.container_class} #{self.container_options}."
|
@@ -29,24 +29,33 @@ require 'async/io/unix_endpoint'
|
|
29
29
|
|
30
30
|
module Falcon
|
31
31
|
module Command
|
32
|
+
# Implements the `falcon supervisor` command.
|
33
|
+
#
|
34
|
+
# Talks to an instance of the supervisor to issue commands and print results.
|
32
35
|
class Supervisor < Samovar::Command
|
33
|
-
self.description = "Control and query a specific
|
36
|
+
self.description = "Control and query a specific supervisor."
|
34
37
|
|
38
|
+
# The command line options.
|
39
|
+
# @attribute [Samovar::Options]
|
35
40
|
options do
|
36
41
|
option "--path <path>", "The control IPC path.", default: "supervisor.ipc"
|
37
42
|
end
|
38
43
|
|
44
|
+
# Implements the `falcon supervisor restart` command.
|
39
45
|
class Restart < Samovar::Command
|
40
46
|
self.description = "Restart the process group."
|
41
47
|
|
48
|
+
# Send the restart message to the supervisor.
|
42
49
|
def call(stream)
|
43
50
|
stream.puts({please: 'restart'}.to_json, separator: "\0")
|
44
51
|
end
|
45
52
|
end
|
46
53
|
|
54
|
+
# Implements the `falcon supervisor metrics` command.
|
47
55
|
class Metrics < Samovar::Command
|
48
56
|
self.description = "Show metrics about the falcon processes."
|
49
57
|
|
58
|
+
# Send the metrics message to the supervisor and print the results.
|
50
59
|
def call(stream)
|
51
60
|
stream.puts({please: 'metrics'}.to_json, separator: "\0")
|
52
61
|
response = JSON.parse(stream.gets("\0"), symbolize_names: true)
|
@@ -55,15 +64,20 @@ module Falcon
|
|
55
64
|
end
|
56
65
|
end
|
57
66
|
|
67
|
+
# The nested command to execute.
|
68
|
+
# @name nested
|
69
|
+
# @attribute [Command]
|
58
70
|
nested :command, {
|
59
71
|
'restart' => Restart,
|
60
72
|
'metrics' => Metrics,
|
61
73
|
}, default: 'metrics'
|
62
74
|
|
75
|
+
# The endpoint the supervisor is bound to.
|
63
76
|
def endpoint
|
64
77
|
Async::IO::Endpoint.unix(@options[:path])
|
65
78
|
end
|
66
79
|
|
80
|
+
# Connect to the supervisor and execute the requested command.
|
67
81
|
def call
|
68
82
|
Async do
|
69
83
|
endpoint.connect do |socket|
|
data/lib/falcon/command/top.rb
CHANGED
@@ -33,9 +33,12 @@ require 'samovar'
|
|
33
33
|
|
34
34
|
module Falcon
|
35
35
|
module Command
|
36
|
+
# The top level command for the `falcon` executable.
|
36
37
|
class Top < Samovar::Command
|
37
38
|
self.description = "An asynchronous HTTP server."
|
38
39
|
|
40
|
+
# The command line options.
|
41
|
+
# @attribute [Samovar::Options]
|
39
42
|
options do
|
40
43
|
option '--verbose | --quiet', "Verbosity of output for debugging.", key: :logging
|
41
44
|
option '-h/--help', "Print out help information."
|
@@ -43,6 +46,9 @@ module Falcon
|
|
43
46
|
option '-e/--encoding', "Specify the default external encoding of the server.", default: "UTF-8"
|
44
47
|
end
|
45
48
|
|
49
|
+
# The nested command to execute.
|
50
|
+
# @name nested
|
51
|
+
# @attribute [Command]
|
46
52
|
nested :command, {
|
47
53
|
'serve' => Serve,
|
48
54
|
'host' => Host,
|
@@ -52,15 +58,23 @@ module Falcon
|
|
52
58
|
'supervisor' => Supervisor,
|
53
59
|
}, default: 'serve'
|
54
60
|
|
61
|
+
# Whether verbose logging is enabled.
|
62
|
+
# @returns [Boolean]
|
55
63
|
def verbose?
|
56
64
|
@options[:logging] == :verbose
|
57
65
|
end
|
58
66
|
|
67
|
+
# Whether quiet logging was enabled.
|
68
|
+
# @returns [Boolean]
|
59
69
|
def quiet?
|
60
70
|
@options[:logging] == :quiet
|
61
71
|
end
|
62
72
|
|
73
|
+
# Update the external encoding.
|
74
|
+
#
|
63
75
|
# If you don't specify these, it's possible to have issues when encodings mismatch on the server.
|
76
|
+
#
|
77
|
+
# @parameter encoding [Encoding] Defaults to `Encoding::UTF_8`.
|
64
78
|
def update_external_encoding!(encoding = Encoding::UTF_8)
|
65
79
|
if Encoding.default_external != encoding
|
66
80
|
Console.logger.warn(self) {"Updating Encoding.default_external from #{Encoding.default_external} to #{encoding}"}
|
@@ -68,12 +82,14 @@ module Falcon
|
|
68
82
|
end
|
69
83
|
end
|
70
84
|
|
85
|
+
# The desired external encoding.
|
71
86
|
def encoding
|
72
87
|
if name = @options[:encoding]
|
73
88
|
Encoding.find(name)
|
74
89
|
end
|
75
90
|
end
|
76
91
|
|
92
|
+
# Prepare the environment and invoke the sub-command.
|
77
93
|
def call
|
78
94
|
if encoding = self.encoding
|
79
95
|
update_external_encoding!(encoding)
|
@@ -27,9 +27,14 @@ require 'samovar'
|
|
27
27
|
|
28
28
|
module Falcon
|
29
29
|
module Command
|
30
|
+
# Implements the `falcon virtual` command. Designed for *deployment*.
|
31
|
+
#
|
32
|
+
# Manages a {Controller::Virtual} instance which is responsible for running the {Proxy} and {Redirect} instances.
|
30
33
|
class Virtual < Samovar::Command
|
31
34
|
self.description = "Run one or more virtual hosts with a front-end proxy."
|
32
35
|
|
36
|
+
# The command line options.
|
37
|
+
# @attribute [Samovar::Options]
|
33
38
|
options do
|
34
39
|
option '--bind-insecure <address>', "Bind redirection to the given hostname/address", default: "http://[::]:80"
|
35
40
|
option '--bind-secure <address>', "Bind proxy to the given hostname/address", default: "https://[::]:443"
|
@@ -37,26 +42,34 @@ module Falcon
|
|
37
42
|
option '-t/--timeout <duration>', "Specify the maximum time to wait for non-blocking operations.", type: Float, default: 30
|
38
43
|
end
|
39
44
|
|
45
|
+
# One or more paths to the configuration files.
|
46
|
+
# @name paths
|
47
|
+
# @attribute [Array(String)]
|
40
48
|
many :paths
|
41
49
|
|
42
50
|
include Paths
|
43
51
|
|
52
|
+
# Prepare a new controller for the command.
|
44
53
|
def controller
|
45
54
|
Controller::Virtual.new(self)
|
46
55
|
end
|
47
56
|
|
57
|
+
# The URI to bind the `HTTPS` -> `falcon host` proxy.
|
48
58
|
def bind_secure
|
49
59
|
@options[:bind_secure]
|
50
60
|
end
|
51
61
|
|
62
|
+
# The URI to bind the `HTTP` -> `HTTPS` redirector.
|
52
63
|
def bind_insecure
|
53
64
|
@options[:bind_insecure]
|
54
65
|
end
|
55
66
|
|
67
|
+
# The connection timeout to use for incoming connections.
|
56
68
|
def timeout
|
57
69
|
@options[:timeout]
|
58
70
|
end
|
59
71
|
|
72
|
+
# Prepare the environment and run the controller.
|
60
73
|
def call
|
61
74
|
Async.logger.info(self) do |buffer|
|
62
75
|
buffer.puts "Falcon Virtual v#{VERSION} taking flight!"
|
@@ -67,10 +80,12 @@ module Falcon
|
|
67
80
|
self.controller.run
|
68
81
|
end
|
69
82
|
|
83
|
+
# The insecure endpoint for connecting to the {Redirect} instance.
|
70
84
|
def insecure_endpoint(**options)
|
71
85
|
Async::HTTP::Endpoint.parse(@options[:bind_insecure], **options)
|
72
86
|
end
|
73
87
|
|
88
|
+
# The secure endpoint for connecting to the {Proxy} instance.
|
74
89
|
def secure_endpoint(**options)
|
75
90
|
Async::HTTP::Endpoint.parse(@options[:bind_secure], **options)
|
76
91
|
end
|
data/lib/falcon/configuration.rb
CHANGED
@@ -23,13 +23,36 @@
|
|
23
23
|
require 'build/environment'
|
24
24
|
|
25
25
|
module Falcon
|
26
|
+
# Manages environments which describes how to host a specific application.
|
27
|
+
#
|
28
|
+
# Environments are key-value maps with lazy value resolution. An environment can inherit from a parent environment, which can provide defaults
|
29
|
+
#
|
30
|
+
# A typical configuration file might look something like:
|
31
|
+
#
|
32
|
+
# ~~~ ruby
|
33
|
+
# #!/usr/bin/env falcon-host
|
34
|
+
# # frozen_string_literal: true
|
35
|
+
#
|
36
|
+
# load :rack, :self_signed_tls, :supervisor
|
37
|
+
#
|
38
|
+
# supervisor
|
39
|
+
#
|
40
|
+
# rack 'hello.localhost', :self_signed_tls do
|
41
|
+
# end
|
42
|
+
# ~~~
|
43
|
+
#
|
26
44
|
class Configuration
|
27
|
-
|
45
|
+
# Initialize an empty configuration.
|
46
|
+
def initialize
|
28
47
|
@environments = {}
|
29
48
|
end
|
30
49
|
|
50
|
+
# The map of named environments.
|
51
|
+
# @attribute [Hash(String, Build::Environment)]
|
31
52
|
attr :environments
|
32
53
|
|
54
|
+
# Enumerate all environments that have the specified key.
|
55
|
+
# @parameter key [Symbol] Filter environments that don't have this key.
|
33
56
|
def each(key = :authority)
|
34
57
|
return to_enum(key) unless block_given?
|
35
58
|
|
@@ -42,6 +65,7 @@ module Falcon
|
|
42
65
|
end
|
43
66
|
end
|
44
67
|
|
68
|
+
# Add the named environment to the configuration.
|
45
69
|
def add(environment)
|
46
70
|
name = environment.name
|
47
71
|
|
@@ -56,11 +80,17 @@ module Falcon
|
|
56
80
|
@environments[name] = environment
|
57
81
|
end
|
58
82
|
|
83
|
+
# Load the specified configuration file. See {Loader#load_file} for more details.
|
59
84
|
def load_file(path)
|
60
85
|
Loader.load_file(self, path)
|
61
86
|
end
|
62
87
|
|
88
|
+
# The domain specific language for loading configuration files.
|
63
89
|
class Loader
|
90
|
+
# Initialize the loader, attached to a specific configuration instance.
|
91
|
+
# Any environments generated by the loader will be added to the configuration.
|
92
|
+
# @parameter configuration [Configuration]
|
93
|
+
# @parameter root [String] The file-system root path for relative path computations.
|
64
94
|
def initialize(configuration, root = nil)
|
65
95
|
@loaded = {}
|
66
96
|
@configuration = configuration
|
@@ -68,9 +98,17 @@ module Falcon
|
|
68
98
|
@root = root
|
69
99
|
end
|
70
100
|
|
71
|
-
|
101
|
+
# The file-system root path which is injected into the environments as required.
|
102
|
+
# @attribute [String]
|
103
|
+
attr :root
|
104
|
+
|
105
|
+
# The attached configuration instance.
|
106
|
+
# @attribute [Configuration]
|
72
107
|
attr :configuration
|
73
108
|
|
109
|
+
# Load the specified file into the given configuration.
|
110
|
+
# @parameter configuration [Configuration]
|
111
|
+
# @oaram path [String] The path to the configuration file, e.g. `falcon.rb`.
|
74
112
|
def self.load_file(configuration, path)
|
75
113
|
path = File.realpath(path)
|
76
114
|
root = File.dirname(path)
|
@@ -80,11 +118,16 @@ module Falcon
|
|
80
118
|
loader.instance_eval(File.read(path), path)
|
81
119
|
end
|
82
120
|
|
121
|
+
# Load specific features into the current configuration.
|
122
|
+
#
|
123
|
+
# Falcon provides default environments for different purposes. These are included in the gem, in the `environments/` directory. This method loads the code in those files into the current configuration.
|
124
|
+
#
|
125
|
+
# @parameter features [Array(Symbol)] The features to load.
|
83
126
|
def load(*features)
|
84
127
|
features.each do |feature|
|
85
128
|
next if @loaded.include?(feature)
|
86
129
|
|
87
|
-
relative_path = File.join(__dir__, "
|
130
|
+
relative_path = File.join(__dir__, "environments", "#{feature}.rb")
|
88
131
|
|
89
132
|
self.instance_eval(File.read(relative_path), relative_path)
|
90
133
|
|
@@ -92,11 +135,18 @@ module Falcon
|
|
92
135
|
end
|
93
136
|
end
|
94
137
|
|
95
|
-
|
138
|
+
# Add the named environment, with zero or more parent environments, defined using the specified `block`.
|
139
|
+
# @parameter name [String] The name of the environment.
|
140
|
+
# @parameter parents [Array(Symbol)] The names of the parent environments to inherit.
|
141
|
+
# @yields {...} The block that will generate the environment.
|
142
|
+
def environment(name, *parents, &block)
|
96
143
|
raise KeyError.new("#{name} is already set", key: name) if @environments.key?(name)
|
97
144
|
@environments[name] = merge(name, *parents, &block)
|
98
145
|
end
|
99
|
-
|
146
|
+
|
147
|
+
# Define a host with the specified name.
|
148
|
+
# Adds `root` and `authority` keys.
|
149
|
+
# @parameter name [String] The name of the environment, usually a hostname.
|
100
150
|
def host(name, *parents, &block)
|
101
151
|
environment = merge(name, :host, *parents, &block)
|
102
152
|
|
@@ -106,6 +156,9 @@ module Falcon
|
|
106
156
|
@configuration.add(environment.flatten)
|
107
157
|
end
|
108
158
|
|
159
|
+
# Define a proxy with the specified name.
|
160
|
+
# Adds `root` and `authority` keys.
|
161
|
+
# @parameter name [String] The name of the environment, usually a hostname.
|
109
162
|
def proxy(name, *parents, &block)
|
110
163
|
environment = merge(name, :proxy, *parents, &block)
|
111
164
|
|
@@ -115,6 +168,9 @@ module Falcon
|
|
115
168
|
@configuration.add(environment.flatten)
|
116
169
|
end
|
117
170
|
|
171
|
+
# Define a rack application with the specified name.
|
172
|
+
# Adds `root` and `authority` keys.
|
173
|
+
# @parameter name [String] The name of the environment, usually a hostname.
|
118
174
|
def rack(name, *parents, &block)
|
119
175
|
environment = merge(name, :rack, *parents, &block)
|
120
176
|
|
@@ -124,9 +180,11 @@ module Falcon
|
|
124
180
|
@configuration.add(environment.flatten)
|
125
181
|
end
|
126
182
|
|
127
|
-
|
183
|
+
# Define a supervisor instance
|
184
|
+
# Adds `root` key.
|
185
|
+
def supervisor(&block)
|
128
186
|
name = File.join(@root, "supervisor")
|
129
|
-
environment = merge(name, :supervisor)
|
187
|
+
environment = merge(name, :supervisor, &block)
|
130
188
|
|
131
189
|
environment[:root] = @root
|
132
190
|
|
@@ -135,6 +193,10 @@ module Falcon
|
|
135
193
|
|
136
194
|
private
|
137
195
|
|
196
|
+
# Build a new environment with the specified name and the given parents.
|
197
|
+
# @parameter name [String]
|
198
|
+
# @parameter parents [Array(Build::Environment)]
|
199
|
+
# @yields {...} The block that will generate the environment.
|
138
200
|
def merge(name, *parents, &block)
|
139
201
|
environments = parents.map{|name| @environments.fetch(name)}
|
140
202
|
|