Skip to content

Commit 0888484

Browse files
committed
Minor documentation improvements.
1 parent 8a67214 commit 0888484

File tree

13 files changed

+413
-197
lines changed

13 files changed

+413
-197
lines changed

context/deployment.md

Lines changed: 108 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Falcon can be deployed into production either as a standalone application server
1616

1717
`falcon host` loads configuration from the `falcon.rb` file in your application directory. This file contains configuration blocks which define how to host the application and any related services. This file should be executable and it invokes `falcon-host` which starts all defined services.
1818

19-
Here is a basic example which hosts a rack application using :
19+
Here is a basic example which hosts a rack application:
2020

2121
~~~ ruby
2222
#!/usr/bin/env falcon-host
@@ -33,29 +33,134 @@ service hostname do
3333

3434
# Insert an in-memory cache in front of the application (using async-http-cache).
3535
cache true
36+
37+
# Connect to the supervisor for monitoring.
38+
include Async::Container::Supervisor::Supervised
3639
end
3740

3841
service "supervisor" do
3942
include Falcon::Environment::Supervisor
43+
44+
monitors do
45+
[
46+
MemoryMonitor.new(
47+
# Check every 10 seconds:
48+
interval: 10,
49+
# Per-supervisor (cluster) limit:
50+
total_size_limit: 1000*1024*1024,
51+
# Per-process limit:
52+
maximum_size_limit: 200*1024*1024
53+
)
54+
]
55+
end
4056
end
4157
~~~
4258

