zbatery 0.0.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/lib/zbatery.rb ADDED
@@ -0,0 +1,154 @@
1
+ # -*- encoding: binary -*-
2
+ require 'rainbows'
3
+
4
+ module Zbatery
5
+
6
+ # current version of Zbatery
7
+ VERSION = "0.0.0"
8
+
9
+ class << self
10
+
11
+ # runs the Zbatery HttpServer with +app+ and +options+ and does
12
+ # not return until the server has exited.
13
+ def run(app, options = {})
14
+ HttpServer.new(app, options).start.join
15
+ end
16
+ end
17
+
18
+ Rainbows::Const::RACK_DEFAULTS["SERVER_SOFTWARE"] = "Zbatery #{VERSION}"
19
+
20
+ # true if our Ruby implementation supports unlinked files
21
+ UnlinkedIO = begin
22
+ tmp = Unicorn::Util.tmpio
23
+ tmp.chmod(0)
24
+ tmp.close
25
+ true
26
+ rescue
27
+ false
28
+ end
29
+
30
+ # we don't actually fork workers, but allow using the
31
+ # {before,after}_fork hooks found in Unicorn/Rainbows!
32
+ # config files...
33
+ FORK_HOOK = lambda { |_,_| }
34
+
35
+ class HttpServer < Rainbows::HttpServer
36
+
37
+ # only used if no concurrency model is specified
38
+ def worker_loop(worker)
39
+ init_worker_process(worker)
40
+ begin
41
+ ret = IO.select(LISTENERS, nil, nil, nil) and
42
+ ret.first.each do |sock|
43
+ begin
44
+ process_client(sock.accept_nonblock)
45
+ rescue Errno::EAGAIN, Errno::ECONNABORTED
46
+ end
47
+ end
48
+ rescue Errno::EINTR
49
+ rescue Errno::EBADF, TypeError
50
+ break
51
+ rescue => e
52
+ Rainbows::Error.listen_loop(e)
53
+ end while G.alive
54
+ end
55
+
56
+ # no-op
57
+ def maintain_worker_count; end
58
+
59
+ # can't just do a graceful exit if reopening logs fails, so we just
60
+ # continue on...
61
+ def reopen_logs
62
+ logger.info "reopening logs"
63
+ Unicorn::Util.reopen_logs
64
+ logger.info "done reopening logs"
65
+ rescue => e
66
+ logger.error "failed reopening logs #{e.message}"
67
+ end
68
+
69
+ def join
70
+ begin
71
+ trap(:INT) { stop(false) } # Mongrel trapped INT for Win32...
72
+
73
+ # try these anyways regardless of platform...
74
+ trap(:TERM) { stop(false) }
75
+ trap(:QUIT) { stop }
76
+ trap(:USR1) { reopen_logs }
77
+ trap(:USR2) { reexec }
78
+
79
+ # no other way to reliably switch concurrency models...
80
+ trap(:HUP) { reexec; stop }
81
+
82
+ # technically feasible in some cases, just not sanely supportable:
83
+ %w(TTIN TTOU WINCH).each do |sig|
84
+ trap(sig) { logger.info "SIG#{sig} is not handled by Zbatery" }
85
+ end
86
+ rescue => e # hopefully ignores errors on Win32...
87
+ logger.error "failed to setup signal handler: #{e.message}"
88
+ end
89
+ worker = Worker.new(0, $stdout)
90
+ before_fork.call(self, worker)
91
+ worker_loop(worker) # runs forever
92
+ end
93
+
94
+ def stop(graceful = true)
95
+ Rainbows::G.quit!
96
+ exit!(0) unless graceful
97
+ end
98
+
99
+ def before_fork
100
+ hook = super
101
+ hook == FORK_HOOK or
102
+ logger.warn "calling before_fork without forking"
103
+ hook
104
+ end
105
+
106
+ def after_fork
107
+ hook = super
108
+ hook == FORK_HOOK or
109
+ logger.warn "calling after_fork without having forked"
110
+ hook
111
+ end
112
+ end
113
+ end
114
+
115
+ # :stopdoc:
116
+ # override stuff we don't need or can't use portably
117
+ module Rainbows
118
+
119
+ module Base
120
+ # master == worker in our case
121
+ def init_worker_process(worker)
122
+ after_fork.call(self, worker)
123
+ build_app! unless preload_app
124
+ logger.info "Zbatery #@use worker_connections=#@worker_connections"
125
+ end
126
+ end
127
+
128
+ # we can't/don't need to do the fchmod heartbeat Unicorn/Rainbows! does
129
+ def G.tick
130
+ alive
131
+ end
132
+ end
133
+
134
+ module Unicorn
135
+
136
+ class Configurator
137
+ DEFAULTS[:before_fork] = DEFAULTS[:after_fork] = Zbatery::FORK_HOOK
138
+ end
139
+
140
+ unless Zbatery::UnlinkedIO
141
+ require 'tempfile'
142
+ class Util
143
+
144
+ # Tempfiles should get automatically unlinked by GC
145
+ def self.tmpio
146
+ fp = Tempfile.new("zbatery")
147
+ fp.binmode
148
+ fp.sync = true
149
+ fp
150
+ end
151
+ end
152
+ end
153
+
154
+ end
data/local.mk.sample ADDED
@@ -0,0 +1,78 @@
1
+
2
+ # this is the local.mk file used by Eric Wong on his dev boxes.
3
+ # GNUmakefile will source local.mk in the top-level source tree
4
+ # if it is present.
5
+ #
6
+ # This is depends on a bunch of GNU-isms from bash, sed, touch.
7
+
8
+ RSYNC = rsync
9
+ DLEXT := so
10
+ gems := rack-1.0.1
11
+ # gems += unicorn-0.95.2 # installed via setup.rb
12
+ # gems += rainbows-0.8.0 # installed via setup.rb
13
+ gems += rev-0.3.1
14
+ gems += iobuffer-0.1.1
15
+ gems += eventmachine-0.12.10
16
+ gems += async_sinatra-0.1.5 sinatra-0.9.4
17
+
18
+ # Avoid loading rubygems to speed up tests because gmake is
19
+ # fork+exec heavy with Ruby.
20
+ prefix = $(HOME)
21
+ ifeq ($(r19),)
22
+ RUBY := $(prefix)/bin/ruby
23
+ gem_paths := $(addprefix $(prefix)/lib/ruby/gems/1.8/gems/,$(gems))
24
+ else
25
+ prefix := $(prefix)/ruby-1.9
26
+ export PATH := $(prefix)/bin:$(PATH)
27
+ RUBY := $(prefix)/bin/ruby --disable-gems
28
+ gems += case-0.5 revactor-0.1.5
29
+ gem_paths := $(addprefix $(prefix)/lib/ruby/gems/1.9.1/gems/,$(gems))
30
+ endif
31
+
32
+ ifdef gem_paths
33
+ sp :=
34
+ sp +=
35
+ export RUBYLIB := $(subst $(sp),:,$(addsuffix /lib,$(gem_paths)))
36
+ endif
37
+
38
+ # pipefail is THE reason to use bash (v3+) or never revisions of ksh93
39
+ # SHELL := /bin/bash -e -o pipefail
40
+ SHELL := /bin/ksh93 -e -o pipefail
41
+
42
+ # trace execution of tests
43
+ # TRACER = strace -f -o $(t_pfx).strace -s 100000
44
+ TRACER = /usr/bin/time -v -o $(t_pfx).time
45
+
46
+ full-test: test-18 test-19
47
+ test-18:
48
+ $(MAKE) test 2>&1 | sed -e 's!^!1.8 !'
49
+ test-19:
50
+ $(MAKE) test r19=t 2>&1 | sed -e 's!^!1.9 !'
51
+
52
+ latest: NEWS
53
+ @awk 'BEGIN{RS="=== ";ORS=""}NR==2{sub(/\n$$/,"");print RS""$$0 }' < $<
54
+
55
+ # publishes docs to http://zbatery.bogomip.org/
56
+ publish_doc:
57
+ -git set-file-times
58
+ $(RM) -r doc ChangeLog NEWS
59
+ $(MAKE) doc LOG_VERSION=$(shell git tag -l | tail -1)
60
+ $(MAKE) -s latest > doc/LATEST
61
+ find doc/images doc/js -type f | \
62
+ TZ=UTC xargs touch -d '1970-01-01 00:00:00' doc/rdoc.css
63
+ $(MAKE) doc_gz
64
+ chmod 644 $$(find doc -type f)
65
+ $(RSYNC) -av doc/ dcvr:/srv/zbatery/
66
+ git ls-files | xargs touch
67
+
68
+ # Create gzip variants of the same timestamp as the original so nginx
69
+ # "gzip_static on" can serve the gzipped versions directly.
70
+ doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.\(gif\|jpg\|png\|gz\)$$')
71
+ doc_gz:
72
+ touch doc/NEWS.atom.xml -d "$$(awk 'NR==1{print $$4,$$5,$$6}' NEWS)"
73
+ for i in $(docs); do \
74
+ gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
75
+
76
+ # launches any of the following shells with RUBYLIB set
77
+ irb sh bash ksh:
78
+ $@
@@ -0,0 +1,187 @@
1
+ .TH zbatery 1 "December 9, 2009" "Zbatery User Manual"
2
+ .SH NAME
3
+ .PP
4
+ zbatery - rackup-like command to launch Zbatery
5
+ .SH SYNOPSIS
6
+ .PP
7
+ zbatery [-c CONFIG_FILE] [-E RACK_ENV] [-D] [RACKUP_FILE]
8
+ .SH DESCRIPTION
9
+ .PP
10
+ A rackup(1)-like command to launch Rack applications using Zbatery.
11
+ It is expected to be started in your application root (APP_ROOT),
12
+ but \[lq]Dir.chdir\[rq] may also be executed in the CONFIG_FILE or
13
+ RACKUP_FILE.
14
+ .PP
15
+ While Zbatery takes a myriad of command-line options for
16
+ compatibility with ruby(1) and rackup(1), it is recommended to
17
+ stick to the few command-line options specified in the SYNOPSIS and
18
+ use the CONFIG_FILE as much as possible.
19
+ .SH RACKUP FILE
20
+ .PP
21
+ This defaults to "config.ru" in APP_ROOT.
22
+ It should be the same file used by rackup(1) and other Rack
23
+ launchers, it uses the \f[I]Rack::Builder\f[] DSL.
24
+ .PP
25
+ Embedded command-line options are mostly parsed for compatibility
26
+ with rackup(1) but strongly discouraged.
27
+ .SH UNICORN OPTIONS
28
+ .TP
29
+ .B -c, --config-file CONFIG_FILE
30
+ Path to the Unicorn-specific config file.
31
+ The config file is implemented as a Ruby DSL, so Ruby code may
32
+ executed (e.g.
33
+ \[lq]Dir.chdir\[rq], \[lq]Process::UID.change_privilege\[rq]).
34
+ See the RDoc/ri for the \f[I]Unicorn::Configurator\f[] class for
35
+ the full list of directives available from the DSL.
36
+ .RS
37
+ .RE
38
+ .TP
39
+ .B -D, --daemonize
40
+ Run daemonized in the background.
41
+ The process is detached from the controlling terminal and stdin is
42
+ redirected to \[lq]/dev/null\[rq].
43
+ Unlike many common UNIX daemons, we do not chdir to "/" upon
44
+ daemonization to allow more control over the startup/upgrade
45
+ process.
46
+ Unless specified in the CONFIG_FILE, stderr and stdout will also be
47
+ redirected to \[lq]/dev/null\[rq].
48
+ .RS
49
+ .RE
50
+ .TP
51
+ .B -E, --env RACK_ENV
52
+ Run under the given RACK_ENV.
53
+ See the RACK ENVIRONMENT section for more details.
54
+ .RS
55
+ .RE
56
+ .TP
57
+ .B -l, --listen ADDRESS
58
+ Listens on a given ADDRESS.
59
+ ADDRESS may be in the form of HOST:PORT or PATH, HOST:PORT is taken
60
+ to mean a TCP socket and PATH is meant to be a path to a UNIX
61
+ domain socket.
62
+ Defaults to \[lq]0.0.0.0:8080\[rq] (all addresses on TCP port 8080)
63
+ For production deployments, specifying the \[lq]listen\[rq]
64
+ directive in CONFIG_FILE is recommended as it allows fine-tuning of
65
+ socket options.
66
+ .RS
67
+ .RE
68
+ .SH RACKUP COMPATIBILITY OPTIONS
69
+ .TP
70
+ .B -o, --host HOST
71
+ Listen on a TCP socket belonging to HOST, default is
72
+ \[lq]0.0.0.0\[rq] (all addresses).
73
+ If specified multiple times on the command-line, only the
74
+ last-specified value takes effect.
75
+ This option only exists for compatibility with the rackup(1)
76
+ command, use of \[lq]-l\[rq]/\[lq]--listen\[rq] switch is
77
+ recommended instead.
78
+ .RS
79
+ .RE
80
+ .TP
81
+ .B -p, --port PORT
82
+ Listen on the specified TCP PORT, default is 8080.
83
+ If specified multiple times on the command-line, only the
84
+ last-specified value takes effect.
85
+ This option only exists for compatibility with the rackup(1)
86
+ command, use of \[lq]-l\[rq]/\[lq]--listen\[rq] switch is
87
+ recommended instead.
88
+ .RS
89
+ .RE
90
+ .TP
91
+ .B -s, --server SERVER
92
+ No-op, this exists only for compatibility with rackup(1).
93
+ .RS
94
+ .RE
95
+ .SH RUBY OPTIONS
96
+ .TP
97
+ .B -e, --eval LINE
98
+ Evaluate a LINE of Ruby code.
99
+ This evaluation happens immediately as the command-line is being
100
+ parsed.
101
+ .RS
102
+ .RE
103
+ .TP
104
+ .B -d, --debug
105
+ Turn on debug mode, the $DEBUG variable is set to true.
106
+ .RS
107
+ .RE
108
+ .TP
109
+ .B -w, --warn
110
+ Turn on verbose warnings, the $VERBOSE variable is set to true.
111
+ .RS
112
+ .RE
113
+ .TP
114
+ .B -I, --include PATH
115
+ specify $LOAD_PATH.
116
+ PATH will be prepended to $LOAD_PATH.
117
+ The \[aq]:\[aq] character may be used to delimit multiple
118
+ directories.
119
+ This directive may be used more than once.
120
+ Modifications to $LOAD_PATH take place immediately and in the order
121
+ they were specified on the command-line.
122
+ .RS
123
+ .RE
124
+ .TP
125
+ .B -r, --require LIBRARY
126
+ require a specified LIBRARY before executing the application.
127
+ The "require" statement will be executed immediately and in the
128
+ order they were specified on the command-line.
129
+ .RS
130
+ .RE
131
+ .SH SIGNALS
132
+ .PP
133
+ The following UNIX signals may be sent to Zbatery (only supported
134
+ on UNIX):
135
+ .IP \[bu] 2
136
+ HUP - reexecute the binary and exit the current one
137
+ .IP \[bu] 2
138
+ INT/TERM - quick shutdown, quit immediately
139
+ .IP \[bu] 2
140
+ QUIT - graceful shutdown, waits for current requests before exiting
141
+ .IP \[bu] 2
142
+ USR1 - reopen all logs owned by the master and all workers See
143
+ Unicorn::Util.reopen_logs for what is considered a log.
144
+ .IP \[bu] 2
145
+ USR2 - reexecute the running binary.
146
+ A separate QUIT should be sent to the original process once the
147
+ child is verified to be up and running.
148
+ .SH RACK ENVIRONMENT
149
+ .PP
150
+ Accepted values of RACK_ENV and the middleware they automatically
151
+ load (outside of RACKUP_FILE) are exactly as those in rackup(1):
152
+ .IP \[bu] 2
153
+ development - loads Rack::CommonLogger, Rack::ShowExceptions, and
154
+ Rack::Lint middleware
155
+ .IP \[bu] 2
156
+ deployment - loads Rack::CommonLogger middleware
157
+ .IP \[bu] 2
158
+ none - loads no middleware at all, relying entirely on RACKUP_FILE
159
+ .PP
160
+ All unrecognized values for RACK_ENV are assumed to be
161
+ \[lq]none\[rq].
162
+ Production deployments are strongly encouraged to use
163
+ \[lq]deployment\[rq] or \[lq]none\[rq] for maximum performance.
164
+ .PP
165
+ Note that the Rack::ContentLength and Rack::Chunked middlewares are
166
+ never loaded by default.
167
+ If needed, they should be individually specified in the
168
+ RACKUP_FILE, some frameworks do not require them.
169
+ .SH SEE ALSO
170
+ .IP \[bu] 2
171
+ unicorn(1)
172
+ .IP \[bu] 2
173
+ rainbows(1)
174
+ .IP \[bu] 2
175
+ \f[I]Rack::Builder\f[] ri/RDoc
176
+ .IP \[bu] 2
177
+ \f[I]Unicorn::Configurator\f[] ri/RDoc
178
+ .IP \[bu] 2
179
+ Zbatery RDoc (http://zbatery.bogomip.org/)
180
+ .IP \[bu] 2
181
+ Rack RDoc (http://rack.rubyforge.org/doc/)
182
+ .IP \[bu] 2
183
+ Rackup HowTo (http://wiki.github.com/rack/rack/tutorial-rackup-howto)
184
+ .IP \[bu] 2
185
+ Rainbows! RDoc (http://rainbows.rubyforge.org/)
186
+ .SH AUTHOR
187
+ Zbatery hackers <rainbows-talk@rubyforge.org>