unicorn 0.7.0 → 0.7.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.
- data/.document +1 -0
- data/CHANGELOG +1 -0
- data/GNUmakefile +4 -2
- data/Manifest +3 -0
- data/README +2 -2
- data/TODO +0 -2
- data/TUNING +63 -0
- data/examples/init.sh +54 -0
- data/lib/unicorn.rb +3 -3
- data/lib/unicorn/app/exec_cgi.rb +3 -3
- data/lib/unicorn/app/old_rails.rb +2 -2
- data/lib/unicorn/configurator.rb +24 -22
- data/lib/unicorn/const.rb +1 -1
- data/lib/unicorn/http_response.rb +1 -1
- data/lib/unicorn/util.rb +10 -5
- data/test/unit/test_request.rb +0 -5
- data/test/unit/test_response.rb +9 -1
- data/test/unit/test_upload.rb +18 -0
- data/test/unit/test_util.rb +87 -0
- data/unicorn.gemspec +6 -6
- metadata +15 -9
data/.document
CHANGED
data/CHANGELOG
CHANGED
data/GNUmakefile
CHANGED
@@ -53,8 +53,10 @@ $(test_prefix)/.stamp: $(inst_deps)
|
|
53
53
|
$(MAKE) -C $(test_prefix) http11 shebang
|
54
54
|
> $@
|
55
55
|
|
56
|
+
bins := $(wildcard bin/*)
|
57
|
+
|
56
58
|
# this is only intended to be run within $(test_prefix)
|
57
|
-
shebang:
|
59
|
+
shebang: $(bins)
|
58
60
|
$(ruby) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $^
|
59
61
|
|
60
62
|
t_log := $(T_log) $(T_n_log)
|
@@ -97,7 +99,7 @@ $(T): export RUBYLIB := $(test_prefix)/lib:$(RUBYLIB)
|
|
97
99
|
$(T): $(test_prefix)/.stamp
|
98
100
|
$(run_test)
|
99
101
|
|
100
|
-
install:
|
102
|
+
install: $(bins)
|
101
103
|
$(prep_setup_rb)
|
102
104
|
$(RM) -r .install-tmp
|
103
105
|
mkdir .install-tmp
|
data/Manifest
CHANGED
@@ -11,8 +11,10 @@ README
|
|
11
11
|
Rakefile
|
12
12
|
SIGNALS
|
13
13
|
TODO
|
14
|
+
TUNING
|
14
15
|
bin/unicorn
|
15
16
|
bin/unicorn_rails
|
17
|
+
examples/init.sh
|
16
18
|
ext/unicorn/http11/ext_help.h
|
17
19
|
ext/unicorn/http11/extconf.rb
|
18
20
|
ext/unicorn/http11/http11.c
|
@@ -127,3 +129,4 @@ test/unit/test_server.rb
|
|
127
129
|
test/unit/test_signals.rb
|
128
130
|
test/unit/test_socket_helper.rb
|
129
131
|
test/unit/test_upload.rb
|
132
|
+
test/unit/test_util.rb
|
data/README
CHANGED
@@ -103,7 +103,7 @@ In RAILS_ROOT, run:
|
|
103
103
|
unicorn_rails
|
104
104
|
|
105
105
|
Unicorn will bind to all interfaces TCP port 8080 by default.
|
106
|
-
You may use the
|
106
|
+
You may use the +-l/--listen+ switch to bind to a different
|
107
107
|
address:port or a UNIX socket.
|
108
108
|
|
109
109
|
=== Configuration File(s)
|
@@ -111,7 +111,7 @@ address:port or a UNIX socket.
|
|
111
111
|
Unicorn will look for the config.ru file used by rackup in APP_ROOT.
|
112
112
|
|
113
113
|
For deployments, it can use a config file for Unicorn-specific options
|
114
|
-
specified by the
|
114
|
+
specified by the +--config-file/-c+ command-line switch. See
|
115
115
|
Unicorn::Configurator for the syntax of the Unicorn-specific options.
|
116
116
|
The default settings are designed for maximum out-of-the-box
|
117
117
|
compatibility with existing applications.
|
data/TODO
CHANGED
data/TUNING
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
= Tuning Unicorn
|
2
|
+
|
3
|
+
Unicorn performance is generally as good as a (mostly) Ruby web server
|
4
|
+
can provide. Most often the performance bottleneck is in the web
|
5
|
+
application running on Unicorn rather than Unicorn itself.
|
6
|
+
|
7
|
+
== Unicorn Configuration
|
8
|
+
|
9
|
+
See Unicorn::Configurator for details on the config file format.
|
10
|
+
|
11
|
+
* Setting a very low value for the :backlog parameter in "listen"
|
12
|
+
directives can allow failover to happen more quickly if your
|
13
|
+
cluster is configured for it.
|
14
|
+
|
15
|
+
* :rcvbuf and :sndbuf parameters generally do not need to be set for TCP
|
16
|
+
listeners under Linux 2.6 because auto-tuning is enabled. UNIX domain
|
17
|
+
sockets do not have auto-tuning buffer sizes; so increasing those will
|
18
|
+
allow syscalls and task switches to be saved for larger requests
|
19
|
+
and responses.
|
20
|
+
|
21
|
+
* Setting "preload_app true" can allow copy-on-write-friendly GC to
|
22
|
+
be used to save memory. It will probably not work out of the box with
|
23
|
+
applications that open sockets or perform random I/O on files.
|
24
|
+
Databases like TokyoCabinet use concurrency-safe pread()/pwrite()
|
25
|
+
functions for safe sharing of database file descriptors across
|
26
|
+
processes.
|
27
|
+
|
28
|
+
* On POSIX-compliant filesystems, it is safe for multiple threads or
|
29
|
+
processes to append to one log file as long as all the processes are
|
30
|
+
have them unbuffered (File#sync = true) or they are
|
31
|
+
record(line)-buffered in userspace.
|
32
|
+
|
33
|
+
* worker_processes should be scaled to the number of processes your
|
34
|
+
backend system(s) can support. DO NOT scale it to the number of
|
35
|
+
external network clients your application expects to be serving.
|
36
|
+
Unicorn is NOT for serving slow clients, that is the job of nginx.
|
37
|
+
|
38
|
+
== Kernel Parameters (Linux sysctl)
|
39
|
+
|
40
|
+
WARNING: Do not change system parameters unless you know what you're doing!
|
41
|
+
|
42
|
+
* net.core.rmem_max and net.core.wmem_max can increase the allowed
|
43
|
+
size of :rcvbuf and :sndbuf respectively. This is mostly only useful
|
44
|
+
for UNIX domain sockets which do not have auto-tuning buffer sizes.
|
45
|
+
|
46
|
+
* For load testing/benchmarking with UNIX domain sockets, you should
|
47
|
+
consider increasing net.core.somaxconn or else nginx will start
|
48
|
+
failing to connect under heavy load.
|
49
|
+
|
50
|
+
* If you're running out of local ports, consider lowering
|
51
|
+
net.ipv4.tcp_fin_timeout to 20-30 (default: 60 seconds). Also
|
52
|
+
consider widening the usable port range by changing
|
53
|
+
net.ipv4.ip_local_port_range.
|
54
|
+
|
55
|
+
* Setting net.ipv4.tcp_timestamps=1 will also allow setting
|
56
|
+
net.ipv4.tcp_tw_reuse=1 and net.ipv4.tcp_tw_recycle=1, which along
|
57
|
+
with the above settings can slow down port exhaustion. Not all
|
58
|
+
networks are compatible with these settings, check with your friendly
|
59
|
+
network administrator before changing these.
|
60
|
+
|
61
|
+
* Increasing the MTU size can reduce framing overhead for larger
|
62
|
+
transfers. One often-overlooked detail is that the loopback
|
63
|
+
device (usually "lo") can have its MTU increased, too.
|
data/examples/init.sh
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
set -u
|
3
|
+
set -e
|
4
|
+
# Example init script, this can be used with nginx, too,
|
5
|
+
# since nginx and unicorn accept the same signals
|
6
|
+
|
7
|
+
# Feel free to change any of the following variables for your app:
|
8
|
+
APP_ROOT=/home/x/my_app/current
|
9
|
+
PID=$APP_ROOT/tmp/pids/unicorn.pid
|
10
|
+
CMD="/usr/bin/unicorn -D -c $APP_ROOT/config/unicorn.rb"
|
11
|
+
INIT_CONF=$APP_ROOT/config/init.conf
|
12
|
+
|
13
|
+
test -f "$INIT_CONF" && . $INIT_CONF
|
14
|
+
|
15
|
+
old_pid="$PID.oldbin"
|
16
|
+
|
17
|
+
cd $APP_ROOT || exit 1
|
18
|
+
|
19
|
+
sig () {
|
20
|
+
test -s "$PID" && kill -$1 `cat $PID`
|
21
|
+
}
|
22
|
+
|
23
|
+
oldsig () {
|
24
|
+
test -s $old_pid && kill -$1 `cat $old_pid`
|
25
|
+
}
|
26
|
+
|
27
|
+
case $1 in
|
28
|
+
start)
|
29
|
+
sig 0 && echo >&2 "Already running" && exit 0
|
30
|
+
$CMD
|
31
|
+
;;
|
32
|
+
stop)
|
33
|
+
sig QUIT && exit 0
|
34
|
+
echo >&2 "Not running"
|
35
|
+
;;
|
36
|
+
force-stop)
|
37
|
+
sig TERM && exit 0
|
38
|
+
echo >&2 "Not running"
|
39
|
+
;;
|
40
|
+
restart|reload)
|
41
|
+
sig HUP && echo reloaded OK && exit 0
|
42
|
+
echo >&2 "Couldn't reload, starting '$CMD' instead"
|
43
|
+
$CMD
|
44
|
+
;;
|
45
|
+
upgrade)
|
46
|
+
sig USR2 && sleep 2 && sig 0 && oldsig QUIT && exit 0
|
47
|
+
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
|
48
|
+
$CMD
|
49
|
+
;;
|
50
|
+
*)
|
51
|
+
echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop>"
|
52
|
+
exit 1
|
53
|
+
;;
|
54
|
+
esac
|
data/lib/unicorn.rb
CHANGED
@@ -64,6 +64,7 @@ module Unicorn
|
|
64
64
|
# incoming requests on the socket.
|
65
65
|
def initialize(app, options = {})
|
66
66
|
@app = app
|
67
|
+
@pid = nil
|
67
68
|
@reexec_pid = 0
|
68
69
|
@init_listeners = options[:listeners] ? options[:listeners].dup : []
|
69
70
|
@config = Configurator.new(options.merge(:use_defaults => true))
|
@@ -375,9 +376,8 @@ module Unicorn
|
|
375
376
|
# is stale for >@timeout seconds, then we'll kill the corresponding
|
376
377
|
# worker.
|
377
378
|
def murder_lazy_workers
|
378
|
-
now = Time.now
|
379
379
|
WORKERS.each_pair do |pid, worker|
|
380
|
-
|
380
|
+
Time.now - worker.tempfile.ctime <= @timeout and next
|
381
381
|
logger.error "worker=#{worker.nr} PID:#{pid} is too old, killing"
|
382
382
|
kill_worker(:KILL, pid) # take no prisoners for @timeout violations
|
383
383
|
worker.tempfile.close rescue nil
|
@@ -444,7 +444,7 @@ module Unicorn
|
|
444
444
|
# traps for USR1, USR2, and HUP may be set in the @after_fork Proc
|
445
445
|
# by the user.
|
446
446
|
def init_worker_process(worker)
|
447
|
-
QUEUE_SIGS.each { |sig| trap(sig, '
|
447
|
+
QUEUE_SIGS.each { |sig| trap(sig, 'IGNORE') }
|
448
448
|
trap(:CHLD, 'DEFAULT')
|
449
449
|
SIG_QUEUE.clear
|
450
450
|
proc_name "worker[#{worker.nr}]"
|
data/lib/unicorn/app/exec_cgi.rb
CHANGED
@@ -69,9 +69,9 @@ module Unicorn::App
|
|
69
69
|
ENV['GATEWAY_INTERFACE'] = 'CGI/1.1'
|
70
70
|
env.keys.grep(/^HTTP_/) { |key| ENV[key] = env[key] }
|
71
71
|
|
72
|
-
IO.new(0).reopen(inp)
|
73
|
-
IO.new(1).reopen(out)
|
74
|
-
IO.new(2).reopen(err)
|
72
|
+
a = IO.new(0).reopen(inp)
|
73
|
+
b = IO.new(1).reopen(out)
|
74
|
+
c = IO.new(2).reopen(err)
|
75
75
|
exec(*@args)
|
76
76
|
end
|
77
77
|
|
@@ -19,8 +19,8 @@ class Unicorn::App::OldRails
|
|
19
19
|
cgi.body)
|
20
20
|
rescue Object => e
|
21
21
|
err = env['rack.errors']
|
22
|
-
|
23
|
-
e.backtrace.each { |line|
|
22
|
+
err.write("#{e} #{e.message}\n")
|
23
|
+
e.backtrace.each { |line| err.write("#{line}\n") }
|
24
24
|
end
|
25
25
|
cgi.out # finalize the response
|
26
26
|
cgi.rack_response
|
data/lib/unicorn/configurator.rb
CHANGED
@@ -143,12 +143,14 @@ module Unicorn
|
|
143
143
|
# handling the request/app.call/response cycle taking longer than
|
144
144
|
# this time period will be forcibly killed (via SIGKILL). This
|
145
145
|
# timeout is enforced by the master process itself and not subject
|
146
|
-
# to the scheduling limitations by the worker process.
|
146
|
+
# to the scheduling limitations by the worker process. Due the
|
147
|
+
# low-complexity, low-overhead implementation, timeouts of less
|
148
|
+
# than 3.0 seconds can be considered inaccurate and unsafe.
|
147
149
|
def timeout(seconds)
|
148
150
|
Numeric === seconds or raise ArgumentError,
|
149
151
|
"not numeric: timeout=#{seconds.inspect}"
|
150
|
-
seconds
|
151
|
-
"
|
152
|
+
seconds >= 3 or raise ArgumentError,
|
153
|
+
"too low: timeout=#{seconds.inspect}"
|
152
154
|
@set[:timeout] = seconds
|
153
155
|
end
|
154
156
|
|
@@ -179,32 +181,32 @@ module Unicorn
|
|
179
181
|
#
|
180
182
|
# +backlog+: this is the backlog of the listen() syscall.
|
181
183
|
#
|
182
|
-
#
|
183
|
-
#
|
184
|
-
#
|
185
|
-
#
|
186
|
-
#
|
187
|
-
#
|
184
|
+
# Some operating systems allow negative values here to specify the
|
185
|
+
# maximum allowable value. In most cases, this number is only
|
186
|
+
# recommendation and there are other OS-specific tunables and
|
187
|
+
# variables that can affect this number. See the listen(2)
|
188
|
+
# syscall documentation of your OS for the exact semantics of
|
189
|
+
# this.
|
188
190
|
#
|
189
|
-
#
|
190
|
-
#
|
191
|
-
#
|
191
|
+
# If you are running unicorn on multiple machines, lowering this number
|
192
|
+
# can help your load balancer detect when a machine is overloaded
|
193
|
+
# and give requests to a different machine.
|
192
194
|
#
|
193
|
-
#
|
195
|
+
# Default: 1024
|
194
196
|
#
|
195
197
|
# +rcvbuf+, +sndbuf+: maximum send and receive buffer sizes of sockets
|
196
198
|
#
|
197
|
-
#
|
198
|
-
#
|
199
|
-
#
|
200
|
-
#
|
199
|
+
# These correspond to the SO_RCVBUF and SO_SNDBUF settings which
|
200
|
+
# can be set via the setsockopt(2) syscall. Some kernels
|
201
|
+
# (e.g. Linux 2.4+) have intelligent auto-tuning mechanisms and
|
202
|
+
# there is no need (and it is sometimes detrimental) to specify them.
|
201
203
|
#
|
202
|
-
#
|
203
|
-
#
|
204
|
-
#
|
205
|
-
#
|
204
|
+
# See the socket API documentation of your operating system
|
205
|
+
# to determine the exact semantics of these settings and
|
206
|
+
# other operating system-specific knobs where they can be
|
207
|
+
# specified.
|
206
208
|
#
|
207
|
-
#
|
209
|
+
# Defaults: operating system defaults
|
208
210
|
def listen(address, opt = { :backlog => 1024 })
|
209
211
|
address = expand_addr(address)
|
210
212
|
if String === address
|
data/lib/unicorn/const.rb
CHANGED
@@ -59,7 +59,7 @@ module Unicorn
|
|
59
59
|
REQUEST_URI='REQUEST_URI'.freeze
|
60
60
|
REQUEST_PATH='REQUEST_PATH'.freeze
|
61
61
|
|
62
|
-
UNICORN_VERSION="0.7.
|
62
|
+
UNICORN_VERSION="0.7.1".freeze
|
63
63
|
|
64
64
|
DEFAULT_HOST = "0.0.0.0".freeze # default TCP listen host address
|
65
65
|
DEFAULT_PORT = "8080".freeze # default TCP listen port
|
@@ -31,7 +31,7 @@ module Unicorn
|
|
31
31
|
# writes the rack_response to socket as an HTTP response
|
32
32
|
def self.write(socket, rack_response)
|
33
33
|
status, headers, body = rack_response
|
34
|
-
status = HTTP_STATUS_CODES[status]
|
34
|
+
status = HTTP_STATUS_CODES[status.to_i]
|
35
35
|
OUT.clear
|
36
36
|
|
37
37
|
# Don't bother enforcing duplicate supression, it's a Hash most of
|
data/lib/unicorn/util.rb
CHANGED
@@ -4,6 +4,8 @@ module Unicorn
|
|
4
4
|
class Util
|
5
5
|
class << self
|
6
6
|
|
7
|
+
APPEND_FLAGS = File::WRONLY | File::APPEND
|
8
|
+
|
7
9
|
# this reopens logs that have been rotated (using logrotate(8) or
|
8
10
|
# similar). It is recommended that you install
|
9
11
|
# A +File+ object is considered for reopening if it is:
|
@@ -17,17 +19,20 @@ module Unicorn
|
|
17
19
|
ObjectSpace.each_object(File) do |fp|
|
18
20
|
next if fp.closed?
|
19
21
|
next unless (fp.sync && fp.path[0..0] == "/")
|
20
|
-
|
21
|
-
flags = fp.fcntl(Fcntl::F_GETFL)
|
22
|
-
open_flags = File::WRONLY | File::APPEND
|
23
|
-
next unless (flags & open_flags) == open_flags
|
22
|
+
next unless (fp.fcntl(Fcntl::F_GETFL) & APPEND_FLAGS) == APPEND_FLAGS
|
24
23
|
|
25
24
|
begin
|
26
25
|
a, b = fp.stat, File.stat(fp.path)
|
27
26
|
next if a.ino == b.ino && a.dev == b.dev
|
28
27
|
rescue Errno::ENOENT
|
29
28
|
end
|
30
|
-
|
29
|
+
|
30
|
+
open_arg = 'a'
|
31
|
+
if fp.respond_to?(:external_encoding) && enc = fp.external_encoding
|
32
|
+
open_arg << ":#{enc.to_s}"
|
33
|
+
enc = fp.internal_encoding and open_arg << ":#{enc.to_s}"
|
34
|
+
end
|
35
|
+
fp.reopen(fp.path, open_arg)
|
31
36
|
fp.sync = true
|
32
37
|
nr += 1
|
33
38
|
end # each_object
|
data/test/unit/test_request.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
# Copyright (c) 2009 Eric Wong
|
2
2
|
# You can redistribute it and/or modify it under the same terms as Ruby.
|
3
3
|
|
4
|
-
if RUBY_VERSION =~ /1\.9/
|
5
|
-
warn "#$0 current broken under Ruby 1.9 with Rack"
|
6
|
-
exit 0
|
7
|
-
end
|
8
|
-
|
9
4
|
require 'test/test_helper'
|
10
5
|
begin
|
11
6
|
require 'rack'
|
data/test/unit/test_response.rb
CHANGED
@@ -18,11 +18,19 @@ class ResponseTest < Test::Unit::TestCase
|
|
18
18
|
assert out.length > 0, "output didn't have data"
|
19
19
|
end
|
20
20
|
|
21
|
+
def test_response_string_status
|
22
|
+
out = StringIO.new
|
23
|
+
HttpResponse.write(out,['200', {}, []])
|
24
|
+
assert out.closed?
|
25
|
+
assert out.length > 0, "output didn't have data"
|
26
|
+
assert_equal 1, out.string.split(/\r\n/).grep(/^Status: 200 OK/).size
|
27
|
+
end
|
28
|
+
|
21
29
|
def test_response_OFS_set
|
22
30
|
old_ofs = $,
|
23
31
|
$, = "\f\v"
|
24
32
|
out = StringIO.new
|
25
|
-
HttpResponse.write(out,[200, {"X-
|
33
|
+
HttpResponse.write(out,[200, {"X-k" => "cd","X-y" => "z"}, ["cool"]])
|
26
34
|
assert out.closed?
|
27
35
|
resp = out.string
|
28
36
|
assert ! resp.include?("\f\v"), "output didn't use $, ($OFS)"
|
data/test/unit/test_upload.rb
CHANGED
@@ -19,12 +19,28 @@ class UploadTest < Test::Unit::TestCase
|
|
19
19
|
@sha1_app = lambda do |env|
|
20
20
|
input = env['rack.input']
|
21
21
|
resp = { :pos => input.pos, :size => input.size, :class => input.class }
|
22
|
+
|
23
|
+
# sysread
|
22
24
|
@sha1.reset
|
23
25
|
begin
|
24
26
|
loop { @sha1.update(input.sysread(@bs)) }
|
25
27
|
rescue EOFError
|
26
28
|
end
|
27
29
|
resp[:sha1] = @sha1.hexdigest
|
30
|
+
|
31
|
+
# read
|
32
|
+
input.sysseek(0) if input.respond_to?(:sysseek)
|
33
|
+
input.rewind
|
34
|
+
@sha1.reset
|
35
|
+
loop {
|
36
|
+
buf = input.read(@bs) or break
|
37
|
+
@sha1.update(buf)
|
38
|
+
}
|
39
|
+
|
40
|
+
if resp[:sha1] == @sha1.hexdigest
|
41
|
+
resp[:sysread_read_byte_match] = true
|
42
|
+
end
|
43
|
+
|
28
44
|
[ 200, @hdr.merge({'X-Resp' => resp.inspect}), [] ]
|
29
45
|
end
|
30
46
|
end
|
@@ -218,6 +234,7 @@ class UploadTest < Test::Unit::TestCase
|
|
218
234
|
assert $?.success?, 'curl ran OK'
|
219
235
|
assert_match(%r!\b#{sha1}\b!, resp)
|
220
236
|
assert_match(/Tempfile/, resp)
|
237
|
+
assert_match(/sysread_read_byte_match/, resp)
|
221
238
|
|
222
239
|
# small StringIO path
|
223
240
|
assert(system("dd", "if=#{@random.path}", "of=#{tmp.path}",
|
@@ -233,6 +250,7 @@ class UploadTest < Test::Unit::TestCase
|
|
233
250
|
assert $?.success?, 'curl ran OK'
|
234
251
|
assert_match(%r!\b#{sha1}\b!, resp)
|
235
252
|
assert_match(/StringIO/, resp)
|
253
|
+
assert_match(/sysread_read_byte_match/, resp)
|
236
254
|
end
|
237
255
|
|
238
256
|
private
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
class TestUtil < Test::Unit::TestCase
|
5
|
+
|
6
|
+
EXPECT_FLAGS = File::WRONLY | File::APPEND
|
7
|
+
def test_reopen_logs_noop
|
8
|
+
tmp = Tempfile.new(nil)
|
9
|
+
tmp.reopen(tmp.path, 'a')
|
10
|
+
tmp.sync = true
|
11
|
+
ext = tmp.external_encoding rescue nil
|
12
|
+
int = tmp.internal_encoding rescue nil
|
13
|
+
before = tmp.stat.inspect
|
14
|
+
Unicorn::Util.reopen_logs
|
15
|
+
assert_equal before, File.stat(tmp.path).inspect
|
16
|
+
assert_equal ext, (tmp.external_encoding rescue nil)
|
17
|
+
assert_equal int, (tmp.internal_encoding rescue nil)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_reopen_logs_renamed
|
21
|
+
tmp = Tempfile.new(nil)
|
22
|
+
tmp_path = tmp.path.freeze
|
23
|
+
tmp.reopen(tmp_path, 'a')
|
24
|
+
tmp.sync = true
|
25
|
+
ext = tmp.external_encoding rescue nil
|
26
|
+
int = tmp.internal_encoding rescue nil
|
27
|
+
before = tmp.stat.inspect
|
28
|
+
to = Tempfile.new(nil)
|
29
|
+
File.rename(tmp_path, to.path)
|
30
|
+
assert ! File.exist?(tmp_path)
|
31
|
+
Unicorn::Util.reopen_logs
|
32
|
+
assert_equal tmp_path, tmp.path
|
33
|
+
assert File.exist?(tmp_path)
|
34
|
+
assert before != File.stat(tmp_path).inspect
|
35
|
+
assert_equal tmp.stat.inspect, File.stat(tmp_path).inspect
|
36
|
+
assert_equal ext, (tmp.external_encoding rescue nil)
|
37
|
+
assert_equal int, (tmp.internal_encoding rescue nil)
|
38
|
+
assert_equal(EXPECT_FLAGS, EXPECT_FLAGS & tmp.fcntl(Fcntl::F_GETFL))
|
39
|
+
assert tmp.sync
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_reopen_logs_renamed_with_encoding
|
43
|
+
tmp = Tempfile.new(nil)
|
44
|
+
tmp_path = tmp.path.dup.freeze
|
45
|
+
Encoding.list.each { |encoding|
|
46
|
+
tmp.reopen(tmp_path, "a:#{encoding.to_s}")
|
47
|
+
tmp.sync = true
|
48
|
+
assert_equal encoding, tmp.external_encoding
|
49
|
+
assert_nil tmp.internal_encoding
|
50
|
+
File.unlink(tmp_path)
|
51
|
+
assert ! File.exist?(tmp_path)
|
52
|
+
Unicorn::Util.reopen_logs
|
53
|
+
assert_equal tmp_path, tmp.path
|
54
|
+
assert File.exist?(tmp_path)
|
55
|
+
assert_equal tmp.stat.inspect, File.stat(tmp_path).inspect
|
56
|
+
assert_equal encoding, tmp.external_encoding
|
57
|
+
assert_nil tmp.internal_encoding
|
58
|
+
assert_equal(EXPECT_FLAGS, EXPECT_FLAGS & tmp.fcntl(Fcntl::F_GETFL))
|
59
|
+
assert tmp.sync
|
60
|
+
}
|
61
|
+
end if STDIN.respond_to?(:external_encoding)
|
62
|
+
|
63
|
+
def test_reopen_logs_renamed_with_internal_encoding
|
64
|
+
tmp = Tempfile.new(nil)
|
65
|
+
tmp_path = tmp.path.dup.freeze
|
66
|
+
Encoding.list.each { |ext|
|
67
|
+
Encoding.list.each { |int|
|
68
|
+
next if ext == int
|
69
|
+
tmp.reopen(tmp_path, "a:#{ext.to_s}:#{int.to_s}")
|
70
|
+
tmp.sync = true
|
71
|
+
assert_equal ext, tmp.external_encoding
|
72
|
+
assert_equal int, tmp.internal_encoding
|
73
|
+
File.unlink(tmp_path)
|
74
|
+
assert ! File.exist?(tmp_path)
|
75
|
+
Unicorn::Util.reopen_logs
|
76
|
+
assert_equal tmp_path, tmp.path
|
77
|
+
assert File.exist?(tmp_path)
|
78
|
+
assert_equal tmp.stat.inspect, File.stat(tmp_path).inspect
|
79
|
+
assert_equal ext, tmp.external_encoding
|
80
|
+
assert_equal int, tmp.internal_encoding
|
81
|
+
assert_equal(EXPECT_FLAGS, EXPECT_FLAGS & tmp.fcntl(Fcntl::F_GETFL))
|
82
|
+
assert tmp.sync
|
83
|
+
}
|
84
|
+
}
|
85
|
+
end if STDIN.respond_to?(:external_encoding)
|
86
|
+
|
87
|
+
end
|
data/unicorn.gemspec
CHANGED
@@ -2,29 +2,29 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{unicorn}
|
5
|
-
s.version = "0.7.
|
5
|
+
s.version = "0.7.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Eric Wong"]
|
9
|
-
s.date = %q{2009-
|
9
|
+
s.date = %q{2009-05-22}
|
10
10
|
s.description = %q{A small fast HTTP library and server for Rack applications.}
|
11
11
|
s.email = %q{normalperson@yhbt.net}
|
12
12
|
s.executables = ["unicorn", "unicorn_rails"]
|
13
13
|
s.extensions = ["ext/unicorn/http11/extconf.rb"]
|
14
14
|
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "TODO", "bin/unicorn", "bin/unicorn_rails", "ext/unicorn/http11/ext_help.h", "ext/unicorn/http11/extconf.rb", "ext/unicorn/http11/http11.c", "ext/unicorn/http11/http11_parser.h", "ext/unicorn/http11/http11_parser.rl", "ext/unicorn/http11/http11_parser_common.rl", "lib/unicorn.rb", "lib/unicorn/app/exec_cgi.rb", "lib/unicorn/app/old_rails.rb", "lib/unicorn/app/old_rails/static.rb", "lib/unicorn/cgi_wrapper.rb", "lib/unicorn/configurator.rb", "lib/unicorn/const.rb", "lib/unicorn/http_request.rb", "lib/unicorn/http_response.rb", "lib/unicorn/launcher.rb", "lib/unicorn/socket_helper.rb", "lib/unicorn/util.rb"]
|
15
|
-
s.files = [".document", ".gitignore", "CHANGELOG", "CONTRIBUTORS", "DESIGN", "GNUmakefile", "LICENSE", "Manifest", "PHILOSOPHY", "README", "Rakefile", "SIGNALS", "TODO", "bin/unicorn", "bin/unicorn_rails", "ext/unicorn/http11/ext_help.h", "ext/unicorn/http11/extconf.rb", "ext/unicorn/http11/http11.c", "ext/unicorn/http11/http11_parser.h", "ext/unicorn/http11/http11_parser.rl", "ext/unicorn/http11/http11_parser_common.rl", "lib/unicorn.rb", "lib/unicorn/app/exec_cgi.rb", "lib/unicorn/app/old_rails.rb", "lib/unicorn/app/old_rails/static.rb", "lib/unicorn/cgi_wrapper.rb", "lib/unicorn/configurator.rb", "lib/unicorn/const.rb", "lib/unicorn/http_request.rb", "lib/unicorn/http_response.rb", "lib/unicorn/launcher.rb", "lib/unicorn/socket_helper.rb", "lib/unicorn/util.rb", "local.mk.sample", "setup.rb", "test/aggregate.rb", "test/benchmark/README", "test/benchmark/big_request.rb", "test/benchmark/dd.ru", "test/benchmark/request.rb", "test/benchmark/response.rb", "test/exec/README", "test/exec/test_exec.rb", "test/rails/app-1.2.3/.gitignore", "test/rails/app-1.2.3/Rakefile", "test/rails/app-1.2.3/app/controllers/application.rb", "test/rails/app-1.2.3/app/controllers/foo_controller.rb", "test/rails/app-1.2.3/app/helpers/application_helper.rb", "test/rails/app-1.2.3/config/boot.rb", "test/rails/app-1.2.3/config/database.yml", "test/rails/app-1.2.3/config/environment.rb", "test/rails/app-1.2.3/config/environments/development.rb", "test/rails/app-1.2.3/config/environments/production.rb", "test/rails/app-1.2.3/config/routes.rb", "test/rails/app-1.2.3/db/.gitignore", "test/rails/app-1.2.3/log/.gitignore", "test/rails/app-1.2.3/public/404.html", "test/rails/app-1.2.3/public/500.html", "test/rails/app-2.0.2/.gitignore", "test/rails/app-2.0.2/Rakefile", "test/rails/app-2.0.2/app/controllers/application.rb", "test/rails/app-2.0.2/app/controllers/foo_controller.rb", "test/rails/app-2.0.2/app/helpers/application_helper.rb", "test/rails/app-2.0.2/config/boot.rb", "test/rails/app-2.0.2/config/database.yml", "test/rails/app-2.0.2/config/environment.rb", "test/rails/app-2.0.2/config/environments/development.rb", "test/rails/app-2.0.2/config/environments/production.rb", "test/rails/app-2.0.2/config/routes.rb", "test/rails/app-2.0.2/db/.gitignore", "test/rails/app-2.0.2/log/.gitignore", "test/rails/app-2.0.2/public/404.html", "test/rails/app-2.0.2/public/500.html", "test/rails/app-2.1.2/.gitignore", "test/rails/app-2.1.2/Rakefile", "test/rails/app-2.1.2/app/controllers/application.rb", "test/rails/app-2.1.2/app/controllers/foo_controller.rb", "test/rails/app-2.1.2/app/helpers/application_helper.rb", "test/rails/app-2.1.2/config/boot.rb", "test/rails/app-2.1.2/config/database.yml", "test/rails/app-2.1.2/config/environment.rb", "test/rails/app-2.1.2/config/environments/development.rb", "test/rails/app-2.1.2/config/environments/production.rb", "test/rails/app-2.1.2/config/routes.rb", "test/rails/app-2.1.2/db/.gitignore", "test/rails/app-2.1.2/log/.gitignore", "test/rails/app-2.1.2/public/404.html", "test/rails/app-2.1.2/public/500.html", "test/rails/app-2.2.2/.gitignore", "test/rails/app-2.2.2/Rakefile", "test/rails/app-2.2.2/app/controllers/application.rb", "test/rails/app-2.2.2/app/controllers/foo_controller.rb", "test/rails/app-2.2.2/app/helpers/application_helper.rb", "test/rails/app-2.2.2/config/boot.rb", "test/rails/app-2.2.2/config/database.yml", "test/rails/app-2.2.2/config/environment.rb", "test/rails/app-2.2.2/config/environments/development.rb", "test/rails/app-2.2.2/config/environments/production.rb", "test/rails/app-2.2.2/config/routes.rb", "test/rails/app-2.2.2/db/.gitignore", "test/rails/app-2.2.2/log/.gitignore", "test/rails/app-2.2.2/public/404.html", "test/rails/app-2.2.2/public/500.html", "test/rails/app-2.3.2.1/.gitignore", "test/rails/app-2.3.2.1/Rakefile", "test/rails/app-2.3.2.1/app/controllers/application_controller.rb", "test/rails/app-2.3.2.1/app/controllers/foo_controller.rb", "test/rails/app-2.3.2.1/app/helpers/application_helper.rb", "test/rails/app-2.3.2.1/config/boot.rb", "test/rails/app-2.3.2.1/config/database.yml", "test/rails/app-2.3.2.1/config/environment.rb", "test/rails/app-2.3.2.1/config/environments/development.rb", "test/rails/app-2.3.2.1/config/environments/production.rb", "test/rails/app-2.3.2.1/config/routes.rb", "test/rails/app-2.3.2.1/db/.gitignore", "test/rails/app-2.3.2.1/log/.gitignore", "test/rails/app-2.3.2.1/public/404.html", "test/rails/app-2.3.2.1/public/500.html", "test/rails/test_rails.rb", "test/test_helper.rb", "test/tools/trickletest.rb", "test/unit/test_configurator.rb", "test/unit/test_http_parser.rb", "test/unit/test_request.rb", "test/unit/test_response.rb", "test/unit/test_server.rb", "test/unit/test_signals.rb", "test/unit/test_socket_helper.rb", "test/unit/test_upload.rb", "unicorn.gemspec"]
|
15
|
+
s.files = [".document", ".gitignore", "CHANGELOG", "CONTRIBUTORS", "DESIGN", "GNUmakefile", "LICENSE", "Manifest", "PHILOSOPHY", "README", "Rakefile", "SIGNALS", "TODO", "TUNING", "bin/unicorn", "bin/unicorn_rails", "examples/init.sh", "ext/unicorn/http11/ext_help.h", "ext/unicorn/http11/extconf.rb", "ext/unicorn/http11/http11.c", "ext/unicorn/http11/http11_parser.h", "ext/unicorn/http11/http11_parser.rl", "ext/unicorn/http11/http11_parser_common.rl", "lib/unicorn.rb", "lib/unicorn/app/exec_cgi.rb", "lib/unicorn/app/old_rails.rb", "lib/unicorn/app/old_rails/static.rb", "lib/unicorn/cgi_wrapper.rb", "lib/unicorn/configurator.rb", "lib/unicorn/const.rb", "lib/unicorn/http_request.rb", "lib/unicorn/http_response.rb", "lib/unicorn/launcher.rb", "lib/unicorn/socket_helper.rb", "lib/unicorn/util.rb", "local.mk.sample", "setup.rb", "test/aggregate.rb", "test/benchmark/README", "test/benchmark/big_request.rb", "test/benchmark/dd.ru", "test/benchmark/request.rb", "test/benchmark/response.rb", "test/exec/README", "test/exec/test_exec.rb", "test/rails/app-1.2.3/.gitignore", "test/rails/app-1.2.3/Rakefile", "test/rails/app-1.2.3/app/controllers/application.rb", "test/rails/app-1.2.3/app/controllers/foo_controller.rb", "test/rails/app-1.2.3/app/helpers/application_helper.rb", "test/rails/app-1.2.3/config/boot.rb", "test/rails/app-1.2.3/config/database.yml", "test/rails/app-1.2.3/config/environment.rb", "test/rails/app-1.2.3/config/environments/development.rb", "test/rails/app-1.2.3/config/environments/production.rb", "test/rails/app-1.2.3/config/routes.rb", "test/rails/app-1.2.3/db/.gitignore", "test/rails/app-1.2.3/log/.gitignore", "test/rails/app-1.2.3/public/404.html", "test/rails/app-1.2.3/public/500.html", "test/rails/app-2.0.2/.gitignore", "test/rails/app-2.0.2/Rakefile", "test/rails/app-2.0.2/app/controllers/application.rb", "test/rails/app-2.0.2/app/controllers/foo_controller.rb", "test/rails/app-2.0.2/app/helpers/application_helper.rb", "test/rails/app-2.0.2/config/boot.rb", "test/rails/app-2.0.2/config/database.yml", "test/rails/app-2.0.2/config/environment.rb", "test/rails/app-2.0.2/config/environments/development.rb", "test/rails/app-2.0.2/config/environments/production.rb", "test/rails/app-2.0.2/config/routes.rb", "test/rails/app-2.0.2/db/.gitignore", "test/rails/app-2.0.2/log/.gitignore", "test/rails/app-2.0.2/public/404.html", "test/rails/app-2.0.2/public/500.html", "test/rails/app-2.1.2/.gitignore", "test/rails/app-2.1.2/Rakefile", "test/rails/app-2.1.2/app/controllers/application.rb", "test/rails/app-2.1.2/app/controllers/foo_controller.rb", "test/rails/app-2.1.2/app/helpers/application_helper.rb", "test/rails/app-2.1.2/config/boot.rb", "test/rails/app-2.1.2/config/database.yml", "test/rails/app-2.1.2/config/environment.rb", "test/rails/app-2.1.2/config/environments/development.rb", "test/rails/app-2.1.2/config/environments/production.rb", "test/rails/app-2.1.2/config/routes.rb", "test/rails/app-2.1.2/db/.gitignore", "test/rails/app-2.1.2/log/.gitignore", "test/rails/app-2.1.2/public/404.html", "test/rails/app-2.1.2/public/500.html", "test/rails/app-2.2.2/.gitignore", "test/rails/app-2.2.2/Rakefile", "test/rails/app-2.2.2/app/controllers/application.rb", "test/rails/app-2.2.2/app/controllers/foo_controller.rb", "test/rails/app-2.2.2/app/helpers/application_helper.rb", "test/rails/app-2.2.2/config/boot.rb", "test/rails/app-2.2.2/config/database.yml", "test/rails/app-2.2.2/config/environment.rb", "test/rails/app-2.2.2/config/environments/development.rb", "test/rails/app-2.2.2/config/environments/production.rb", "test/rails/app-2.2.2/config/routes.rb", "test/rails/app-2.2.2/db/.gitignore", "test/rails/app-2.2.2/log/.gitignore", "test/rails/app-2.2.2/public/404.html", "test/rails/app-2.2.2/public/500.html", "test/rails/app-2.3.2.1/.gitignore", "test/rails/app-2.3.2.1/Rakefile", "test/rails/app-2.3.2.1/app/controllers/application_controller.rb", "test/rails/app-2.3.2.1/app/controllers/foo_controller.rb", "test/rails/app-2.3.2.1/app/helpers/application_helper.rb", "test/rails/app-2.3.2.1/config/boot.rb", "test/rails/app-2.3.2.1/config/database.yml", "test/rails/app-2.3.2.1/config/environment.rb", "test/rails/app-2.3.2.1/config/environments/development.rb", "test/rails/app-2.3.2.1/config/environments/production.rb", "test/rails/app-2.3.2.1/config/routes.rb", "test/rails/app-2.3.2.1/db/.gitignore", "test/rails/app-2.3.2.1/log/.gitignore", "test/rails/app-2.3.2.1/public/404.html", "test/rails/app-2.3.2.1/public/500.html", "test/rails/test_rails.rb", "test/test_helper.rb", "test/tools/trickletest.rb", "test/unit/test_configurator.rb", "test/unit/test_http_parser.rb", "test/unit/test_request.rb", "test/unit/test_response.rb", "test/unit/test_server.rb", "test/unit/test_signals.rb", "test/unit/test_socket_helper.rb", "test/unit/test_upload.rb", "test/unit/test_util.rb", "unicorn.gemspec"]
|
16
16
|
s.has_rdoc = true
|
17
17
|
s.homepage = %q{http://unicorn.bogomips.org}
|
18
18
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Unicorn", "--main", "README"]
|
19
19
|
s.require_paths = ["lib", "ext"]
|
20
20
|
s.rubyforge_project = %q{unicorn}
|
21
|
-
s.rubygems_version = %q{1.3.
|
21
|
+
s.rubygems_version = %q{1.3.2}
|
22
22
|
s.summary = %q{A small fast HTTP library and server for Rack applications.}
|
23
|
-
s.test_files = ["test/unit/
|
23
|
+
s.test_files = ["test/unit/test_configurator.rb", "test/unit/test_response.rb", "test/unit/test_request.rb", "test/unit/test_signals.rb", "test/unit/test_upload.rb", "test/unit/test_http_parser.rb", "test/unit/test_socket_helper.rb", "test/unit/test_util.rb", "test/unit/test_server.rb"]
|
24
24
|
|
25
25
|
if s.respond_to? :specification_version then
|
26
26
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
27
|
-
s.specification_version =
|
27
|
+
s.specification_version = 3
|
28
28
|
|
29
29
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
30
30
|
else
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unicorn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Wong
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-22 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -59,8 +59,10 @@ files:
|
|
59
59
|
- Rakefile
|
60
60
|
- SIGNALS
|
61
61
|
- TODO
|
62
|
+
- TUNING
|
62
63
|
- bin/unicorn
|
63
64
|
- bin/unicorn_rails
|
65
|
+
- examples/init.sh
|
64
66
|
- ext/unicorn/http11/ext_help.h
|
65
67
|
- ext/unicorn/http11/extconf.rb
|
66
68
|
- ext/unicorn/http11/http11.c
|
@@ -175,9 +177,12 @@ files:
|
|
175
177
|
- test/unit/test_signals.rb
|
176
178
|
- test/unit/test_socket_helper.rb
|
177
179
|
- test/unit/test_upload.rb
|
180
|
+
- test/unit/test_util.rb
|
178
181
|
- unicorn.gemspec
|
179
182
|
has_rdoc: true
|
180
183
|
homepage: http://unicorn.bogomips.org
|
184
|
+
licenses: []
|
185
|
+
|
181
186
|
post_install_message:
|
182
187
|
rdoc_options:
|
183
188
|
- --line-numbers
|
@@ -204,16 +209,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
204
209
|
requirements: []
|
205
210
|
|
206
211
|
rubyforge_project: unicorn
|
207
|
-
rubygems_version: 1.3.
|
212
|
+
rubygems_version: 1.3.2
|
208
213
|
signing_key:
|
209
|
-
specification_version:
|
214
|
+
specification_version: 3
|
210
215
|
summary: A small fast HTTP library and server for Rack applications.
|
211
216
|
test_files:
|
212
|
-
- test/unit/test_request.rb
|
213
|
-
- test/unit/test_http_parser.rb
|
214
|
-
- test/unit/test_server.rb
|
215
|
-
- test/unit/test_response.rb
|
216
217
|
- test/unit/test_configurator.rb
|
217
|
-
- test/unit/
|
218
|
+
- test/unit/test_response.rb
|
219
|
+
- test/unit/test_request.rb
|
218
220
|
- test/unit/test_signals.rb
|
221
|
+
- test/unit/test_upload.rb
|
222
|
+
- test/unit/test_http_parser.rb
|
219
223
|
- test/unit/test_socket_helper.rb
|
224
|
+
- test/unit/test_util.rb
|
225
|
+
- test/unit/test_server.rb
|