unicorn 1.0.0 → 1.0.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/GIT-VERSION-GEN CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v1.0.0.GIT
4
+ DEF_VER=v1.0.1.GIT
5
5
 
6
6
  LF='
7
7
  '
data/lib/unicorn.rb CHANGED
@@ -312,6 +312,11 @@ module Unicorn
312
312
  if path
313
313
  if x = valid_pid?(path)
314
314
  return path if pid && path == pid && x == $$
315
+ if x == reexec_pid && pid =~ /\.oldbin\z/
316
+ logger.warn("will not set pid=#{path} while reexec-ed "\
317
+ "child is running PID:#{x}")
318
+ return
319
+ end
315
320
  raise ArgumentError, "Already running on PID:#{x} " \
316
321
  "(or pid=#{path} is stale)"
317
322
  end
data/lib/unicorn/const.rb CHANGED
@@ -8,8 +8,8 @@ module Unicorn
8
8
  # Symbols did not really improve things much compared to constants.
9
9
  module Const
10
10
 
11
- # The current version of Unicorn, currently 1.0.0
12
- UNICORN_VERSION="1.0.0"
11
+ # The current version of Unicorn, currently 1.0.1
12
+ UNICORN_VERSION="1.0.1"
13
13
 
14
14
  DEFAULT_HOST = "0.0.0.0" # default TCP listen host address
15
15
  DEFAULT_PORT = 8080 # default TCP listen port
@@ -24,11 +24,7 @@ module Unicorn::Launcher
24
24
 
25
25
  # We only start a new process group if we're not being reexecuted
26
26
  # and inheriting file descriptors from our parent
27
- if ENV['UNICORN_FD']
28
- exit if fork
29
- Process.setsid
30
- exit if fork
31
- else
27
+ unless ENV['UNICORN_FD']
32
28
  # grandparent - reads pipe, exits when master is ready
33
29
  # \_ parent - exits immediately ASAP
34
30
  # \_ unicorn master - writes to pipe when ready
@@ -109,7 +109,7 @@ module Unicorn
109
109
  # unlike IO#gets.
110
110
  def gets
111
111
  socket or return tmp.gets
112
- nil == $/ and return read
112
+ sep = $/ or return read
113
113
 
114
114
  orig_size = tmp.size
115
115
  if tmp.pos == orig_size
@@ -117,8 +117,9 @@ module Unicorn
117
117
  tmp.seek(orig_size)
118
118
  end
119
119
 
120
+ sep_size = Rack::Utils.bytesize(sep)
120
121
  line = tmp.gets # cannot be nil here since size > pos
121
- $/ == line[-$/.size, $/.size] and return line
122
+ sep == line[-sep_size, sep_size] and return line
122
123
 
123
124
  # unlikely, if we got here, then tmp is at EOF
124
125
  begin
@@ -126,7 +127,7 @@ module Unicorn
126
127
  tee(Const::CHUNK_SIZE, buf2) or break
127
128
  tmp.seek(orig_size)
128
129
  line << tmp.gets
129
- $/ == line[-$/.size, $/.size] and return line
130
+ sep == line[-sep_size, sep_size] and return line
130
131
  # tmp is at EOF again here, retry the loop
131
132
  end while true
132
133
 
