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.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/lib/falcon/adapters/early_hints.rb +8 -0
  3. data/lib/falcon/adapters/input.rb +32 -11
  4. data/lib/falcon/adapters/output.rb +20 -1
  5. data/lib/falcon/adapters/rack.rb +61 -34
  6. data/lib/falcon/adapters/response.rb +23 -1
  7. data/lib/falcon/adapters/rewindable.rb +10 -3
  8. data/lib/falcon/command.rb +2 -0
  9. data/lib/falcon/command/host.rb +13 -2
  10. data/lib/falcon/command/paths.rb +4 -0
  11. data/lib/falcon/command/proxy.rb +14 -0
  12. data/lib/falcon/command/redirect.rb +12 -0
  13. data/lib/falcon/command/serve.rb +22 -15
  14. data/lib/falcon/command/supervisor.rb +15 -1
  15. data/lib/falcon/command/top.rb +16 -0
  16. data/lib/falcon/command/virtual.rb +15 -0
  17. data/lib/falcon/configuration.rb +69 -7
  18. data/lib/falcon/controller/host.rb +12 -0
  19. data/lib/falcon/controller/proxy.rb +13 -0
  20. data/lib/falcon/controller/redirect.rb +7 -0
  21. data/lib/falcon/controller/serve.rb +16 -1
  22. data/lib/falcon/controller/virtual.rb +17 -0
  23. data/lib/falcon/endpoint.rb +8 -0
  24. data/lib/falcon/{configuration/proxy.rb → environments.rb} +9 -5
  25. data/lib/falcon/environments/application.rb +72 -0
  26. data/lib/falcon/{configuration/application.rb → environments/lets_encrypt_tls.rb} +21 -20
  27. data/lib/falcon/{configuration/lets_encrypt_tls.rb → environments/proxy.rb} +13 -6
  28. data/lib/falcon/{configuration → environments}/rack.rb +14 -2
  29. data/lib/falcon/{configuration → environments}/self_signed_tls.rb +9 -1
  30. data/lib/falcon/{configuration → environments}/supervisor.rb +19 -5
  31. data/lib/falcon/{configuration → environments}/tls.rb +39 -5
  32. data/lib/falcon/extensions/openssl.rb +1 -0
  33. data/lib/falcon/middleware/proxy.rb +26 -5
  34. data/lib/falcon/middleware/redirect.rb +11 -0
  35. data/lib/falcon/{verbose.rb → middleware/verbose.rb} +34 -26
  36. data/lib/falcon/proxy_endpoint.rb +21 -0
  37. data/lib/falcon/server.rb +8 -2
  38. data/lib/falcon/service/application.rb +23 -1
  39. data/lib/falcon/service/generic.rb +18 -0
  40. data/lib/falcon/service/proxy.rb +6 -0
  41. data/lib/falcon/service/supervisor.rb +14 -2
  42. data/lib/falcon/services.rb +21 -0
  43. data/lib/falcon/tls.rb +4 -2
  44. data/lib/falcon/version.rb +1 -1
  45. data/lib/rack/handler/falcon.rb +7 -1
  46. metadata +64 -120
  47. data/.editorconfig +0 -5
  48. data/.github/FUNDING.yml +0 -3
  49. data/.github/workflows/development.yml +0 -60
  50. data/.gitignore +0 -14
  51. data/.rspec +0 -3
  52. data/Gemfile +0 -17
  53. data/README.md +0 -316
  54. data/examples/beer/config.ru +0 -57
  55. data/examples/beer/falcon.rb +0 -8
  56. data/examples/benchmark/config.ru +0 -39
  57. data/examples/benchmark/falcon.rb +0 -6
  58. data/examples/csv/config.ru +0 -31
  59. data/examples/google/falcon.rb +0 -14
  60. data/examples/hello/config.ru +0 -22
  61. data/examples/hello/falcon.rb +0 -24
  62. data/examples/hello/preload.rb +0 -7
  63. data/examples/internet/config.ru +0 -54
  64. data/examples/memory/allocations.rb +0 -39
  65. data/examples/memory/config.ru +0 -14
  66. data/examples/push/client.rb +0 -29
  67. data/examples/push/config.ru +0 -28
  68. data/examples/push/index.html +0 -14
  69. data/examples/push/script.js +0 -2
  70. data/examples/push/style.css +0 -4
  71. data/examples/redis/Gemfile +0 -9
  72. data/examples/redis/config.ru +0 -28
  73. data/examples/sequel/Gemfile +0 -4
  74. data/examples/sequel/config.ru +0 -8
  75. data/examples/sequel/data.sqlite3 +0 -0
  76. data/examples/server/standalone.rb +0 -27
  77. data/examples/sinatra/Gemfile +0 -7
  78. data/examples/sinatra/Gemfile.lock +0 -53
  79. data/examples/sinatra/config.ru +0 -16
  80. data/examples/trailers/config.ru +0 -34
  81. data/examples/trailers/falcon.rb +0 -8
  82. data/falcon.gemspec +0 -45
  83. data/gems/rack1.gemfile +0 -4
  84. data/gems/rack3.gemfile +0 -4
  85. data/logo-square.afdesign +0 -0
  86. data/logo.afdesign +0 -0
  87. data/logo.svg +0 -107
  88. data/server.rb +0 -21
  89. data/tasks/benchmark.rake +0 -103
@@ -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
 
@@ -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
@@ -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
- def slice_options(*keys)
92
- # TODO: Ruby 2.5 introduced Hash#slice
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
- slice_options(:count, :forks, :threads)
106
+ @options.slice(:count, :forks, :threads)
106
107
  end
107
108
 
109
+ # Options for the {endpoint}.
108
110
  def endpoint_options
109
- slice_options(:hostname, :port, :reuse_port, :timeout)
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 host."
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|
@@ -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
@@ -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
- def initialize(verbose = false)
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
- attr :path
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__, "configuration", "#{feature}.rb")
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
- def add(name, *parents, &block)
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
- def supervisor
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