unicorn 0.99.0 → 0.990.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/.document +1 -0
  2. data/.gitignore +3 -1
  3. data/Documentation/unicorn.1.txt +1 -1
  4. data/FAQ +3 -2
  5. data/GIT-VERSION-GEN +1 -1
  6. data/GNUmakefile +43 -8
  7. data/KNOWN_ISSUES +3 -24
  8. data/PHILOSOPHY +3 -2
  9. data/Rakefile +23 -2
  10. data/Sandbox +78 -0
  11. data/bin/unicorn_rails +14 -36
  12. data/examples/big_app_gc.rb +33 -0
  13. data/examples/unicorn.conf.minimal.rb +13 -0
  14. data/examples/unicorn.conf.rb +9 -3
  15. data/ext/unicorn_http/unicorn_http.rl +14 -2
  16. data/ext/unicorn_http/unicorn_http_common.rl +1 -1
  17. data/lib/unicorn.rb +5 -11
  18. data/lib/unicorn/configurator.rb +22 -8
  19. data/lib/unicorn/const.rb +3 -1
  20. data/lib/unicorn/oob_gc.rb +58 -0
  21. data/lib/unicorn/util.rb +7 -9
  22. data/local.mk.sample +32 -36
  23. data/t/GNUmakefile +7 -2
  24. data/t/rails3-app/.gitignore +4 -0
  25. data/t/rails3-app/Gemfile +26 -0
  26. data/t/rails3-app/Rakefile +10 -0
  27. data/t/rails3-app/app/controllers/application_controller.rb +4 -0
  28. data/t/rails3-app/app/helpers/application_helper.rb +2 -0
  29. data/t/rails3-app/app/views/layouts/application.html.erb +14 -0
  30. data/t/rails3-app/config.ru +4 -0
  31. data/t/rails3-app/config/application.rb +46 -0
  32. data/t/rails3-app/config/boot.rb +6 -0
  33. data/t/rails3-app/config/database.yml +22 -0
  34. data/t/rails3-app/config/environment.rb +5 -0
  35. data/t/rails3-app/config/environments/development.rb +19 -0
  36. data/t/rails3-app/config/environments/production.rb +42 -0
  37. data/t/rails3-app/config/environments/test.rb +32 -0
  38. data/t/rails3-app/config/initializers/backtrace_silencers.rb +7 -0
  39. data/t/rails3-app/config/initializers/inflections.rb +10 -0
  40. data/t/rails3-app/config/initializers/mime_types.rb +5 -0
  41. data/t/rails3-app/config/initializers/secret_token.rb +7 -0
  42. data/t/rails3-app/config/initializers/session_store.rb +8 -0
  43. data/t/rails3-app/config/locales/en.yml +5 -0
  44. data/t/rails3-app/config/routes.rb +58 -0
  45. data/t/rails3-app/db/seeds.rb +7 -0
  46. data/t/rails3-app/doc/README_FOR_APP +2 -0
  47. data/{test/rails/app-2.3.5/db/.gitignore → t/rails3-app/lib/tasks/.gitkeep} +0 -0
  48. data/{test/rails/app-2.3.5 → t/rails3-app}/public/404.html +0 -0
  49. data/{test/rails/app-2.3.5 → t/rails3-app}/public/500.html +0 -0
  50. data/{test/rails/app-2.3.5 → t/rails3-app}/public/x.txt +0 -0
  51. data/t/rails3-app/script/rails +9 -0
  52. data/t/rails3-app/test/performance/browsing_test.rb +9 -0
  53. data/t/rails3-app/test/test_helper.rb +13 -0
  54. data/t/rails3-app/vendor/plugins/.gitkeep +0 -0
  55. data/t/t0300-rails3-basic.sh +56 -0
  56. data/t/test-lib.sh +2 -1
  57. data/test/exec/test_exec.rb +20 -3
  58. data/test/rails/{app-2.3.5 → app-2.3.8}/.gitignore +0 -0
  59. data/test/rails/{app-2.3.5 → app-2.3.8}/Rakefile +0 -0
  60. data/test/rails/{app-2.3.5 → app-2.3.8}/app/controllers/application_controller.rb +0 -0
  61. data/test/rails/{app-2.3.5 → app-2.3.8}/app/controllers/foo_controller.rb +0 -0
  62. data/test/rails/{app-2.3.5 → app-2.3.8}/app/helpers/application_helper.rb +0 -0
  63. data/test/rails/{app-2.3.5 → app-2.3.8}/config/boot.rb +0 -0
  64. data/test/rails/{app-2.3.5 → app-2.3.8}/config/database.yml +0 -0
  65. data/test/rails/{app-2.3.5 → app-2.3.8}/config/environment.rb +0 -0
  66. data/test/rails/{app-2.3.5 → app-2.3.8}/config/environments/development.rb +0 -0
  67. data/test/rails/{app-2.3.5 → app-2.3.8}/config/environments/production.rb +0 -0
  68. data/test/rails/{app-2.3.5 → app-2.3.8}/config/routes.rb +0 -0
  69. data/test/rails/app-2.3.8/db/.gitignore +0 -0
  70. data/test/rails/app-2.3.8/public/404.html +1 -0
  71. data/test/rails/app-2.3.8/public/500.html +1 -0
  72. data/test/rails/app-2.3.8/public/x.txt +1 -0
  73. data/test/rails/test_rails.rb +4 -0
  74. data/test/unit/test_http_parser.rb +11 -1
  75. data/test/unit/test_http_parser_ng.rb +21 -1
  76. data/test/unit/test_signals.rb +2 -2
  77. data/test/unit/test_socket_helper.rb +5 -3
  78. data/test/unit/test_util.rb +22 -18
  79. data/unicorn.gemspec +2 -0
  80. metadata +66 -18
data/.document CHANGED
@@ -16,3 +16,4 @@ ext/unicorn_http/unicorn_http.c
16
16
  unicorn_1
17
17
  unicorn_rails_1
18
18
  ISSUES
19
+ Sandbox
data/.gitignore CHANGED
@@ -8,7 +8,8 @@
8
8
  /InstalledFiles
9
9
  /doc
10
10
  /local.mk
11
- /test/install-*
11
+ /test/rbx-*
12
+ /test/ruby-*
12
13
  ext/unicorn_http/Makefile
13
14
  ext/unicorn_http/unicorn_http.c
14
15
  log/
@@ -19,3 +20,4 @@ pkg/
19
20
  /.manifest
20
21
  /GIT-VERSION-FILE
21
22
  /man
23
+ /tmp
@@ -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 Unicorn takes a myriad of command-line options for
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.x.
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
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v0.99.0.GIT
4
+ DEF_VER=v0.990.0.GIT
5
5
 
6
6
  LF='
7
7
  '
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
- # lower-case vars are deprecated
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/install-$(RUBY_VERSION)
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
- $(RUBY) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^
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) | $(RUBY) test/aggregate.rb
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.97.1
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/cloned-stamp
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
- Keep in mind that Rainbows! is still very new (as of October 2009), far
144
- more ambitious, and far less tested than Unicorn.
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 test ?r, mk
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 test ?r, "ext/unicorn_http/unicorn_http.c"
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
- if ru && ru =~ /\.ru\z/
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
- inner_app = case ru
128
- when nil
129
- require 'config/environment'
130
-
131
- defined?(::Rails::VERSION::STRING) or
132
- abort "Rails::VERSION::STRING not defined by config/{boot,environment}"
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
- require ru
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 inner_app.class.to_s == "Unicorn::App::OldRails"
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 inner_app
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 inner_app
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 = rails_builder(ru, daemonize)
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)