falcon 0.24.0 → 0.25.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|