unicorn 0.99.0 → 0.990.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.
- 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)
|