unicorn 4.1.0 → 4.1.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 CHANGED
@@ -19,9 +19,11 @@ lib/unicorn/preread_input.rb
19
19
  lib/unicorn/stream_input.rb
20
20
  lib/unicorn/tee_input.rb
21
21
  lib/unicorn/util.rb
22
+ lib/unicorn/oob_gc.rb
22
23
  lib/unicorn/worker.rb
23
24
  unicorn_1
24
25
  unicorn_rails_1
25
26
  ISSUES
26
27
  Sandbox
27
28
  Links
29
+ Application_Timeouts
@@ -0,0 +1,77 @@
1
+ = Application Timeouts
2
+
3
+ This article focuses on _application_ setup for Rack applications, but
4
+ can be expanded to all applications that connect to external resources
5
+ and expect short response times.
6
+
7
+ This article is not specific to \Unicorn, but exists to discourage
8
+ the overuse of the built-in
9
+ {timeout}[link:Unicorn/Configurator.html#method-i-timeout] directive
10
+ in \Unicorn.
11
+
12
+ == ALL External Resources Are Considered Unreliable
13
+
14
+ Network reliability can _never_ be guaranteed. Network failures cannot
15
+ be detected reliably by the client (Rack application) in a reasonable
16
+ timeframe, not even on a LAN.
17
+
18
+ Thus, application authors must configure timeouts when interacting with
19
+ external resources.
20
+
21
+ Most database adapters allow configurable timeouts.
22
+
23
+ Net::HTTP and Net::SMTP in the Ruby standard library allow
24
+ configurable timeouts.
25
+
26
+ Even for things as fast as {memcached}[http://memcached.org/],
27
+ {dalli}[http://rubygems.org/gems/dalli],
28
+ {memcached}[http://rubygems.org/gems/memcached] and
29
+ {memcache-client}[http://rubygems.org/gems/memcache-client] RubyGems all
30
+ offer configurable timeouts.
31
+
32
+ Consult the relevant documentation for the libraries you use on
33
+ how to configure these timeouts.
34
+
35
+ == Rolling Your Own Socket Code
36
+
37
+ Use non-blocking I/O and IO.select with a timeout to wait on sockets.
38
+
39
+ == Timeout module in the Ruby standard library
40
+
41
+ Ruby offers a Timeout module in its standard library. It has several
42
+ caveats and is not always reliable:
43
+
44
+ * /Some/ Ruby C extensions are not interrupted/timed-out gracefully by
45
+ this module (report these bugs to extension authors, please) but
46
+ pure-Ruby components should be.
47
+
48
+ * Long-running tasks may run inside `ensure' clauses after timeout
49
+ fires, causing the timeout to be ineffective.
50
+
51
+ The Timeout module is a second-to-last-resort solution, timeouts using
52
+ IO.select (or similar) are more reliable. If you depend on libraries
53
+ that do not offer timeouts when connecting to external resources, kindly
54
+ ask those library authors to provide configurable timeouts.
55
+
56
+ === A Note About Filesystems
57
+
58
+ Most operations to regular files on POSIX filesystems are NOT
59
+ interruptable. Thus, the "timeout" module in the Ruby standard library
60
+ can not reliably timeout systems with massive amounts of iowait.
61
+
62
+ If your app relies on the filesystem, ensure all the data your
63
+ application works with is small enough to fit in the kernel page cache.
64
+ Otherwise increase the amount of physical memory you have to match, or
65
+ employ a fast, low-latency storage system (solid state).
66
+
67
+ Volumes mounted over NFS (and thus a potentially unreliable network)
68
+ must be mounted with timeouts and applications must be prepared to
69
+ handle network/server failures.
70
+
71
+ == The Last Line Of Defense
72
+
73
+ The {timeout}[link:Unicorn/Configurator.html#method-i-timeout] mechanism
74
+ in \Unicorn is an extreme solution that should be avoided whenever
75
+ possible. It will help catch bugs in your application where and when
76
+ your application forgets to use timeouts, but it is expensive as it
77
+ kills and respawns a worker process.
data/GIT-VERSION-GEN CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v4.1.0.GIT
4
+ DEF_VER=v4.1.1.GIT
5
5
 
6
6
  LF='
7
7
  '
data/lib/unicorn/const.rb CHANGED
@@ -8,7 +8,7 @@
8
8
  # improve things much compared to constants.
9
9
  module Unicorn::Const
10
10
 
11
- UNICORN_VERSION = "4.1.0"
11
+ UNICORN_VERSION = "4.1.1"
12
12
 
13
13
  # default TCP listen host address (0.0.0.0, all interfaces)
14
14
  DEFAULT_HOST = "0.0.0.0"
@@ -264,8 +264,8 @@ class Unicorn::HttpServer
264
264
  if (last_check + @timeout) >= (last_check = Time.now)
265
265
  sleep_time = murder_lazy_workers
266
266
  else
267
- # wait for workers to wakeup on suspend
268
267
  sleep_time = @timeout/2.0 + 1
268
+ @logger.debug("waiting #{sleep_time}s after suspend/hibernation")
269
269
  end
270
270
  maintain_worker_count if respawn
271
271
  master_sleep(sleep_time)
@@ -441,23 +441,23 @@ class Unicorn::HttpServer
441
441
 
442
442
  # forcibly terminate all workers that haven't checked in in timeout seconds. The timeout is implemented using an unlinked File
443
443
  def murder_lazy_workers
444
- t = @timeout
445
- next_sleep = 1
444
+ next_sleep = @timeout - 1
446
445
  now = Time.now.to_i
447
446
  WORKERS.dup.each_pair do |wpid, worker|
448
447
  tick = worker.tick
449
448
  0 == tick and next # skip workers that are sleeping
450
449
  diff = now - tick
451
- tmp = t - diff
450
+ tmp = @timeout - diff
452
451
  if tmp >= 0
453
- next_sleep < tmp and next_sleep = tmp
452
+ next_sleep > tmp and next_sleep = tmp
454
453
  next
455
454
  end
455
+ next_sleep = 0
456
456
  logger.error "worker=#{worker.nr} PID:#{wpid} timeout " \
457
- "(#{diff}s > #{t}s), killing"
457
+ "(#{diff}s > #{@timeout}s), killing"
458
458
  kill_worker(:KILL, wpid) # take no prisoners for timeout violations
459
459
  end
460
- next_sleep
460
+ next_sleep <= 0 ? 1 : next_sleep
461
461
  end
462
462
 
463
463
  def after_fork_internal
data/test/test_helper.rb CHANGED
@@ -17,11 +17,6 @@ ENV['NO_PROXY'] ||= ENV['UNICORN_TEST_ADDR'] || '127.0.0.1'
17
17
  DEFAULT_TRIES = 1000
18
18
  DEFAULT_RES = 0.2
19
19
 
20
- HERE = File.dirname(__FILE__) unless defined?(HERE)
21
- %w(lib ext).each do |dir|
22
- $LOAD_PATH.unshift "#{HERE}/../#{dir}"
23
- end
24
-
25
20
  require 'test/unit'
26
21
  require 'net/http'
27
22
  require 'digest/sha1'
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: 59
4
+ hash: 57
5
5
  prerelease:
6
6
  segments:
7
7
  - 4
8
8
  - 1
9
- - 0
10
- version: 4.1.0
9
+ - 1
10
+ version: 4.1.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: 2011-08-20 00:00:00 Z
18
+ date: 2011-08-25 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rack
@@ -125,10 +125,12 @@ extra_rdoc_files:
125
125
  - lib/unicorn/stream_input.rb
126
126
  - lib/unicorn/tee_input.rb
127
127
  - lib/unicorn/util.rb
128
+ - lib/unicorn/oob_gc.rb
128
129
  - lib/unicorn/worker.rb
129
130
  - ISSUES
130
131
  - Sandbox
131
132
  - Links
133
+ - Application_Timeouts
132
134
  files:
133
135
  - .CHANGELOG.old
134
136
  - .document
@@ -136,6 +138,7 @@ files:
136
138
  - .mailmap
137
139
  - .manifest
138
140
  - .wrongdoc.yml
141
+ - Application_Timeouts
139
142
  - CONTRIBUTORS
140
143
  - COPYING
141
144
  - ChangeLog