falcon 0.24.0 → 0.25.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
- data/README.md +14 -11
- data/examples/redis/config.ru +1 -1
- data/falcon.gemspec +1 -1
- data/lib/falcon/adapters/rack.rb +1 -1
- data/lib/falcon/adapters/response.rb +9 -2
- data/lib/falcon/command.rb +1 -1
- data/lib/falcon/command/serve.rb +33 -29
- data/lib/falcon/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96425fc2402b25445c421f2d8dec1739c0f2b04701c6d47de48db140f0a55123
|
4
|
+
data.tar.gz: 3c6b31df8560bbf133873e9c37d9600204e2bd893b139c23a0587678c5cbe22e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3ce086375cceb639ba87947f286b66c1d53c2693717233bedb1f1fa2222b0b31b1747e3f39566592e508ad1f97545a5334bd5ff051c397fd7a93591a9c28dd5
|
7
|
+
data.tar.gz: 8bbf6a1e2717969ad54dadef79faa2566a3299069d97f675b697f1b0b5f8283419150f2430141bc6bdae09ea6272fb7a284aac44d131874c79aab3a5a24df5f2
|
data/README.md
CHANGED
@@ -49,23 +49,26 @@ The `falcon serve` command has the following options for you to use:
|
|
49
49
|
```
|
50
50
|
$ falcon --help
|
51
51
|
falcon [--verbose | --quiet] [-h/--help] [-v/--version] <command>
|
52
|
-
An asynchronous HTTP
|
52
|
+
An asynchronous HTTP server.
|
53
53
|
|
54
54
|
[--verbose | --quiet] Verbosity of output for debugging.
|
55
|
-
[-h/--help] Print out help information.
|
55
|
+
[-h/--help] Print out help information.
|
56
56
|
[-v/--version] Print out the application version.
|
57
57
|
<command> One of: serve, virtual. Default: serve
|
58
58
|
|
59
|
-
serve [-b/--bind <address>] [-p/--port <number>] [-h/--hostname <hostname>] [-c/--config <path>] [-n/--
|
59
|
+
serve [-b/--bind <address>] [-p/--port <number>] [-h/--hostname <hostname>] [-t/--timeout <duration>] [--reuse-port] [-c/--config <path>] [--forked | --threaded | --hybrid] [-n/--count <count>] [--forks <count>] [--threads <count>]
|
60
60
|
Run an HTTP server.
|
61
61
|
|
62
|
-
[-b/--bind <address>]
|
63
|
-
[-p/--port <number>]
|
64
|
-
[-h/--hostname <hostname>]
|
65
|
-
[-
|
66
|
-
[-
|
67
|
-
[
|
68
|
-
|
62
|
+
[-b/--bind <address>] Bind to the given hostname/address Default: https://localhost:9292
|
63
|
+
[-p/--port <number>] Override the specified port
|
64
|
+
[-h/--hostname <hostname>] Specify the hostname which would be used for certificates, etc.
|
65
|
+
[-t/--timeout <duration>] Specify the maximum time to wait for blocking operations. Default: 60
|
66
|
+
[--reuse-port] Enable SO_REUSEPORT if possible. Default: false
|
67
|
+
[-c/--config <path>] Rackup configuration file to load Default: config.ru
|
68
|
+
[--forked | --threaded | --hybrid] Select a specific parallelism model Default: forked
|
69
|
+
[-n/--count <count>] Number of instances to start. Default: 8
|
70
|
+
[--forks <count>] Number of forks (hybrid only).
|
71
|
+
[--threads <count>] Number of threads (hybrid only). ```
|
69
72
|
|
70
73
|
To run on a different port:
|
71
74
|
|
@@ -118,7 +121,7 @@ Falcon supports `rack.hijack` for HTTP/1.x connections. You can thus use [async-
|
|
118
121
|
|
119
122
|
#### ActionCable
|
120
123
|
|
121
|
-
The `rack.hijack` functionality is compatible with ActionCable. If you use the `async` adapter, you should run falcon in threaded mode, or in forked mode with `--
|
124
|
+
The `rack.hijack` functionality is compatible with ActionCable. If you use the `async` adapter, you should run falcon in threaded mode, or in forked mode with `--count 1`. Otherwise, your messaging system will be distributed over several processes with no IPC mechanism. You might like to try out [async-redis](https://github.com/socketry/async-redis) as an asynchronous message bus.
|
122
125
|
|
123
126
|
### Early Hints
|
124
127
|
|
data/examples/redis/config.ru
CHANGED
@@ -21,7 +21,7 @@ use MyApp # Then, it will get to Sinatra.
|
|
21
21
|
run lambda {|env| [404, {}, []]} # Bottom of the stack, give 404.
|
22
22
|
|
23
23
|
# Start server like this:
|
24
|
-
# falcon --verbose serve --threaded --
|
24
|
+
# falcon --verbose serve --threaded --count 1 --bind http://localhost:9292
|
25
25
|
|
26
26
|
# Test server, e.g.:
|
27
27
|
# time ab -n 64 -c 64 http://localhost:9292/
|
data/falcon.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_dependency("async", "~> 1.13")
|
22
22
|
spec.add_dependency("async-io", "~> 1.18")
|
23
23
|
spec.add_dependency("async-http", "~> 0.38.0")
|
24
|
-
spec.add_dependency("async-container", "~> 0.
|
24
|
+
spec.add_dependency("async-container", "~> 0.10.0")
|
25
25
|
|
26
26
|
spec.add_dependency("rack", ">= 1.0")
|
27
27
|
|
data/lib/falcon/adapters/rack.rb
CHANGED
@@ -200,7 +200,7 @@ module Falcon
|
|
200
200
|
|
201
201
|
return make_response(request, status, headers, body)
|
202
202
|
rescue => exception
|
203
|
-
@logger.error
|
203
|
+
@logger.error(self) {exception}
|
204
204
|
|
205
205
|
return failure_response(exception)
|
206
206
|
end
|
@@ -20,12 +20,15 @@
|
|
20
20
|
|
21
21
|
require_relative 'output'
|
22
22
|
require_relative '../version'
|
23
|
+
require_relative '../proxy'
|
23
24
|
|
24
25
|
require 'time'
|
25
26
|
|
26
27
|
module Falcon
|
27
28
|
module Adapters
|
28
29
|
class Response < Async::HTTP::Response
|
30
|
+
IGNORE_HEADERS = Set.new(Proxy::HOP_HEADERS)
|
31
|
+
|
29
32
|
# Append a list of newline encoded headers.
|
30
33
|
def self.wrap_headers(fields)
|
31
34
|
headers = ::HTTP::Protocol::Headers.new
|
@@ -36,8 +39,12 @@ module Falcon
|
|
36
39
|
# This is a quick fix, but perhaps it should be part of the protocol, because it IS valid for HTTP/1.
|
37
40
|
key = key.downcase
|
38
41
|
|
39
|
-
|
40
|
-
|
42
|
+
if IGNORE_HEADERS.include? key
|
43
|
+
Async.logger.warn("Ignoring protocol-level header: #{key}: #{value}!")
|
44
|
+
else
|
45
|
+
value.to_s.split("\n").each do |part|
|
46
|
+
headers.add(key, part)
|
47
|
+
end
|
41
48
|
end
|
42
49
|
end
|
43
50
|
|
data/lib/falcon/command.rb
CHANGED
@@ -33,7 +33,7 @@ module Falcon
|
|
33
33
|
end
|
34
34
|
|
35
35
|
class Top < Samovar::Command
|
36
|
-
self.description = "An asynchronous HTTP
|
36
|
+
self.description = "An asynchronous HTTP server."
|
37
37
|
|
38
38
|
options do
|
39
39
|
option '--verbose | --quiet', "Verbosity of output for debugging.", key: :logging
|
data/lib/falcon/command/serve.rb
CHANGED
@@ -42,24 +42,28 @@ module Falcon
|
|
42
42
|
|
43
43
|
option '-p/--port <number>', "Override the specified port", type: Integer
|
44
44
|
option '-h/--hostname <hostname>', "Specify the hostname which would be used for certificates, etc."
|
45
|
-
option '-t/--timeout <duration>', "Specify the maximum time to wait for blocking operations.", type: Float, default: 60
|
45
|
+
option '-t/--timeout <duration>', "Specify the maximum time to wait for blocking operations.", type: Float, default: 60*10
|
46
46
|
|
47
47
|
option '--reuse-port', "Enable SO_REUSEPORT if possible.", default: false
|
48
48
|
|
49
49
|
option '-c/--config <path>', "Rackup configuration file to load", default: 'config.ru'
|
50
|
-
option '-n/--concurrency <count>', "Number of processes to start", default: Async::Container.hardware_concurrency, type: Integer
|
51
50
|
|
52
|
-
option '--forked | --threaded', "Select a specific
|
51
|
+
option '--forked | --threaded | --hybrid', "Select a specific parallelism model", key: :container, default: :forked
|
52
|
+
|
53
|
+
option '-n/--count <count>', "Number of instances to start.", default: Async::Container.processor_count, type: Integer
|
54
|
+
|
55
|
+
option '--forks <count>', "Number of forks (hybrid only).", type: Integer
|
56
|
+
option '--threads <count>', "Number of threads (hybrid only).", type: Integer
|
53
57
|
end
|
54
58
|
|
55
59
|
def container_class
|
56
60
|
case @options[:container]
|
57
61
|
when :threaded
|
58
|
-
require 'async/container/threaded'
|
59
62
|
return Async::Container::Threaded
|
60
63
|
when :forked
|
61
|
-
require 'async/container/forked'
|
62
64
|
return Async::Container::Forked
|
65
|
+
when :hybrid
|
66
|
+
return Async::Container::Hybrid
|
63
67
|
end
|
64
68
|
end
|
65
69
|
|
@@ -69,29 +73,27 @@ module Falcon
|
|
69
73
|
return Server.middleware(rack_app, verbose: verbose), options
|
70
74
|
end
|
71
75
|
|
72
|
-
def
|
73
|
-
#
|
76
|
+
def slice_options(*keys)
|
77
|
+
# TODO: Ruby 2.5 introduced Hash#slice
|
74
78
|
options = {}
|
75
79
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
if @options.key? :port
|
81
|
-
options[:port] = @options[:port]
|
82
|
-
end
|
83
|
-
|
84
|
-
if @options.key? :reuse_port
|
85
|
-
options[:reuse_port] = @options[:reuse_port]
|
86
|
-
end
|
87
|
-
|
88
|
-
if duration = @options[:timeout] and !duration.zero?
|
89
|
-
options[:timeout] = duration
|
80
|
+
keys.each do |key|
|
81
|
+
if @options.key?(key)
|
82
|
+
options[key] = @options[key]
|
83
|
+
end
|
90
84
|
end
|
91
85
|
|
92
86
|
return options
|
93
87
|
end
|
94
88
|
|
89
|
+
def container_options
|
90
|
+
slice_options(:count, :forks, :threads)
|
91
|
+
end
|
92
|
+
|
93
|
+
def endpoint_options
|
94
|
+
slice_options(:hostname, :port, :reuse_port, :timeout)
|
95
|
+
end
|
96
|
+
|
95
97
|
def client_endpoint
|
96
98
|
Async::HTTP::URLEndpoint.parse(@options[:bind], **endpoint_options)
|
97
99
|
end
|
@@ -109,22 +111,22 @@ module Falcon
|
|
109
111
|
Async::IO::SharedEndpoint.bound(endpoint)
|
110
112
|
end.wait
|
111
113
|
|
112
|
-
Async.logger.info(endpoint) do
|
113
|
-
"Falcon taking flight! Using #{container_class}
|
114
|
+
Async.logger.info(endpoint) do |buffer|
|
115
|
+
buffer.puts "Falcon taking flight! Using #{container_class} #{container_options}"
|
116
|
+
buffer.puts "- To terminate: Ctrl-C or kill #{Process.pid}"
|
114
117
|
end
|
115
118
|
|
116
119
|
debug_trap = Async::IO::Trap.new(:USR1)
|
117
|
-
|
118
120
|
debug_trap.ignore!
|
119
121
|
|
120
|
-
|
121
|
-
Async.logger.info "Full status: kill -USR1 #{-Process.pid}"
|
122
|
-
end
|
122
|
+
container = container_class.new
|
123
123
|
|
124
|
-
|
124
|
+
container.run(name: "Falcon Server", restart: true, **container_options) do |task, instance|
|
125
125
|
task.async do
|
126
126
|
if debug_trap.install!
|
127
|
-
Async.logger.info
|
127
|
+
Async.logger.info(instance) do
|
128
|
+
"- Per-process status: kill -USR1 #{Process.pid}"
|
129
|
+
end
|
128
130
|
end
|
129
131
|
|
130
132
|
debug_trap.trap do
|
@@ -140,6 +142,8 @@ module Falcon
|
|
140
142
|
|
141
143
|
task.children.each(&:wait)
|
142
144
|
end
|
145
|
+
|
146
|
+
return container
|
143
147
|
end
|
144
148
|
|
145
149
|
def invoke(parent)
|
data/lib/falcon/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: falcon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.25.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http-protocol
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: 0.10.0
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
82
|
+
version: 0.10.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rack
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|