unicorn 0.8.2 → 0.8.3

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