unicorn-fotopedia 0.99.1

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.
Files changed (163) hide show
  1. data/.CHANGELOG.old +25 -0
  2. data/.document +19 -0
  3. data/.gitignore +21 -0
  4. data/.mailmap +26 -0
  5. data/CONTRIBUTORS +32 -0
  6. data/COPYING +339 -0
  7. data/DESIGN +105 -0
  8. data/Documentation/.gitignore +5 -0
  9. data/Documentation/GNUmakefile +30 -0
  10. data/Documentation/unicorn.1.txt +171 -0
  11. data/Documentation/unicorn_rails.1.txt +172 -0
  12. data/FAQ +52 -0
  13. data/GIT-VERSION-GEN +40 -0
  14. data/GNUmakefile +292 -0
  15. data/HACKING +116 -0
  16. data/ISSUES +36 -0
  17. data/KNOWN_ISSUES +50 -0
  18. data/LICENSE +55 -0
  19. data/PHILOSOPHY +145 -0
  20. data/README +149 -0
  21. data/Rakefile +191 -0
  22. data/SIGNALS +109 -0
  23. data/Sandbox +78 -0
  24. data/TODO +5 -0
  25. data/TUNING +70 -0
  26. data/bin/unicorn +126 -0
  27. data/bin/unicorn_rails +203 -0
  28. data/examples/big_app_gc.rb +33 -0
  29. data/examples/echo.ru +27 -0
  30. data/examples/git.ru +13 -0
  31. data/examples/init.sh +58 -0
  32. data/examples/logger_mp_safe.rb +25 -0
  33. data/examples/nginx.conf +139 -0
  34. data/examples/unicorn.conf.rb +78 -0
  35. data/ext/unicorn_http/CFLAGS +13 -0
  36. data/ext/unicorn_http/c_util.h +124 -0
  37. data/ext/unicorn_http/common_field_optimization.h +111 -0
  38. data/ext/unicorn_http/ext_help.h +77 -0
  39. data/ext/unicorn_http/extconf.rb +14 -0
  40. data/ext/unicorn_http/global_variables.h +89 -0
  41. data/ext/unicorn_http/unicorn_http.rl +714 -0
  42. data/ext/unicorn_http/unicorn_http_common.rl +75 -0
  43. data/lib/unicorn.rb +847 -0
  44. data/lib/unicorn/app/exec_cgi.rb +150 -0
  45. data/lib/unicorn/app/inetd.rb +109 -0
  46. data/lib/unicorn/app/old_rails.rb +33 -0
  47. data/lib/unicorn/app/old_rails/static.rb +58 -0
  48. data/lib/unicorn/cgi_wrapper.rb +145 -0
  49. data/lib/unicorn/configurator.rb +421 -0
  50. data/lib/unicorn/const.rb +34 -0
  51. data/lib/unicorn/http_request.rb +72 -0
  52. data/lib/unicorn/http_response.rb +75 -0
  53. data/lib/unicorn/launcher.rb +65 -0
  54. data/lib/unicorn/oob_gc.rb +58 -0
  55. data/lib/unicorn/socket_helper.rb +152 -0
  56. data/lib/unicorn/tee_input.rb +217 -0
  57. data/lib/unicorn/util.rb +90 -0
  58. data/local.mk.sample +62 -0
  59. data/setup.rb +1586 -0
  60. data/t/.gitignore +2 -0
  61. data/t/GNUmakefile +67 -0
  62. data/t/README +42 -0
  63. data/t/bin/content-md5-put +36 -0
  64. data/t/bin/sha1sum.rb +23 -0
  65. data/t/bin/unused_listen +40 -0
  66. data/t/bin/utee +12 -0
  67. data/t/env.ru +3 -0
  68. data/t/my-tap-lib.sh +200 -0
  69. data/t/t0000-http-basic.sh +50 -0
  70. data/t/t0001-reload-bad-config.sh +52 -0
  71. data/t/t0002-config-conflict.sh +49 -0
  72. data/t/test-lib.sh +100 -0
  73. data/test/aggregate.rb +15 -0
  74. data/test/benchmark/README +50 -0
  75. data/test/benchmark/dd.ru +18 -0
  76. data/test/exec/README +5 -0
  77. data/test/exec/test_exec.rb +1038 -0
  78. data/test/rails/app-1.2.3/.gitignore +2 -0
  79. data/test/rails/app-1.2.3/Rakefile +7 -0
  80. data/test/rails/app-1.2.3/app/controllers/application.rb +6 -0
  81. data/test/rails/app-1.2.3/app/controllers/foo_controller.rb +36 -0
  82. data/test/rails/app-1.2.3/app/helpers/application_helper.rb +4 -0
  83. data/test/rails/app-1.2.3/config/boot.rb +11 -0
  84. data/test/rails/app-1.2.3/config/database.yml +12 -0
  85. data/test/rails/app-1.2.3/config/environment.rb +13 -0
  86. data/test/rails/app-1.2.3/config/environments/development.rb +9 -0
  87. data/test/rails/app-1.2.3/config/environments/production.rb +5 -0
  88. data/test/rails/app-1.2.3/config/routes.rb +6 -0
  89. data/test/rails/app-1.2.3/db/.gitignore +0 -0
  90. data/test/rails/app-1.2.3/public/404.html +1 -0
  91. data/test/rails/app-1.2.3/public/500.html +1 -0
  92. data/test/rails/app-2.0.2/.gitignore +2 -0
  93. data/test/rails/app-2.0.2/Rakefile +7 -0
  94. data/test/rails/app-2.0.2/app/controllers/application.rb +4 -0
  95. data/test/rails/app-2.0.2/app/controllers/foo_controller.rb +36 -0
  96. data/test/rails/app-2.0.2/app/helpers/application_helper.rb +4 -0
  97. data/test/rails/app-2.0.2/config/boot.rb +11 -0
  98. data/test/rails/app-2.0.2/config/database.yml +12 -0
  99. data/test/rails/app-2.0.2/config/environment.rb +17 -0
  100. data/test/rails/app-2.0.2/config/environments/development.rb +8 -0
  101. data/test/rails/app-2.0.2/config/environments/production.rb +5 -0
  102. data/test/rails/app-2.0.2/config/routes.rb +6 -0
  103. data/test/rails/app-2.0.2/db/.gitignore +0 -0
  104. data/test/rails/app-2.0.2/public/404.html +1 -0
  105. data/test/rails/app-2.0.2/public/500.html +1 -0
  106. data/test/rails/app-2.1.2/.gitignore +2 -0
  107. data/test/rails/app-2.1.2/Rakefile +7 -0
  108. data/test/rails/app-2.1.2/app/controllers/application.rb +4 -0
  109. data/test/rails/app-2.1.2/app/controllers/foo_controller.rb +36 -0
  110. data/test/rails/app-2.1.2/app/helpers/application_helper.rb +4 -0
  111. data/test/rails/app-2.1.2/config/boot.rb +111 -0
  112. data/test/rails/app-2.1.2/config/database.yml +12 -0
  113. data/test/rails/app-2.1.2/config/environment.rb +17 -0
  114. data/test/rails/app-2.1.2/config/environments/development.rb +7 -0
  115. data/test/rails/app-2.1.2/config/environments/production.rb +5 -0
  116. data/test/rails/app-2.1.2/config/routes.rb +6 -0
  117. data/test/rails/app-2.1.2/db/.gitignore +0 -0
  118. data/test/rails/app-2.1.2/public/404.html +1 -0
  119. data/test/rails/app-2.1.2/public/500.html +1 -0
  120. data/test/rails/app-2.2.2/.gitignore +2 -0
  121. data/test/rails/app-2.2.2/Rakefile +7 -0
  122. data/test/rails/app-2.2.2/app/controllers/application.rb +4 -0
  123. data/test/rails/app-2.2.2/app/controllers/foo_controller.rb +36 -0
  124. data/test/rails/app-2.2.2/app/helpers/application_helper.rb +4 -0
  125. data/test/rails/app-2.2.2/config/boot.rb +111 -0
  126. data/test/rails/app-2.2.2/config/database.yml +12 -0
  127. data/test/rails/app-2.2.2/config/environment.rb +17 -0
  128. data/test/rails/app-2.2.2/config/environments/development.rb +7 -0
  129. data/test/rails/app-2.2.2/config/environments/production.rb +5 -0
  130. data/test/rails/app-2.2.2/config/routes.rb +6 -0
  131. data/test/rails/app-2.2.2/db/.gitignore +0 -0
  132. data/test/rails/app-2.2.2/public/404.html +1 -0
  133. data/test/rails/app-2.2.2/public/500.html +1 -0
  134. data/test/rails/app-2.3.5/.gitignore +2 -0
  135. data/test/rails/app-2.3.5/Rakefile +7 -0
  136. data/test/rails/app-2.3.5/app/controllers/application_controller.rb +5 -0
  137. data/test/rails/app-2.3.5/app/controllers/foo_controller.rb +36 -0
  138. data/test/rails/app-2.3.5/app/helpers/application_helper.rb +4 -0
  139. data/test/rails/app-2.3.5/config/boot.rb +109 -0
  140. data/test/rails/app-2.3.5/config/database.yml +12 -0
  141. data/test/rails/app-2.3.5/config/environment.rb +17 -0
  142. data/test/rails/app-2.3.5/config/environments/development.rb +7 -0
  143. data/test/rails/app-2.3.5/config/environments/production.rb +6 -0
  144. data/test/rails/app-2.3.5/config/routes.rb +6 -0
  145. data/test/rails/app-2.3.5/db/.gitignore +0 -0
  146. data/test/rails/app-2.3.5/public/404.html +1 -0
  147. data/test/rails/app-2.3.5/public/500.html +1 -0
  148. data/test/rails/app-2.3.5/public/x.txt +1 -0
  149. data/test/rails/test_rails.rb +280 -0
  150. data/test/test_helper.rb +301 -0
  151. data/test/unit/test_configurator.rb +150 -0
  152. data/test/unit/test_http_parser.rb +555 -0
  153. data/test/unit/test_http_parser_ng.rb +443 -0
  154. data/test/unit/test_request.rb +184 -0
  155. data/test/unit/test_response.rb +110 -0
  156. data/test/unit/test_server.rb +291 -0
  157. data/test/unit/test_signals.rb +206 -0
  158. data/test/unit/test_socket_helper.rb +147 -0
  159. data/test/unit/test_tee_input.rb +257 -0
  160. data/test/unit/test_upload.rb +298 -0
  161. data/test/unit/test_util.rb +96 -0
  162. data/unicorn.gemspec +52 -0
  163. metadata +283 -0
