unicorn 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,4 @@
1
+ v0.8.3 - Ruby 1.9.2 preview1 compatibility
1
2
  v0.8.2 - socket handling bugfixes and usability tweaks
2
3
  v0.8.1 - safer timeout handling, more consistent reload behavior
3
4
  v0.8.0 - enforce Rack dependency, minor performance improvements and fixes
data/GNUmakefile CHANGED
@@ -48,7 +48,7 @@ http11: lib/unicorn/http11.$(DLEXT)
48
48
 
49
49
  $(test_prefix)/.stamp: $(inst_deps)
50
50
  mkdir -p $(test_prefix)/.ccache
51
- tar c bin ext lib GNUmakefile Manifest | (cd $(test_prefix) && tar x)
51
+ tar c `cat Manifest` | (cd $(test_prefix) && tar x)
52
52
  $(MAKE) -C $(test_prefix) clean
53
53
  $(MAKE) -C $(test_prefix) http11 shebang
54
54
  > $@
@@ -88,14 +88,14 @@ run_test = $(quiet_pre) setsid $(ruby) -w $(arg) $(TEST_OPTS) $(quiet_post) || \
88
88
  %.n: arg = $(subst .n,,$(subst --, -n ,$@))
89
89
  %.n: t = $(subst .n,$(log_suffix),$@)
90
90
  %.n: export PATH := $(test_prefix)/bin:$(PATH)
91
- %.n: export RUBYLIB := $(test_prefix)/lib:$(RUBYLIB)
91
+ %.n: export RUBYLIB := $(test_prefix):$(test_prefix)/lib:$(RUBYLIB)
92
92
  %.n: $(test_prefix)/.stamp
93
93
  $(run_test)
94
94
 
95
95
  $(T): arg = $@
96
96
  $(T): t = $(subst .rb,$(log_suffix),$@)
97
97
  $(T): export PATH := $(test_prefix)/bin:$(PATH)
98
- $(T): export RUBYLIB := $(test_prefix)/lib:$(RUBYLIB)
98
+ $(T): export RUBYLIB := $(test_prefix):$(test_prefix)/lib:$(RUBYLIB)
99
99
  $(T): $(test_prefix)/.stamp
100
100
  $(run_test)
101
101
 
@@ -141,7 +141,7 @@ $(T_r).%.r: rv = $(subst .r,,$(subst $(T_r).,,$@))
141
141
  $(T_r).%.r: extra = ' 'v$(rv)
142
142
  $(T_r).%.r: arg = $(T_r)
143
143
  $(T_r).%.r: export PATH := $(test_prefix)/bin:$(PATH)
144
- $(T_r).%.r: export RUBYLIB := $(test_prefix)/lib:$(RUBYLIB)
144
+ $(T_r).%.r: export RUBYLIB := $(test_prefix):$(test_prefix)/lib:$(RUBYLIB)
145
145
  $(T_r).%.r: export UNICORN_RAILS_TEST_VERSION = $(rv)
146
146
  $(T_r).%.r: export RAILS_GIT_REPO = $(CURDIR)/$(rails_git)
147
147
  $(T_r).%.r: $(test_prefix)/.stamp $(rails_git)/info/cloned-stamp
data/lib/unicorn.rb CHANGED
@@ -54,8 +54,7 @@ module Unicorn
54
54
  0 => $0.dup,
55
55
  }
56
56
 
57
- Worker = Struct.new(:nr, :tempfile) unless defined?(Worker)
58
- class Worker
57
+ class Worker < Struct.new(:nr, :tmp)
59
58
  # worker objects may be compared to just plain numbers
60
59
  def ==(other_nr)
61
60
  self.nr == other_nr
@@ -323,7 +322,7 @@ module Unicorn
323
322
  self.pid = @pid.chomp('.oldbin') if @pid
324
323
  proc_name 'master'
325
324
  else
326
- worker = WORKERS.delete(pid) and worker.tempfile.close rescue nil
325
+ worker = WORKERS.delete(pid) and worker.tmp.close rescue nil
327
326
  logger.info "reaped #{status.inspect} " \
328
327
  "worker=#{worker.nr rescue 'unknown'}"
329
328
  end
@@ -383,16 +382,16 @@ module Unicorn
383
382
  end
384
383
 
385
384
  # forcibly terminate all workers that haven't checked in in @timeout
386
- # seconds. The timeout is implemented using an unlinked tempfile
385
+ # seconds. The timeout is implemented using an unlinked File
387
386
  # shared between the parent process and each worker. The worker
388
- # runs File#chmod to modify the ctime of the tempfile. If the ctime
387
+ # runs File#chmod to modify the ctime of the File. If the ctime
389
388
  # is stale for >@timeout seconds, then we'll kill the corresponding
390
389
  # worker.
391
390
  def murder_lazy_workers
392
391
  diff = stat = nil
