unicorn-shopify 4.8.2.5.23
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.
- checksums.yaml +7 -0
- data/.CHANGELOG.old +25 -0
- data/.document +28 -0
- data/.gitignore +25 -0
- data/.mailmap +26 -0
- data/.olddoc.yml +15 -0
- data/Application_Timeouts +77 -0
- data/CONTRIBUTORS +35 -0
- data/COPYING +674 -0
- data/DESIGN +97 -0
- data/Documentation/.gitignore +5 -0
- data/Documentation/GNUmakefile +30 -0
- data/Documentation/unicorn.1.txt +185 -0
- data/Documentation/unicorn_rails.1.txt +175 -0
- data/FAQ +61 -0
- data/GIT-VERSION-GEN +39 -0
- data/GNUmakefile +252 -0
- data/HACKING +120 -0
- data/ISSUES +100 -0
- data/KNOWN_ISSUES +79 -0
- data/LICENSE +67 -0
- data/Links +59 -0
- data/PHILOSOPHY +145 -0
- data/README +145 -0
- data/Rakefile +16 -0
- data/SIGNALS +123 -0
- data/Sandbox +103 -0
- data/TODO +5 -0
- data/TUNING +101 -0
- data/archive/.gitignore +3 -0
- data/archive/slrnpull.conf +4 -0
- data/bin/unicorn +126 -0
- data/bin/unicorn_rails +209 -0
- data/examples/big_app_gc.rb +2 -0
- data/examples/echo.ru +27 -0
- data/examples/init.sh +74 -0
- data/examples/logger_mp_safe.rb +25 -0
- data/examples/logrotate.conf +29 -0
- data/examples/nginx.conf +156 -0
- data/examples/unicorn.conf.minimal.rb +13 -0
- data/examples/unicorn.conf.rb +113 -0
- data/ext/unicorn_http/CFLAGS +13 -0
- data/ext/unicorn_http/c_util.h +124 -0
- data/ext/unicorn_http/common_field_optimization.h +111 -0
- data/ext/unicorn_http/ext_help.h +82 -0
- data/ext/unicorn_http/extconf.rb +10 -0
- data/ext/unicorn_http/global_variables.h +97 -0
- data/ext/unicorn_http/httpdate.c +78 -0
- data/ext/unicorn_http/unicorn_http.rl +934 -0
- data/ext/unicorn_http/unicorn_http_common.rl +76 -0
- data/lib/unicorn.rb +112 -0
- data/lib/unicorn/app/old_rails.rb +35 -0
- data/lib/unicorn/app/old_rails/static.rb +59 -0
- data/lib/unicorn/cgi_wrapper.rb +147 -0
- data/lib/unicorn/configurator.rb +686 -0
- data/lib/unicorn/const.rb +21 -0
- data/lib/unicorn/http_request.rb +125 -0
- data/lib/unicorn/http_response.rb +73 -0
- data/lib/unicorn/http_server.rb +816 -0
- data/lib/unicorn/launcher.rb +62 -0
- data/lib/unicorn/oob_gc.rb +81 -0
- data/lib/unicorn/preread_input.rb +33 -0
- data/lib/unicorn/socket_helper.rb +197 -0
- data/lib/unicorn/stream_input.rb +146 -0
- data/lib/unicorn/tee_input.rb +133 -0
- data/lib/unicorn/tmpio.rb +27 -0
- data/lib/unicorn/util.rb +90 -0
- data/lib/unicorn/worker.rb +140 -0
- data/setup.rb +1586 -0
- data/t/.gitignore +4 -0
- data/t/GNUmakefile +74 -0
- data/t/README +42 -0
- data/t/before_murder.ru +7 -0
- data/t/bin/content-md5-put +36 -0
- data/t/bin/sha1sum.rb +17 -0
- data/t/bin/unused_listen +40 -0
- data/t/broken-app.ru +12 -0
- data/t/detach.ru +11 -0
- data/t/env.ru +3 -0
- data/t/fails-rack-lint.ru +5 -0
- data/t/heartbeat-timeout.ru +12 -0
- data/t/hijack.ru +42 -0
- data/t/listener_names.ru +4 -0
- data/t/my-tap-lib.sh +201 -0
- data/t/oob_gc.ru +20 -0
- data/t/oob_gc_path.ru +20 -0
- data/t/pid.ru +3 -0
- data/t/preread_input.ru +17 -0
- data/t/rack-input-tests.ru +21 -0
- data/t/t0000-http-basic.sh +50 -0
- data/t/t0001-reload-bad-config.sh +53 -0
- data/t/t0002-config-conflict.sh +49 -0
- data/t/t0002-parser-error.sh +94 -0
- data/t/t0003-working_directory.sh +51 -0
- data/t/t0004-heartbeat-timeout.sh +69 -0
- data/t/t0004-working_directory_broken.sh +24 -0
- data/t/t0005-working_directory_app.rb.sh +40 -0
- data/t/t0006-reopen-logs.sh +83 -0
- data/t/t0006.ru +13 -0
- data/t/t0007-working_directory_no_embed_cli.sh +44 -0
- data/t/t0008-back_out_of_upgrade.sh +110 -0
- data/t/t0009-broken-app.sh +56 -0
- data/t/t0009-winch_ttin.sh +59 -0
- data/t/t0010-reap-logging.sh +55 -0
- data/t/t0011-active-unix-socket.sh +79 -0
- data/t/t0012-reload-empty-config.sh +85 -0
- data/t/t0013-rewindable-input-false.sh +24 -0
- data/t/t0013.ru +12 -0
- data/t/t0014-rewindable-input-true.sh +24 -0
- data/t/t0014.ru +12 -0
- data/t/t0015-configurator-internals.sh +25 -0
- data/t/t0018-write-on-close.sh +23 -0
- data/t/t0019-max_header_len.sh +49 -0
- data/t/t0020-at_exit-handler.sh +49 -0
- data/t/t0021-process_detach.sh +29 -0
- data/t/t0022-listener_names-preload_app.sh +32 -0
- data/t/t0023-before-murder.sh +40 -0
- data/t/t0024-before-murder_once.sh +52 -0
- data/t/t0100-rack-input-tests.sh +124 -0
- data/t/t0116-client_body_buffer_size.sh +80 -0
- data/t/t0116.ru +16 -0
- data/t/t0200-rack-hijack.sh +27 -0
- data/t/t0300-no-default-middleware.sh +20 -0
- data/t/t9000-preread-input.sh +48 -0
- data/t/t9001-oob_gc.sh +47 -0
- data/t/t9002-oob_gc-path.sh +75 -0
- data/t/test-lib.sh +128 -0
- data/t/write-on-close.ru +11 -0
- data/test/aggregate.rb +15 -0
- data/test/benchmark/README +50 -0
- data/test/benchmark/dd.ru +18 -0
- data/test/benchmark/stack.ru +8 -0
- data/test/exec/README +5 -0
- data/test/exec/test_exec.rb +1047 -0
- data/test/test_helper.rb +297 -0
- data/test/unit/test_configurator.rb +175 -0
- data/test/unit/test_droplet.rb +28 -0
- data/test/unit/test_http_parser.rb +854 -0
- data/test/unit/test_http_parser_ng.rb +622 -0
- data/test/unit/test_request.rb +182 -0
- data/test/unit/test_response.rb +93 -0
- data/test/unit/test_server.rb +268 -0
- data/test/unit/test_signals.rb +188 -0
- data/test/unit/test_socket_helper.rb +197 -0
- data/test/unit/test_stream_input.rb +203 -0
- data/test/unit/test_tee_input.rb +304 -0
- data/test/unit/test_upload.rb +306 -0
- data/test/unit/test_util.rb +105 -0
- data/unicorn.gemspec +41 -0
- metadata +311 -0
data/FAQ
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
= Frequently Asked Questions about Unicorn
|
|
2
|
+
|
|
3
|
+
=== Why aren't my Rails log files rotated when I use SIGUSR1?
|
|
4
|
+
|
|
5
|
+
The Rails autoflush_log option must remain disabled with multiprocess
|
|
6
|
+
servers such as unicorn. Buffering in userspace may cause lines to be
|
|
7
|
+
partially written and lead to corruption in the presence of multiple
|
|
8
|
+
processes. With reasonable amounts of logging, the performance impact
|
|
9
|
+
of autoflush_log should be negligible on Linux and other modern kernels.
|
|
10
|
+
|
|
11
|
+
=== I've installed Rack 1.1.x, why can't Unicorn load Rails (2.3.5)?
|
|
12
|
+
|
|
13
|
+
Rails 2.3.5 is not compatible with Rack 1.1.x. Unicorn is compatible
|
|
14
|
+
with both Rack 1.1.x and Rack 1.0.x, and RubyGems will load the latest
|
|
15
|
+
version of Rack installed on the system. Uninstalling the Rack 1.1.x
|
|
16
|
+
gem should solve gem loading issues with Rails 2.3.5. Rails 2.3.6
|
|
17
|
+
and later correctly support Rack 1.1.x.
|
|
18
|
+
|
|
19
|
+
=== Why are my redirects going to "http" URLs when my site uses https?
|
|
20
|
+
|
|
21
|
+
If your site is entirely behind https, then Rack applications that use
|
|
22
|
+
"rack.url_scheme" can set the following in the Unicorn config file:
|
|
23
|
+
|
|
24
|
+
HttpRequest::DEFAULTS["rack.url_scheme"] = "https"
|
|
25
|
+
|
|
26
|
+
For frameworks that do not use "rack.url_scheme", you can also
|
|
27
|
+
try setting one or both of the following:
|
|
28
|
+
|
|
29
|
+
HttpRequest::DEFAULTS["HTTPS"] = "on"
|
|
30
|
+
HttpRequest::DEFAULTS["HTTP_X_FORWARDED_PROTO"] = "https"
|
|
31
|
+
|
|
32
|
+
Otherwise, you can configure your proxy (nginx) to send the
|
|
33
|
+
"X-Forwarded-Proto: https" header only for parts of the site that use
|
|
34
|
+
https. For nginx, you can do it with the following line in appropriate
|
|
35
|
+
"location" blocks of your nginx config file:
|
|
36
|
+
|
|
37
|
+
proxy_set_header X-Forwarded-Proto https;
|
|
38
|
+
|
|
39
|
+
=== Why are log messages from Unicorn are unformatted when using Rails?
|
|
40
|
+
|
|
41
|
+
Current versions of Rails unfortunately overrides the default Logger
|
|
42
|
+
formatter.
|
|
43
|
+
|
|
44
|
+
You can undo this behavior with the default logger in your Unicorn
|
|
45
|
+
config file:
|
|
46
|
+
|
|
47
|
+
Configurator::DEFAULTS[:logger].formatter = Logger::Formatter.new
|
|
48
|
+
|
|
49
|
+
Of course you can specify an entirely different logger as well
|
|
50
|
+
with the "logger" directive described by Unicorn::Configurator.
|
|
51
|
+
|
|
52
|
+
=== Why am I getting "connection refused"/502 errors under high load?
|
|
53
|
+
|
|
54
|
+
Short answer: your application cannot keep up.
|
|
55
|
+
|
|
56
|
+
You can increase the size of the :backlog parameter if your kernel
|
|
57
|
+
supports a larger listen() queue, but keep in mind having a large listen
|
|
58
|
+
queue makes failover to a different machine more difficult.
|
|
59
|
+
|
|
60
|
+
See the TUNING and Unicorn::Configurator documents for more information
|
|
61
|
+
on :backlog-related topics.
|
data/GIT-VERSION-GEN
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
DEF_VER = "v5.0.0.GIT"
|
|
3
|
+
CONSTANT = "Unicorn::Const::UNICORN_VERSION"
|
|
4
|
+
RVF = "lib/unicorn/version.rb"
|
|
5
|
+
GVF = "GIT-VERSION-FILE"
|
|
6
|
+
vn = DEF_VER
|
|
7
|
+
|
|
8
|
+
# First see if there is a version file (included in release tarballs),
|
|
9
|
+
# then try git-describe, then default.
|
|
10
|
+
if File.exist?(".git")
|
|
11
|
+
describe = `git describe --abbrev=4 HEAD 2>/dev/null`.strip
|
|
12
|
+
case describe
|
|
13
|
+
when /\Av[0-9]*/
|
|
14
|
+
vn = describe
|
|
15
|
+
system(*%w(git update-index -q --refresh))
|
|
16
|
+
unless `git diff-index --name-only HEAD --`.chomp.empty?
|
|
17
|
+
vn << "-dirty"
|
|
18
|
+
end
|
|
19
|
+
vn.tr!('-', '.')
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
vn = vn.sub!(/\Av/, "")
|
|
24
|
+
|
|
25
|
+
# generate the Ruby constant
|
|
26
|
+
new_ruby_version = "#{CONSTANT} = '#{vn}'\n"
|
|
27
|
+
cur_ruby_version = File.read(RVF) rescue nil
|
|
28
|
+
if new_ruby_version != cur_ruby_version
|
|
29
|
+
File.open(RVF, "w") { |fp| fp.write(new_ruby_version) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# generate the makefile snippet
|
|
33
|
+
new_make_version = "GIT_VERSION = #{vn}\n"
|
|
34
|
+
cur_make_version = File.read(GVF) rescue nil
|
|
35
|
+
if new_make_version != cur_make_version
|
|
36
|
+
File.open(GVF, "w") { |fp| fp.write(new_make_version) }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
puts vn if $0 == __FILE__
|
data/GNUmakefile
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# use GNU Make to run tests in parallel, and without depending on RubyGems
|
|
2
|
+
all:: test
|
|
3
|
+
|
|
4
|
+
RLFLAGS = -G2
|
|
5
|
+
|
|
6
|
+
MRI = ruby
|
|
7
|
+
RUBY = ruby
|
|
8
|
+
RAKE = rake
|
|
9
|
+
RAGEL = ragel
|
|
10
|
+
RSYNC = rsync
|
|
11
|
+
OLDDOC = olddoc
|
|
12
|
+
RDOC = rdoc
|
|
13
|
+
|
|
14
|
+
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
|
15
|
+
@./GIT-VERSION-GEN
|
|
16
|
+
-include GIT-VERSION-FILE
|
|
17
|
+
-include local.mk
|
|
18
|
+
ruby_bin := $(shell which $(RUBY))
|
|
19
|
+
ifeq ($(DLEXT),) # "so" for Linux
|
|
20
|
+
DLEXT := $(shell $(RUBY) -rrbconfig -e 'puts RbConfig::CONFIG["DLEXT"]')
|
|
21
|
+
endif
|
|
22
|
+
ifeq ($(RUBY_VERSION),)
|
|
23
|
+
RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
|
|
24
|
+
endif
|
|
25
|
+
|
|
26
|
+
RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))')
|
|
27
|
+
|
|
28
|
+
MYLIBS = $(RUBYLIB)
|
|
29
|
+
|
|
30
|
+
# dunno how to implement this as concisely in Ruby, and hell, I love awk
|
|
31
|
+
awk_slow := awk '/def test_/{print FILENAME"--"$$2".n"}' 2>/dev/null
|
|
32
|
+
|
|
33
|
+
slow_tests := test/unit/test_server.rb test/exec/test_exec.rb \
|
|
34
|
+
test/unit/test_signals.rb test/unit/test_upload.rb
|
|
35
|
+
log_suffix = .$(RUBY_ENGINE).$(RUBY_VERSION).log
|
|
36
|
+
T := $(filter-out $(slow_tests), $(wildcard test/*/test*.rb))
|
|
37
|
+
T_n := $(shell $(awk_slow) $(slow_tests))
|
|
38
|
+
T_log := $(subst .rb,$(log_suffix),$(T))
|
|
39
|
+
T_n_log := $(subst .n,$(log_suffix),$(T_n))
|
|
40
|
+
test_prefix = $(CURDIR)/test/$(RUBY_ENGINE)-$(RUBY_VERSION)
|
|
41
|
+
|
|
42
|
+
ext := ext/unicorn_http
|
|
43
|
+
c_files := $(ext)/unicorn_http.c $(ext)/httpdate.c $(wildcard $(ext)/*.h)
|
|
44
|
+
rl_files := $(wildcard $(ext)/*.rl)
|
|
45
|
+
base_bins := unicorn unicorn_rails
|
|
46
|
+
bins := $(addprefix bin/, $(base_bins))
|
|
47
|
+
man1_rdoc := $(addsuffix _1, $(base_bins))
|
|
48
|
+
man1_bins := $(addsuffix .1, $(base_bins))
|
|
49
|
+
man1_paths := $(addprefix man/man1/, $(man1_bins))
|
|
50
|
+
rb_files := $(bins) $(shell find lib ext -type f -name '*.rb')
|
|
51
|
+
inst_deps := $(c_files) $(rb_files) GNUmakefile test/test_helper.rb
|
|
52
|
+
|
|
53
|
+
ragel: $(ext)/unicorn_http.c
|
|
54
|
+
$(ext)/unicorn_http.c: $(rl_files)
|
|
55
|
+
cd $(@D) && $(RAGEL) unicorn_http.rl -C $(RLFLAGS) -o $(@F)
|
|
56
|
+
$(ext)/Makefile: $(ext)/extconf.rb $(c_files)
|
|
57
|
+
cd $(@D) && $(RUBY) extconf.rb
|
|
58
|
+
$(ext)/unicorn_http.$(DLEXT): $(ext)/Makefile
|
|
59
|
+
$(MAKE) -C $(@D)
|
|
60
|
+
http: $(ext)/unicorn_http.$(DLEXT)
|
|
61
|
+
|
|
62
|
+
# only used for tests
|
|
63
|
+
http-install: $(ext)/unicorn_http.$(DLEXT)
|
|
64
|
+
install -m644 $< lib/
|
|
65
|
+
|
|
66
|
+
test-install: $(test_prefix)/.stamp
|
|
67
|
+
$(test_prefix)/.stamp: $(inst_deps)
|
|
68
|
+
mkdir -p $(test_prefix)/.ccache
|
|
69
|
+
tar cf - $(inst_deps) GIT-VERSION-GEN | \
|
|
70
|
+
(cd $(test_prefix) && tar xf -)
|
|
71
|
+
$(MAKE) -C $(test_prefix) clean
|
|
72
|
+
$(MAKE) -C $(test_prefix) http-install shebang RUBY="$(RUBY)"
|
|
73
|
+
> $@
|
|
74
|
+
|
|
75
|
+
# this is only intended to be run within $(test_prefix)
|
|
76
|
+
shebang: $(bins)
|
|
77
|
+
$(MRI) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^
|
|
78
|
+
|
|
79
|
+
t_log := $(T_log) $(T_n_log)
|
|
80
|
+
test: $(T) $(T_n)
|
|
81
|
+
@cat $(t_log) | $(MRI) test/aggregate.rb
|
|
82
|
+
@$(RM) $(t_log)
|
|
83
|
+
|
|
84
|
+
test-exec: $(wildcard test/exec/test_*.rb)
|
|
85
|
+
test-unit: $(wildcard test/unit/test_*.rb)
|
|
86
|
+
$(slow_tests): $(test_prefix)/.stamp
|
|
87
|
+
@$(MAKE) $(shell $(awk_slow) $@)
|
|
88
|
+
|
|
89
|
+
# ensure we can require just the HTTP parser without the rest of unicorn
|
|
90
|
+
test-require: $(ext)/unicorn_http.$(DLEXT)
|
|
91
|
+
$(RUBY) --disable-gems -I$(ext) -runicorn_http -e Unicorn
|
|
92
|
+
|
|
93
|
+
test-integration: $(test_prefix)/.stamp
|
|
94
|
+
$(MAKE) -C t
|
|
95
|
+
|
|
96
|
+
check: test-require test test-integration
|
|
97
|
+
test-all: check
|
|
98
|
+
|
|
99
|
+
TEST_OPTS = -v
|
|
100
|
+
check_test = grep '0 failures, 0 errors' $(t) >/dev/null
|
|
101
|
+
ifndef V
|
|
102
|
+
quiet_pre = @echo '* $(arg)$(extra)';
|
|
103
|
+
quiet_post = >$(t) 2>&1 && $(check_test)
|
|
104
|
+
else
|
|
105
|
+
# we can't rely on -o pipefail outside of bash 3+,
|
|
106
|
+
# so we use a stamp file to indicate success and
|
|
107
|
+
# have rm fail if the stamp didn't get created
|
|
108
|
+
stamp = $@$(log_suffix).ok
|
|
109
|
+
quiet_pre = @echo $(RUBY) $(arg) $(TEST_OPTS); ! test -f $(stamp) && (
|
|
110
|
+
quiet_post = && > $(stamp) )2>&1 | tee $(t); \
|
|
111
|
+
rm $(stamp) 2>/dev/null && $(check_test)
|
|
112
|
+
endif
|
|
113
|
+
|
|
114
|
+
# not all systems have setsid(8), we need it because we spam signals
|
|
115
|
+
# stupidly in some tests...
|
|
116
|
+
rb_setsid := $(RUBY) -e 'Process.setsid' -e 'exec *ARGV'
|
|
117
|
+
|
|
118
|
+
# TRACER='strace -f -o $(t).strace -s 100000'
|
|
119
|
+
run_test = $(quiet_pre) \
|
|
120
|
+
$(rb_setsid) $(TRACER) $(RUBY) -w $(arg) $(TEST_OPTS) $(quiet_post) || \
|
|
121
|
+
(sed "s,^,$(extra): ," >&2 < $(t); exit 1)
|
|
122
|
+
|
|
123
|
+
%.n: arg = $(subst .n,,$(subst --, -n ,$@))
|
|
124
|
+
%.n: t = $(subst .n,$(log_suffix),$@)
|
|
125
|
+
%.n: export PATH := $(test_prefix)/bin:$(PATH)
|
|
126
|
+
%.n: export RUBYLIB := $(test_prefix)/lib:$(MYLIBS)
|
|
127
|
+
%.n: $(test_prefix)/.stamp
|
|
128
|
+
$(run_test)
|
|
129
|
+
|
|
130
|
+
$(T): arg = $@
|
|
131
|
+
$(T): t = $(subst .rb,$(log_suffix),$@)
|
|
132
|
+
$(T): export PATH := $(test_prefix)/bin:$(PATH)
|
|
133
|
+
$(T): export RUBYLIB := $(test_prefix)/lib:$(MYLIBS)
|
|
134
|
+
$(T): $(test_prefix)/.stamp
|
|
135
|
+
$(run_test)
|
|
136
|
+
|
|
137
|
+
install: $(bins) $(ext)/unicorn_http.c
|
|
138
|
+
$(prep_setup_rb)
|
|
139
|
+
$(RM) -r .install-tmp
|
|
140
|
+
mkdir .install-tmp
|
|
141
|
+
cp -p bin/* .install-tmp
|
|
142
|
+
$(RUBY) setup.rb all
|
|
143
|
+
$(RM) $^
|
|
144
|
+
mv .install-tmp/* bin/
|
|
145
|
+
$(RM) -r .install-tmp
|
|
146
|
+
$(prep_setup_rb)
|
|
147
|
+
|
|
148
|
+
setup_rb_files := .config InstalledFiles
|
|
149
|
+
prep_setup_rb := @-$(RM) $(setup_rb_files);$(MAKE) -C $(ext) clean
|
|
150
|
+
|
|
151
|
+
clean:
|
|
152
|
+
-$(MAKE) -C $(ext) clean
|
|
153
|
+
-$(MAKE) -C Documentation clean
|
|
154
|
+
$(RM) $(ext)/Makefile
|
|
155
|
+
$(RM) $(setup_rb_files) $(t_log)
|
|
156
|
+
$(RM) -r $(test_prefix) man
|
|
157
|
+
|
|
158
|
+
man html:
|
|
159
|
+
$(MAKE) -C Documentation install-$@
|
|
160
|
+
|
|
161
|
+
pkg_extra := GIT-VERSION-FILE lib/unicorn/version.rb LATEST NEWS \
|
|
162
|
+
$(ext)/unicorn_http.c $(man1_paths)
|
|
163
|
+
|
|
164
|
+
NEWS:
|
|
165
|
+
$(OLDDOC) prepare
|
|
166
|
+
|
|
167
|
+
.manifest: $(ext)/unicorn_http.c man NEWS
|
|
168
|
+
(git ls-files && for i in $@ $(pkg_extra); do echo $$i; done) | \
|
|
169
|
+
LC_ALL=C sort > $@+
|
|
170
|
+
cmp $@+ $@ || mv $@+ $@
|
|
171
|
+
$(RM) $@+
|
|
172
|
+
|
|
173
|
+
PLACEHOLDERS = $(man1_rdoc)
|
|
174
|
+
doc: .document $(ext)/unicorn_http.c man html .olddoc.yml $(PLACEHOLDERS)
|
|
175
|
+
find bin lib -type f -name '*.rbc' -exec rm -f '{}' ';'
|
|
176
|
+
$(RM) -r doc
|
|
177
|
+
$(OLDDOC) prepare
|
|
178
|
+
$(RDOC) -f oldweb
|
|
179
|
+
$(OLDDOC) merge
|
|
180
|
+
install -m644 COPYING doc/COPYING
|
|
181
|
+
install -m644 $(shell LC_ALL=C grep '^[A-Z]' .document) doc/
|
|
182
|
+
install -m644 $(man1_paths) doc/
|
|
183
|
+
tar cf - $$(git ls-files examples/) | (cd doc && tar xf -)
|
|
184
|
+
|
|
185
|
+
# publishes docs to http://unicorn.bogomips.org
|
|
186
|
+
publish_doc:
|
|
187
|
+
-git set-file-times
|
|
188
|
+
$(MAKE) doc
|
|
189
|
+
$(MAKE) doc_gz
|
|
190
|
+
chmod 644 $$(find doc -type f)
|
|
191
|
+
$(RSYNC) -av doc/ unicorn.bogomips.org:/srv/unicorn/
|
|
192
|
+
git ls-files | xargs touch
|
|
193
|
+
|
|
194
|
+
# Create gzip variants of the same timestamp as the original so nginx
|
|
195
|
+
# "gzip_static on" can serve the gzipped versions directly.
|
|
196
|
+
doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.gz$$')
|
|
197
|
+
doc_gz:
|
|
198
|
+
for i in $(docs); do \
|
|
199
|
+
gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
|
|
200
|
+
|
|
201
|
+
ifneq ($(VERSION),)
|
|
202
|
+
rfpackage := unicorn
|
|
203
|
+
pkggem := pkg/$(rfpackage)-$(VERSION).gem
|
|
204
|
+
pkgtgz := pkg/$(rfpackage)-$(VERSION).tgz
|
|
205
|
+
|
|
206
|
+
# ensures we're actually on the tagged $(VERSION), only used for release
|
|
207
|
+
verify:
|
|
208
|
+
test x"$(shell umask)" = x0022
|
|
209
|
+
git rev-parse --verify refs/tags/v$(VERSION)^{}
|
|
210
|
+
git diff-index --quiet HEAD^0
|
|
211
|
+
test `git rev-parse --verify HEAD^0` = \
|
|
212
|
+
`git rev-parse --verify refs/tags/v$(VERSION)^{}`
|
|
213
|
+
|
|
214
|
+
fix-perms:
|
|
215
|
+
git ls-tree -r HEAD | awk '/^100644 / {print $$NF}' | xargs chmod 644
|
|
216
|
+
git ls-tree -r HEAD | awk '/^100755 / {print $$NF}' | xargs chmod 755
|
|
217
|
+
|
|
218
|
+
gem: $(pkggem)
|
|
219
|
+
|
|
220
|
+
install-gem: $(pkggem)
|
|
221
|
+
gem install $(CURDIR)/$<
|
|
222
|
+
|
|
223
|
+
$(pkggem): .manifest fix-perms
|
|
224
|
+
gem build $(rfpackage).gemspec
|
|
225
|
+
mkdir -p pkg
|
|
226
|
+
mv $(@F) $@
|
|
227
|
+
|
|
228
|
+
$(pkgtgz): distdir = $(basename $@)
|
|
229
|
+
$(pkgtgz): HEAD = v$(VERSION)
|
|
230
|
+
$(pkgtgz): .manifest fix-perms
|
|
231
|
+
@test -n "$(distdir)"
|
|
232
|
+
$(RM) -r $(distdir)
|
|
233
|
+
mkdir -p $(distdir)
|
|
234
|
+
tar cf - $$(cat .manifest) | (cd $(distdir) && tar xf -)
|
|
235
|
+
cd pkg && tar cf - $(basename $(@F)) | gzip -9 > $(@F)+
|
|
236
|
+
mv $@+ $@
|
|
237
|
+
|
|
238
|
+
package: $(pkgtgz) $(pkggem)
|
|
239
|
+
|
|
240
|
+
release: verify package
|
|
241
|
+
# push gem to Gemcutter
|
|
242
|
+
gem push $(pkggem)
|
|
243
|
+
else
|
|
244
|
+
gem install-gem: GIT-VERSION-FILE
|
|
245
|
+
$(MAKE) $@ VERSION=$(GIT_VERSION)
|
|
246
|
+
endif
|
|
247
|
+
|
|
248
|
+
$(PLACEHOLDERS):
|
|
249
|
+
echo olddoc_placeholder > $@
|
|
250
|
+
|
|
251
|
+
.PHONY: .FORCE-GIT-VERSION-FILE doc $(T) $(slow_tests) man
|
|
252
|
+
.PHONY: test-install
|
data/HACKING
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
= Unicorn Hacker's Guide
|
|
2
|
+
|
|
3
|
+
== Polyglot Infrastructure
|
|
4
|
+
|
|
5
|
+
Like Mongrel, we use Ruby where it makes sense, and Ragel with C where
|
|
6
|
+
it helps performance. All of the code that actually runs your Rack
|
|
7
|
+
application is written Ruby, Ragel or C.
|
|
8
|
+
|
|
9
|
+
As far as tests and documentation goes, we're not afraid to embrace Unix
|
|
10
|
+
and use traditional Unix tools where they make sense and get the job
|
|
11
|
+
done.
|
|
12
|
+
|
|
13
|
+
=== Tests
|
|
14
|
+
|
|
15
|
+
Tests are good, but slow tests make development slow, so we make tests
|
|
16
|
+
faster (in parallel) with GNU make (instead of Rake) and avoiding
|
|
17
|
+
RubyGems.
|
|
18
|
+
|
|
19
|
+
Users of GNU-based systems (such as GNU/Linux) usually have GNU make
|
|
20
|
+
installed as "make" instead of "gmake".
|
|
21
|
+
|
|
22
|
+
Running the entire test suite with 4 tests in parallel:
|
|
23
|
+
|
|
24
|
+
gmake -j4 check
|
|
25
|
+
|
|
26
|
+
Running just one unit test:
|
|
27
|
+
|
|
28
|
+
gmake test/unit/test_http_parser.rb
|
|
29
|
+
|
|
30
|
+
Running just one test case in a unit test:
|
|
31
|
+
|
|
32
|
+
gmake test/unit/test_http_parser.rb--test_parse_simple.n
|
|
33
|
+
|
|
34
|
+
=== HttpServer
|
|
35
|
+
|
|
36
|
+
We strive to write as little code as possible while still maintaining
|
|
37
|
+
readability. However, readability and flexibility may be sacrificed for
|
|
38
|
+
performance in hot code paths. For Ruby, less code generally means
|
|
39
|
+
faster code.
|
|
40
|
+
|
|
41
|
+
Memory allocation should be minimized as much as practically possible.
|
|
42
|
+
Buffers for IO#readpartial are preallocated in the hot paths to avoid
|
|
43
|
+
building up garbage. Hash assignments use frozen strings to avoid the
|
|
44
|
+
duplication behind-the-scenes.
|
|
45
|
+
|
|
46
|
+
We spend as little time as possible inside signal handlers and instead
|
|
47
|
+
defer handling them for predictability and robustness. Most of the
|
|
48
|
+
Unix-specific things are in the Unicorn::HttpServer class. Unix systems
|
|
49
|
+
programming experience will come in handy (or be learned) here.
|
|
50
|
+
|
|
51
|
+
=== Documentation
|
|
52
|
+
|
|
53
|
+
Due to the lack of RDoc-to-manpage converters we know about, we're
|
|
54
|
+
writing manpages in Markdown and converting to troff/HTML with Pandoc.
|
|
55
|
+
|
|
56
|
+
Please wrap documentation at 72 characters-per-line or less (long URLs
|
|
57
|
+
are exempt) so it is comfortably readable from terminals.
|
|
58
|
+
|
|
59
|
+
When referencing mailing list posts, use
|
|
60
|
+
"http://bogomips.org/unicorn-public/m/$MESSAGE_ID.html" if possible
|
|
61
|
+
since the Message-ID remains searchable even if a particular site
|
|
62
|
+
becomes unavailable.
|
|
63
|
+
|
|
64
|
+
=== Ruby/C Compatibility
|
|
65
|
+
|
|
66
|
+
We target mainline Ruby 1.9.3 and later. We need the Ruby
|
|
67
|
+
implementation to support fork, exec, pipe, UNIX signals, access to
|
|
68
|
+
integer file descriptors and ability to use unlinked files.
|
|
69
|
+
|
|
70
|
+
All of our C code is OS-independent and should run on compilers
|
|
71
|
+
supported by the versions of Ruby we target.
|
|
72
|
+
|
|
73
|
+
=== Ragel Compatibility
|
|
74
|
+
|
|
75
|
+
We target the latest released version of Ragel and will update our code
|
|
76
|
+
to keep up with new releases. Packaged tarballs and gems include the
|
|
77
|
+
generated source code so they will remain usable if compatibility is
|
|
78
|
+
broken.
|
|
79
|
+
|
|
80
|
+
== Contributing
|
|
81
|
+
|
|
82
|
+
Contributions are welcome in the form of patches, pull requests, code
|
|
83
|
+
review, testing, documentation, user support or any other feedback is
|
|
84
|
+
welcome. The mailing list is the central coordination point for all
|
|
85
|
+
user and developer feedback and bug reports.
|
|
86
|
+
|
|
87
|
+
=== Submitting Patches
|
|
88
|
+
|
|
89
|
+
Follow conventions already established in the code and do not exceed 80
|
|
90
|
+
characters per line.
|
|
91
|
+
|
|
92
|
+
Inline patches (from "git format-patch -M") to the mailing list are
|
|
93
|
+
preferred because they allow code review and comments in the reply to
|
|
94
|
+
the patch.
|
|
95
|
+
|
|
96
|
+
We will adhere to mostly the same conventions for patch submissions as
|
|
97
|
+
git itself. See the
|
|
98
|
+
{SubmittingPatches}[https://git.kernel.org/cgit/git/git.git/tree/Documentation/SubmittingPatches]
|
|
99
|
+
document
|
|
100
|
+
distributed with git on on patch submission guidelines to follow. Just
|
|
101
|
+
don't email the git mailing list or maintainer with Unicorn patches :)
|
|
102
|
+
|
|
103
|
+
== Building a Gem
|
|
104
|
+
|
|
105
|
+
In order to build the gem, you must install the following components:
|
|
106
|
+
|
|
107
|
+
* olddoc (RubyGem)
|
|
108
|
+
* pandoc
|
|
109
|
+
|
|
110
|
+
You can build the Unicorn gem with the following command:
|
|
111
|
+
|
|
112
|
+
gmake gem
|
|
113
|
+
|
|
114
|
+
== Running Development Versions
|
|
115
|
+
|
|
116
|
+
It is easy to install the contents of your git working directory:
|
|
117
|
+
|
|
118
|
+
Via RubyGems
|
|
119
|
+
|
|
120
|
+
gmake install-gem
|