unicorn 5.0.1 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.manifest +11 -5
- data/.olddoc.yml +16 -6
- data/Application_Timeouts +4 -4
- data/CONTRIBUTORS +6 -2
- data/Documentation/.gitignore +1 -3
- data/Documentation/unicorn.1 +222 -0
- data/Documentation/unicorn_rails.1 +207 -0
- data/FAQ +1 -1
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +118 -58
- data/HACKING +2 -10
- data/ISSUES +40 -35
- data/KNOWN_ISSUES +2 -2
- data/LATEST +23 -28
- data/LICENSE +2 -2
- data/Links +13 -11
- data/NEWS +612 -0
- data/README +30 -29
- data/SIGNALS +1 -1
- data/Sandbox +8 -7
- data/TODO +0 -2
- data/TUNING +19 -1
- data/archive/slrnpull.conf +1 -1
- data/bin/unicorn +3 -1
- data/bin/unicorn_rails +2 -2
- data/examples/big_app_gc.rb +1 -1
- data/examples/init.sh +36 -8
- data/examples/logrotate.conf +17 -2
- data/examples/nginx.conf +4 -3
- data/examples/unicorn.conf.minimal.rb +2 -2
- data/examples/unicorn.conf.rb +2 -2
- data/examples/unicorn@.service +14 -0
- data/ext/unicorn_http/c_util.h +5 -13
- data/ext/unicorn_http/common_field_optimization.h +22 -5
- data/ext/unicorn_http/epollexclusive.h +124 -0
- data/ext/unicorn_http/ext_help.h +0 -44
- data/ext/unicorn_http/extconf.rb +32 -6
- data/ext/unicorn_http/global_variables.h +2 -2
- data/ext/unicorn_http/httpdate.c +2 -1
- data/ext/unicorn_http/unicorn_http.c +853 -498
- data/ext/unicorn_http/unicorn_http.rl +86 -30
- data/ext/unicorn_http/unicorn_http_common.rl +1 -1
- data/lib/unicorn/configurator.rb +93 -13
- data/lib/unicorn/http_request.rb +101 -11
- data/lib/unicorn/http_response.rb +8 -4
- data/lib/unicorn/http_server.rb +141 -72
- data/lib/unicorn/launcher.rb +1 -1
- data/lib/unicorn/oob_gc.rb +6 -6
- data/lib/unicorn/select_waiter.rb +6 -0
- data/lib/unicorn/socket_helper.rb +23 -7
- data/lib/unicorn/stream_input.rb +5 -4
- data/lib/unicorn/tee_input.rb +8 -10
- data/lib/unicorn/tmpio.rb +8 -2
- data/lib/unicorn/util.rb +3 -3
- data/lib/unicorn/version.rb +1 -1
- data/lib/unicorn/worker.rb +33 -8
- data/lib/unicorn.rb +55 -29
- data/man/man1/unicorn.1 +120 -118
- data/man/man1/unicorn_rails.1 +106 -107
- data/t/GNUmakefile +3 -72
- data/t/README +4 -4
- data/t/t0011-active-unix-socket.sh +1 -1
- data/t/t0012-reload-empty-config.sh +2 -1
- data/t/t0301-no-default-middleware-ignored-in-config.sh +25 -0
- data/t/t0301.ru +13 -0
- data/t/test-lib.sh +4 -3
- data/test/benchmark/README +14 -4
- data/test/benchmark/ddstream.ru +50 -0
- data/test/benchmark/readinput.ru +40 -0
- data/test/benchmark/uconnect.perl +66 -0
- data/test/exec/test_exec.rb +26 -24
- data/test/test_helper.rb +38 -30
- data/test/unit/test_ccc.rb +91 -0
- data/test/unit/test_droplet.rb +1 -1
- data/test/unit/test_http_parser.rb +46 -16
- data/test/unit/test_http_parser_ng.rb +81 -0
- data/test/unit/test_request.rb +10 -10
- data/test/unit/test_server.rb +86 -12
- data/test/unit/test_signals.rb +8 -8
- data/test/unit/test_socket_helper.rb +13 -9
- data/test/unit/test_upload.rb +9 -14
- data/test/unit/test_util.rb +31 -5
- data/test/unit/test_waiter.rb +34 -0
- data/unicorn.gemspec +21 -22
- metadata +21 -28
- data/Documentation/GNUmakefile +0 -30
- data/Documentation/unicorn.1.txt +0 -188
- data/Documentation/unicorn_rails.1.txt +0 -175
- data/t/hijack.ru +0 -43
- data/t/t0200-rack-hijack.sh +0 -30
data/README
CHANGED
@@ -10,10 +10,9 @@ both the the request and response in between unicorn and slow clients.
|
|
10
10
|
|
11
11
|
* Designed for Rack, Unix, fast clients, and ease-of-debugging. We
|
12
12
|
cut out everything that is better supported by the operating system,
|
13
|
-
{nginx}[
|
13
|
+
{nginx}[https://nginx.org/] or {Rack}[https://rack.github.io/].
|
14
14
|
|
15
|
-
* Compatible with Ruby
|
16
|
-
unicorn 4.8.x will remain supported for Ruby 1.8 users.
|
15
|
+
* Compatible with Ruby 2.0.0 and later.
|
17
16
|
|
18
17
|
* Process management: unicorn will reap and restart workers that
|
19
18
|
die from broken apps. There is no need to manage multiple processes
|
@@ -27,9 +26,6 @@ both the the request and response in between unicorn and slow clients.
|
|
27
26
|
all run within their own isolated address space and only serve one
|
28
27
|
client at a time for maximum robustness.
|
29
28
|
|
30
|
-
* Supports all Rack applications, along with pre-Rack versions of
|
31
|
-
Ruby on Rails via a Rack wrapper.
|
32
|
-
|
33
29
|
* Builtin reopening of all log files in your application via
|
34
30
|
USR1 signal. This allows logrotate to rotate files atomically and
|
35
31
|
quickly via rename instead of the racy and slow copytruncate method.
|
@@ -40,12 +36,15 @@ both the the request and response in between unicorn and slow clients.
|
|
40
36
|
You can upgrade unicorn, your entire application, libraries
|
41
37
|
and even your Ruby interpreter without dropping clients.
|
42
38
|
|
39
|
+
* transparent upgrades using systemd socket activation is
|
40
|
+
supported since unicorn 5.0
|
41
|
+
|
43
42
|
* before_fork and after_fork hooks in case your application
|
44
43
|
has special needs when dealing with forked processes. These
|
45
44
|
should not be needed when the "preload_app" directive is
|
46
45
|
false (the default).
|
47
46
|
|
48
|
-
* Can be used with copy-on-write-friendly
|
47
|
+
* Can be used with copy-on-write-friendly GC in Ruby 2.0+
|
49
48
|
to save memory (by setting "preload_app" to true).
|
50
49
|
|
51
50
|
* Able to listen on multiple interfaces including UNIX sockets,
|
@@ -54,13 +53,11 @@ both the the request and response in between unicorn and slow clients.
|
|
54
53
|
|
55
54
|
* Simple and easy Ruby DSL for configuration.
|
56
55
|
|
57
|
-
* Decodes chunked
|
58
|
-
notification to be implemented as well as being able to tunnel
|
59
|
-
arbitrary stream-based protocols over HTTP.
|
56
|
+
* Decodes chunked requests on-the-fly.
|
60
57
|
|
61
58
|
== License
|
62
59
|
|
63
|
-
unicorn is copyright 2009 by all contributors (see logs in git).
|
60
|
+
unicorn is copyright 2009-2018 by all contributors (see logs in git).
|
64
61
|
It is based on Mongrel 1.1.5.
|
65
62
|
Mongrel is copyright 2007 Zed A. Shaw and contributors.
|
66
63
|
|
@@ -68,7 +65,7 @@ unicorn is licensed under (your choice) of the GPLv2 or later
|
|
68
65
|
(GPLv3+ preferred), or Ruby (1.8)-specific terms.
|
69
66
|
See the included LICENSE file for details.
|
70
67
|
|
71
|
-
unicorn is 100% Free Software.
|
68
|
+
unicorn is 100% Free Software (including all development tools used).
|
72
69
|
|
73
70
|
== Install
|
74
71
|
|
@@ -82,14 +79,13 @@ You may install it via RubyGems on RubyGems.org:
|
|
82
79
|
You can get the latest source via git from the following locations
|
83
80
|
(these versions may not be stable):
|
84
81
|
|
85
|
-
|
86
|
-
|
82
|
+
https://yhbt.net/unicorn.git
|
83
|
+
https://repo.or.cz/unicorn.git (mirror)
|
87
84
|
|
88
|
-
You may browse the code from the web
|
89
|
-
tarballs here:
|
85
|
+
You may browse the code from the web:
|
90
86
|
|
91
|
-
*
|
92
|
-
*
|
87
|
+
* https://yhbt.net/unicorn.git
|
88
|
+
* https://repo.or.cz/w/unicorn.git (gitweb)
|
93
89
|
|
94
90
|
See the HACKING guide on how to contribute and build prerelease gems
|
95
91
|
from git.
|
@@ -102,12 +98,6 @@ In APP_ROOT, run:
|
|
102
98
|
|
103
99
|
unicorn
|
104
100
|
|
105
|
-
=== Ancient Rails 1.2 - 2.x versions
|
106
|
-
|
107
|
-
In RAILS_ROOT, run:
|
108
|
-
|
109
|
-
unicorn_rails
|
110
|
-
|
111
101
|
unicorn will bind to all interfaces on TCP port 8080 by default.
|
112
102
|
You may use the +--listen/-l+ switch to bind to a different
|
113
103
|
address:port or a UNIX socket.
|
@@ -134,17 +124,28 @@ unicorn is designed to only serve fast clients either on the local host
|
|
134
124
|
or a fast LAN. See the PHILOSOPHY and DESIGN documents for more details
|
135
125
|
regarding this.
|
136
126
|
|
127
|
+
Due to its ability to tolerate crashes and isolate clients, unicorn
|
128
|
+
is unfortunately known to prolong the existence of bugs in applications
|
129
|
+
and libraries which run on top of it.
|
130
|
+
|
137
131
|
== Contact
|
138
132
|
|
139
133
|
All feedback (bug reports, user/development dicussion, patches, pull
|
140
134
|
requests) go to the mailing list/newsgroup. See the ISSUES document for
|
141
|
-
information on the {mailing list}[mailto:unicorn-public@
|
135
|
+
information on the {mailing list}[mailto:unicorn-public@yhbt.net].
|
136
|
+
|
137
|
+
The mailing list is archived at https://yhbt.net/unicorn-public/
|
142
138
|
|
143
|
-
The mailing list is archived at http://bogomips.org/unicorn-public/
|
144
139
|
Read-only NNTP access is available at:
|
145
|
-
|
146
|
-
nntp://news.gmane.
|
140
|
+
nntps://news.public-inbox.org/inbox.comp.lang.ruby.unicorn and
|
141
|
+
nntp://news.gmane.io/gmane.comp.lang.ruby.unicorn.general
|
142
|
+
|
143
|
+
Read-only IMAP access is also avaialble at:
|
144
|
+
imaps://yhbt.net/inbox.comp.lang.ruby.unicorn.0 and
|
145
|
+
imap://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.lang.ruby.unicorn.0
|
146
|
+
The AUTH=ANONYMOUS mechanism is supported, as is any username+password
|
147
|
+
combination.
|
147
148
|
|
148
149
|
For the latest on unicorn releases, you may also finger us at
|
149
|
-
unicorn@
|
150
|
+
unicorn@yhbt.net or check our NEWS page (and subscribe to our Atom
|
150
151
|
feed).
|
data/SIGNALS
CHANGED
@@ -8,7 +8,7 @@ should be possible to easily share process management scripts between
|
|
8
8
|
Unicorn and nginx.
|
9
9
|
|
10
10
|
One example init script is distributed with unicorn:
|
11
|
-
|
11
|
+
https://yhbt.net/unicorn/examples/init.sh
|
12
12
|
|
13
13
|
=== Master Process
|
14
14
|
|
data/Sandbox
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Since unicorn includes executables and is usually used to start a Ruby
|
4
4
|
process, there are certain caveats to using it with tools that sandbox
|
5
5
|
RubyGems installations such as
|
6
|
-
{Bundler}[
|
6
|
+
{Bundler}[https://bundler.io/] or
|
7
7
|
{Isolate}[https://github.com/jbarnette/isolate].
|
8
8
|
|
9
9
|
== General deployment
|
@@ -34,7 +34,7 @@ is the primary issue with sandboxing tools such as Bundler and Isolate.
|
|
34
34
|
If you're bundling unicorn, use "bundle exec unicorn" (or "bundle exec
|
35
35
|
unicorn_rails") to start unicorn with the correct environment variables
|
36
36
|
|
37
|
-
ref:
|
37
|
+
ref: https://yhbt.net/unicorn-public/9ECF07C4-5216-47BE-961D-AFC0F0C82060@internetfamo.us/
|
38
38
|
|
39
39
|
Otherwise (if you choose to not sandbox your unicorn installation), we
|
40
40
|
expect the tips for Isolate (below) apply, too.
|
@@ -43,7 +43,8 @@ expect the tips for Isolate (below) apply, too.
|
|
43
43
|
|
44
44
|
This is no longer be an issue as of bundler 0.9.17
|
45
45
|
|
46
|
-
ref:
|
46
|
+
ref:
|
47
|
+
https://yhbt.net/unicorn-public/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com/
|
47
48
|
|
48
49
|
=== BUNDLE_GEMFILE for Capistrano users
|
49
50
|
|
@@ -63,9 +64,9 @@ before_exec hook as illustrated by https://gist.github.com/534668
|
|
63
64
|
=== Ruby 2.0.0 close-on-exec and SIGUSR2 incompatibility
|
64
65
|
|
65
66
|
Ruby 2.0.0 enforces FD_CLOEXEC on file descriptors by default. unicorn
|
66
|
-
has been prepared for this behavior since unicorn 4.1.0,
|
67
|
-
|
68
|
-
https://
|
67
|
+
has been prepared for this behavior since unicorn 4.1.0, and bundler
|
68
|
+
needs the "--keep-file-descriptors" option for "bundle exec":
|
69
|
+
https://bundler.io/man/bundle-exec.1.html
|
69
70
|
|
70
71
|
== Isolate
|
71
72
|
|
@@ -86,7 +87,7 @@ For now workarounds include doing one of the following:
|
|
86
87
|
|
87
88
|
3. Explicitly setting RUBYLIB or $LOAD_PATH to include any gem path
|
88
89
|
where the unicorn gem is installed
|
89
|
-
(e.g. /usr/lib/ruby/gems/
|
90
|
+
(e.g. /usr/lib/ruby/gems/3.0.0/gems/unicorn-VERSION/lib)
|
90
91
|
|
91
92
|
=== RUBYOPT pollution from SIGUSR2 upgrades
|
92
93
|
|
data/TODO
CHANGED
data/TUNING
CHANGED
@@ -72,10 +72,28 @@ See Unicorn::Configurator for details on the config file format.
|
|
72
72
|
have them unbuffered (File#sync = true) or they are
|
73
73
|
record(line)-buffered in userspace before any writes.
|
74
74
|
|
75
|
-
== Kernel Parameters (Linux sysctl)
|
75
|
+
== Kernel Parameters (Linux sysctl and sysfs)
|
76
76
|
|
77
77
|
WARNING: Do not change system parameters unless you know what you're doing!
|
78
78
|
|
79
|
+
* Transparent hugepages (THP) improves performance in many cases,
|
80
|
+
but can also increase memory use when relying on a
|
81
|
+
copy-on-write(CoW)-friendly GC (Ruby 2.0+) with "preload_app true".
|
82
|
+
CoW operates at the page level, so writing to a huge page would
|
83
|
+
trigger a 2 MB copy (x86-64), as opposed to a 4 KB copy on a
|
84
|
+
regular (non-huge) page.
|
85
|
+
|
86
|
+
Consider only allowing THP to be used when it is requested via the
|
87
|
+
madvise(2) syscall:
|
88
|
+
|
89
|
+
echo madvise >/sys/kernel/mm/transparent_hugepage/enabled
|
90
|
+
|
91
|
+
Or disabling it system-wide, via "never".
|
92
|
+
|
93
|
+
n.b. "page" in this context only applies to the OS kernel,
|
94
|
+
Ruby GC implementations also use this term for the same concept
|
95
|
+
in a way that is agnostic to the OS.
|
96
|
+
|
79
97
|
* net.core.rmem_max and net.core.wmem_max can increase the allowed
|
80
98
|
size of :rcvbuf and :sndbuf respectively. This is mostly only useful
|
81
99
|
for UNIX domain sockets which do not have auto-tuning buffer sizes.
|
data/archive/slrnpull.conf
CHANGED
data/bin/unicorn
CHANGED
@@ -6,6 +6,7 @@ require 'optparse'
|
|
6
6
|
ENV["RACK_ENV"] ||= "development"
|
7
7
|
rackup_opts = Unicorn::Configurator::RACKUP
|
8
8
|
options = rackup_opts[:options]
|
9
|
+
set_no_default_middleware = true
|
9
10
|
|
10
11
|
op = OptionParser.new("", 24, ' ') do |opts|
|
11
12
|
cmd = File.basename($0)
|
@@ -60,7 +61,7 @@ op = OptionParser.new("", 24, ' ') do |opts|
|
|
60
61
|
|
61
62
|
opts.on("-N", "--no-default-middleware",
|
62
63
|
"do not load middleware implied by RACK_ENV") do |e|
|
63
|
-
rackup_opts[:no_default_middleware] = true
|
64
|
+
rackup_opts[:no_default_middleware] = true if set_no_default_middleware
|
64
65
|
end
|
65
66
|
|
66
67
|
opts.on("-D", "--daemonize", "run daemonized in the background") do |d|
|
@@ -110,6 +111,7 @@ op = OptionParser.new("", 24, ' ') do |opts|
|
|
110
111
|
opts.parse! ARGV
|
111
112
|
end
|
112
113
|
|
114
|
+
set_no_default_middleware = false
|
113
115
|
app = Unicorn.builder(ARGV[0] || 'config.ru', op)
|
114
116
|
op = nil
|
115
117
|
|
data/bin/unicorn_rails
CHANGED
@@ -132,11 +132,11 @@ def rails_builder(ru, op, daemonize)
|
|
132
132
|
|
133
133
|
# this lambda won't run until after forking if preload_app is false
|
134
134
|
# this runs after config file reloading
|
135
|
-
lambda do
|
135
|
+
lambda do |x, server|
|
136
136
|
# Rails 3 includes a config.ru, use it if we find it after
|
137
137
|
# working_directory is bound.
|
138
138
|
::File.exist?('config.ru') and
|
139
|
-
return Unicorn.builder('config.ru', op).call
|
139
|
+
return Unicorn.builder('config.ru', op).call(x, server)
|
140
140
|
|
141
141
|
# Load Rails and (possibly) the private version of Rack it bundles.
|
142
142
|
begin
|
data/examples/big_app_gc.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
# see {Unicorn::OobGC}[
|
1
|
+
# see {Unicorn::OobGC}[https://yhbt.net/unicorn/Unicorn/OobGC.html]
|
2
2
|
# Unicorn::OobGC was broken in Unicorn v3.3.1 - v3.6.1 and fixed in v3.6.2
|
data/examples/init.sh
CHANGED
@@ -1,7 +1,16 @@
|
|
1
1
|
#!/bin/sh
|
2
2
|
set -e
|
3
|
+
### BEGIN INIT INFO
|
4
|
+
# Provides: unicorn
|
5
|
+
# Required-Start: $local_fs $network
|
6
|
+
# Required-Stop: $local_fs $network
|
7
|
+
# Default-Start: 2 3 4 5
|
8
|
+
# Default-Stop: 0 1 6
|
9
|
+
# Short-Description: Start/stop unicorn Rack app server
|
10
|
+
### END INIT INFO
|
11
|
+
|
3
12
|
# Example init script, this can be used with nginx, too,
|
4
|
-
# since nginx and unicorn accept the same signals
|
13
|
+
# since nginx and unicorn accept the same signals.
|
5
14
|
|
6
15
|
# Feel free to change any of the following variables for your app:
|
7
16
|
TIMEOUT=${TIMEOUT-60}
|
@@ -9,21 +18,22 @@ APP_ROOT=/home/x/my_app/current
|
|
9
18
|
PID=$APP_ROOT/tmp/pids/unicorn.pid
|
10
19
|
CMD="/usr/bin/unicorn -D -c $APP_ROOT/config/unicorn.rb"
|
11
20
|
INIT_CONF=$APP_ROOT/config/init.conf
|
21
|
+
UPGRADE_DELAY=${UPGRADE_DELAY-2}
|
12
22
|
action="$1"
|
13
23
|
set -u
|
14
24
|
|
15
25
|
test -f "$INIT_CONF" && . $INIT_CONF
|
16
26
|
|
17
|
-
|
27
|
+
OLD="$PID.oldbin"
|
18
28
|
|
19
29
|
cd $APP_ROOT || exit 1
|
20
30
|
|
21
31
|
sig () {
|
22
|
-
test -s "$PID" && kill -$1
|
32
|
+
test -s "$PID" && kill -$1 $(cat $PID)
|
23
33
|
}
|
24
34
|
|
25
35
|
oldsig () {
|
26
|
-
test -s $
|
36
|
+
test -s "$OLD" && kill -$1 $(cat $OLD)
|
27
37
|
}
|
28
38
|
|
29
39
|
case $action in
|
@@ -45,18 +55,36 @@ restart|reload)
|
|
45
55
|
$CMD
|
46
56
|
;;
|
47
57
|
upgrade)
|
48
|
-
if
|
58
|
+
if oldsig 0
|
59
|
+
then
|
60
|
+
echo >&2 "Old upgraded process still running with $OLD"
|
61
|
+
exit 1
|
62
|
+
fi
|
63
|
+
|
64
|
+
cur_pid=
|
65
|
+
if test -s "$PID"
|
66
|
+
then
|
67
|
+
cur_pid=$(cat $PID)
|
68
|
+
fi
|
69
|
+
|
70
|
+
if test -n "$cur_pid" &&
|
71
|
+
kill -USR2 "$cur_pid" &&
|
72
|
+
sleep $UPGRADE_DELAY &&
|
73
|
+
new_pid=$(cat $PID) &&
|
74
|
+
test x"$new_pid" != x"$cur_pid" &&
|
75
|
+
kill -0 "$new_pid" &&
|
76
|
+
kill -QUIT "$cur_pid"
|
49
77
|
then
|
50
78
|
n=$TIMEOUT
|
51
|
-
while
|
79
|
+
while kill -0 "$cur_pid" 2>/dev/null && test $n -ge 0
|
52
80
|
do
|
53
81
|
printf '.' && sleep 1 && n=$(( $n - 1 ))
|
54
82
|
done
|
55
83
|
echo
|
56
84
|
|
57
|
-
if test $n -lt 0 &&
|
85
|
+
if test $n -lt 0 && kill -0 "$cur_pid" 2>/dev/null
|
58
86
|
then
|
59
|
-
echo >&2 "$
|
87
|
+
echo >&2 "$cur_pid still running after $TIMEOUT seconds"
|
60
88
|
exit 1
|
61
89
|
fi
|
62
90
|
exit 0
|
data/examples/logrotate.conf
CHANGED
@@ -2,7 +2,10 @@
|
|
2
2
|
# /etc/logrotate.d/unicorn_app on my Debian systems
|
3
3
|
#
|
4
4
|
# See the logrotate(8) manpage for more information:
|
5
|
-
#
|
5
|
+
# https://linux.die.net/man/8/logrotate
|
6
|
+
#
|
7
|
+
# public logrotate-related discussion in our archives:
|
8
|
+
# https://yhbt.net/unicorn-public/?q=logrotate
|
6
9
|
|
7
10
|
# Modify the following glob to match the logfiles your app writes to:
|
8
11
|
/var/log/unicorn_app/*.log {
|
@@ -22,7 +25,19 @@
|
|
22
25
|
# config. Unicorn supports the USR1 signal and we send it
|
23
26
|
# as our "lastaction" action:
|
24
27
|
lastaction
|
25
|
-
#
|
28
|
+
# For systemd users, assuming you use two services
|
29
|
+
# (as recommended) to allow zero-downtime upgrades.
|
30
|
+
# Only one service needs to be started, but signaling
|
31
|
+
# both here is harmless as long as they're both enabled
|
32
|
+
systemctl kill -s SIGUSR1 unicorn@1.service
|
33
|
+
systemctl kill -s SIGUSR1 unicorn@2.service
|
34
|
+
|
35
|
+
# Examples for other process management systems appreciated
|
36
|
+
# Mail us at unicorn-public@yhbt.net
|
37
|
+
# (see above for archives)
|
38
|
+
|
39
|
+
# If you use a pid file and assuming your pid file
|
40
|
+
# is in /var/run/unicorn_app/pid
|
26
41
|
pid=/var/run/unicorn_app/pid
|
27
42
|
test -s $pid && kill -USR1 "$(cat $pid)"
|
28
43
|
endscript
|
data/examples/nginx.conf
CHANGED
@@ -56,7 +56,8 @@ http {
|
|
56
56
|
# to configure it all in one place here for static files and also
|
57
57
|
# to disable gzip for clients who don't get gzip/deflate right.
|
58
58
|
# There are other gzip settings that may be needed used to deal with
|
59
|
-
# bad clients out there, see
|
59
|
+
# bad clients out there, see
|
60
|
+
# https://nginx.org/en/docs/http/ngx_http_gzip_module.html
|
60
61
|
gzip on;
|
61
62
|
gzip_http_version 1.0;
|
62
63
|
gzip_proxied any;
|
@@ -112,12 +113,12 @@ http {
|
|
112
113
|
# try_files directive appeared in in nginx 0.7.27 and has stabilized
|
113
114
|
# over time. Older versions of nginx (e.g. 0.6.x) requires
|
114
115
|
# "if (!-f $request_filename)" which was less efficient:
|
115
|
-
#
|
116
|
+
# https://yhbt.net/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
|
116
117
|
try_files $uri/index.html $uri.html $uri @app;
|
117
118
|
|
118
119
|
location @app {
|
119
120
|
# an HTTP header important enough to have its own Wikipedia entry:
|
120
|
-
#
|
121
|
+
# https://en.wikipedia.org/wiki/X-Forwarded-For
|
121
122
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
122
123
|
|
123
124
|
# enable this if you forward HTTPS traffic to unicorn,
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# Minimal sample configuration file for Unicorn (not Rack) when used
|
2
2
|
# with daemonization (unicorn -D) started in your working directory.
|
3
3
|
#
|
4
|
-
# See
|
4
|
+
# See https://yhbt.net/unicorn/Unicorn/Configurator.html for complete
|
5
5
|
# documentation.
|
6
|
-
# See also
|
6
|
+
# See also https://yhbt.net/unicorn/examples/unicorn.conf.rb for
|
7
7
|
# a more verbose configuration using more features.
|
8
8
|
|
9
9
|
listen 2007 # by default Unicorn listens on port 8080
|
data/examples/unicorn.conf.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
#
|
3
3
|
# This configuration file documents many features of Unicorn
|
4
4
|
# that may not be needed for some applications. See
|
5
|
-
#
|
5
|
+
# https://yhbt.net/unicorn/examples/unicorn.conf.minimal.rb
|
6
6
|
# for a much simpler configuration file.
|
7
7
|
#
|
8
|
-
# See
|
8
|
+
# See https://yhbt.net/unicorn/Unicorn/Configurator.html for complete
|
9
9
|
# documentation.
|
10
10
|
|
11
11
|
# Use at least one worker per core if you're on a dedicated server,
|
data/examples/unicorn@.service
CHANGED
@@ -11,8 +11,17 @@ Wants = unicorn.socket
|
|
11
11
|
After = unicorn.socket
|
12
12
|
|
13
13
|
[Service]
|
14
|
+
# bundler users must use the "--keep-file-descriptors" switch, here:
|
15
|
+
# ExecStart = bundle exec --keep-file-descriptors unicorn -c ...
|
14
16
|
ExecStart = /usr/bin/unicorn -c /path/to/unicorn.conf.rb /path/to/config.ru
|
17
|
+
|
18
|
+
# NonBlocking MUST be true if using socket activation with unicorn.
|
19
|
+
# Otherwise, there's a small window in-between when the non-blocking
|
20
|
+
# flag is set by us and our accept4 call where systemd can momentarily
|
21
|
+
# make the socket blocking, causing us to block on accept4:
|
22
|
+
NonBlocking = true
|
15
23
|
Sockets = unicorn.socket
|
24
|
+
|
16
25
|
KillSignal = SIGQUIT
|
17
26
|
User = nobody
|
18
27
|
Group = nogroup
|
@@ -22,5 +31,10 @@ ExecReload = /bin/kill -HUP $MAINPID
|
|
22
31
|
# adding a few seconds for scheduling differences:
|
23
32
|
TimeoutStopSec = 62
|
24
33
|
|
34
|
+
# Only kill the master process, it may be harmful to signal
|
35
|
+
# workers via default "control-group" setting since some
|
36
|
+
# Ruby extensions and applications misbehave on interrupts
|
37
|
+
KillMode = process
|
38
|
+
|
25
39
|
[Install]
|
26
40
|
WantedBy = multi-user.target
|
data/ext/unicorn_http/c_util.h
CHANGED
@@ -8,23 +8,15 @@
|
|
8
8
|
|
9
9
|
#include <unistd.h>
|
10
10
|
#include <assert.h>
|
11
|
+
#include <limits.h>
|
11
12
|
|
12
13
|
#define MIN(a,b) (a < b ? a : b)
|
13
14
|
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
14
15
|
|
15
|
-
#
|
16
|
-
# define
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
#if SIZEOF_OFF_T == 4
|
21
|
-
# define UH_OFF_T_MAX 0x7fffffff
|
22
|
-
#elif SIZEOF_OFF_T == 8
|
23
|
-
# if SIZEOF_LONG == 4
|
24
|
-
# define UH_OFF_T_MAX 0x7fffffffffffffffLL
|
25
|
-
# else
|
26
|
-
# define UH_OFF_T_MAX 0x7fffffffffffffff
|
27
|
-
# endif
|
16
|
+
#if SIZEOF_OFF_T == SIZEOF_INT
|
17
|
+
# define UH_OFF_T_MAX INT_MAX
|
18
|
+
#elif SIZEOF_OFF_T == SIZEOF_LONG_LONG
|
19
|
+
# define UH_OFF_T_MAX LLONG_MAX
|
28
20
|
#else
|
29
21
|
# error off_t size unknown for this platform!
|
30
22
|
#endif /* SIZEOF_OFF_T check */
|
@@ -58,6 +58,23 @@ static struct common_field common_http_fields[] = {
|
|
58
58
|
|
59
59
|
#define HTTP_PREFIX "HTTP_"
|
60
60
|
#define HTTP_PREFIX_LEN (sizeof(HTTP_PREFIX) - 1)
|
61
|
+
static ID id_uminus;
|
62
|
+
|
63
|
+
/* this dedupes under Ruby 2.5+ (December 2017) */
|
64
|
+
static VALUE str_dd_freeze(VALUE str)
|
65
|
+
{
|
66
|
+
if (STR_UMINUS_DEDUPE)
|
67
|
+
return rb_funcall(str, id_uminus, 0);
|
68
|
+
|
69
|
+
/* freeze,since it speeds up older MRI slightly */
|
70
|
+
OBJ_FREEZE(str);
|
71
|
+
return str;
|
72
|
+
}
|
73
|
+
|
74
|
+
static VALUE str_new_dd_freeze(const char *ptr, long len)
|
75
|
+
{
|
76
|
+
return str_dd_freeze(rb_str_new(ptr, len));
|
77
|
+
}
|
61
78
|
|
62
79
|
/* this function is not performance-critical, called only at load time */
|
63
80
|
static void init_common_fields(void)
|
@@ -65,19 +82,19 @@ static void init_common_fields(void)
|
|
65
82
|
int i;
|
66
83
|
struct common_field *cf = common_http_fields;
|
67
84
|
char tmp[64];
|
85
|
+
|
68
86
|
memcpy(tmp, HTTP_PREFIX, HTTP_PREFIX_LEN);
|
69
87
|
|
70
88
|
for(i = ARRAY_SIZE(common_http_fields); --i >= 0; cf++) {
|
71
89
|
/* Rack doesn't like certain headers prefixed with "HTTP_" */
|
72
90
|
if (!strcmp("CONTENT_LENGTH", cf->name) ||
|
73
91
|
!strcmp("CONTENT_TYPE", cf->name)) {
|
74
|
-
cf->value =
|
92
|
+
cf->value = str_new_dd_freeze(cf->name, cf->len);
|
75
93
|
} else {
|
76
94
|
memcpy(tmp + HTTP_PREFIX_LEN, cf->name, cf->len + 1);
|
77
|
-
cf->value =
|
95
|
+
cf->value = str_new_dd_freeze(tmp, HTTP_PREFIX_LEN + cf->len);
|
78
96
|
}
|
79
|
-
|
80
|
-
rb_global_variable(&cf->value);
|
97
|
+
rb_gc_register_mark_object(cf->value);
|
81
98
|
}
|
82
99
|
}
|
83
100
|
|
@@ -105,7 +122,7 @@ static VALUE uncommon_field(const char *field, size_t flen)
|
|
105
122
|
memcpy(RSTRING_PTR(f) + HTTP_PREFIX_LEN, field, flen);
|
106
123
|
assert(*(RSTRING_PTR(f) + RSTRING_LEN(f)) == '\0' &&
|
107
124
|
"string didn't end with \\0"); /* paranoia */
|
108
|
-
return
|
125
|
+
return HASH_ASET_DEDUPE ? f : str_dd_freeze(f);
|
109
126
|
}
|
110
127
|
|
111
128
|
#endif /* common_field_optimization_h */
|