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