393
392
  WORKERS.dup.each_pair do |pid, worker|
394
393
  stat = begin
395
- worker.tempfile.stat
394
+ worker.tmp.stat
396
395
  rescue => e
397
396
  logger.warn "worker=#{worker.nr} PID:#{pid} stat error: #{e.inspect}"
398
397
  kill_worker(:QUIT, pid)
@@ -416,9 +415,7 @@ module Unicorn
416
415
  SIG_QUEUE << :QUIT # forcibly emulate SIGQUIT
417
416
  return
418
417
  end
419
- tempfile = Tempfile.new(nil) # as short as possible to save dir space
420
- tempfile.unlink # don't allow other processes to find or see it
421
- worker = Worker.new(worker_nr, tempfile)
418
+ worker = Worker.new(worker_nr, Unicorn::Util.tmpio)
422
419
  @before_fork.call(self, worker)
423
420
  pid = fork { worker_loop(worker) }
424
421
  WORKERS[pid] = worker
@@ -466,10 +463,10 @@ module Unicorn
466
463
  proc_name "worker[#{worker.nr}]"
467
464
  START_CTX.clear
468
465
  init_self_pipe!
469
- WORKERS.values.each { |other| other.tempfile.close! rescue nil }
466
+ WORKERS.values.each { |other| other.tmp.close rescue nil }
470
467
  WORKERS.clear
471
468
  LISTENERS.each { |sock| sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) }
472
- worker.tempfile.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
469
+ worker.tmp.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
473
470
  @after_fork.call(self, worker) # can drop perms
474
471
  @timeout /= 2.0 # halve it for select()
475
472
  build_app! unless @preload_app
@@ -489,7 +486,7 @@ module Unicorn
489
486
  master_pid = Process.ppid # slightly racy, but less memory usage
490
487
  init_worker_process(worker)
491
488
  nr = 0 # this becomes negative if we need to reopen logs
492
- alive = worker.tempfile # tempfile is our lifeline to the master process
489
+ alive = worker.tmp # tmp is our lifeline to the master process
493
490
  ready = LISTENERS
494
491
  t = ti = 0
495
492
 
@@ -555,7 +552,7 @@ module Unicorn
555
552
  begin
556
553
  Process.kill(signal, pid)
557
554
  rescue Errno::ESRCH
558
- worker = WORKERS.delete(pid) and worker.tempfile.close rescue nil
555
+ worker = WORKERS.delete(pid) and worker.tmp.close rescue nil
559
556
  end
560
557
  end
561
558
 
@@ -42,11 +42,8 @@ module Unicorn::App
42
42
 
43
43
  # Calls the app
44
44
  def call(env)
45
- out, err = Tempfile.new(''), Tempfile.new('')
46
- out.unlink
47
- err.unlink
45
+ out, err = Unicorn::Util.tmpio, Unicorn::Util.tmpio
48
46
  inp = force_file_input(env)
49
- inp.sync = out.sync = err.sync = true
50
47
  pid = fork { run_child(inp, out, err, env) }
51
48
  inp.close
52
49
  pid, status = Process.waitpid2(pid)
@@ -124,14 +121,12 @@ module Unicorn::App
124
121
  if inp.respond_to?(:fileno) && Integer === inp.fileno
125
122
  inp
126
123
  elsif inp.size == 0 # inp could be a StringIO or StringIO-like object
127
- ::File.open('/dev/null')
124
+ ::File.open('/dev/null', 'rb')
128
125
  else
129
- tmp = Tempfile.new('')
130
- tmp.unlink
131
- tmp.binmode
126
+ tmp = Unicorn::Util.tmpio
132
127
 
133
128
  # Rack::Lint::InputWrapper doesn't allow sysread :(
134
- buf = ''
129
+ buf = Unicorn::Z.dup
135
130
  while inp.read(CHUNK_SIZE, buf)
136
131
  tmp.syswrite(buf)
137
132
  end
data/lib/unicorn/const.rb CHANGED
@@ -5,7 +5,7 @@ module Unicorn
5
5
  # gave about a 3% to 10% performance improvement over using the strings directly.
6
6
  # Symbols did not really improve things much compared to constants.
7
7
  module Const
8
- UNICORN_VERSION="0.8.2".freeze
8
+ UNICORN_VERSION="0.8.3".freeze
9
9
 
10
10
  DEFAULT_HOST = "0.0.0.0".freeze # default TCP listen host address
11
11
  DEFAULT_PORT = "8080".freeze # default TCP listen port
data/lib/unicorn/util.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'fcntl'
2
+ require 'tmpdir'
2
3
 
3
4
  module Unicorn
4
5
  class Util
@@ -39,6 +40,22 @@ module Unicorn
39
40
  nr
40
41
  end
41
42
 
