unicorn 0.99.0 → 0.990.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +1 -0
- data/.gitignore +3 -1
- data/Documentation/unicorn.1.txt +1 -1
- data/FAQ +3 -2
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +43 -8
- data/KNOWN_ISSUES +3 -24
- data/PHILOSOPHY +3 -2
- data/Rakefile +23 -2
- data/Sandbox +78 -0
- data/bin/unicorn_rails +14 -36
- data/examples/big_app_gc.rb +33 -0
- data/examples/unicorn.conf.minimal.rb +13 -0
- data/examples/unicorn.conf.rb +9 -3
- data/ext/unicorn_http/unicorn_http.rl +14 -2
- data/ext/unicorn_http/unicorn_http_common.rl +1 -1
- data/lib/unicorn.rb +5 -11
- data/lib/unicorn/configurator.rb +22 -8
- data/lib/unicorn/const.rb +3 -1
- data/lib/unicorn/oob_gc.rb +58 -0
- data/lib/unicorn/util.rb +7 -9
- data/local.mk.sample +32 -36
- data/t/GNUmakefile +7 -2
- data/t/rails3-app/.gitignore +4 -0
- data/t/rails3-app/Gemfile +26 -0
- data/t/rails3-app/Rakefile +10 -0
- data/t/rails3-app/app/controllers/application_controller.rb +4 -0
- data/t/rails3-app/app/helpers/application_helper.rb +2 -0
- data/t/rails3-app/app/views/layouts/application.html.erb +14 -0
- data/t/rails3-app/config.ru +4 -0
- data/t/rails3-app/config/application.rb +46 -0
- data/t/rails3-app/config/boot.rb +6 -0
- data/t/rails3-app/config/database.yml +22 -0
- data/t/rails3-app/config/environment.rb +5 -0
- data/t/rails3-app/config/environments/development.rb +19 -0
- data/t/rails3-app/config/environments/production.rb +42 -0
- data/t/rails3-app/config/environments/test.rb +32 -0
- data/t/rails3-app/config/initializers/backtrace_silencers.rb +7 -0
- data/t/rails3-app/config/initializers/inflections.rb +10 -0
- data/t/rails3-app/config/initializers/mime_types.rb +5 -0
- data/t/rails3-app/config/initializers/secret_token.rb +7 -0
- data/t/rails3-app/config/initializers/session_store.rb +8 -0
- data/t/rails3-app/config/locales/en.yml +5 -0
- data/t/rails3-app/config/routes.rb +58 -0
- data/t/rails3-app/db/seeds.rb +7 -0
- data/t/rails3-app/doc/README_FOR_APP +2 -0
- data/{test/rails/app-2.3.5/db/.gitignore → t/rails3-app/lib/tasks/.gitkeep} +0 -0
- data/{test/rails/app-2.3.5 → t/rails3-app}/public/404.html +0 -0
- data/{test/rails/app-2.3.5 → t/rails3-app}/public/500.html +0 -0
- data/{test/rails/app-2.3.5 → t/rails3-app}/public/x.txt +0 -0
- data/t/rails3-app/script/rails +9 -0
- data/t/rails3-app/test/performance/browsing_test.rb +9 -0
- data/t/rails3-app/test/test_helper.rb +13 -0
- data/t/rails3-app/vendor/plugins/.gitkeep +0 -0
- data/t/t0300-rails3-basic.sh +56 -0
- data/t/test-lib.sh +2 -1
- data/test/exec/test_exec.rb +20 -3
- data/test/rails/{app-2.3.5 → app-2.3.8}/.gitignore +0 -0
- data/test/rails/{app-2.3.5 → app-2.3.8}/Rakefile +0 -0
- data/test/rails/{app-2.3.5 → app-2.3.8}/app/controllers/application_controller.rb +0 -0
- data/test/rails/{app-2.3.5 → app-2.3.8}/app/controllers/foo_controller.rb +0 -0
- data/test/rails/{app-2.3.5 → app-2.3.8}/app/helpers/application_helper.rb +0 -0
- data/test/rails/{app-2.3.5 → app-2.3.8}/config/boot.rb +0 -0
- data/test/rails/{app-2.3.5 → app-2.3.8}/config/database.yml +0 -0
- data/test/rails/{app-2.3.5 → app-2.3.8}/config/environment.rb +0 -0
- data/test/rails/{app-2.3.5 → app-2.3.8}/config/environments/development.rb +0 -0
- data/test/rails/{app-2.3.5 → app-2.3.8}/config/environments/production.rb +0 -0
- data/test/rails/{app-2.3.5 → app-2.3.8}/config/routes.rb +0 -0
- data/test/rails/app-2.3.8/db/.gitignore +0 -0
- data/test/rails/app-2.3.8/public/404.html +1 -0
- data/test/rails/app-2.3.8/public/500.html +1 -0
- data/test/rails/app-2.3.8/public/x.txt +1 -0
- data/test/rails/test_rails.rb +4 -0
- data/test/unit/test_http_parser.rb +11 -1
- data/test/unit/test_http_parser_ng.rb +21 -1
- data/test/unit/test_signals.rb +2 -2
- data/test/unit/test_socket_helper.rb +5 -3
- data/test/unit/test_util.rb +22 -18
- data/unicorn.gemspec +2 -0
- metadata +66 -18
data/.document
CHANGED
data/.gitignore
CHANGED
data/Documentation/unicorn.1.txt
CHANGED
@@ -16,7 +16,7 @@ A rackup(1)-like command to launch Rack applications using Unicorn.
|
|
16
16
|
It is expected to be started in your application root (APP_ROOT),
|
17
17
|
but the "working_directory" directive may be used in the CONFIG_FILE.
|
18
18
|
|
19
|
-
While
|
19
|
+
While unicorn takes a myriad of command-line options for
|
20
20
|
compatibility with ruby(1) and rackup(1), it is recommended to stick
|
21
21
|
to the few command-line options specified in the SYNOPSIS and use
|
22
22
|
the CONFIG_FILE as much as possible.
|
data/FAQ
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
= Frequently Asked Questions about Unicorn
|
2
2
|
|
3
|
-
=== I've installed Rack 1.1.x, why can't Unicorn load Rails?
|
3
|
+
=== I've installed Rack 1.1.x, why can't Unicorn load Rails (2.3.5)?
|
4
4
|
|
5
5
|
Rails 2.3.5 is not compatible with Rack 1.1.x. Unicorn is compatible
|
6
6
|
with both Rack 1.1.x and Rack 1.0.x, and RubyGems will load the latest
|
7
7
|
version of Rack installed on the system. Uninstalling the Rack 1.1.x
|
8
|
-
gem should solve gem loading issues with Rails 2.3.
|
8
|
+
gem should solve gem loading issues with Rails 2.3.5. Rails 2.3.6
|
9
|
+
and later correctly support Rack 1.1.x.
|
9
10
|
|
10
11
|
=== Why are my redirects going to "http" URLs when my site uses https?
|
11
12
|
|
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
@@ -4,7 +4,7 @@ all:: test
|
|
4
4
|
GIT_URL = git://git.bogomips.org/unicorn.git
|
5
5
|
RLFLAGS = -G2
|
6
6
|
|
7
|
-
|
7
|
+
MRI = ruby
|
8
8
|
RUBY = ruby
|
9
9
|
RAKE = rake
|
10
10
|
RAGEL = ragel
|
@@ -21,20 +21,22 @@ ifeq ($(RUBY_VERSION),)
|
|
21
21
|
RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
|
22
22
|
endif
|
23
23
|
|
24
|
+
RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))')
|
25
|
+
|
24
26
|
# dunno how to implement this as concisely in Ruby, and hell, I love awk
|
25
27
|
awk_slow := awk '/def test_/{print FILENAME"--"$$2".n"}' 2>/dev/null
|
26
28
|
|
27
29
|
rails_vers := $(subst test/rails/app-,,$(wildcard test/rails/app-*))
|
28
30
|
slow_tests := test/unit/test_server.rb test/exec/test_exec.rb \
|
29
31
|
test/unit/test_signals.rb test/unit/test_upload.rb
|
30
|
-
log_suffix = .$(RUBY_VERSION).log
|
32
|
+
log_suffix = .$(RUBY_ENGINE).$(RUBY_VERSION).log
|
31
33
|
T_r := $(wildcard test/rails/test*.rb)
|
32
34
|
T := $(filter-out $(slow_tests) $(T_r), $(wildcard test/*/test*.rb))
|
33
35
|
T_n := $(shell $(awk_slow) $(slow_tests))
|
34
36
|
T_log := $(subst .rb,$(log_suffix),$(T))
|
35
37
|
T_n_log := $(subst .n,$(log_suffix),$(T_n))
|
36
38
|
T_r_log := $(subst .r,$(log_suffix),$(T_r))
|
37
|
-
test_prefix = $(CURDIR)/test
|
39
|
+
test_prefix = $(CURDIR)/test/$(RUBY_ENGINE)-$(RUBY_VERSION)
|
38
40
|
|
39
41
|
ext := ext/unicorn_http
|
40
42
|
c_files := $(ext)/unicorn_http.c $(wildcard $(ext)/*.h)
|
@@ -65,16 +67,16 @@ $(test_prefix)/.stamp: $(inst_deps)
|
|
65
67
|
tar cf - $(inst_deps) GIT-VERSION-GEN | \
|
66
68
|
(cd $(test_prefix) && tar xf -)
|
67
69
|
$(MAKE) -C $(test_prefix) clean
|
68
|
-
$(MAKE) -C $(test_prefix) http shebang
|
70
|
+
$(MAKE) -C $(test_prefix) http shebang RUBY="$(RUBY)"
|
69
71
|
> $@
|
70
72
|
|
71
73
|
# this is only intended to be run within $(test_prefix)
|
72
74
|
shebang: $(bins)
|
73
|
-
$(
|
75
|
+
$(MRI) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^
|
74
76
|
|
75
77
|
t_log := $(T_log) $(T_n_log)
|
76
78
|
test: $(T) $(T_n)
|
77
|
-
@cat $(t_log) | $(
|
79
|
+
@cat $(t_log) | $(MRI) test/aggregate.rb
|
78
80
|
@$(RM) $(t_log)
|
79
81
|
|
80
82
|
test-exec: $(wildcard test/exec/test_*.rb)
|
@@ -82,6 +84,11 @@ test-unit: $(wildcard test/unit/test_*.rb)
|
|
82
84
|
$(slow_tests): $(test_prefix)/.stamp
|
83
85
|
@$(MAKE) $(shell $(awk_slow) $@)
|
84
86
|
|
87
|
+
test-integration: $(test_prefix)/.stamp
|
88
|
+
$(MAKE) -C t
|
89
|
+
|
90
|
+
test-all: test test-rails test-integration
|
91
|
+
|
85
92
|
TEST_OPTS = -v
|
86
93
|
check_test = grep '0 failures, 0 errors' $(t) >/dev/null
|
87
94
|
ifndef V
|
@@ -161,7 +168,7 @@ NEWS: GIT-VERSION-FILE .manifest
|
|
161
168
|
$(RAKE) -s news_rdoc > $@+
|
162
169
|
mv $@+ $@
|
163
170
|
|
164
|
-
SINCE = 0.
|
171
|
+
SINCE = 0.99.0
|
165
172
|
ChangeLog: LOG_VERSION = \
|
166
173
|
$(shell git rev-parse -q "$(GIT_VERSION)" >/dev/null 2>&1 && \
|
167
174
|
echo $(GIT_VERSION) || git describe)
|
@@ -202,12 +209,40 @@ doc: .document $(ext)/unicorn_http.c NEWS ChangeLog
|
|
202
209
|
cd doc && ln README.html tmp && mv tmp index.html
|
203
210
|
$(RM) $(man1_rdoc)
|
204
211
|
|
212
|
+
# publishes docs to http://unicorn.bogomips.org
|
213
|
+
publish_doc:
|
214
|
+
-git set-file-times
|
215
|
+
$(RM) -r doc ChangeLog NEWS
|
216
|
+
$(MAKE) doc LOG_VERSION=$(shell git tag -l | tail -1)
|
217
|
+
@awk 'BEGIN{RS="=== ";ORS=""}NR==2{sub(/\n$$/,"");print RS""$$0 }' \
|
218
|
+
< NEWS > doc/LATEST
|
219
|
+
find doc/images doc/js -type f | \
|
220
|
+
TZ=UTC xargs touch -d '1970-01-01 00:00:00' doc/rdoc.css
|
221
|
+
$(MAKE) doc_gz
|
222
|
+
tar cf - $$(git ls-files examples/) | (cd doc && tar xf -)
|
223
|
+
chmod 644 $$(find doc -type f)
|
224
|
+
rsync -av doc/ unicorn.bogomips.org:/srv/unicorn/
|
225
|
+
git ls-files | xargs touch
|
226
|
+
|
227
|
+
# Create gzip variants of the same timestamp as the original so nginx
|
228
|
+
# "gzip_static on" can serve the gzipped versions directly.
|
229
|
+
doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.\(gif\|jpg\|png\|gz\)$$')
|
230
|
+
doc_gz:
|
231
|
+
touch doc/NEWS.atom.xml -d "$$(awk 'NR==1{print $$4,$$5,$$6}' NEWS)"
|
232
|
+
for i in $(docs); do \
|
233
|
+
gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
|
234
|
+
|
205
235
|
rails_git_url = git://github.com/rails/rails.git
|
206
236
|
rails_git := vendor/rails.git
|
207
237
|
$(rails_git)/info/cloned-stamp:
|
208
238
|
git clone --mirror -q $(rails_git_url) $(rails_git)
|
209
239
|
> $@
|
210
240
|
|
241
|
+
$(rails_git)/info/v2.3.8-stamp: $(rails_git)/info/cloned-stamp
|
242
|
+
cd $(rails_git) && git fetch
|
243
|
+
cd $(rails_git) && git rev-parse --verify refs/tags/v2.3.8
|
244
|
+
> $@
|
245
|
+
|
211
246
|
rails_tests := $(addsuffix .r,$(addprefix $(T_r).,$(rails_vers)))
|
212
247
|
test-rails: $(rails_tests)
|
213
248
|
$(T_r).%.r: t = $(addsuffix $(log_suffix),$@)
|
@@ -218,7 +253,7 @@ $(T_r).%.r: export PATH := $(test_prefix)/bin:$(PATH)
|
|
218
253
|
$(T_r).%.r: export RUBYLIB := $(test_prefix):$(test_prefix)/lib:$(RUBYLIB)
|
219
254
|
$(T_r).%.r: export UNICORN_RAILS_TEST_VERSION = $(rv)
|
220
255
|
$(T_r).%.r: export RAILS_GIT_REPO = $(CURDIR)/$(rails_git)
|
221
|
-
$(T_r).%.r: $(test_prefix)/.stamp $(rails_git)/info/
|
256
|
+
$(T_r).%.r: $(test_prefix)/.stamp $(rails_git)/info/v2.3.8-stamp
|
222
257
|
$(run_test)
|
223
258
|
|
224
259
|
ifneq ($(VERSION),)
|
data/KNOWN_ISSUES
CHANGED
@@ -3,6 +3,9 @@
|
|
3
3
|
Occasionally odd {issues}[link:ISSUES.html] arise without a transparent or
|
4
4
|
acceptable solution. Those issues are documented here.
|
5
5
|
|
6
|
+
* For notes on sandboxing tools such as Bundler or Isolate,
|
7
|
+
see the {Sandbox}[link:Sandbox.html] page.
|
8
|
+
|
6
9
|
* Under Ruby 1.9.1, methods like Array#shuffle and Array#sample will
|
7
10
|
segfault if called after forking. This is fixed in trunk (r26936) and
|
8
11
|
should be backported to the next 1.9.1 stable release (after p378).
|
@@ -32,30 +35,6 @@ acceptable solution. Those issues are documented here.
|
|
32
35
|
Note: the workaround described in the article above only made
|
33
36
|
the issue more subtle and we didn't notice them immediately.
|
34
37
|
|
35
|
-
* Installing "unicorn" as a system-wide Rubygem and using the
|
36
|
-
{isolate}[http://github.com/jbarnette/isolate] gem may cause issues if
|
37
|
-
you're using any of the bundled application-level libraries in
|
38
|
-
unicorn/app/* (for compatibility with CGI-based applications, Rails <=
|
39
|
-
2.2.2, or ExecCgi). For now workarounds include:
|
40
|
-
|
41
|
-
* installing the same version of unicorn as a system-wide Rubygem
|
42
|
-
_and_ isolating unicorn as well.
|
43
|
-
* explicitly setting RUBYLIB or $LOAD_PATH to include any gem path
|
44
|
-
where the unicorn gem is installed (e.g.
|
45
|
-
/usr/lib/ruby/gems/1.8/gems/unicorn-VERSION/lib)
|
46
|
-
|
47
|
-
With current versions of isolate, it is also recommended that you
|
48
|
-
disable it with the <tt>before_exec</tt> hook prevent the PATH and
|
49
|
-
RUBYOPT environment variable modifications from propagating between
|
50
|
-
upgrades in your Unicorn config file:
|
51
|
-
|
52
|
-
before_exec do |server|
|
53
|
-
Isolate.disable
|
54
|
-
end
|
55
|
-
|
56
|
-
Future versions (unreleased as of 2010.04.20) of isolate will not
|
57
|
-
require this as environment variable modifications will be idempotent.
|
58
|
-
|
59
38
|
* WONTFIX: code reloading and restarts with Sinatra 0.3.x (and likely older
|
60
39
|
versions) apps is broken. The workaround is to force production
|
61
40
|
mode to disable code reloading as well as disabling "run" in your
|
data/PHILOSOPHY
CHANGED
@@ -140,5 +140,6 @@ Unicorn may still outweigh the drawbacks for these applications.
|
|
140
140
|
|
141
141
|
The {Rainbows!}[http://rainbows.rubyforge.org/] aims to fill the gap for
|
142
142
|
odd corner cases where the nginx + Unicorn combination is not enough.
|
143
|
-
|
144
|
-
more ambitious
|
143
|
+
While Rainbows! management/administration is largely identical to
|
144
|
+
Unicorn, Rainbows! is far more ambitious and has seen little real-world
|
145
|
+
usage.
|
data/Rakefile
CHANGED
@@ -176,11 +176,11 @@ end
|
|
176
176
|
# optional rake-compiler support in case somebody needs to cross compile
|
177
177
|
begin
|
178
178
|
mk = "ext/unicorn_http/Makefile"
|
179
|
-
if
|
179
|
+
if File.readable?(mk)
|
180
180
|
warn "run 'gmake -C ext/unicorn_http clean' and\n" \
|
181
181
|
"remove #{mk} before using rake-compiler"
|
182
182
|
else
|
183
|
-
unless
|
183
|
+
unless File.readable?("ext/unicorn_http/unicorn_http.c")
|
184
184
|
abort "run 'gmake ragel' or 'make ragel' to generate the Ragel source"
|
185
185
|
end
|
186
186
|
spec = Gem::Specification.load('unicorn.gemspec')
|
@@ -189,3 +189,24 @@ begin
|
|
189
189
|
end
|
190
190
|
rescue LoadError
|
191
191
|
end
|
192
|
+
|
193
|
+
task :isolate do
|
194
|
+
require 'isolate'
|
195
|
+
opts = {
|
196
|
+
:system => false,
|
197
|
+
:path => "tmp/isolate/ruby-#{RUBY_VERSION}",
|
198
|
+
:multiruby => false, # we want "1.8.7" instead of "1.8"
|
199
|
+
}
|
200
|
+
|
201
|
+
# C extensions aren't binary-compatible across Ruby versions
|
202
|
+
fork { Isolate.now!(opts) { gem 'sqlite3-ruby', '1.2.5' } }
|
203
|
+
|
204
|
+
# pure Ruby gems can be shared across all Rubies
|
205
|
+
%w(3.0.0.beta3).each do |rails_ver|
|
206
|
+
opts[:path] = "tmp/isolate/rails-#{rails_ver}"
|
207
|
+
fork { Isolate.now!(opts) { gem 'rails', rails_ver } }
|
208
|
+
end
|
209
|
+
|
210
|
+
failed = Process.waitall.delete_if { |(_,status)| status.success? }
|
211
|
+
abort failed.inspect unless failed.empty?
|
212
|
+
end
|
data/Sandbox
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
= Tips for using \Unicorn with Sandbox installation tools
|
2
|
+
|
3
|
+
Since unicorn includes executables and is usually used to start a Ruby
|
4
|
+
process, there are certain caveats to using it with tools that sandbox
|
5
|
+
RubyGems installations such as
|
6
|
+
{Bundler}[http://github.com/carlhuda/bundler] or
|
7
|
+
{Isolate}[http://github.com/jbarnette/isolate].
|
8
|
+
|
9
|
+
== General deployment
|
10
|
+
|
11
|
+
If you're sandboxing your unicorn installation and using Capistrano (or
|
12
|
+
similar), it's required that you sandbox your RubyGems in a per-application
|
13
|
+
shared directory that can be used between different revisions.
|
14
|
+
|
15
|
+
unicorn will stash its original command-line at startup for the USR2
|
16
|
+
upgrades, and cleaning up old revisions will cause revision-specific
|
17
|
+
installations of unicorn to go missing and upgrades to fail. If you
|
18
|
+
find yourself in this situation and can't afford downtime, you can
|
19
|
+
override the existing unicorn executable path in the config file like
|
20
|
+
this:
|
21
|
+
|
22
|
+
Unicorn::HttpServer::START_CTX[0] = "/some/path/to/bin/unicorn"
|
23
|
+
|
24
|
+
Then use HUP to reload, and then continue with the USR2+QUIT upgrade
|
25
|
+
sequence.
|
26
|
+
|
27
|
+
== Bundler
|
28
|
+
|
29
|
+
=== Running
|
30
|
+
|
31
|
+
If you're bundling unicorn, use "bundle exec unicorn" (or "bundle exec
|
32
|
+
unicorn_rails") to start unicorn with the correct environment variables
|
33
|
+
|
34
|
+
ref: http://mid.gmane.org/9ECF07C4-5216-47BE-961D-AFC0F0C82060@internetfamo.us
|
35
|
+
|
36
|
+
Otherwise (if you choose to not sandbox your unicorn installation), we
|
37
|
+
expect the tips for Isolate (below) apply, too.
|
38
|
+
|
39
|
+
=== RUBYOPT pollution from SIGUSR2 upgrades
|
40
|
+
|
41
|
+
This is no longer be an issue as of bundler 0.9.17
|
42
|
+
|
43
|
+
ref: http://mid.gmane.org/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com
|
44
|
+
|
45
|
+
== Isolate
|
46
|
+
|
47
|
+
=== Running
|
48
|
+
|
49
|
+
Installing "unicorn" as a system-wide Rubygem and using the
|
50
|
+
isolate gem may cause issues if you're using any of the bundled
|
51
|
+
application-level libraries in unicorn/app/* (for compatibility
|
52
|
+
with CGI-based applications, Rails <= 2.2.2, or ExecCgi).
|
53
|
+
For now workarounds include doing one of the following:
|
54
|
+
|
55
|
+
1. Isolating unicorn, setting GEM_HOME to your Isolate path,
|
56
|
+
and running the isolated version of unicorn. You *must* set
|
57
|
+
GEM_HOME before running your isolated unicorn install in this way.
|
58
|
+
|
59
|
+
2. Installing the same version of unicorn as a system-wide Rubygem
|
60
|
+
*and* isolating unicorn as well.
|
61
|
+
|
62
|
+
3. Explicitly setting RUBYLIB or $LOAD_PATH to include any gem path
|
63
|
+
where the unicorn gem is installed
|
64
|
+
(e.g. /usr/lib/ruby/gems/1.9.1/gems/unicorn-VERSION/lib)
|
65
|
+
|
66
|
+
=== RUBYOPT pollution from SIGUSR2 upgrades
|
67
|
+
|
68
|
+
If you are using Isolate, using Isolate 2.x is strongly recommended as
|
69
|
+
environment modifications are idempotent.
|
70
|
+
|
71
|
+
If you are stuck with 1.x versions of Isolate, it is recommended that
|
72
|
+
you disable it with the <tt>before_exec</tt> hook prevent the PATH and
|
73
|
+
RUBYOPT environment variable modifications from propagating between
|
74
|
+
upgrades in your Unicorn config file:
|
75
|
+
|
76
|
+
before_exec do |server|
|
77
|
+
Isolate.disable
|
78
|
+
end
|
data/bin/unicorn_rails
CHANGED
@@ -109,53 +109,30 @@ end
|
|
109
109
|
|
110
110
|
ru = ARGV[0] || (File.exist?('config.ru') ? 'config.ru' : nil)
|
111
111
|
|
112
|
-
|
113
|
-
# parse embedded command-line options in config.ru comments
|
114
|
-
/^#\\(.*)/ =~ File.read(ru) and opts.parse!($1.split(/\s+/))
|
115
|
-
end
|
116
|
-
|
117
|
-
def rails_builder(ru, daemonize)
|
112
|
+
def rails_builder(daemonize)
|
118
113
|
# this lambda won't run until after forking if preload_app is false
|
119
114
|
lambda do ||
|
120
115
|
# Load Rails and (possibly) the private version of Rack it bundles.
|
121
116
|
begin
|
122
117
|
require 'config/boot'
|
118
|
+
require 'config/environment'
|
123
119
|
rescue LoadError => err
|
124
120
|
abort "#$0 must be run inside RAILS_ROOT: #{err.inspect}"
|
125
121
|
end
|
126
122
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
# it seems Rails >=2.2 support Rack, but only >=2.3 requires it
|
134
|
-
old_rails = case ::Rails::VERSION::MAJOR
|
135
|
-
when 0, 1 then true
|
136
|
-
when 2 then Rails::VERSION::MINOR < 3 ? true : false
|
137
|
-
else
|
138
|
-
false
|
139
|
-
end
|
140
|
-
|
141
|
-
if old_rails
|
142
|
-
require 'unicorn/app/old_rails'
|
143
|
-
Unicorn::App::OldRails.new
|
144
|
-
else
|
145
|
-
ActionController::Dispatcher.new
|
146
|
-
end
|
147
|
-
when /\.ru$/
|
148
|
-
raw = File.read(ru)
|
149
|
-
raw.sub!(/^__END__\n.*/, '')
|
150
|
-
eval("Rack::Builder.new {(#{raw}\n)}.to_app", TOPLEVEL_BINDING, ru)
|
123
|
+
defined?(::Rails::VERSION::STRING) or
|
124
|
+
abort "Rails::VERSION::STRING not defined by config/{boot,environment}"
|
125
|
+
# it seems Rails >=2.2 support Rack, but only >=2.3 requires it
|
126
|
+
old_rails = case ::Rails::VERSION::MAJOR
|
127
|
+
when 0, 1 then true
|
128
|
+
when 2 then Rails::VERSION::MINOR < 3 ? true : false
|
151
129
|
else
|
152
|
-
|
153
|
-
Object.const_get(File.basename(ru, '.rb').capitalize)
|
130
|
+
false
|
154
131
|
end
|
155
132
|
|
156
133
|
Rack::Builder.new do
|
157
134
|
map_path = ENV['RAILS_RELATIVE_URL_ROOT'] || '/'
|
158
|
-
if
|
135
|
+
if old_rails
|
159
136
|
if map_path != '/'
|
160
137
|
# patches + tests welcome, but I really cbf to deal with this
|
161
138
|
# since all apps I've ever dealt with just use "/" ...
|
@@ -163,23 +140,24 @@ def rails_builder(ru, daemonize)
|
|
163
140
|
end
|
164
141
|
$stderr.puts "LogTailer not available for Rails < 2.3" unless daemonize
|
165
142
|
$stderr.puts "Debugger not available" if $DEBUG
|
143
|
+
require 'unicorn/app/old_rails'
|
166
144
|
map(map_path) do
|
167
145
|
use Unicorn::App::OldRails::Static
|
168
|
-
run
|
146
|
+
run Unicorn::App::OldRails.new
|
169
147
|
end
|
170
148
|
else
|
171
149
|
use Rails::Rack::LogTailer unless daemonize
|
172
150
|
use Rails::Rack::Debugger if $DEBUG
|
173
151
|
map(map_path) do
|
174
152
|
use Rails::Rack::Static
|
175
|
-
run
|
153
|
+
run ActionController::Dispatcher.new
|
176
154
|
end
|
177
155
|
end
|
178
156
|
end.to_app
|
179
157
|
end
|
180
158
|
end
|
181
159
|
|
182
|
-
app =
|
160
|
+
app = ru ? Unicorn.builder(ru, opts) : rails_builder(daemonize)
|
183
161
|
options[:listeners] << "#{host}:#{port}" if set_listener
|
184
162
|
|
185
163
|
if $DEBUG
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Run GC after every request, before attempting to accept more connections.
|
2
|
+
#
|
3
|
+
# You could customize this patch to read REQ["PATH_INFO"] and only
|
4
|
+
# call GC.start after expensive requests.
|
5
|
+
#
|
6
|
+
# We could have this wrap the response body.close as middleware, but the
|
7
|
+
# scannable stack is would still be bigger than it would be here.
|
8
|
+
#
|
9
|
+
# This shouldn't hurt overall performance as long as the server cluster
|
10
|
+
# is at <=50% CPU capacity, and improves the performance of most memory
|
11
|
+
# intensive requests. This serves to improve _client-visible_
|
12
|
+
# performance (possibly at the cost of overall performance).
|
13
|
+
#
|
14
|
+
# We'll call GC after each request is been written out to the socket, so
|
15
|
+
# the client never sees the extra GC hit it. It's ideal to call the GC
|
16
|
+
# inside the HTTP server (vs middleware or hooks) since the stack is
|
17
|
+
# smaller at this point, so the GC will both be faster and more
|
18
|
+
# effective at releasing unused memory.
|
19
|
+
#
|
20
|
+
# This monkey patch is _only_ effective for applications that use a lot
|
21
|
+
# of memory, and will hurt simpler apps/endpoints that can process
|
22
|
+
# multiple requests before incurring GC.
|
23
|
+
|
24
|
+
class Unicorn::HttpServer
|
25
|
+
REQ = Unicorn::HttpRequest::REQ
|
26
|
+
alias _process_client process_client
|
27
|
+
undef_method :process_client
|
28
|
+
def process_client(client)
|
29
|
+
_process_client(client)
|
30
|
+
REQ.clear
|
31
|
+
GC.start
|
32
|
+
end
|
33
|
+
end if defined?(Unicorn)
|