unicorn 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,12 @@
1
+ README
2
+ DESIGN
3
+ CHANGELOG
4
+ CONTRIBUTORS
5
+ LICENSE
6
+ SIGNALS
7
+ TODO
8
+ bin
9
+ lib
10
+ ext/**/*.c
11
+ ext/**/*.rl
12
+ ext/**/*.h
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ *.bundle
2
+ *.log
3
+ *.so
4
+ .DS_Store
5
+ /.config
6
+ /InstalledFiles
7
+ /doc
8
+ /local.mk
9
+ /test/install-*
10
+ ext/unicorn/http11/Makefile
11
+ log/
12
+ pkg/
data/CHANGELOG ADDED
@@ -0,0 +1,19 @@
1
+ v0.1.0 - Unicorn - UNIX-only fork of Mongrel free of threading
2
+
3
+ v2.0. (WIP) Rack support.
4
+
5
+ v1.1.4. Fix camping handler. Correct treatment of @throttle parameter.
6
+
7
+ v1.1.3. Fix security flaw of DirHandler; reported on mailing list.
8
+
9
+ v1.1.2. Fix worker termination bug; fix JRuby 1.0.3 load order issue; fix require issue on systems without Rubygems.
10
+
11
+ v1.1.1. Fix mongrel_rails restart bug; fix bug with Rack status codes.
12
+
13
+ v1.1. Pure Ruby URIClassifier. More modular architecture. JRuby support. Move C URIClassifier into mongrel_experimental project.
14
+
15
+ v1.0.4. Backport fixes for versioning inconsistency, mongrel_rails bug, and DirHandler bug.
16
+
17
+ v1.0.3. Fix user-switching bug; make people upgrade to the latest from the RC.
18
+
19
+ v1.0.2. Signed gem; many minor bugfixes and patches.
data/CONTRIBUTORS ADDED
@@ -0,0 +1,20 @@
1
+ Unicorn would not be possible without Zed and all the contributors to Mongrel.
2
+
3
+ Eric Wong
4
+ Ezra Zygmuntowicz
5
+ Zed A. Shaw
6
+ Luis Lavena
7
+ Wilson Bilkovich
8
+ Why the Lucky Stiff
9
+ Dan Kubb
10
+ MenTaLguY
11
+ Filipe Lautert
12
+ Rick Olson
13
+ Wayne E. Seguin
14
+ Kirk Haines
15
+ Bradley Taylor
16
+ Matt Pelletier
17
+ Ry Dahl
18
+ Nick Sieger
19
+ Evan Weaver
20
+ Marc-André Cournoyer
data/DESIGN ADDED
@@ -0,0 +1,80 @@
1
+ == Design
2
+
3
+ * Simplicity: Unicorn is a traditional UNIX prefork web server.
4
+ No threads are used at all, this makes applications easier to debug
5
+ and fix. When your application goes awry, a BOFH can just
6
+ "kill -9" the runaway worker process without worrying about tearing
7
+ all clients down, just one. Only UNIX-like systems supporting
8
+ fork() and file descriptor inheritance are supported.
9
+
10
+ * The Ragel->C HTTP parser is taken from Mongrel. This is the
11
+ only non-Ruby part and there are no plans to add any more
12
+ non-Ruby components.
13
+
14
+ * All HTTP protocol parsing and I/O is done just like Mongrel:
15
+ 1. read/parse HTTP request in full
16
+ 2. call Rack application
17
+ 3. write HTTP response back to the client
18
+
19
+ * Like Mongrel, neither keepalive nor pipelining are supported.
20
+ These aren't needed since Unicorn is only designed to serve
21
+ fast, low-latency clients directly. Do one thing, do it well;
22
+ let nginx handle slow clients.
23
+
24
+ * Configuration is purely in Ruby and eval(). Ruby is less
25
+ ambiguous than YAML and lets lambdas for
26
+ before_fork/after_fork/before_exec hooks be defined inline. An
27
+ optional, separate config_file may be used to modify supported
28
+ configuration changes (and also gives you plenty of rope if you RTFS
29
+ :>)
30
+
31
+ * One master process spawns and reaps worker processes. The
32
+ Rack application itself is called only within the worker process (but
33
+ can be loaded within the master). A copy-on-write friendly garbage
34
+ collector like Ruby Enterprise Edition can be used to minimize memory
35
+ usage along with the "preload_app true" directive.
36
+
37
+ * The number of worker processes should be scaled to the number of
38
+ CPUs, memory or even spindles you have. If you have an existing
39
+ Mongrel cluster, using the same amount of processes should work.
40
+ Let a full-HTTP-request-buffering reverse proxy like nginx manage
41
+ concurrency to thousands of slow clients for you. Unicorn scaling
42
+ should only be concerned about limits of your backend system(s).
43
+
44
+ * Load balancing between worker processes is done by the OS kernel.
45
+ All workers share a common set of listener sockets and does
46
+ non-blocking accept() on them. The kernel will decide which worker
47
+ process to give a socket to and workers will sleep if there is
48
+ nothing to accept().
49
+
50
+ * Since non-blocking accept() is used, there can be a thundering
51
+ herd when an occasional client connects when application
52
+ *is not busy*. The thundering herd problem should not affect
53
+ applications that are running all the time since worker processes
54
+ will only select()/accept() outside of the application dispatch.
55
+
56
+ * Blocking I/O is used for clients. This allows a simpler code path
57
+ to be followed within the Ruby interpreter and fewer syscalls.
58
+ Applications that use threads should continue to work if Unicorn
59
+ is serving LAN or localhost clients.
60
+
61
+ * Timeout implementation is done via fchmod(2) in each worker
62
+ on a shared file descriptor to update st_ctime on the inode.
63
+ Master process wakeups for checking on timeouts is throttled
64
+ one a second to minimize the performance impact and simplify
65
+ the code path within the worker. Neither futimes(2) nor
66
+ pwrite(2)/pread(2) are supported by base MRI, nor are they as
67
+ portable on UNIX systems as fchmod(2).
68
+
69
+ * SIGKILL is used to terminate the timed-out workers as reliably
70
+ as possible on a UNIX system.
71
+
72
+ * The poor performance of select() on large FD sets is avoided
73
+ as few file descriptors are used in each worker.
74
+ There should be no gain from moving to highly scalable but
75
+ unportable event notification solutions for watching few
76
+ file descriptors.
77
+
78
+ * If the master process dies unexpectedly for any reason,
79
+ workers will notice within :timeout/2 seconds and follow
80
+ the master to its death.
data/GNUmakefile ADDED
@@ -0,0 +1,111 @@
1
+ # use GNU Make to run tests in parallel, and without depending on Rubygems
2
+ all:: test
3
+ ruby = ruby
4
+ -include local.mk
5
+ ruby_bin := $(shell which $(ruby))
6
+ ifeq ($(DLEXT),) # "so" for Linux
7
+ DLEXT := $(shell $(ruby) -rrbconfig -e 'puts Config::CONFIG["DLEXT"]')
8
+ endif
9
+ ifeq ($(RUBY_VERSION),)
10
+ RUBY_VERSION := $(shell $(ruby) -e 'puts RUBY_VERSION')
11
+ endif
12
+
13
+ # dunno how to implement this as concisely in Ruby, and hell, I love awk
14
+ awk_slow := awk '/def test_/{print FILENAME"--"$$2".n"}' 2>/dev/null
15
+
16
+ slow_tests := test/unit/test_server.rb test/exec/test_exec.rb
17
+ log_suffix = .$(RUBY_VERSION).log
18
+ T := $(filter-out $(slow_tests),$(wildcard test/*/test*.rb))
19
+ T_n := $(shell $(awk_slow) $(slow_tests))
20
+ T_log := $(subst .rb,$(log_suffix),$(T))
21
+ T_n_log := $(subst .n,$(log_suffix),$(T_n))
22
+ test_prefix = $(CURDIR)/test/install-$(RUBY_VERSION)
23
+
24
+ http11_deps := $(addprefix ext/unicorn/http11/, \
25
+ ext_help.h http11.c http11_parser.c http11_parser.h \
26
+ http11_parser.rl http11_parser_common.rl)
27
+ inst_deps := $(wildcard bin/*) $(wildcard lib/*.rb) \
28
+ $(wildcard lib/*/*.rb) $(http11_deps)
29
+
30
+ ext/unicorn/http11/http11_parser.c: ext/unicorn/http11/http11_parser.rl
31
+ cd $(@D) && ragel $(<F) -C -G2 -o $(@F)
32
+ ext/unicorn/http11/Makefile: ext/unicorn/http11/extconf.rb
33
+ cd $(@D) && $(ruby) $(<F)
34
+ ext/unicorn/http11/http11.$(DLEXT): $(http11_deps) ext/unicorn/http11/Makefile
35
+ $(MAKE) -C $(@D)
36
+ lib/unicorn/http11.$(DLEXT): ext/unicorn/http11/http11.$(DLEXT)
37
+ @mkdir -p lib
38
+ install -m644 $< $@
39
+ http11: lib/unicorn/http11.$(DLEXT)
40
+
41
+ $(test_prefix)/.stamp: $(inst_deps)
42
+ $(MAKE) clean-http11
43
+ $(MAKE) install-test
44
+ > $@
45
+
46
+ install-test:
47
+ mkdir -p $(test_prefix)/.ccache
48
+ tar c bin ext lib GNUmakefile | (cd $(test_prefix) && tar x)
49
+ $(MAKE) -C $(test_prefix) http11 shebang
50
+
51
+ # this is only intended to be run within $(test_prefix)
52
+ shebang: bin/unicorn
53
+ $(ruby) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $<
54
+
55
+ t_log := $(T_log) $(T_n_log)
56
+ test: $(T) $(T_n)
57
+ @cat $(t_log) | $(ruby) test/aggregate.rb
58
+ @$(RM) $(t_log)
59
+
60
+ slow-tests: $(slow_tests)
61
+ $(slow_tests):
62
+ @$(MAKE) $(shell $(awk_slow) $@)
63
+
64
+ TEST_OPTS = -v
65
+ run_test = @echo '*** $(arg) ***'; \
66
+ setsid $(ruby) $(arg) $(TEST_OPTS) >$(t) 2>&1 || \
67
+ (cat >&2 < $(t); exit 1)
68
+
69
+ %.n: arg = $(subst .n,,$(subst --, -n ,$@))
70
+ %.n: t = $(subst .n,$(log_suffix),$@)
71
+ %.n: export PATH := $(test_prefix)/bin:$(PATH)
72
+ %.n: export RUBYLIB := $(test_prefix)/lib:$(RUBYLIB)
73
+ %.n: $(test_prefix)/.stamp
74
+ $(run_test)
75
+
76
+ $(T): arg = $@
77
+ $(T): t = $(subst .rb,$(log_suffix),$@)
78
+ $(T): export PATH := $(test_prefix)/bin:$(PATH)
79
+ $(T): export RUBYLIB := $(test_prefix)/lib:$(RUBYLIB)
80
+ $(T): $(test_prefix)/.stamp
81
+ $(run_test)
82
+
83
+ install: bin/unicorn
84
+ $(prep_setup_rb)
85
+ git diff --quiet $<
86
+ $(ruby) setup.rb all
87
+ git checkout $<
88
+ $(prep_setup_rb)
89
+
90
+ clean-http11:
91
+ -$(MAKE) -C ext/unicorn/http11 clean
92
+ $(RM) ext/unicorn/http11/Makefile lib/unicorn/http11.$(DLEXT)
93
+
94
+ setup_rb_files := .config InstalledFiles
95
+ prep_setup_rb := @-$(RM) $(setup_rb_files);$(MAKE) -C ext/unicorn/http11 clean
96
+
97
+ clean: clean-http11
98
+ $(RM) $(setup_rb_files)
99
+ $(RM) $(t_log)
100
+ $(RM) -r $(test_prefix)
101
+
102
+ Manifest:
103
+ git ls-files > $@+
104
+ cmp $@+ $@ || mv $@+ $@
105
+ $(RM) -f $@+
106
+
107
+ # using rdoc 2.4.1
108
+ doc: .document
109
+ rdoc -Na -m README -t "$(shell sed -ne '1s/^= //p' README)"
110
+
111
+ .PHONY: doc $(T) $(slow_tests) Manifest
data/LICENSE ADDED
@@ -0,0 +1,53 @@
1
+ Unicorn Web Server (unicorn) is copyrighted free software by Eric Wong
2
+ (normalperson@yhbt.net) and contributors. You can redistribute it
3
+ and/or modify it under either the terms of the GPL2 or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise make them
13
+ Freely Available, such as by posting said modifications to Usenet or an
14
+ equivalent medium, or by allowing the author to include your
15
+ modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) rename any non-standard executables so the names do not conflict with
21
+ standard executables, which must also be provided.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or executable
26
+ form, provided that you do at least ONE of the following:
27
+
28
+ a) distribute the executables and library files of the software,
29
+ together with instructions (in the manual page or equivalent) on where
30
+ to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of the
33
+ software.
34
+
35
+ c) give non-standard executables non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under this terms.
43
+
44
+ 5. The scripts and library files supplied as input to or produced as
45
+ output from the software do not automatically fall under the
46
+ copyright of the software, but belong to whomever generated them,
47
+ and may be sold commercially, and may be aggregated with this
48
+ software.
49
+
50
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
51
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
52
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53
+ PURPOSE.
data/Manifest ADDED
@@ -0,0 +1,41 @@
1
+ .document
2
+ .gitignore
3
+ CHANGELOG
4
+ CONTRIBUTORS
5
+ DESIGN
6
+ GNUmakefile
7
+ LICENSE
8
+ Manifest
9
+ README
10
+ Rakefile
11
+ SIGNALS
12
+ TODO
13
+ bin/unicorn
14
+ ext/unicorn/http11/ext_help.h
15
+ ext/unicorn/http11/extconf.rb
16
+ ext/unicorn/http11/http11.c
17
+ ext/unicorn/http11/http11_parser.c
18
+ ext/unicorn/http11/http11_parser.h
19
+ ext/unicorn/http11/http11_parser.rl
20
+ ext/unicorn/http11/http11_parser_common.rl
21
+ lib/unicorn.rb
22
+ lib/unicorn/configurator.rb
23
+ lib/unicorn/const.rb
24
+ lib/unicorn/http_request.rb
25
+ lib/unicorn/http_response.rb
26
+ lib/unicorn/socket.rb
27
+ lib/unicorn/util.rb
28
+ setup.rb
29
+ test/aggregate.rb
30
+ test/benchmark/previous.rb
31
+ test/benchmark/simple.rb
32
+ test/benchmark/utils.rb
33
+ test/exec/README
34
+ test/exec/test_exec.rb
35
+ test/test_helper.rb
36
+ test/tools/trickletest.rb
37
+ test/unit/test_configurator.rb
38
+ test/unit/test_http_parser.rb
39
+ test/unit/test_response.rb
40
+ test/unit/test_server.rb
41
+ test/unit/test_upload.rb
data/README ADDED
@@ -0,0 +1,73 @@
1
+ = Unicorn: UNIX + LAN/localhost-only fork of Mongrel
2
+
3
+ Only run this behind a full-HTTP-request-buffering reverse proxy if
4
+ you're serving slow clients. That said, nginx is the only reverse
5
+ proxy we know of that meets this requirement.
6
+
7
+ == Features
8
+
9
+ * process management: Unicorn will reap and restart workers that
10
+ die because of broken apps and there is no need to manage
11
+ multiple processes yourself.
12
+
13
+ * does not care if your application is thread-safe or not, workers
14
+ all run within their own isolated address space and only serve one
15
+ client at a time...
16
+
17
+ * able to listen on multiple interfaces, including UNIX sockets,
18
+ each worker process can also bind to a private port via the
19
+ after_fork hook for easy debugging.
20
+
21
+ * supports all Rack applications
22
+
23
+ * nginx-style binary re-execution without losing connections.
24
+ You can upgrade unicorn, your entire application, libraries
25
+ and even your Ruby interpreter as long as unicorn is
26
+ installed in the same path.
27
+
28
+ * before_fork and after_fork hooks in case your application
29
+ has special needs when dealing with forked processes.
30
+
31
+ * builtin log rotation via USR1 signal
32
+
33
+ * Ruby 1.9-compatible (at least the test cases all pass :>)
34
+
35
+ == License
36
+
37
+ Unicorn is copyright 2009 Eric Wong and contributors.
38
+ It is based on Mongrel:
39
+
40
+ Mongrel is copyright 2007 Zed A. Shaw and contributors. It is licensed
41
+ under the Ruby license and the GPL2. See the include LICENSE file for
42
+ details.
43
+
44
+ == Install
45
+
46
+ The library consists of a C extension so you'll need a C compiler or at
47
+ least a friend who can build it for you.
48
+
49
+ Finally, the source includes a setup.rb for those who hate RubyGems.
50
+
51
+ You can get the source via git via the following locations:
52
+
53
+ git://git.bogomips.org/unicorn.git
54
+
55
+ http://git.bogomips.org/unicorn.git
56
+
57
+ == Usage
58
+
59
+ Unicorn will look for the config.ru file used by rackup in APP_ROOT.
60
+ Optionally, it can use a config file specified by the --config-file/-c
61
+ command-line switch.
62
+
63
+ Unicorn should be capable of running all Rack applications. Since this
64
+ is a preforking webserver, you do not have to worry about thread-safety
65
+ of your application or libraries. However, your Rack application may use
66
+ threads internally (and should even be able to continue running threads
67
+ after the request is complete).
68
+
69
+ == Contact
70
+
71
+ Newsgroup and mailing list coming, or it'll be a part of the Mongrel project...
72
+
73
+ Email Eric Wong at normalperson@yhbt.net for now.
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+
2
+ require 'rubygems'
3
+ require 'echoe'
4
+
5
+ Echoe.new("unicorn") do |p|
6
+ p.summary = "A small fast HTTP library and server for Rack applications."
7
+ p.author = "Eric Wong"
8
+ p.email = "normalperson@yhbt.net"
9
+ p.clean_pattern = ['ext/unicorn/http11/*.{bundle,so,o,obj,pdb,lib,def,exp}',
10
+ 'lib/*.{bundle,so,o,obj,pdb,lib,def,exp}',
11
+ 'ext/unicorn/http11/Makefile',
12
+ 'pkg', 'lib/*.bundle', '*.gem',
13
+ 'site/output', '.config', 'coverage',
14
+ 'test_*.log', 'log', 'doc']
15
+ p.url = "http://unicorn.bogomips.org"
16
+ p.ignore_pattern = /^(pkg|site|projects|doc|log)|CVS|\.log/
17
+ p.need_tar_gz = false
18
+ p.need_tgz = true
19
+
20
+ p.extension_pattern = ["ext/**/extconf.rb"]
21
+
22
+ # Eric hasn't bothered to figure out running exec tests properly
23
+ # from Rake, but Eric prefers GNU make to Rake for tests anyways...
24
+ p.test_pattern = [ 'test/unit/test*.rb' ]
25
+ end
26
+
27
+ #### Ragel builder
28
+
29
+ desc "Rebuild the Ragel sources"
30
+ task :ragel do
31
+ Dir.chdir "ext/unicorn/http11" do
32
+ target = "http11_parser.c"
33
+ File.unlink target if File.exist? target
34
+ sh "ragel http11_parser.rl -C -G2 -o #{target}"
35
+ raise "Failed to build C source" unless File.exist? target
36
+ end
37
+ end