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.
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
12 == ALL External Resources Are Considered Unreliable
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.
18 Thus, application authors must configure timeouts when interacting with
21 Most database adapters allow configurable timeouts.
23 Net::HTTP and Net::SMTP in the Ruby standard library allow
24 configurable timeouts.
26 Even for things as fast as {memcached}[https://memcached.org/],
27 {dalli}[https://rubygems.org/gems/dalli],
28 {memcached}[https://rubygems.org/gems/memcached] and
29 {memcache-client}[https://rubygems.org/gems/memcache-client] RubyGems all
30 offer configurable timeouts.
32 Consult the relevant documentation for the libraries you use on
33 how to configure these timeouts.
35 == Rolling Your Own Socket Code
37 Use non-blocking I/O and IO.select with a timeout to wait on sockets.
39 == Timeout module in the Ruby standard library
41 Ruby offers a Timeout module in its standard library. It has several
42 caveats and is not always reliable:
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.
48 * Long-running tasks may run inside `ensure' clauses after timeout
49 fires, causing the timeout to be ineffective.
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.
56 === A Note About Filesystems
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.
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).
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.
71 == The Last Line Of Defense
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.