unicorn 0.1.0

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.
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