43
+ # creates and returns a new File object. The File is unlinked
44
+ # immediately, switched to binary mode, and userspace output
45
+ # buffering is disabled
46
+ def tmpio
47
+ fp = begin
48
+ File.open("#{Dir::tmpdir}/#{rand}",
49
+ File::RDWR|File::CREAT|File::EXCL, 0600)
50
+ rescue Errno::EEXIST
51
+ retry
52
+ end
53
+ File.unlink(fp.path)
54
+ fp.binmode
55
+ fp.sync = true
56
+ fp
57
+ end
58
+
42
59
  end
43
60
 
44
61
  end
@@ -43,20 +43,21 @@ class TestUtil < Test::Unit::TestCase
43
43
  tmp = Tempfile.new(nil)
44
44
  tmp_path = tmp.path.dup.freeze
45
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
46
+ File.open(tmp_path, "a:#{encoding.to_s}") { |fp|
47
+ fp.sync = true
48
+ assert_equal encoding, fp.external_encoding
49
+ assert_nil fp.internal_encoding
50
+ File.unlink(tmp_path)
51
+ assert ! File.exist?(tmp_path)
52
+ Unicorn::Util.reopen_logs
53
+ assert_equal tmp_path, fp.path
54
+ assert File.exist?(tmp_path)
55
+ assert_equal fp.stat.inspect, File.stat(tmp_path).inspect
56
+ assert_equal encoding, fp.external_encoding
57
+ assert_nil fp.internal_encoding
58
+ assert_equal(EXPECT_FLAGS, EXPECT_FLAGS & fp.fcntl(Fcntl::F_GETFL))
59
+ assert fp.sync
60
+ }
60
61
  }
61
62
  end if STDIN.respond_to?(:external_encoding)
62
63
 
@@ -66,20 +67,21 @@ class TestUtil < Test::Unit::TestCase
66
67
  Encoding.list.each { |ext|
67
68
  Encoding.list.each { |int|
68
69
  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
70
+ File.open(tmp_path, "a:#{ext.to_s}:#{int.to_s}") { |fp|
71
+ fp.sync = true
72
+ assert_equal ext, fp.external_encoding
73
+ assert_equal int, fp.internal_encoding
74
+ File.unlink(tmp_path)
75
+ assert ! File.exist?(tmp_path)
76
+ Unicorn::Util.reopen_logs
77
+ assert_equal tmp_path, fp.path
78
+ assert File.exist?(tmp_path)
79
+ assert_equal fp.stat.inspect, File.stat(tmp_path).inspect
80
+ assert_equal ext, fp.external_encoding
81
+ assert_equal int, fp.internal_encoding
82
+ assert_equal(EXPECT_FLAGS, EXPECT_FLAGS & fp.fcntl(Fcntl::F_GETFL))
83
+ assert fp.sync
84
+ }
83
85
  }
84
86
  }
85
87
  end if STDIN.respond_to?(:external_encoding)
data/unicorn.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{unicorn}
5
- s.version = "0.8.2"
5
+ s.version = "0.8.3"
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-07-09}
9
+ s.date = %q{2009-07-19}
10
10
  s.description = %q{Rack HTTP server for Unix, fast clients and nothing else}
11
11
  s.email = %q{normalperson@yhbt.net}
12
12
  s.executables = ["unicorn", "unicorn_rails"]
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.rubyforge_project = %q{unicorn}
20
20
  s.rubygems_version = %q{1.3.4}
21
21
  s.summary = %q{Rack HTTP server for Unix, fast clients and nothing else}
22
- 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"]
22
+ s.test_files = ["test/unit/test_request.rb", "test/unit/test_http_parser.rb", "test/unit/test_server.rb", "test/unit/test_response.rb", "test/unit/test_configurator.rb", "test/unit/test_util.rb", "test/unit/test_upload.rb", "test/unit/test_signals.rb", "test/unit/test_socket_helper.rb"]
23
23
 
24
24
  if s.respond_to? :specification_version then
25
25
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
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.8.2
4
+ version: 0.8.3
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-07-09 00:00:00 -07:00
12
+ date: 2009-07-19 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -222,12 +222,12 @@ signing_key:
222
222
  specification_version: 3
223
223
  summary: Rack HTTP server for Unix, fast clients and nothing else
224
224
  test_files:
225
- - test/unit/test_configurator.rb
226
- - test/unit/test_response.rb
227
225
  - test/unit/test_request.rb
228
- - test/unit/test_signals.rb
229
- - test/unit/test_upload.rb
230
226
  - test/unit/test_http_parser.rb
231
- - test/unit/test_socket_helper.rb
232
- - test/unit/test_util.rb
233
227
  - test/unit/test_server.rb
228
+ - test/unit/test_response.rb
229
+ - test/unit/test_configurator.rb
230
+ - test/unit/test_util.rb
231
+ - test/unit/test_upload.rb
232
+ - test/unit/test_signals.rb
233
+ - test/unit/test_socket_helper.rb