Skip to content

Commit 34b400c

Browse files
author
Eric Wong
committed
doc: add Application Timeouts document
Hopefully this leads to fewer worker processes being killed.
1 parent b781e5b commit 34b400c

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

.document

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ unicorn_rails_1
2626
ISSUES
2727
Sandbox
2828
Links
29+
Application_Timeouts

Application_Timeouts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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.

0 commit comments

Comments
 (0)