4359
These configuration blocks are evaluated using the [async-service](https://github.com/socketry/async-service) gem. The supervisor is an independent service which monitors the health of the application and can restart it if necessary. Other services like background job processors can be added to the configuration.
4460

4561
### Environments
4662

47-
The service blocks define configuration that is loaded by the serivce layer to control how the service is run. The `service ... do` block defines the service name and the environment in which it runs. Different modules can be included to provide different functionality, such as `Falcon::Environment::Rack` for Rack applications, or `Falcon::Environment::LetsEncryptTLS` for automatic TLS certificate management.
63+
The service blocks define configuration that is loaded by the service layer to control how the service is run. The `service ... do` block defines the service name and the environment in which it runs. Different modules can be included to provide different functionality, such as `Falcon::Environment::Rack` for Rack applications, or `Falcon::Environment::LetsEncryptTLS` for automatic TLS certificate management.
64+
65+
### Application Configuration
66+
67+
The environment configuration is defined in the `Falcon::Environment` module. The {ruby Falcon::Environment::Application} environment supports the generic virtual host functionality, but you can customise any parts of the configuration, e.g. to bind a production host to `localhost:3000` using plaintext HTTP/2:
68+
69+
~~~ ruby
70+
#!/usr/bin/env falcon host
71+
# frozen_string_literal: true
72+
73+
require "falcon/environment/rack"
74+
require "falcon/environment/supervisor"
75+
76+
hostname = File.basename(__dir__)
77+
service hostname do
78+
include Falcon::Environment::Rack
79+
include Falcon::Environment::LetsEncryptTLS
80+
81+
endpoint do
82+
Async::HTTP::Endpoint
83+
.parse('http://localhost:3000')
84+
.with(protocol: Async::HTTP::Protocol::HTTP2)
85+
end
86+
end
87+
88+
service "supervisor" do
89+
include Falcon::Environment::Supervisor
90+
end
91+
~~~
92+
93+
You can verify this is working using `nghttp -v http://localhost:3000`.
94+
95+
#### Application Configuration Example for Heroku
96+
97+
Building on the examples above, the following is a full configuration example for Heroku:
98+
99+
~~~ bash
100+
# Procfile
101+
102+
web: bundle exec falcon host
103+
~~~
104+
105+
~~~ ruby
106+
# falcon.rb
107+
108+
#!/usr/bin/env -S falcon host
109+
# frozen_string_literal: true
110+
111+
require "falcon/environment/rack"
112+
113+
hostname = File.basename(__dir__)
114+
115+
service hostname do
116+
include Falcon::Environment::Rack
117+
118+
# By default, Falcon uses Etc.nprocessors to set the count, which is likely incorrect on shared hosts like Heroku.
119+
# Review the following for guidance about how to find the right value for your app:
120+
# https://help.heroku.com/88G3XLA6/what-is-an-acceptable-amount-of-dyno-load
121+
# https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#workers
122+
count ENV.fetch("WEB_CONCURRENCY", 1).to_i
123+
124+
# If using count > 1 you may want to preload your app to reduce memory usage and increase performance:
125+
preload "preload.rb"
126+
127+
# The default port should be 3000, but you can change it to match your Heroku configuration.
128+
port {ENV.fetch("PORT", 3000).to_i}
129+
130+
# Heroku only supports HTTP/1.1 at the time of this writing. Review the following for possible updates in the future:
131+
# https://devcenter.heroku.com/articles/http-routing#http-versions-supported
132+
# https://github.com/heroku/roadmap/issues/34
133+
endpoint do
134+
Async::HTTP::Endpoint
135+
.parse("http://0.0.0.0:#{port}")
136+
.with(protocol: Async::HTTP::Protocol::HTTP11)
137+
end
138+
~~~
139+
140+
~~~ ruby
141+
# preload.rb
142+
143+
# frozen_string_literal: true
144+
145+
require_relative "config/environment"
146+
~~~
48147

49148
## Falcon Virtual
50149

51150
Falcon virtual provides a virtual host proxy and HTTP-to-HTTPS redirection for multiple applications. It is designed to be a zero-configuration deployment option, allowing you to run multiple applications on the same server.
52151

152+
~~~ mermaid
153+
graph TD;
154+
client[Client Browser] -->|TLS + HTTP/2 TCP| proxy["Falcon Proxy (SNI)"];
155+
proxy -->|HTTP/2 UNIX PIPE| server["Application Server (Rack Compatible)"];
156+
~~~
157+
53158
You need to create a `falcon.rb` configuration in the root of your applications, and start the virtual host:
54159

55160
~~~ bash
56161
falcon virtual /srv/http/*/falcon.rb
57162
~~~
58163

59-
By default, it binds to both HTTP and HTTPS ports, and automatically redirects HTTP requests to HTTPS. It also supports automatic TLS certificate management using Let's Encrypt.
164+
By default, it binds to both HTTP and HTTPS ports, and automatically redirects HTTP requests to HTTPS. It also supports TLS SNI for resolving the certificates.
60165

61166
See the [docker example](https://github.com/socketry/falcon-virtual-docker-example) for a complete working example.

context/extended-features.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Extended Features
2+
3+
This guide explains some of the extended features and functionality of Falcon.
4+
5+
## WebSockets
6+
7+
Falcon supports (partial and full) `rack.hijack` for both for HTTP/1 and HTTP/2 connections. You can use [async-websocket] in any controller layer to serve WebSocket connections.
8+
9+
[async-websocket]: https://github.com/socketry/async-websocket
10+
11+
## Early Hints
12+
13+
Falcon supports the `rack.early_hints` API when running over HTTP/2. You can [read more about the implementation and proposed interface](https://www.codeotaku.com/journal/2019-02/falcon-early-hints/index).

context/getting-started.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Getting Started
2+
3+
This guide gives an overview of how to use Falcon for running Ruby web applications.
4+
5+
## Installation
6+
7+
Add the gem to your project:
8+
9+
~~~ bash
10+
$ bundle add falcon
11+
~~~
12+
13+
Or, if you prefer, install it globally:
14+
15+
~~~ bash
16+
$ gem install falcon
17+
~~~
18+
19+
## Core Concepts
20+
21+
Falcon is a high-performance web server for Ruby. It is designed to be fast, lightweight, and easy to use.
22+
23+
- **Asynchronous**: Falcon is built on top of the fiber scheduler and the [async gem](https://github.com/socketry/async) which allow it to handle thousands of connections concurrently.
24+
- **Rack Compatible**: Falcon is a Rack server. It can run any Rack application, including Rails, Sinatra, and Roda with no modifications.
25+
- **Secure**: Falcon supports TLS out of the box. It can generate self-signed certificates for localhost.
26+
- **HTTP/2**: Falcon is build on top of the [async-http gem](https://github.com/socketry/async-http) which supports HTTP/2. It can serve multiple requests over a single connection.
27+
- **WebSockets**: Falcon supports WebSockets using the [async-websocket gem](https://github.com/socketry/async-websocket) which takes advantage of Rack 3 streaming responses. You can build complex real-time applications with ease.
28+
29+
### Rack
30+
31+
Falcon is a Rack server. This means it can run any Rack application, including Rails, Sinatra, and Roda. It is compatible with the Rack 2 and Rack 3 specifications. Typically these applications have a `config.ru` file that defines the application. Falcon can run these applications directly:
32+
33+
~~~ ruby
34+
# config.ru
35+
36+
run do |env|
37+
[200, {'Content-Type' => 'text/plain'}, ['Hello, World!']]
38+
end
39+
~~~
40+
41+
Then run the application with:
42+
43+
~~~ bash
44+
$ falcon serve
45+
~~~
46+
47+
## Running a Local Server
48+
49+
For local application development, you can use the `falcon serve` command. This will start a local server on `https://localhost:9292`. Falcon generates self-signed certificates for `localhost`. This allows you to test your application with HTTPS locally.
50+
51+
To run on a different port:
52+
53+
~~~ bash
54+
$ falcon serve --port 3000
55+
~~~
56+
57+
### Unencrypted HTTP
58+
59+
If you want to run Falcon without TLS, you can use the `--bind` option to bind to an unencrypted HTTP endpoint:
60+
61+
~~~ bash
62+
$ falcon serve --bind http://localhost:3000
63+
~~~
64+
65+
### Using with Rackup
66+
67+
You can invoke Falcon via `rackup`:
68+
69+
~~~ bash
70+
$ rackup --server falcon
71+
~~~
72+
73+
This will run a single-threaded instance of Falcon using `http/1`. While it works fine, it's not recommended to use `rackup` with `falcon`, because performance will be limited.

context/how-it-works.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# How It Works
2+
3+
This guide gives an overview of how Falcon handles an incoming web request.
4+
5+
## Overview
6+
7+
When you run `falcon serve`, Falcon creates a {ruby Falcon::Controller::Serve} which is used to create several worker threads or processes. Before starting the workers, the controller binds to an endpoint (e.g. a local unix socket, a TCP network socket, etc). The workers are spawned and receive this bound endpoint, and start accepting connections.
8+
9+
The workers individually load a copy of your rack application. These applications are wrapped using {ruby Falcon::Adapters::Rack} which modifies the incoming {ruby Protocol::HTTP::Request} object into an `env` object suitable for your application. It also handles converting the output of your rack application `[status, headers, body]` into an instance of {ruby Falcon::Adapters::Response} which is derived from {ruby Protocol::HTTP::Response}.
10+
11+
## Server
12+
13+
The server itself is mostly implemented by {ruby Async::HTTP::Server} which in turn depends on the `protocol-http` gems for the actual protocol implementations. Therefore, Falcon is primarily a bridge between the underlying protocol objects and the Rack interface.

context/index.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Automatically generated context index for Utopia::Project guides.
2+
# Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
3+
---
4+
getting-started:
5+
title: Getting Started
6+
order: 1
7+
description: This guide gives an overview of how to use Falcon for running Ruby
8+
web applications.
9+
rails-integration:
10+
title: Rails Integration
11+
order: 2
12+
description: This guide explains how to host Rails applications with Falcon.
13+
deployment:
14+
title: Deployment
15+
order: 3
16+
description: This guide explains how to use Falcon in production environments.
17+
extended-features:
18+
title: Extended Features
19+
order: 4
20+
description: This guide explains some of the extended features and functionality
21+
of Falcon.
22+
performance-tuning:
23+
title: Performance Tuning
24+
order: 5
25+
description: This guide explains the performance characteristics of Falcon.
26+
how-it-works:
27+
title: How It Works
28+
order: 6
29+
description: This guide gives an overview of how Falcon handles an incoming web
30+
request.

context/performance-tuning.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Performance Tuning
2+
3+
This guide explains the performance characteristics of Falcon.
4+
5+
## Scalability
6+
7+
Falcon uses an asynchronous event-driven reactor to provide non-blocking IO. It uses one Fiber per request, which have minimal overhead. Falcon can handle a large number of in-flight requests including long-running connections like websockets, HTTP/2 streaming, etc.
8+
9+
- [Improving Ruby Concurrency](https://www.codeotaku.com/journal/2018-06/improving-ruby-concurrency/index#performance) – Comparison of Falcon and Puma.
10+
11+
### Falcon Benchmark
12+
13+
The [falcon-benchmark] suite looks at how various servers respond to different levels of concurrency across several sample applications.
14+
15+
[falcon-benchmark]: https://github.com/socketry/falcon-benchmark
16+
17+
## Memory Usage
18+
19+
Falcon uses [async-container] to start multiple copies of your application. Each instance of your application is isolated by default for maximum fault-tolerance. However, this can lead to increased memory usage. Preloading parts of your application reduce this overhead and in addition can improve instance start-up time. To understand your application memory usage, you should use [process-metrics] which take into account memory shared between processes.
20+
21+
[async-container]: https://github.com/socketry/async-container
22+
[process-metrics]: https://github.com/socketry/process-metrics
23+
24+
### Preloading
25+
26+
Falcon offers two mechanisms for preloading code.
27+
28+
#### Preloading Gems
29+
30+
By default, falcon will load all gems in the `preload` group:
31+
32+
~~~ ruby
33+
# In gems.rb:
34+
35+
source "https://rubygems.org"
36+
37+
group :preload do
38+
# List any gems you want to be pre-loaded into the falcon process before forking.
39+
end
40+
~~~
41+
42+
#### Preloading Files
43+
44+
Create a file in your application called `preload.rb`. You can put this file anywhere in your application.
45+
46+
##### Falcon Serve
47+
48+
`falcon serve` has a `--preload` option which accepts the path to this file.
49+
50+
##### Falcon Host
51+
52+
`falcon.rb` applications may have a `preload` configuration option.
53+
54+
## System Limitations
55+
56+
If you are expecting to handle many simultaneous connections, please ensure you configure your file limits correctly.
57+
58+
~~~
59+
Errno::EMFILE: Too many open files - accept(2)
60+
~~~
61+
62+
This means that your system is limiting the number of files that can be opened by falcon. Please check the `ulimit` of your system and set it appropriately.

0 commit comments

Comments
 (0)