data/t/pid.ru ADDED
@@ -0,0 +1,3 @@
1
+ use Rack::ContentLength
2
+ use Rack::ContentType, "text/plain"
3
+ run lambda { |env| [ 200, {}, [ "#$$\n" ] ] }
@@ -0,0 +1,110 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 13 "backout of USR2 upgrade"
4
+
5
+ worker_wait_start () {
6
+ test xSTART = x"$(cat $fifo)"
7
+ unicorn_pid=$(cat $pid)
8
+ }
9
+
10
+ t_begin "setup and start" && {
11
+ unicorn_setup
12
+ rm -f $pid.oldbin
13
+
14
+ cat >> $unicorn_config <<EOF
15
+ after_fork do |server, worker|
16
+ # test script will block while reading from $fifo,
17
+ # so notify the script on the first worker we spawn
18
+ # by opening the FIFO
19
+ if worker.nr == 0
20
+ File.open("$fifo", "wb") { |fp| fp.syswrite "START" }
21
+ end
22
+ end
23
+ EOF
24
+ unicorn -D -c $unicorn_config pid.ru
25
+ worker_wait_start
26
+ orig_master_pid=$unicorn_pid
27
+ }
28
+
29
+ t_begin "read original worker pid" && {
30
+ orig_worker_pid=$(curl -sSf http://$listen/)
31
+ test -n "$orig_worker_pid" && kill -0 $orig_worker_pid
32
+ }
33
+
34
+ t_begin "upgrade to new master" && {
35
+ kill -USR2 $orig_master_pid
36
+ }
37
+
38
+ t_begin "kill old worker" && {
39
+ kill -WINCH $orig_master_pid
40
+ }
41
+
42
+ t_begin "wait for new worker to start" && {
43
+ worker_wait_start
44
+ test $unicorn_pid -ne $orig_master_pid
45
+ new_master_pid=$unicorn_pid
46
+ }
47
+
48
+ t_begin "old master pid is stashed in $pid.oldbin" && {
49
+ test -s "$pid.oldbin"
50
+ test $orig_master_pid -eq $(cat $pid.oldbin)
51
+ }
52
+
53
+ t_begin "ensure old worker is no longer running" && {
54
+ i=0
55
+ while kill -0 $orig_worker_pid 2>/dev/null
56
+ do
57
+ i=$(( $i + 1 ))
58
+ test $i -lt 600 || die "timed out"
59
+ sleep 1
60
+ done
61
+ }
62
+
63
+ t_begin "capture pid of new worker" && {
64
+ new_worker_pid=$(curl -sSf http://$listen/)
65
+ }
66
+
67
+ t_begin "reload old master process" && {
68
+ kill -HUP $orig_master_pid
69
+ worker_wait_start
70
+ }
71
+
72
+ t_begin "gracefully kill new master and ensure it dies" && {
73
+ kill -QUIT $new_master_pid
74
+ i=0
75
+ while kill -0 $new_worker_pid 2>/dev/null
76
+ do
77
+ i=$(( $i + 1 ))
78
+ test $i -lt 600 || die "timed out"
79
+ sleep 1
80
+ done
81
+ }
82
+
83
+ t_begin "ensure $pid.oldbin does not exist" && {
84
+ i=0
85
+ while test -s $pid.oldbin
86
+ do
87
+ i=$(( $i + 1 ))
88
+ test $i -lt 600 || die "timed out"
89
+ sleep 1
90
+ done
91
+ while ! test -s $pid
92
+ do
93
+ i=$(( $i + 1 ))
94
+ test $i -lt 600 || die "timed out"
95
+ sleep 1
96
+ done
97
+ }
98
+
99
+ t_begin "ensure $pid is correct" && {
100
+ cur_master_pid=$(cat $pid)
101
+ test $orig_master_pid -eq $cur_master_pid
102
+ }
103
+
104
+ t_begin "killing succeeds" && {
105
+ kill $orig_master_pid
106
+ }
107
+
108
+ dbgcat r_err
109
+
110
+ t_done
@@ -54,6 +54,20 @@ before_fork do |server, worker|
54
54
  end
55
55
  EOS
56
56
 
57
+ WORKING_DIRECTORY_CHECK_RU = <<-EOS
58
+ use Rack::ContentLength
59
+ run lambda { |env|
60
+ pwd = ENV['PWD']
61
+ a = ::File.stat(pwd)
62
+ b = ::File.stat(Dir.pwd)
63
+ if (a.ino == b.ino && a.dev == b.dev)
64
+ [ 200, { 'Content-Type' => 'text/plain' }, [ pwd ] ]
65
+ else
66
+ [ 404, { 'Content-Type' => 'text/plain' }, [] ]
67
+ end
68
+ }
69
+ EOS
70
+
57
71
  def setup
58
72
  @pwd = Dir.pwd
59
73
  @tmpfile = Tempfile.new('unicorn_exec_test')
@@ -87,10 +101,7 @@ end
87
101
  File.unlink(other.path)
88
102
  Dir.mkdir(other.path)
89
103
  File.open("config.ru", "wb") do |fp|
90
- fp.syswrite <<EOF
91
- use Rack::ContentLength
92
- run proc { |env| [ 200, { 'Content-Type' => 'text/plain' }, [ Dir.pwd ] ] }
93
- EOF
104
+ fp.syswrite WORKING_DIRECTORY_CHECK_RU
94
105
  end
95
106
  FileUtils.cp("config.ru", other.path + "/config.ru")
96
107
  Dir.chdir(@tmpdir)
@@ -138,10 +149,7 @@ EOF
138
149
  File.unlink(other.path)
139
150
  Dir.mkdir(other.path)
140
151
  File.open("config.ru", "wb") do |fp|
141
- fp.syswrite <<EOF
142
- use Rack::ContentLength
143
- run proc { |env| [ 200, { 'Content-Type' => 'text/plain' }, [ Dir.pwd ] ] }
144
- EOF
152
+ fp.syswrite WORKING_DIRECTORY_CHECK_RU
145
153
  end
146
154
  FileUtils.cp("config.ru", other.path + "/config.ru")
147
155
  tmp = Tempfile.new('unicorn.config')
@@ -177,10 +185,7 @@ EOF
177
185
  File.unlink(other.path)
178
186
  Dir.mkdir(other.path)
179
187
  File.open("config.ru", "wb") do |fp|
180
- fp.syswrite <<EOF
181
- use Rack::ContentLength
182
- run proc { |env| [ 200, { 'Content-Type' => 'text/plain' }, [ Dir.pwd ] ] }
183
- EOF
188
+ fp.syswrite WORKING_DIRECTORY_CHECK_RU
184
189
  end
185
190
  FileUtils.cp("config.ru", other.path + "/config.ru")
186
191
  system('mkfifo', "#{other.path}/fifo")
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unicorn
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 0
10
- version: 1.0.0
9
+ - 1
10
+ version: 1.0.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Unicorn hackers
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-17 00:00:00 +00:00
18
+ date: 2010-07-13 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -169,6 +169,7 @@ files:
169
169
  - t/bin/utee
170
170
  - t/env.ru
171
171
  - t/my-tap-lib.sh
172
+ - t/pid.ru
172
173
  - t/rails3-app/.gitignore
173
174
  - t/rails3-app/Gemfile
174
175
  - t/rails3-app/Rakefile
@@ -209,6 +210,7 @@ files:
209
210
  - t/t0006-reopen-logs.sh
210
211
  - t/t0006.ru
211
212
  - t/t0007-working_directory_no_embed_cli.sh
213
+ - t/t0008-back_out_of_upgrade.sh
212
214
  - t/t0300-rails3-basic.sh
213
215
  - t/t0301-rails3-missing-config-ru.sh
214
216
  - t/t0302-rails3-alt-working_directory.sh