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 +2 -0
- data/Application_Timeouts +77 -0
- data/GIT-VERSION-GEN +1 -1
- data/lib/unicorn/const.rb +1 -1
- data/lib/unicorn/http_server.rb +7 -7
- data/test/test_helper.rb +0 -5
- metadata +7 -4
data/.document
CHANGED
@@ -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
data/lib/unicorn/const.rb
CHANGED
data/lib/unicorn/http_server.rb
CHANGED
@@ -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
|
-
|
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 =
|
450
|
+
tmp = @timeout - diff
|
452
451
|
if tmp >= 0
|
453
|
-
next_sleep
|
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 > #{
|
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:
|
4
|
+
hash: 57
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 4
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 4.1.
|
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-
|
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
|