giraffesoft-unicorn 0.93.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. data/.CHANGELOG.old +25 -0
  2. data/.document +16 -0
  3. data/.gitignore +20 -0
  4. data/.mailmap +26 -0
  5. data/CONTRIBUTORS +31 -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 +167 -0
  11. data/Documentation/unicorn_rails.1.txt +169 -0
  12. data/GIT-VERSION-GEN +40 -0
  13. data/GNUmakefile +270 -0
  14. data/HACKING +113 -0
  15. data/KNOWN_ISSUES +40 -0
  16. data/LICENSE +55 -0
  17. data/PHILOSOPHY +144 -0
  18. data/README +153 -0
  19. data/Rakefile +108 -0
  20. data/SIGNALS +97 -0
  21. data/TODO +16 -0
  22. data/TUNING +70 -0
  23. data/bin/unicorn +165 -0
  24. data/bin/unicorn_rails +208 -0
  25. data/examples/echo.ru +27 -0
  26. data/examples/git.ru +13 -0
  27. data/examples/init.sh +53 -0
  28. data/ext/unicorn_http/c_util.h +107 -0
  29. data/ext/unicorn_http/common_field_optimization.h +111 -0
  30. data/ext/unicorn_http/ext_help.h +73 -0
  31. data/ext/unicorn_http/extconf.rb +14 -0
  32. data/ext/unicorn_http/global_variables.h +91 -0
  33. data/ext/unicorn_http/unicorn_http.rl +715 -0
  34. data/ext/unicorn_http/unicorn_http_common.rl +74 -0
  35. data/lib/unicorn.rb +730 -0
  36. data/lib/unicorn/app/exec_cgi.rb +150 -0
  37. data/lib/unicorn/app/inetd.rb +109 -0
  38. data/lib/unicorn/app/old_rails.rb +31 -0
  39. data/lib/unicorn/app/old_rails/static.rb +60 -0
  40. data/lib/unicorn/cgi_wrapper.rb +145 -0
  41. data/lib/unicorn/configurator.rb +403 -0
  42. data/lib/unicorn/const.rb +37 -0
  43. data/lib/unicorn/http_request.rb +74 -0
  44. data/lib/unicorn/http_response.rb +74 -0
  45. data/lib/unicorn/launcher.rb +39 -0
  46. data/lib/unicorn/socket_helper.rb +138 -0
  47. data/lib/unicorn/tee_input.rb +174 -0
  48. data/lib/unicorn/util.rb +64 -0
  49. data/local.mk.sample +53 -0
  50. data/setup.rb +1586 -0
  51. data/test/aggregate.rb +15 -0
  52. data/test/benchmark/README +50 -0
  53. data/test/benchmark/dd.ru +18 -0
  54. data/test/exec/README +5 -0
  55. data/test/exec/test_exec.rb +855 -0
  56. data/test/rails/app-1.2.3/.gitignore +2 -0
  57. data/test/rails/app-1.2.3/Rakefile +7 -0
  58. data/test/rails/app-1.2.3/app/controllers/application.rb +6 -0
  59. data/test/rails/app-1.2.3/app/controllers/foo_controller.rb +36 -0
  60. data/test/rails/app-1.2.3/app/helpers/application_helper.rb +4 -0
  61. data/test/rails/app-1.2.3/config/boot.rb +11 -0
  62. data/test/rails/app-1.2.3/config/database.yml +12 -0
  63. data/test/rails/app-1.2.3/config/environment.rb +13 -0
  64. data/test/rails/app-1.2.3/config/environments/development.rb +9 -0
  65. data/test/rails/app-1.2.3/config/environments/production.rb +5 -0
  66. data/test/rails/app-1.2.3/config/routes.rb +6 -0
  67. data/test/rails/app-1.2.3/db/.gitignore +0 -0
  68. data/test/rails/app-1.2.3/public/404.html +1 -0
  69. data/test/rails/app-1.2.3/public/500.html +1 -0
  70. data/test/rails/app-2.0.2/.gitignore +2 -0
  71. data/test/rails/app-2.0.2/Rakefile +7 -0
  72. data/test/rails/app-2.0.2/app/controllers/application.rb +4 -0
  73. data/test/rails/app-2.0.2/app/controllers/foo_controller.rb +36 -0
  74. data/test/rails/app-2.0.2/app/helpers/application_helper.rb +4 -0
  75. data/test/rails/app-2.0.2/config/boot.rb +11 -0
  76. data/test/rails/app-2.0.2/config/database.yml +12 -0
  77. data/test/rails/app-2.0.2/config/environment.rb +17 -0
  78. data/test/rails/app-2.0.2/config/environments/development.rb +8 -0
  79. data/test/rails/app-2.0.2/config/environments/production.rb +5 -0
  80. data/test/rails/app-2.0.2/config/routes.rb +6 -0
  81. data/test/rails/app-2.0.2/db/.gitignore +0 -0
  82. data/test/rails/app-2.0.2/public/404.html +1 -0
  83. data/test/rails/app-2.0.2/public/500.html +1 -0
  84. data/test/rails/app-2.1.2/.gitignore +2 -0
  85. data/test/rails/app-2.1.2/Rakefile +7 -0
  86. data/test/rails/app-2.1.2/app/controllers/application.rb +4 -0
  87. data/test/rails/app-2.1.2/app/controllers/foo_controller.rb +36 -0
  88. data/test/rails/app-2.1.2/app/helpers/application_helper.rb +4 -0
  89. data/test/rails/app-2.1.2/config/boot.rb +111 -0
  90. data/test/rails/app-2.1.2/config/database.yml +12 -0
  91. data/test/rails/app-2.1.2/config/environment.rb +17 -0
  92. data/test/rails/app-2.1.2/config/environments/development.rb +7 -0
  93. data/test/rails/app-2.1.2/config/environments/production.rb +5 -0
  94. data/test/rails/app-2.1.2/config/routes.rb +6 -0
  95. data/test/rails/app-2.1.2/db/.gitignore +0 -0
  96. data/test/rails/app-2.1.2/public/404.html +1 -0
  97. data/test/rails/app-2.1.2/public/500.html +1 -0
  98. data/test/rails/app-2.2.2/.gitignore +2 -0
  99. data/test/rails/app-2.2.2/Rakefile +7 -0
  100. data/test/rails/app-2.2.2/app/controllers/application.rb +4 -0
  101. data/test/rails/app-2.2.2/app/controllers/foo_controller.rb +36 -0
  102. data/test/rails/app-2.2.2/app/helpers/application_helper.rb +4 -0
  103. data/test/rails/app-2.2.2/config/boot.rb +111 -0
  104. data/test/rails/app-2.2.2/config/database.yml +12 -0
  105. data/test/rails/app-2.2.2/config/environment.rb +17 -0
  106. data/test/rails/app-2.2.2/config/environments/development.rb +7 -0
  107. data/test/rails/app-2.2.2/config/environments/production.rb +5 -0
  108. data/test/rails/app-2.2.2/config/routes.rb +6 -0
  109. data/test/rails/app-2.2.2/db/.gitignore +0 -0
  110. data/test/rails/app-2.2.2/public/404.html +1 -0
  111. data/test/rails/app-2.2.2/public/500.html +1 -0
  112. data/test/rails/app-2.3.3.1/.gitignore +2 -0
  113. data/test/rails/app-2.3.3.1/Rakefile +7 -0
  114. data/test/rails/app-2.3.3.1/app/controllers/application_controller.rb +5 -0
  115. data/test/rails/app-2.3.3.1/app/controllers/foo_controller.rb +36 -0
  116. data/test/rails/app-2.3.3.1/app/helpers/application_helper.rb +4 -0
  117. data/test/rails/app-2.3.3.1/config/boot.rb +109 -0
  118. data/test/rails/app-2.3.3.1/config/database.yml +12 -0
  119. data/test/rails/app-2.3.3.1/config/environment.rb +17 -0
  120. data/test/rails/app-2.3.3.1/config/environments/development.rb +7 -0
  121. data/test/rails/app-2.3.3.1/config/environments/production.rb +6 -0
  122. data/test/rails/app-2.3.3.1/config/routes.rb +6 -0
  123. data/test/rails/app-2.3.3.1/db/.gitignore +0 -0
  124. data/test/rails/app-2.3.3.1/public/404.html +1 -0
  125. data/test/rails/app-2.3.3.1/public/500.html +1 -0
  126. data/test/rails/app-2.3.3.1/public/x.txt +1 -0
  127. data/test/rails/test_rails.rb +280 -0
  128. data/test/test_helper.rb +296 -0
  129. data/test/unit/test_configurator.rb +150 -0
  130. data/test/unit/test_http_parser.rb +492 -0
  131. data/test/unit/test_http_parser_ng.rb +308 -0
  132. data/test/unit/test_request.rb +184 -0
  133. data/test/unit/test_response.rb +110 -0
  134. data/test/unit/test_server.rb +188 -0
  135. data/test/unit/test_signals.rb +202 -0
  136. data/test/unit/test_socket_helper.rb +133 -0
  137. data/test/unit/test_tee_input.rb +229 -0
  138. data/test/unit/test_upload.rb +297 -0
  139. data/test/unit/test_util.rb +96 -0
  140. data/unicorn.gemspec +42 -0
  141. metadata +228 -0