data/SIGNALS ADDED
@@ -0,0 +1,109 @@
1
+ == Signal handling
2
+
3
+ In general, signals need only be sent to the master process. However,
4
+ the signals Unicorn uses internally to communicate with the worker
5
+ processes are documented here as well. With the exception of TTIN/TTOU,
6
+ signal handling matches the behavior of {nginx}[http://nginx.net/] so it
7
+ should be possible to easily share process management scripts between
8
+ Unicorn and nginx.
9
+
10
+ === Master Process
11
+
12
+ * HUP - reloads config file and gracefully restart all workers.
13
+ If the "preload_app" directive is false (the default), then workers
14
+ will also pick up any application code changes when restarted. If
15
+ "preload_app" is true, then application code changes will have no
16
+ effect; USR2 + QUIT (see below) must be used to load newer code in
17
+ this case.
18
+
19
+ * INT/TERM - quick shutdown, kills all workers immediately
20
+
21
+ * QUIT - graceful shutdown, waits for workers to finish their
22
+ current request before finishing.
23
+
24
+ * USR1 - reopen all logs owned by the master and all workers
25
+ See Unicorn::Util.reopen_logs for what is considered a log.
26
+
27
+ * USR2 - reexecute the running binary. A separate QUIT
28
+ should be sent to the original process once the child is verified to
29
+ be up and running.
30
+
31
+ * WINCH - gracefully stops workers but keep the master running.
32
+ This will only work for daemonized processes.
33
+
34
+ * TTIN - increment the number of worker processes by one
35
+
36
+ * TTOU - decrement the number of worker processes by one
37
+
38
+ === Worker Processes
39
+
40
+ Sending signals directly to the worker processes should not normally be
41
+ needed. If the master process is running, any exited worker will be
42
+ automatically respawned.
43
+
44
+ * INT/TERM - Quick shutdown, immediately exit.
45
+ Unless WINCH has been sent to the master (or the master is killed),
46
+ the master process will respawn a worker to replace this one.
47
+
48
+ * QUIT - Gracefully exit after finishing the current request.
49
+ Unless WINCH has been sent to the master (or the master is killed),
50
+ the master process will respawn a worker to replace this one.
51
+
52
+ * USR1 - Reopen all logs owned by the worker process.
53
+ See Unicorn::Util.reopen_logs for what is considered a log.
54
+ Log files are not reopened until it is done processing
55
+ the current request, so multiple log lines for one request
56
+ (as done by Rails) will not be split across multiple logs.
57
+
58
+ It is NOT recommended to send the USR1 signal directly to workers via
59
+ "killall -USR1 unicorn" if you are using user/group-switching support
60
+ in your workers. You will encounter incorrect file permissions and
61
+ workers will need to be respawned. Sending USR1 to the master process
62
+ first will ensure logs have the correct permissions before the master
63
+ forwards the USR1 signal to workers.
64
+
65
+ === Procedure to replace a running unicorn executable
66
+
67
+ You may replace a running instance of unicorn with a new one without
68
+ losing any incoming connections. Doing so will reload all of your
69
+ application code, Unicorn config, Ruby executable, and all libraries.
70
+ The only things that will not change (due to OS limitations) are:
71
+
72
+ 1. The path to the unicorn executable script. If you want to change to
73
+ a different installation of Ruby, you can modify the shebang
74
+ line to point to your alternative interpreter.
75
+
76
+ The procedure is exactly like that of nginx:
77
+
78
+ 1. Send USR2 to the master process
79
+
80
+ 2. Check your process manager or pid files to see if a new master spawned
81
+ successfully. If you're using a pid file, the old process will have
82
+ ".oldbin" appended to its path. You should have two master instances
83
+ of unicorn running now, both of which will have workers servicing
84
+ requests. Your process tree should look something like this:
85
+
86
+ unicorn master (old)
87
+ \_ unicorn worker[0]
88
+ \_ unicorn worker[1]
89
+ \_ unicorn worker[2]
90
+ \_ unicorn worker[3]
91
+ \_ unicorn master
92
+ \_ unicorn worker[0]
93
+ \_ unicorn worker[1]
94
+ \_ unicorn worker[2]
95
+ \_ unicorn worker[3]
96
+
97
+ 3. You can now send WINCH to the old master process so only the new workers
98
+ serve requests. If your unicorn process is bound to an interactive
99
+ terminal, you can skip this step. Step 5 will be more difficult but
100
+ you can also skip it if your process is not daemonized.
101
+
102
+ 4. You should now ensure that everything is running correctly with the
103
+ new workers as the old workers die off.
104
+
105
+ 5. If everything seems ok, then send QUIT to the old master. You're done!
106
+
107
+ If something is broken, then send HUP to the old master to reload
108
+ the config and restart its workers. Then send QUIT to the new master
109
+ process.
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/TODO ADDED
@@ -0,0 +1,5 @@
1
+ * Documentation improvements
2
+
3
+ * performance validation (esp. TeeInput)
4
+
5
+ * improve test suite
data/TUNING ADDED
@@ -0,0 +1,70 @@
1
+ = Tuning Unicorn
2
+
3
+ Unicorn performance is generally as good as a (mostly) Ruby web server
4
+ can provide. Most often the performance bottleneck is in the web
5
+ application running on Unicorn rather than Unicorn itself.
6
+
7
+ == Unicorn Configuration
8
+
9
+ See Unicorn::Configurator for details on the config file format.
10
+
11
+ * Setting a very low value for the :backlog parameter in "listen"
12
+ directives can allow failover to happen more quickly if your
13
+ cluster is configured for it.
14
+
15
+ * If you're doing extremely simple benchmarks and getting connection
16
+ errors under high request rates, increasing your :backlog parameter
17
+ above the already-generous default of 1024 can help avoid connection
18
+ errors. Keep in mind this is not recommended for real traffic if
19
+ you have another machine to failover to (see above).
20
+
21
+ * :rcvbuf and :sndbuf parameters generally do not need to be set for TCP
22
+ listeners under Linux 2.6 because auto-tuning is enabled. UNIX domain
23
+ sockets do not have auto-tuning buffer sizes; so increasing those will
24
+ allow syscalls and task switches to be saved for larger requests
25
+ and responses.
26
+
27
+ * Setting "preload_app true" can allow copy-on-write-friendly GC to
28
+ be used to save memory. It will probably not work out of the box with
29
+ applications that open sockets or perform random I/O on files.
30
+ Databases like TokyoCabinet use concurrency-safe pread()/pwrite()
31
+ functions for safe sharing of database file descriptors across
32
+ processes.
33
+
34
+ * On POSIX-compliant filesystems, it is safe for multiple threads or
35
+ processes to append to one log file as long as all the processes are
36
+ have them unbuffered (File#sync = true) or they are
37
+ record(line)-buffered in userspace.
38
+
39
+ * worker_processes should be scaled to the number of processes your
40
+ backend system(s) can support. DO NOT scale it to the number of
41
+ external network clients your application expects to be serving.
42
+ Unicorn is NOT for serving slow clients, that is the job of nginx.
43
+
44
+ == Kernel Parameters (Linux sysctl)
45
+
46
+ WARNING: Do not change system parameters unless you know what you're doing!
47
+
48
+ * net.core.rmem_max and net.core.wmem_max can increase the allowed
49
+ size of :rcvbuf and :sndbuf respectively. This is mostly only useful
50
+ for UNIX domain sockets which do not have auto-tuning buffer sizes.
51
+
52
+ * For load testing/benchmarking with UNIX domain sockets, you should
53
+ consider increasing net.core.somaxconn or else nginx will start
54
+ failing to connect under heavy load. You may also consider setting
55
+ a higher :backlog to listen on as noted earlier.
56
+
57
+ * If you're running out of local ports, consider lowering
58
+ net.ipv4.tcp_fin_timeout to 20-30 (default: 60 seconds). Also
59
+ consider widening the usable port range by changing
60
+ net.ipv4.ip_local_port_range.
61
+
62
+ * Setting net.ipv4.tcp_timestamps=1 will also allow setting
63
+ net.ipv4.tcp_tw_reuse=1 and net.ipv4.tcp_tw_recycle=1, which along
64
+ with the above settings can slow down port exhaustion. Not all
65
+ networks are compatible with these settings, check with your friendly
66
+ network administrator before changing these.
67
+
68
+ * Increasing the MTU size can reduce framing overhead for larger
69
+ transfers. One often-overlooked detail is that the loopback
70
+ device (usually "lo") can have its MTU increased, too.
@@ -0,0 +1,126 @@
1
+ #!/this/will/be/overwritten/or/wrapped/anyways/do/not/worry/ruby
2
+ # -*- encoding: binary -*-
3
+ require 'unicorn/launcher'
4
+ require 'optparse'
5
+
6
+ ENV["RACK_ENV"] ||= "development"
7
+ daemonize = false
8
+ options = { :listeners => [] }
9
+ host, port = Unicorn::Const::DEFAULT_HOST, Unicorn::Const::DEFAULT_PORT
10
+ set_listener = false
11
+
12
+ opts = OptionParser.new("", 24, ' ') do |opts|
13
+ opts.banner = "Usage: #{File.basename($0)} " \
14
+ "[ruby options] [unicorn options] [rackup config file]"
15
+
16
+ opts.separator "Ruby options:"
17
+
18
+ lineno = 1
19
+ opts.on("-e", "--eval LINE", "evaluate a LINE of code") do |line|
20
+ eval line, TOPLEVEL_BINDING, "-e", lineno
21
+ lineno += 1
22
+ end
23
+
24
+ opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") do
25
+ $DEBUG = true
26
+ end
27
+
28
+ opts.on("-w", "--warn", "turn warnings on for your script") do
29
+ $-w = true
30
+ end
31
+
32
+ opts.on("-I", "--include PATH",
33
+ "specify $LOAD_PATH (may be used more than once)") do |path|
34
+ $LOAD_PATH.unshift(*path.split(/:/))
35
+ end
36
+
37
+ opts.on("-r", "--require LIBRARY",
38
+ "require the library, before executing your script") do |library|
39
+ require library
40
+ end
41
+
42
+ opts.separator "Unicorn options:"
43
+
44
+ # some of these switches exist for rackup command-line compatibility,
45
+
46
+ opts.on("-o", "--host HOST",
47
+ "listen on HOST (default: #{Unicorn::Const::DEFAULT_HOST})") do |h|
48
+ host = h
49
+ set_listener = true
50
+ end
51
+
52
+ opts.on("-p", "--port PORT",
53
+ "use PORT (default: #{Unicorn::Const::DEFAULT_PORT})") do |p|
54
+ port = p.to_i
55
+ set_listener = true
56
+ end
57
+
58
+ opts.on("-E", "--env ENVIRONMENT",
59
+ "use ENVIRONMENT for defaults (default: development)") do |e|
60
+ ENV["RACK_ENV"] = e
61
+ end
62
+
63
+ opts.on("-D", "--daemonize", "run daemonized in the background") do |d|
64
+ daemonize = d ? true : false
65
+ end
66
+
67
+ opts.on("-P", "--pid FILE", "DEPRECATED") do |f|
68
+ warn %q{Use of --pid/-P is strongly discouraged}
69
+ warn %q{Use the 'pid' directive in the Unicorn config file instead}
70
+ options[:pid] = f
71
+ end
72
+
73
+ opts.on("-s", "--server SERVER",
74
+ "this flag only exists for compatibility") do |s|
75
+ warn "-s/--server only exists for compatibility with rackup"
76
+ end
77
+
78
+ # Unicorn-specific stuff
79
+ opts.on("-l", "--listen {HOST:PORT|PATH}",
80
+ "listen on HOST:PORT or PATH",
81
+ "this may be specified multiple times",
82
+ "(default: #{Unicorn::Const::DEFAULT_LISTEN})") do |address|
83
+ options[:listeners] << address
84
+ end
85
+
86
+ opts.on("-c", "--config-file FILE", "Unicorn-specific config file") do |f|
87
+ options[:config_file] = f
88
+ end
89
+
90
+ # I'm avoiding Unicorn-specific config options on the command-line.
91
+ # IMNSHO, config options on the command-line are redundant given
92
+ # config files and make things unnecessarily complicated with multiple
93
+ # places to look for a config option.
94
+
95
+ opts.separator "Common options:"
96
+
97
+ opts.on_tail("-h", "--help", "Show this message") do
98
+ puts opts.to_s.gsub(/^.*DEPRECATED.*$/s, '')
99
+ exit
100
+ end
101
+
102
+ opts.on_tail("-v", "--version", "Show version") do
103
+ puts "unicorn v#{Unicorn::Const::UNICORN_VERSION}"
104
+ exit
105
+ end
106
+
107
+ opts.parse! ARGV
108
+ end
109
+
110
+ ru = ARGV[0] || "config.ru"
111
+ abort "configuration file #{ru} not found" unless File.exist?(ru)
112
+
113
+ app = Unicorn.builder(ru, opts)
114
+ options[:listeners] << "#{host}:#{port}" if set_listener
115
+
116
+ if $DEBUG
117
+ require 'pp'
118
+ pp({
119
+ :unicorn_options => options,
120
+ :app => app,
121
+ :daemonize => daemonize,
122
+ })
123
+ end
124
+
125
+ Unicorn::Launcher.daemonize!(options) if daemonize
126
+ Unicorn.run(app, options)
@@ -0,0 +1,203 @@
1
+ #!/this/will/be/overwritten/or/wrapped/anyways/do/not/worry/ruby
2
+ # -*- encoding: binary -*-
3
+ require 'unicorn/launcher'
4
+ require 'optparse'
5
+ require 'fileutils'
6
+
7
+ daemonize = false
8
+ options = { :listeners => [] }
9
+ host, port = Unicorn::Const::DEFAULT_HOST, Unicorn::Const::DEFAULT_PORT
10
+ set_listener = false
11
+ ENV['RAILS_ENV'] ||= "development"
12
+
13
+ opts = OptionParser.new("", 24, ' ') do |opts|
14
+ cmd = File.basename($0)
15
+ opts.banner = "Usage: #{cmd} " \
16
+ "[ruby options] [#{cmd} options] [rackup config file]"
17
+ opts.separator "Ruby options:"
18
+
19
+ lineno = 1
20
+ opts.on("-e", "--eval LINE", "evaluate a LINE of code") do |line|
21
+ eval line, TOPLEVEL_BINDING, "-e", lineno
22
+ lineno += 1
23
+ end
24
+
25
+ opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") do
26
+ $DEBUG = true
27
+ end
28
+
29
+ opts.on("-w", "--warn", "turn warnings on for your script") do
30
+ $-w = true
31
+ end
32
+
33
+ opts.on("-I", "--include PATH",
34
+ "specify $LOAD_PATH (may be used more than once)") do |path|
35
+ $LOAD_PATH.unshift(*path.split(/:/))
36
+ end
37
+
38
+ opts.on("-r", "--require LIBRARY",
39
+ "require the library, before executing your script") do |library|
40
+ require library
41
+ end
42
+
43
+ opts.separator "#{cmd} options:"
44
+
45
+ # some of these switches exist for rackup command-line compatibility,
46
+
47
+ opts.on("-o", "--host HOST",
48
+ "listen on HOST (default: #{Unicorn::Const::DEFAULT_HOST})") do |h|
49
+ host = h
50
+ set_listener = true
51
+ end
52
+
53
+ opts.on("-p", "--port PORT", "use PORT (default: #{port})") do |p|
54
+ port = p.to_i
55
+ set_listener = true
56
+ end
57
+
58
+ opts.on("-E", "--env RAILS_ENV",
59
+ "use RAILS_ENV for defaults (default: development)") do |e|
60
+ ENV['RAILS_ENV'] = e
61
+ end
62
+
63
+ opts.on("-D", "--daemonize", "run daemonized in the background") do |d|
64
+ daemonize = d ? true : false
65
+ end
66
+
67
+ # Unicorn-specific stuff
68
+ opts.on("-l", "--listen {HOST:PORT|PATH}",
69
+ "listen on HOST:PORT or PATH",
70
+ "this may be specified multiple times",
71
+ "(default: #{Unicorn::Const::DEFAULT_LISTEN})") do |address|
72
+ options[:listeners] << address
73
+ end
74
+
75
+ opts.on("-c", "--config-file FILE", "Unicorn-specific config file") do |f|
76
+ options[:config_file] = f
77
+ end
78
+
79
+ opts.on("-P PATH", "DEPRECATED") do |v|
80
+ warn %q{Use of -P is ambiguous and discouraged}
81
+ warn %q{Use --path or RAILS_RELATIVE_URL_ROOT instead}
82
+ ENV['RAILS_RELATIVE_URL_ROOT'] = v
83
+ end
84
+
85
+ opts.on("--path PATH", "Runs Rails app mounted at a specific path.",
86
+ "(default: /)") do |v|
87
+ ENV['RAILS_RELATIVE_URL_ROOT'] = v
88
+ end
89
+
90
+ # I'm avoiding Unicorn-specific config options on the command-line.
91
+ # IMNSHO, config options on the command-line are redundant given
92
+ # config files and make things unnecessarily complicated with multiple
93
+ # places to look for a config option.
94
+
95
+ opts.separator "Common options:"
96
+
97
+ opts.on_tail("-h", "--help", "Show this message") do
98
+ puts opts.to_s.gsub(/^.*DEPRECATED.*$/s, '')
99
+ exit
100
+ end
101
+
102
+ opts.on_tail("-v", "--version", "Show version") do
103
+ puts " v#{Unicorn::Const::UNICORN_VERSION}"
104
+ exit
105
+ end
106
+
107
+ opts.parse! ARGV
108
+ end
109
+
110
+ ru = ARGV[0] || (File.exist?('config.ru') ? 'config.ru' : nil)
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)
118
+ # this lambda won't run until after forking if preload_app is false
119
+ lambda do ||
120
+ # Load Rails and (possibly) the private version of Rack it bundles.
121
+ begin
122
+ require 'config/boot'
123
+ rescue LoadError => err
124
+ abort "#$0 must be run inside RAILS_ROOT: #{err.inspect}"
125
+ end
126
+
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)
151
+ else
152
+ require ru
153
+ Object.const_get(File.basename(ru, '.rb').capitalize)
154
+ end
155
+
156
+ Rack::Builder.new do
157
+ map_path = ENV['RAILS_RELATIVE_URL_ROOT'] || '/'
158
+ if inner_app.class.to_s == "Unicorn::App::OldRails"
159
+ if map_path != '/'
160
+ # patches + tests welcome, but I really cbf to deal with this
161
+ # since all apps I've ever dealt with just use "/" ...
162
+ $stderr.puts "relative URL roots may not work for older Rails"
163
+ end
164
+ $stderr.puts "LogTailer not available for Rails < 2.3" unless daemonize
165
+ $stderr.puts "Debugger not available" if $DEBUG
166
+ map(map_path) do
167
+ use Unicorn::App::OldRails::Static
168
+ run inner_app
169
+ end
170
+ else
171
+ use Rails::Rack::LogTailer unless daemonize
172
+ use Rails::Rack::Debugger if $DEBUG
173
+ map(map_path) do
174
+ use Rails::Rack::Static
175
+ run inner_app
176
+ end
177
+ end
178
+ end.to_app
179
+ end
180
+ end
181
+
182
+ app = rails_builder(ru, daemonize)
183
+ options[:listeners] << "#{host}:#{port}" if set_listener
184
+
185
+ if $DEBUG
186
+ require 'pp'
187
+ pp({
188
+ :unicorn_options => options,
189
+ :app => app,
190
+ :daemonize => daemonize,
191
+ })
192
+ end
193
+
194
+ # ensure Rails standard tmp paths exist
195
+ options[:after_reload] = lambda do
196
+ FileUtils.mkdir_p(%w(cache pids sessions sockets).map! { |d| "tmp/#{d}" })
197
+ end
198
+
199
+ if daemonize
200
+ options[:pid] = "tmp/pids/unicorn.pid"
201
+ Unicorn::Launcher.daemonize!(options)
202
+ end
203
+ Unicorn.run(app, options)