data/GIT-VERSION-GEN ADDED
@@ -0,0 +1,40 @@
1
+ #!/bin/sh
2
+
3
+ GVF=GIT-VERSION-FILE
4
+ DEF_VER=v0.93.5.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,270 @@
1
+ # use GNU Make to run tests in parallel, and without depending on Rubygems
2
+ all:: test
3
+ ruby = ruby
4
+ rake = rake
5
+ ragel = ragel
6
+ GIT_URL = git://git.bogomips.org/unicorn.git
7
+ RLFLAGS = -G2
8
+
9
+ GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
10
+ @./GIT-VERSION-GEN
11
+ -include GIT-VERSION-FILE
12
+ -include local.mk
13
+ ruby_bin := $(shell which $(ruby))
14
+ ifeq ($(DLEXT),) # "so" for Linux
15
+ DLEXT := $(shell $(ruby) -rrbconfig -e 'puts Config::CONFIG["DLEXT"]')
16
+ endif
17
+ ifeq ($(RUBY_VERSION),)
18
+ RUBY_VERSION := $(shell $(ruby) -e 'puts RUBY_VERSION')
19
+ endif
20
+
21
+ # dunno how to implement this as concisely in Ruby, and hell, I love awk
22
+ awk_slow := awk '/def test_/{print FILENAME"--"$$2".n"}' 2>/dev/null
23
+
24
+ rails_vers := $(subst test/rails/app-,,$(wildcard test/rails/app-*))
25
+ slow_tests := test/unit/test_server.rb test/exec/test_exec.rb \
26
+ test/unit/test_signals.rb test/unit/test_upload.rb
27
+ log_suffix = .$(RUBY_VERSION).log
28
+ T_r := $(wildcard test/rails/test*.rb)
29
+ T := $(filter-out $(slow_tests) $(T_r), $(wildcard test/*/test*.rb))
30
+ T_n := $(shell $(awk_slow) $(slow_tests))
31
+ T_log := $(subst .rb,$(log_suffix),$(T))
32
+ T_n_log := $(subst .n,$(log_suffix),$(T_n))
33
+ T_r_log := $(subst .r,$(log_suffix),$(T_r))
34
+ test_prefix = $(CURDIR)/test/install-$(RUBY_VERSION)
35
+
36
+ ext := ext/unicorn_http
37
+ c_files := $(ext)/unicorn_http.c $(wildcard $(ext)/*.h)
38
+ rl_files := $(wildcard $(ext)/*.rl)
39
+ base_bins := unicorn unicorn_rails
40
+ bins := $(addprefix bin/, $(base_bins))
41
+ man1_bins := $(addsuffix .1, $(base_bins))
42
+ man1_paths := $(addprefix man/man1/, $(man1_bins))
43
+ rb_files := $(bins) $(shell find lib ext -type f -name '*.rb')
44
+ inst_deps := $(c_files) $(rb_files) GNUmakefile test/test_helper.rb
45
+
46
+ ragel: $(ext)/unicorn_http.c
47
+ $(ext)/unicorn_http.c: $(rl_files)
48
+ cd $(@D) && $(ragel) unicorn_http.rl -C $(RLFLAGS) -o $(@F)
49
+ $(ext)/Makefile: $(ext)/extconf.rb $(c_files)
50
+ cd $(@D) && $(ruby) extconf.rb
51
+ $(ext)/unicorn_http.$(DLEXT): $(ext)/Makefile
52
+ $(MAKE) -C $(@D)
53
+ lib/unicorn_http.$(DLEXT): $(ext)/unicorn_http.$(DLEXT)
54
+ @mkdir -p lib
55
+ install -m644 $< $@
56
+ http: lib/unicorn_http.$(DLEXT)
57
+
58
+ $(test_prefix)/.stamp: $(inst_deps)
59
+ mkdir -p $(test_prefix)/.ccache
60
+ tar cf - $(inst_deps) GIT-VERSION-GEN | \
61
+ (cd $(test_prefix) && tar xf -)
62
+ $(MAKE) -C $(test_prefix) clean
63
+ $(MAKE) -C $(test_prefix) http shebang
64
+ > $@
65
+
66
+ # this is only intended to be run within $(test_prefix)
67
+ shebang: $(bins)
68
+ $(ruby) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^
69
+
70
+ t_log := $(T_log) $(T_n_log)
71
+ test: $(T) $(T_n)
72
+ @cat $(t_log) | $(ruby) test/aggregate.rb
73
+ @$(RM) $(t_log)
74
+
75
+ test-exec: $(wildcard test/exec/test_*.rb)
76
+ test-unit: $(wildcard test/unit/test_*.rb)
77
+ $(slow_tests): $(test_prefix)/.stamp
78
+ @$(MAKE) $(shell $(awk_slow) $@)
79
+
80
+ TEST_OPTS = -v
81
+ check_test = grep '0 failures, 0 errors' $(t) >/dev/null
82
+ ifndef V
83
+ quiet_pre = @echo '* $(arg)$(extra)';
84
+ quiet_post = >$(t) 2>&1 && $(check_test)
85
+ else
86
+ # we can't rely on -o pipefail outside of bash 3+,
87
+ # so we use a stamp file to indicate success and
88
+ # have rm fail if the stamp didn't get created
89
+ stamp = $@$(log_suffix).ok
90
+ quiet_pre = @echo $(ruby) $(arg) $(TEST_OPTS); ! test -f $(stamp) && (
91
+ quiet_post = && > $(stamp) )2>&1 | tee $(t); \
92
+ rm $(stamp) 2>/dev/null && $(check_test)
93
+ endif
94
+
95
+ # not all systems have setsid(8), we need it because we spam signals
96
+ # stupidly in some tests...
97
+ rb_setsid := $(ruby) -e 'Process.setsid' -e 'exec *ARGV'
98
+
99
+ # TRACER='strace -f -o $(t).strace -s 100000'
100
+ run_test = $(quiet_pre) \
101
+ $(rb_setsid) $(TRACER) $(ruby) -w $(arg) $(TEST_OPTS) $(quiet_post) || \
102
+ (sed "s,^,$(extra): ," >&2 < $(t); exit 1)
103
+
104
+ %.n: arg = $(subst .n,,$(subst --, -n ,$@))
105
+ %.n: t = $(subst .n,$(log_suffix),$@)
106
+ %.n: export PATH := $(test_prefix)/bin:$(PATH)
107
+ %.n: export RUBYLIB := $(test_prefix):$(test_prefix)/lib:$(RUBYLIB)
108
+ %.n: $(test_prefix)/.stamp
109
+ $(run_test)
110
+
111
+ $(T): arg = $@
112
+ $(T): t = $(subst .rb,$(log_suffix),$@)
113
+ $(T): export PATH := $(test_prefix)/bin:$(PATH)
114
+ $(T): export RUBYLIB := $(test_prefix):$(test_prefix)/lib:$(RUBYLIB)
115
+ $(T): $(test_prefix)/.stamp
116
+ $(run_test)
117
+
118
+ install: $(bins) $(ext)/unicorn_http.c
119
+ $(prep_setup_rb)
120
+ $(RM) lib/unicorn_http.$(DLEXT)
121
+ $(RM) -r .install-tmp
122
+ mkdir .install-tmp
123
+ cp -p bin/* .install-tmp
124
+ $(ruby) setup.rb all
125
+ $(RM) $^
126
+ mv .install-tmp/* bin/
127
+ $(RM) -r .install-tmp
128
+ $(prep_setup_rb)
129
+
130
+ setup_rb_files := .config InstalledFiles
131
+ prep_setup_rb := @-$(RM) $(setup_rb_files);$(MAKE) -C $(ext) clean
132
+
133
+ clean:
134
+ -$(MAKE) -C $(ext) clean
135
+ -$(MAKE) -C Documentation clean
136
+ $(RM) $(ext)/Makefile lib/unicorn_http.$(DLEXT)
137
+ $(RM) $(setup_rb_files) $(t_log)
138
+ $(RM) -r $(test_prefix) man
139
+
140
+ pkg_extra := GIT-VERSION-FILE NEWS ChangeLog $(ext)/unicorn_http.c
141
+ manifest: $(pkg_extra)
142
+ $(RM) .manifest
143
+ $(MAKE) .manifest
144
+
145
+ .manifest:
146
+ (git ls-files && \
147
+ for i in $@ $(pkg_extra) $(man1_paths); \
148
+ do echo $$i; done) | LC_ALL=C sort > $@+
149
+ cmp $@+ $@ || mv $@+ $@
150
+ $(RM) $@+
151
+
152
+ NEWS: GIT-VERSION-FILE
153
+ $(rake) -s news_rdoc > $@+
154
+ mv $@+ $@
155
+
156
+ SINCE = 0.92.0
157
+ ChangeLog: log_range = $(shell test -n "$(SINCE)" && echo v$(SINCE)..)
158
+ ChangeLog: GIT-VERSION-FILE
159
+ @echo "ChangeLog from $(GIT_URL) ($(SINCE)..$(GIT_VERSION))" > $@+
160
+ @echo >> $@+
161
+ git log $(log_range) | sed -e 's/^/ /' >> $@+
162
+ mv $@+ $@
163
+
164
+ news_atom := http://unicorn.bogomips.org/NEWS.atom.xml
165
+ cgit_atom := http://git.bogomips.org/cgit/unicorn.git/atom/?h=master
166
+ atom = <link rel="alternate" title="Atom feed" href="$(1)" \
167
+ type="application/atom+xml"/>
168
+
169
+ # using rdoc 2.4.1+
170
+ doc: .document $(ext)/unicorn_http.c NEWS ChangeLog
171
+ for i in $(man1_bins); do > $$i; done
172
+ rdoc -Na -t "$(shell sed -ne '1s/^= //p' README)"
173
+ install -m644 COPYING doc/COPYING
174
+ install -m644 $(shell grep '^[A-Z]' .document) doc/
175
+ $(MAKE) -C Documentation install-html install-man
176
+ install -m644 $(man1_paths) doc/
177
+ cd doc && for i in $(base_bins); do \
178
+ sed -e '/"documentation">/r man1/'$$i'.1.html' \
179
+ < $${i}_1.html > tmp && mv tmp $${i}_1.html; done
180
+ $(ruby) -i -p -e \
181
+ '$$_.gsub!("</title>",%q{\&$(call atom,$(cgit_atom))})' \
182
+ doc/ChangeLog.html
183
+ $(ruby) -i -p -e \
184
+ '$$_.gsub!("</title>",%q{\&$(call atom,$(news_atom))})' \
185
+ doc/NEWS.html doc/README.html
186
+ $(rake) -s news_atom > doc/NEWS.atom.xml
187
+ cd doc && ln README.html tmp && mv tmp index.html
188
+ $(RM) $(man1_bins)
189
+
190
+ rails_git_url = git://github.com/rails/rails.git
191
+ rails_git := vendor/rails.git
192
+ $(rails_git)/info/cloned-stamp:
193
+ git clone --mirror -q $(rails_git_url) $(rails_git)
194
+ > $@
195
+
196
+ rails_tests := $(addsuffix .r,$(addprefix $(T_r).,$(rails_vers)))
197
+ test-rails: $(rails_tests)
198
+ $(T_r).%.r: t = $(addsuffix $(log_suffix),$@)
199
+ $(T_r).%.r: rv = $(subst .r,,$(subst $(T_r).,,$@))
200
+ $(T_r).%.r: extra = ' 'v$(rv)
201
+ $(T_r).%.r: arg = $(T_r)
202
+ $(T_r).%.r: export PATH := $(test_prefix)/bin:$(PATH)
203
+ $(T_r).%.r: export RUBYLIB := $(test_prefix):$(test_prefix)/lib:$(RUBYLIB)
204
+ $(T_r).%.r: export UNICORN_RAILS_TEST_VERSION = $(rv)
205
+ $(T_r).%.r: export RAILS_GIT_REPO = $(CURDIR)/$(rails_git)
206
+ $(T_r).%.r: $(test_prefix)/.stamp $(rails_git)/info/cloned-stamp
207
+ $(run_test)
208
+
209
+ ifneq ($(VERSION),)
210
+ rfproject := mongrel
211
+ rfpackage := unicorn
212
+ pkggem := pkg/$(rfpackage)-$(VERSION).gem
213
+ pkgtgz := pkg/$(rfpackage)-$(VERSION).tgz
214
+ release_notes := release_notes-$(VERSION)
215
+ release_changes := release_changes-$(VERSION)
216
+
217
+ release-notes: $(release_notes)
218
+ release-changes: $(release_changes)
219
+ $(release_changes):
220
+ $(rake) -s release_changes > $@+
221
+ $(VISUAL) $@+ && test -s $@+ && mv $@+ $@
222
+ $(release_notes):
223
+ GIT_URL=$(GIT_URL) $(rake) -s release_notes > $@+
224
+ $(VISUAL) $@+ && test -s $@+ && mv $@+ $@
225
+
226
+ # ensures we're actually on the tagged $(VERSION), only used for release
227
+ verify:
228
+ test x"$(shell umask)" = x0022
229
+ git rev-parse --verify refs/tags/v$(VERSION)^{}
230
+ git diff-index --quiet HEAD^0
231
+ test `git rev-parse --verify HEAD^0` = \
232
+ `git rev-parse --verify refs/tags/v$(VERSION)^{}`
233
+
234
+ fix-perms:
235
+ git ls-tree -r HEAD | awk '/^100644 / {print $$NF}' | xargs chmod 644
236
+ git ls-tree -r HEAD | awk '/^100755 / {print $$NF}' | xargs chmod 755
237
+
238
+ gem: $(pkggem)
239
+
240
+ install-gem: $(pkggem)
241
+ gem install $(CURDIR)/$<
242
+
243
+ $(pkggem): manifest fix-perms
244
+ gem build $(rfpackage).gemspec
245
+ mkdir -p pkg
246
+ mv $(@F) $@
247
+
248
+ $(pkgtgz): distdir = $(basename $@)
249
+ $(pkgtgz): HEAD = v$(VERSION)
250
+ $(pkgtgz): manifest fix-perms
251
+ @test -n "$(distdir)"
252
+ $(RM) -r $(distdir)
253
+ mkdir -p $(distdir)
254
+ tar cf - `cat .manifest` | (cd $(distdir) && tar xf -)
255
+ cd pkg && tar cf - $(basename $(@F)) | gzip -9 > $(@F)+
256
+ mv $@+ $@
257
+
258
+ package: $(pkgtgz) $(pkggem)
259
+
260
+ release: verify package $(release_notes) $(release_changes)
261
+ rubyforge add_release -f -n $(release_notes) -a $(release_changes) \
262
+ $(rfproject) $(rfpackage) $(VERSION) $(pkggem)
263
+ rubyforge add_file \
264
+ $(rfproject) $(rfpackage) $(VERSION) $(pkgtgz)
265
+ else
266
+ gem install-gem: GIT-VERSION-FILE
267
+ $(MAKE) $@ VERSION=$(GIT_VERSION)
268
+ endif
269
+
270
+ .PHONY: .FORCE-GIT-VERSION-FILE doc $(T) $(slow_tests) manifest man
data/HACKING ADDED
@@ -0,0 +1,113 @@
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
+ Since we don't load RubyGems by default, loading Rack properly requires
20
+ setting up RUBYLIB to point to where Rack is located. Not loading
21
+ Rubygems drastically lowers the time to run the full test suite. You
22
+ may setup a "local.mk" file in the top-level working directory to setup
23
+ your RUBYLIB and any other environment variables. A "local.mk.sample"
24
+ file is provided for reference.
25
+
26
+ Running the entire test suite with 4 tests in parallel:
27
+
28
+ make -j4 test
29
+
30
+ Running just one unit test:
31
+
32
+ make test/unit/test_http_parser.rb
33
+
34
+ Running just one test case in a unit test:
35
+
36
+ make test/unit/test_http_parser.rb--test_parse_simple.n
37
+
38
+ === HttpServer
39
+
40
+ We strive to write as little code as possible while still maintaining
41
+ readability. However, readability and flexibility may be sacrificed for
42
+ performance in hot code paths. For Ruby, less code generally means
43
+ faster code.
44
+
45
+ Memory allocation should be minimized as much as practically possible.
46
+ Buffers for IO#readpartial are preallocated in the hot paths to avoid
47
+ building up garbage. Hash assignments use frozen strings to avoid the
48
+ duplication behind-the-scenes.
49
+
50
+ We spend as little time as possible inside signal handlers and instead
51
+ defer handling them for predictability and robustness. Most of the
52
+ Unix-specific things are in the Unicorn::HttpServer class. Unix systems
53
+ programming experience will come in handy (or be learned) here.
54
+
55
+ === Documentation
56
+
57
+ We use RDoc 2.4.x with Darkfish for documentation as much as possible,
58
+ if you're on Ruby 1.8 you want to install the latest "rdoc" gem. Due to
59
+ the lack of RDoc-to-manpage converters we know about, we're writing
60
+ manpages in Markdown and converting to troff/HTML with Pandoc.
61
+
62
+ === Ruby/C Compatibility
63
+
64
+ We target Ruby 1.8.6+, 1.9 and will target Rubinius as it becomes
65
+ production-ready. We need the Ruby implementation to support fork,
66
+ exec, pipe, UNIX signals, access to integer file descriptors and
67
+ ability to use unlinked files.
68
+
69
+ All of our C code is OS-independent and should run on compilers
70
+ supported by the versions of Ruby we target.
71
+
72
+ === Ragel Compatibility
73
+
74
+ We target the latest released version of Ragel and will update our code
75
+ to keep up with new releases. Packaged tarballs and gems include the
76
+ generated source code so they will remain usable if compatibility is
77
+ broken.
78
+
79
+ == Contributing
80
+
81
+ Contributions are welcome in the form of patches, pull requests, code
82
+ review, testing, documentation, user support or any other feedback is
83
+ welcome. The mailing list is the central coordination point for all
84
+ user and developer feedback and bug reports.
85
+
86
+ === Submitting Patches
87
+
88
+ Follow conventions already established in the code and do not exceed 80
89
+ characters per line.
90
+
91
+ Inline patches (from "git format-patch") to the mailing list are
92
+ preferred because they allow code review and comments in the reply to
93
+ the patch.
94
+
95
+ We will adhere to mostly the same conventions for patch submissions as
96
+ git itself. See the Documentation/SubmittingPatches document
97
+ distributed with git on on patch submission guidelines to follow. Just
98
+ don't email the git mailing list or maintainer with Unicorn patches :)
99
+
100
+ == Running Development Versions
101
+
102
+ It is easy to install the contents of your git working directory:
103
+
104
+ Via RubyGems (RubyGems 1.3.5+ recommended for prerelease versions):
105
+
106
+ make install-gem
107
+
108
+ Without RubyGems (via setup.rb):
109
+
110
+ make install
111
+
112
+ It is not at all recommended to mix a RubyGems installation with an
113
+ installation done without RubyGems, however.
data/KNOWN_ISSUES ADDED
@@ -0,0 +1,40 @@
1
+ = Known Issues
2
+
3
+ * Rails 2.3.2 bundles its own version of Rack. This may cause subtle
4
+ bugs when simultaneously loaded with the system-wide Rack Rubygem
5
+ which Unicorn depends on. Upgrading to Rails 2.3.4 (or later) is
6
+ strongly recommended for all Rails 2.3.x users for this (and security
7
+ reasons). Rails 2.2.x series (or before) did not bundle Rack and are
8
+ should be unnaffected. If there is any reason which forces your
9
+ application to use Rails 2.3.2 and you have no other choice, then
10
+ you may edit your Unicorn gemspec and remove the Rack dependency.
11
+
12
+ ref: http://mid.gmane.org/20091014221552.GA30624@dcvr.yhbt.net
13
+ Note: the workaround described in the article above only made
14
+ the issue more subtle and we didn't notice them immediately.
15
+
16
+ * Installing "unicorn" as a system-wide Rubygem and using the
17
+ {isolate}[http://github.com/jbarnette/isolate] gem may cause issues if
18
+ you're using any of the bundled application-level libraries in
19
+ unicorn/app/* (for compatibility with CGI-based applications, Rails <=
20
+ 2.2.2, or ExecCgi). For now workarounds include:
21
+
22
+ * installing the same version of unicorn as a system-wide Rubygem
23
+ _and_ isolating unicorn as well.
24
+ * explicitly setting RUBYLIB or $LOAD_PATH to include any gem path
25
+ where the unicorn gem is installed (e.g.
26
+ /usr/lib/ruby/gems/1.8/gems/unicorn-VERSION/lib)
27
+
28
+ * WONTFIX: code reloading and restarts with Sinatra 0.3.x (and likely older
29
+ versions) apps is broken. The workaround is to force production
30
+ mode to disable code reloading as well as disabling "run" in your
31
+ Sinatra application:
32
+ set :env, :production
33
+ set :run, false
34
+ Since this is no longer an issue with Sinatra 0.9.x apps, this will not be
35
+ fixed on our end. Since Unicorn is itself the application launcher, the
36
+ at_exit handler used in old Sinatra always caused Mongrel to be launched
37
+ whenever a Unicorn worker was about to exit.
38
+
39
+ Also remember we're capable of replacing the running binary without dropping
40
+ any connections regardless of framework :)